Low level keyboard Hook nie na wątku UI

0

Chcę stworzyć ładnie działającą bibliotekę umożliwiającą hooka na klawiaturę. Korzystam z metody SetWindowsHookEx i zauważyłem, że funkcja hookProc która ma być wywoływana w momencie wykrycia wciśnięcia przycisku nie wykona się gdy główny wątek aplikacji będzie akurat zajęty, np. jakimiś obliczeniami. Uznałem więc, że potrzebne jest stworzenie tego hooka tak, aby odpowiadał za niego osobny wątek. Jak to zrobić? Jest taka możliwość?

2

trzeba stworzyć wątek, który będzie miał własne okno z kolejką komunikatów (RegisterClass, CreateWindowEx, DestroyWindow, SetWindowLong + GWL_WNDPROC). Tutaj masz jak stworzyć okno z kolejką komunikatów http://www.lloydkinsella.net/index.php/2011/02/allocatehwnd-for-net/

2

Okno chyba nie jest potrzebne. Na pewno musi być, kolejka komunikatów. Aby takową utworzyć wywołaj funkcję PeekMessage (prawdopodobnie trzeba to zrobić jeszcze przed założeniem hook'a). Przekazywanie otrzymanych komunikatów do DefWindowProc powinno załatwić sprawę bez tworzenia okien.

Możesz sprawdzić takie coś, powinno działać:

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    /* ... */
}

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    MSG msg;

    /* tworzymy kolejkę komunikatów */
    PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);

    /* zakładamy hook */
    HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, NULL);
    if (hHook == NULL) return JAKIS_NUMER_BLEDU;

    /* przetwarzamy komunikaty */
    while (GetMessage(&msg, NULL, 0, 0))
    {
        DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
    }

    /* ściągamy hook */
    UnhookWindowsHookEx(hHook);

    return msg.wParam;
}

Aby zatrzymać taki wątek wyślij do niego komunikat WM_QUIT funkcją PostThreadMessage.

1 użytkowników online, w tym zalogowanych: 0, gości: 1