WH_KEYBOARD_LL и сообщения
От: NeoSap Россия  
Дата: 19.10.05 21:06
Оценка:
Доброго времени суток!
Рассматривается следующая ситуация: ставлю хук WH_KEYBOARD_LL на клавиатуру. Мой процесс ловит нажатия кнопок, вызывается нужная функция, но возникает вот какая проблема: как определить, в каком приложении была нажата эта кнопка? По идее(как пишет MSDN), ОС оповещат мой процесс путем постановки в очередь соответствующего сообщения. Можно ли как то определить источник сообщения и поможет ли это в решении задачи?
Re: WH_KEYBOARD_LL и сообщения
От: sjukov Украина  
Дата: 20.10.05 04:15
Оценка:
GetForegroundWindow

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), ОС оповещат мой процесс путем постановки в очередь соответствующего сообщения. Можно ли как то определить источник сообщения и поможет ли это в решении задачи?
Posted via RSDN NNTP Server 1.9
Re[2]: WH_KEYBOARD_LL и сообщения
От: NeoSap Россия  
Дата: 24.10.05 19:53
Оценка:
Здравствуйте, sjukov, Вы писали:


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;

    // переводим вирт. коды в символы ASCII
    int iCharsReturned = ToAscii(KeyInfo->vkCode,
                     KeyInfo->scanCode, // Scan-code
                     pKeyBoardState,
                     pRetKeys,Command==WM_SYSKEYDOWN);
    ...
}


С чем это может быть связано?
Re: WH_KEYBOARD_LL и сообщения
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 26.10.05 02:28
Оценка:
Hello NeoSap, you wrote:

> Рассматривается следующая ситуация: ставлю хук WH_KEYBOARD_LL на клавиатуру. Мой процесс ловит нажатия кнопок, вызывается нужная функция, но возникает вот какая проблема: как определить, в каком приложении была нажата эта кнопка? По идее(как пишет MSDN), ОС оповещат мой процесс путем постановки в очередь соответствующего сообщения.


Вы неправильно поняли то, что написано в МСДН. Совершенно непривильно. Там сказано, что хук СРАБАТЫВАЕТ перед постановкой сообщения в thread input queue.

--
Всего хорошего, Слава
ICQ: 197577902
Posted via RSDN NNTP Server 1.9
Re[2]: WH_KEYBOARD_LL и сообщения
От: NeoSap Россия  
Дата: 26.10.05 16:13
Оценка:
Здравствуйте, 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]

Ну да не в этом дело. Теперь сложность в том, что следующий код:

        
LogKey(WPARAM Command,PKBDLLHOOKSTRUCT KeyInfo, HWND fgHWND)        
{
 .....
        BYTE pKeyBoardState[256];
    WORD pRetKeys[3]={0,0,0};
        

    DWORD ThisThread = GetCurrentThreadId();
    DWORD ThatThread = GetWindowThreadProcessId(fgHWND,NULL);
    
    
    AttachThreadInput(ThisThread, ThatThread,TRUE);
    
        HKL KBLayout = GetKeyboardLayout(ThatThread);
    
    if (!GetKeyboardState(pKeyBoardState))
        return -1;

    AttachThreadInput(ThisThread, ThatThread,FALSE);

    // переводим вирт. коды в символы ASCII
    int iCharsReturned = ToAsciiEx(KeyInfo->vkCode,
                    KeyInfo->scanCode, // Scan-code
                    pKeyBoardState,
                    pRetKeys,0,KBLayout);
....
}

корректно обрабатывает нажатия кнопок и правильно переводит вирутальные коды в символы до тех пор, пока не переключаем раскладку и, не отпуская shift, вводим какую-нибудь кнопку — тогда этот символ преобразуется на выходе ToAsciiEx в какую-то аброкадабру. Как это можно исправить?
Re[3]: WH_KEYBOARD_LL и сообщения
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 27.10.05 03:13
Оценка:
Hello NeoSap, you wrote:

> корректно обрабатывает нажатия кнопок и правильно переводит вирутальные коды в символы до тех пор, пока не переключаем раскладку и, не отпуская shift, вводим какую-нибудь кнопку — тогда этот символ преобразуется на выходе ToAsciiEx в какую-то аброкадабру. Как это можно исправить?


Для начала введите проверки результатов АПИ функций + GetLastError.

--
Всего хорошего, Слава
ICQ: 197577902
Posted via RSDN NNTP Server 1.9
Re[3]: WH_KEYBOARD_LL и сообщения
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 27.10.05 03:13
Оценка:
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.

Syntax

LRESULT CALLBACK LowLevelKeyboardProc( int nCode,
WPARAM wParam,
LPARAM lParam
);
[/msdn]

--
Всего хорошего, Слава
ICQ: 197577902
Posted via RSDN NNTP Server 1.9
Re[4]: WH_KEYBOARD_LL и сообщения
От: NeoSap Россия  
Дата: 28.10.05 11:01
Оценка:
Здравствуйте, Slava Antonov, Вы писали:

SA>Где конкретно вы это откопали?


Откопал я это в той же статье, что и вы цитировали, только из раздела Remarks

По поводу кода — API работает без видимых ошибок(только вот результат их работы не всегда удовлетворительный)
Возможно, это происходит в силу того, что локали процесса, в котором работает пользователь, и процесса, в котором обрабатывается хук, различны(хотя я указываю, чтобы ToAsciiEx использовала локаль того треда). Либо сообщение о смене раскладки не "успевает" дойти до моего процесса прежде, чем я обработаю нажатую кнопку.... Вобщем, идей нет
Re[5]: WH_KEYBOARD_LL и сообщения
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 29.10.05 05:59
Оценка:
Hello NeoSap, you wrote:

> Возможно, это происходит в силу того, что локали процесса, в котором работает пользователь, и процесса, в котором обрабатывается хук, различны(хотя я указываю, чтобы ToAsciiEx использовала локаль того треда). Либо сообщение о смене раскладки не "успевает" дойти до моего процесса прежде, чем я обработаю нажатую кнопку.... Вобщем, идей нет


Попробовать писать в лог входные и возвращаемые данные (локаль, результаты и т.п.). Может дело тогда прояснится.

--
Всего хорошего, Слава
ICQ: 197577902
Posted via RSDN NNTP Server 1.9
Re[5]: WH_KEYBOARD_LL и сообщения
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 29.10.05 05:59
Оценка:
Hello NeoSap, you wrote:

> Возможно, это происходит в силу того, что локали процесса, в котором работает пользователь, и процесса, в котором обрабатывается хук, различны(хотя я указываю, чтобы ToAsciiEx использовала локаль того треда). Либо сообщение о смене раскладки не "успевает" дойти до моего процесса прежде, чем я обработаю нажатую кнопку.... Вобщем, идей нет


Попробовать писать в лог входные и возвращаемые данные (локаль, результаты и т.п.). Может дело тогда прояснится.

--
Всего хорошего, Слава
ICQ: 197577902
Posted via RSDN NNTP Server 1.9
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.