Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.11;
Скачать: CL | DM;

Вниз

Как эмулировать нажатие клавиш на клавиатуре для чужой программы   Найти похожие ветки 

 
ANB ©   (2005-05-04 18:04) [0]

Пытаюсь эмулировать нажатие клавиш для программ написанных на Magic (вряд ли кто слышал). Программы пишут наши проги, а исходников оболочки нет. Работает как интерпретатор. Столкнулся с проблемой : не могу эмулировать по человечески нажатие клавиш. Для делфовых приложений сделал через WM_KEYDOWN, WM_KEYUP и WM_CHAR. Все работает. А для Magic смог эмулировать только через keybd_event. Это плохо, так как при работе нельзя будет переключатся в другие программы.

Кто подскажет, куда рыть при разбирательстве ? Какими хитрым способом этот д..й Magic может обрабатывать сообщения клавиатуры ? Мышь он по человечески обрабатывает.

Я пробовал посылать WM_KEYDOWN, WM_KEYUP и WM_CHAR и главному окну и MDI Child и едитам - эффекта 0. Даже просто буквы и цифры не печатаются.


 
alpet ©   (2005-05-04 18:09) [1]

Может он просто не ловит сообщения, а использует функции типа Get(Async)KeyState. Попробуй внедрить библиотеку с клавирным хуком которая будет устанавливать нажатия клавиш с помощью функции SetKeyboardState (работает в пределах одного потока), в момент обработки сообщения WM_KEYDOWN.


 
ANB ©   (2005-05-05 09:24) [2]

Вот козлы. Ну никак сообщения не ест. Причем он их получает и выбирает из очереди, я это хуком вижу. И, похоже, полностью игнорит. А как определить момент, что он уже вытащил клавишу через GetKeyState и можно записывать следующую ?


 
alpet ©   (2005-05-05 10:06) [3]

ANB ©   (05.05.05 09:24) [2]
>А как определить момент, что он уже вытащил клавишу через GetKeyState и можно записывать следующую ?

Поставить API hook на эту функцию, а так же на GetKeyboardState и GetAsyncKeyState.


 
ANB ©   (2005-05-05 10:45) [4]

Мрак. Похоже, проще будет таки плюнуть на моргания и перейти на keybd_event. :((( Имхо, так проще будет и начальство уже добро дало.
А как нибудь проверить alpet ©   (04.05.05 18:09) [1] можно ?


 
alpet ©   (2005-05-05 10:50) [5]

>А как нибудь проверить alpet ©   (04.05.05 18:09) [1]  можно ?

В обработчике хука клавиатуры устанавливай состояние клавиш указанным способом. Если программа не будет реагировать - этот способ не подходит.


 
ANB ©   (2005-05-05 12:50) [6]

Ну, в обработчике хука клавиатуры у меня вряд ли что получится. Как я там разберу - надо или не надо жать кнопки. По моему WH_GETMESSAGE лучше проканает.
Я так и сделал - но, если я двигаю мышей или жму кнопки на клаве - все сообщения хук ловит. А если посылаю сообщение сам - нет. Причем не только мое, вообще никакие. Хендл, вроде правильный.


 
ANB ©   (2005-05-05 13:02) [7]

Хм. Хук WH_GETMESSAGE вообще не ловит мои сообщения . . .


 
alpet ©   (2005-05-05 14:09) [8]

Он ловит те что отправляются PostMessage и игнорирует сообщения проходящие мимо очереди (sended via SendMessage).

WH_GETMESSAGE
Installs a hook procedure that monitors messages posted to a message queue.
...
The system calls this function whenever the GetMessage or PeekMessage function has retrieved a message from an application message queue.


 
ANB ©   (2005-05-05 17:01) [9]

Я пока сделал через keybd_event и оставил старый вариант под параметром. Кажется, начинаю въезжать, в чем проблема. Например TOAD есть буквы, но сочетания (Shift+Ctrl+F, F1) съел только через keybd_event. Чего то я не досылаю . . . Мне тут один гуру подсказал, что проблема в акселераторах. Надо покопатся.


 
ANB ©   (2005-05-05 17:05) [10]

Left ест, Ctrl + Left - не ест. Никак. Пробовал и по отдельности кнопки нажимать - отпускать и все вместе - не работает.


 
ANB ©   (2005-05-05 17:12) [11]

В spy включил просмотр событий клавиатуры - приходят только KEYDOWN, KEYUP. Больше ничего.


 
xShadow ©   (2005-05-05 17:18) [12]

А если попробовать хук wh_JournalPlayback и вставлять сообщения в очередь?


 
alpet ©   (2005-05-05 20:29) [13]

WM_SYSKEYDOWN не приходит ?


 
ANB ©   (2005-05-06 08:59) [14]


> alpet ©   (05.05.05 20:29) [13]
не, не приходит.

> xShadow ©   (05.05.05 17:18) [12]
- wh_JournalPlayback  - чем он лучше keybd_event ?


 
xShadow ©   (2005-05-06 09:42) [15]


> - wh_JournalPlayback  - чем он лучше keybd_event ?

http://www.firststeps.ru/mfc/winapi/hook/r.php?11
http://www.rsdn.ru/article/baseserv/winhooks.xml#ELBA


 
xShadow ©   (2005-05-06 10:00) [16]

Пока установлен хук все остальные мышиные и клавиатурные события отдыхают. На http://delphiworld.narod.ru/ есть пример его правда нужно переделать малость


 
ANB ©   (2005-05-06 10:56) [17]

Э, мне не надо, чтобы они отдыхали. Своим то приложением я должен управлять. И другими, кроме тестируемого. Плюс для wh_JournalPlayback нужно спецом готовить записи . . . Хотя может это и выход. Можно сделать 2 ветки, одну нормальную, другую для "кривых" приложений через wh_JournalPlayback (если он поможет, но, чувствую, вряд ли)


 
ANB ©   (2005-05-06 11:01) [18]

Статью в RSDN я уже читал, когда надо было рекордер писать. Вообще то мне wh_JournalRecord не подошел - он для клавы окно не присылал. Мне то нужно управлять окнами конкретного процесса, который я сам и запускаю.


 
xShadow ©   (2005-05-06 11:57) [19]


> ANB ©   (06.05.05 11:01) [18]

Так ведь можно перед эмитацией переключиться на требуемое окно. По крайней мере делал так, для дубовых приложений.
Хотя в этом методе если большой минус, это отладка приложения в момент эмитации если, что не так будет и хук не снимется система подвиснет.


 
alpet ©   (2005-05-06 12:32) [20]

Насчет акселераторов: WM_HOTKEY проходит сообщение ?


 
ANB ©   (2005-05-06 12:39) [21]


> это отладка приложения в момент эмитации если
- во во. Я пока отлаживал рекордер - задрался. Хорошо, в DLL фильтров наставил, чтобы он на мою прогу не реагировал.


> WM_HOTKEY
- не приходили. А где можно покопать насчет акселераторов ? Может через них что получится. Тут мне наши высказали идею, что Magic все кнопки на акселераторы повесил, потому и не получается их иммитировать, как обычно.


 
alpet ©   (2005-05-06 13:31) [22]

>Тут мне наши высказали идею, что Magic все кнопки на акселераторы повесил, потому и не получается их иммитировать, как обычно.

Это было бы очень странно, даже не правильно. Он бы ловил нажатия всех клавиш в всех открытых окнах, что есть не порядок.

Тебе все же стоит сделать API hook и посмотреть пользуется ли он Get(Async)KeyState. Еще: если ты симулируешь нажатия с помощью WM_KEYDOWN (UP), внимательнее присмотрись к параметру lParam - в нем задаются дополнительные флажки.


 
ANB ©   (2005-05-06 14:35) [23]

Проверил я флажки. Все задано, и скэнкод и количество повторений. А Magic автоматически закрывает свои окна, если переходишь в другой режим. Если он юзает GetKeyState, то чем внедрятся, мне проще оставить keybd_event.


 
alpet ©   (2005-05-06 16:10) [24]

Что бы проверить, вызывается ли GetKeyState - не обязательно даже через API подключатся. Можно попробывать подключится к этому процессу отладчиком и поставить бряк. Срабатывание (или не срабатывание) его и поможет вывести процесс на чистую воду.


 
ANB ©   (2005-05-06 16:27) [25]

Да толку то. Ну выясню я, что юзает. Чтобы теперь подсунуть ему мои кнопки, мне все равно придется внедряться.


 
alpet ©   (2005-05-06 19:11) [26]

Может сработает SetKeyboardState вместе с AttachThreadInput ? В MSDN это впрочем не оговаривается.


 
ANB ©   (2005-05-11 15:34) [27]

Дамс. Без Digitmana не разобраться.


 
Digitman ©   (2005-05-11 15:45) [28]


> ANB ©   (11.05.05 15:34) [27]


странно это ...

это самое Magic - обычное Win32 GUI-приложение ?
тогда оно должно точно так же как и другие GUI-приложения реагировать сообщения клав.ввода


 
ANB ©   (2005-05-11 16:04) [29]


> Digitman ©   (11.05.05 15:45) [28]
- да вот черт его знает, обычное или нет. Работает на платформе Win32. Первые версии писались еще под Win 3.11 в 1992 году. Писали израильтяне. Исходников нет. Описания ядра нет. Только руководство по программированию.
Поисследовал, и что узнал :
- форму проги рисуют в дизайнтайме как в VS.
- палитра маленькая, только ограниченный набор компонентов, свои вставлять нельзя, есть возможность вставить OLE, но она не работает.
- при создании формы она выглядит просто как картинка (принцип Java), но, например, если на форме 5 эдитов, то для одного из них (который в фокусе) создается едит своего класса. Этот эдит - обычный WinControl с хэндлом и реагирует на все сообщения (мышь, замена текста, получение текста), кроме сообщений от клавиатуры.
- работает, есно, в режиме интерпретатора.


 
alpet ©   (2005-05-11 16:07) [30]

А у этого EDITa родная оконная процедура (в АП user32.dll)?


 
ANB ©   (2005-05-11 16:08) [31]


> alpet ©   (11.05.05 16:07) [30]
- узнать бы еще это . . . Может подскажешь как ????


 
Digitman ©   (2005-05-11 16:13) [32]


> Этот эдит - обычный WinControl с хэндлом и реагирует на
> все сообщения (мышь, замена текста, получение текста), кроме
> сообщений от клавиатуры


такого быть не может
ведь юзер как-то вводит текст в этот контрол ..

возьми spyxx.exe и проследи, какие сообщения получает конкретный интерисующий тебя эдит-контрол, будучи в фокусе, при клавиатурных событиях, инициируемых юзером


 
ANB ©   (2005-05-11 16:20) [33]

Смотрел :
WM_KEYDOWN, WM_KEYCHAR, EM_SETSEL, EM_REPLACESEL, WM_KEYUP
Остальные я или опознаны или связаны с фокусом и движением мыши.


 
Digitman ©   (2005-05-11 16:29) [34]


> ANB ©   (11.05.05 16:20) [33]


ну вот видишь !
интересующие тебя сообщения таки посылаются интересующему тебя контролу ...


 
alpet ©   (2005-05-11 16:30) [35]

ANB ©   (11.05.05 16:08) [31]

Эт просто - GetWindowLong (edit_hwnd, GWL_WNDPROC).
Я еще подумал что не вызывается TranslateMessage, и в таком случае не должны получатся WM_CHAR и WM_DEADCHAR, но тогда не работал бы и пользовательский ввод.


 
ANB ©   (2005-05-11 16:39) [36]


> Digitman ©   (11.05.05 16:29) [34]
- но если я сам их посылаю, то они полностью игнорятся. А EM_REPLACESEL я не могу посылать, так как вообще то мне нужно кнопки со стрелками иммитировать, и не для едита, а для грида, который вообще на форме картинкой лежит.


> alpet ©   (11.05.05 16:30) [35]
- надо попробовать. А с чем сравнить результат ?


 
alpet ©   (2005-05-11 16:43) [37]

ANB ©   (11.05.05 16:39) [36]
> - надо попробовать. А с чем сравнить результат ?

Обычно с адресом библиотеки user32.dll, в принципе и так будет ясно - если адрес в hex будет больше $71000000 скорее всего он принадлежит одной из dll Windows.


 
Digitman ©   (2005-05-11 16:47) [38]


> который вообще на форме картинкой лежит


значит, посылать соотв.сообщения нужно тому виз.окну, оконная ф-ция которого отвечает и за отрисовку грида и за пользовательский ввод


 
ANB ©   (2005-05-11 16:57) [39]

Да я уже всем окнам этого мэйджика в цикле эти сообщения отправлял. И главному и мди_клиенту и мди_чилду и всем кнопкам, всему, у чего хэндл нашел. Ноль эмоций. А на keybd_event реагирует. Причем, когда я спаем ловил сообщения, то он говорил, что сообщения послаются кнопке на форме (она класса Button и имеет хендл). Мне бы хотя бы чему нибудь и хоть одну клавишу запихать, чтобы сработало. Потом доделаю и остальное. Вот alpet дело говорит, но это я завтра смотреть буду.


 
ANB ©   (2005-05-12 09:35) [40]

Посмотрел спаем. Адрес оконной процедуры эдита - $00428D75. И что это может значить ?



Страницы: 1 2 вся ветка

Текущий архив: 2005.07.11;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.028 c
4-1115847544
NikNet
2005-05-12 01:39
2005.07.11
Как записать в реестр запрещенным администраторам?


11-1100453600
Slay
2004-11-14 20:33
2005.07.11
Вопрос про Drag&Drop в TreeView


1-1118732313
Dummes
2005-06-14 10:58
2005.07.11
Функции Overload.


1-1118653916
KeHra
2005-06-13 13:11
2005.07.11
MDI формы


1-1119358489
intaari
2005-06-21 16:54
2005.07.11
Прога не находит класс при старте программы