Доброго времени суток!
Рассматривается следующая ситуация: ставлю хук WH_KEYBOARD_LL на клавиатуру. Мой процесс ловит нажатия кнопок, вызывается нужная функция, но возникает вот какая проблема: как определить, в каком приложении была нажата эта кнопка? По идее(как пишет MSDN), ОС оповещат мой процесс путем постановки в очередь соответствующего сообщения. Можно ли как то определить источник сообщения и поможет ли это в решении задачи?
The GetForegroundWindow function returns a handle to the foreground window (the window with which the user is currently working).
The system assigns a slightly higher priority to the thread that creates the foreground window than it does to other threads.
HWND GetForegroundWindow(VOID);
Function Information
Minimum DLL Version user32.dll
Header Declared in Winuser.h, include Windows.h
Import library User32.lib
Minimum operating systems Windows 95, Windows NT 3.1
"NeoSap" <44763@users.rsdn.ru> сообщил/сообщила в новостях следующее: news:1445170@news.rsdn.ru... > Доброго времени суток! > Рассматривается следующая ситуация: ставлю хук WH_KEYBOARD_LL на клавиатуру. Мой процесс ловит нажатия кнопок, вызывается нужная функция, но возникает вот какая проблема: как определить, в каком приложении была нажата эта кнопка? По идее(как пишет MSDN), ОС оповещат мой процесс путем постановки в очередь соответствующего сообщения. Можно ли как то определить источник сообщения и поможет ли это в решении задачи?
S>GetForegroundWindow
S>The GetForegroundWindow function returns a handle to the foreground window (the window with which the user is currently working). S>The system assigns a slightly higher priority to the thread that creates the foreground window than it does to other threads.
S>HWND GetForegroundWindow(VOID);
S>Function Information
S>Minimum DLL Version user32.dll S>Header Declared in Winuser.h, include Windows.h S>Import library User32.lib S>Minimum operating systems Windows 95, Windows NT 3.1
Спасиб, это помогло...но только частично. Проблема в том, что при попытке вызова
int i = GetWindowModuleFileName(hWnd,buf,MAX_NAME);
либо вообще ничего не возвращается(i=0), либо в buf возвращается имя программы, установившей хук(когда как должно, по идее, возвращаться имя программы-владельца окна hWnd).
И еще 1 вопрос: перехватываемые в некоторых приложениях(таких, как Word, cmd.exe) коды клавиш неправильно расшифровываются(не учитывается текущая раскладка и нажатия SHIFT — то есть все символы трактуются как строчные латинские буквы ). Трансляция происходит следующим образом:
LogKey(WPARAM Command,PKBDLLHOOKSTRUCT KeyInfo)
{
...
if (!GetKeyboardState(pKeyBoardState))
return -1;
// переводим вирт. коды в символы ASCIIint iCharsReturned = ToAscii(KeyInfo->vkCode,
KeyInfo->scanCode, // Scan-code
pKeyBoardState,
pRetKeys,Command==WM_SYSKEYDOWN);
...
}
Hello NeoSap, you wrote:
> Рассматривается следующая ситуация: ставлю хук WH_KEYBOARD_LL на клавиатуру. Мой процесс ловит нажатия кнопок, вызывается нужная функция, но возникает вот какая проблема: как определить, в каком приложении была нажата эта кнопка? По идее(как пишет MSDN), ОС оповещат мой процесс путем постановки в очередь соответствующего сообщения.
Вы неправильно поняли то, что написано в МСДН. Совершенно непривильно. Там сказано, что хук СРАБАТЫВАЕТ перед постановкой сообщения в thread input queue.
Здравствуйте, Slava Antonov, Вы писали:
SA>Вы неправильно поняли то, что написано в МСДН. Совершенно непривильно. Там сказано, что хук СРАБАТЫВАЕТ перед постановкой сообщения в thread input queue.
SA>-- SA>Всего хорошего, Слава SA>ICQ: 197577902
Странно, как еще можно понять следующее:
[msdn] This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.
[/msdn]
Ну да не в этом дело. Теперь сложность в том, что следующий код:
корректно обрабатывает нажатия кнопок и правильно переводит вирутальные коды в символы до тех пор, пока не переключаем раскладку и, не отпуская shift, вводим какую-нибудь кнопку — тогда этот символ преобразуется на выходе ToAsciiEx в какую-то аброкадабру. Как это можно исправить?
Hello NeoSap, you wrote:
> корректно обрабатывает нажатия кнопок и правильно переводит вирутальные коды в символы до тех пор, пока не переключаем раскладку и, не отпуская shift, вводим какую-нибудь кнопку — тогда этот символ преобразуется на выходе ToAsciiEx в какую-то аброкадабру. Как это можно исправить?
Для начала введите проверки результатов АПИ функций + GetLastError.
Hello NeoSap, you wrote:
> Странно, как еще можно понять следующее: > [msdn] This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop. > [/msdn]
Где конкретно вы это откопали?
А то в моем MSDN 2005 вот что написано:
[msdn]
LowLevelKeyboardProc Function
The LowLevelKeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input was "injected". However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.
The HOOKPROC type defines a pointer to this callback function. LowLevelKeyboardProc is a placeholder for the application-defined or library-defined function name.
Здравствуйте, Slava Antonov, Вы писали:
SA>Где конкретно вы это откопали?
Откопал я это в той же статье, что и вы цитировали, только из раздела Remarks
По поводу кода — API работает без видимых ошибок(только вот результат их работы не всегда удовлетворительный)
Возможно, это происходит в силу того, что локали процесса, в котором работает пользователь, и процесса, в котором обрабатывается хук, различны(хотя я указываю, чтобы ToAsciiEx использовала локаль того треда). Либо сообщение о смене раскладки не "успевает" дойти до моего процесса прежде, чем я обработаю нажатую кнопку.... Вобщем, идей нет
Hello NeoSap, you wrote:
> Возможно, это происходит в силу того, что локали процесса, в котором работает пользователь, и процесса, в котором обрабатывается хук, различны(хотя я указываю, чтобы ToAsciiEx использовала локаль того треда). Либо сообщение о смене раскладки не "успевает" дойти до моего процесса прежде, чем я обработаю нажатую кнопку.... Вобщем, идей нет
Попробовать писать в лог входные и возвращаемые данные (локаль, результаты и т.п.). Может дело тогда прояснится.
Hello NeoSap, you wrote:
> Возможно, это происходит в силу того, что локали процесса, в котором работает пользователь, и процесса, в котором обрабатывается хук, различны(хотя я указываю, чтобы ToAsciiEx использовала локаль того треда). Либо сообщение о смене раскладки не "успевает" дойти до моего процесса прежде, чем я обработаю нажатую кнопку.... Вобщем, идей нет
Попробовать писать в лог входные и возвращаемые данные (локаль, результаты и т.п.). Может дело тогда прояснится.