簡體   English   中英

SetWindowsHookEx(WH_KEYBOARD)無法與線程ID一起使用

[英]SetWindowsHookEx(WH_KEYBOARD) not working with thread ID

我有一個由進程調用的dll,現在我想在dll中實現輸入檢查,以對應用程序中發生的某些輸入做出反應。

帶有KeyboardProc函數的SetWindowsHookEx()似乎是一種可能的解決方案,所以我實現了它。

這大致是dll中代碼的樣子:

static HHOOK hhk = NULL;
LRESULT CALLBACK keyboardProc(int code, WPARAM wParam, LPARAM lParam)
{  
    if(code == HC_ACTION && ((DWORD)lParam & 0x80000000) == 0)  // if there is an incoming action and a key was pressed
    {
       switch(wParam)
       {
       case VK_SPACE:
          printf("Space was pressed\n");
          break;
       }
    }
    return CallNextHookEx(hhk, code, wParam, lParam);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if(ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        if(AllocConsole()){
            freopen("CONOUT$", "w", stdout);  // redirect output to console for debugging
        }
        printf("Dll loaded, lastError = %i\n", GetLastError());
        printf("lastError = %i\n", GetLastError());
        // sidenote: for some reason the first GetLastError() returns 0 while the second one returns 6 (invalid handle)

        hhk = SetWindowsHookEx(WH_KEYBOARD, keyboardProc, hModule, GetCurrentThreadId());
    }
    else if (ul_reason_for_call == DLL_PROCESS_DETACH)
    {
        printf("\nCleaning up...");
        FreeConsole();
        UnhookWindowsHookEx(hhk);
    }
    return TRUE;
}

但是,當我按任意鍵時,“控制台”窗口中什么都不會發生(或打印)。 似乎似乎都無法隨時訪問keyboardProc函數。

盡管當我將NULL而不是GetCurrentThreadId()傳遞給SetWindowsHookEx()時,它確實起作用。 但是,這會導致鈎子在全局范圍內起作用,這意味着每當我在另一個應用程序中按一個鍵時,就會彈出一個控制台窗口(因為再次調用了dll),然后他會在那里檢查鍵輸入。 顯然這是不希望的,我只想使用最初稱為dll的進程來完成這項工作。

我已經檢查了GetCurrentThreadId()返回有效ID,並且它似乎確實是最初調用dll的進程的主線程ID(已通過Process Explorer檢查)。

所以現在我的問題是可能是什么問題,更重要的是,我應該怎么做才能使其起作用?

[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

uint process_id;
uint thread_id = GetWindowThreadProcessId(windowHandle, out process_id);
hhook = SetWindowsHookEx(WH_KEYBOARD, a_KeyboardProc, hInstance, 0);

我已使用上面的代碼來獲取特定進程的主thread_ID。 好的部分是,SetWindowsHookEx函數提供了邏輯輸出。 不幸的是,最糟糕的是,如果在已鈎住的線程中按下一個鍵,該線程將停止工作。

具體來說,在我的情況下,對於非低級鍵盤事件,SetWindowsHoookEx函數的idHook參數設置為2(而不是13)。 至少在我看來,LL對應於低級別,其中keyboardProc應該帶有WH_KEYBOARD而不是WH_KEYBOARD_LL。

目前,我不確定我的答復與您的問題有何關系。 希望我們能通過討論得到所需的東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM