2014-03-02 55 views
2

我想自己繪製和移動我的窗口(使用鉻嵌入式框架)。 要做到這一點,我需要當鼠標移動時,我的窗口之外的全球回調 - 所以我安裝了一個低級別鼠標鉤子:低級別的鼠標鉤 - 斷點上的鼠標凍結

hMouseLLHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)mouseHookProc, hInstance, NULL); 

掛鉤簡單抓起鼠標事件,並呼籲「CallNextHookEx方法」 。這裏沒有任何問題,一切都按照原則進行。 我現在的問題:如果拋出的調試器中斷或異常,我無法移動鼠標了..

我試圖在另一個線程處理鉤,就像這樣:

HANDLE mouseProcHandle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)mouseProcessor, NULL, NULL, &dwMouseProcThread); 

DWORD WINAPI Win32Application::mouseProcessor(LPVOID lpParm) { 
    hMouseLLHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)mouseHookProc, ((Win32Application*)Application::getInstance())->hInstance, NULL); 

    MSG message; 
    while (GetMessage(&message, NULL, 0, 0)) { 
     TranslateMessage(&message); 
     DispatchMessage(&message); 
    } 

    UnhookWindowsHookEx(hMouseLLHook); 
    return 0; 
} 

但這也不能解決問題。有沒有解決方法,解決方案或其他方法來做到這一點? 另外,我認爲低級別的鉤子可能並不是必要的,因爲我只需要知道這個問題,如果我是最後一個,那麼系統/其他進程就可以處理首先是鼠標回調。

+0

你不破鉤,鉤斷了! – CodeAngry

+0

你真的需要一個鉤子嗎?捕獲不夠好嗎? –

+0

就夠了,但它必須是無處不在,獨立於窗戶的。你有另一種解決方案來歸檔這個嗎? – lunatix

回答

3

當你的調試器停止整個程序(它的所有線程)
如果使用鉤子,可能沒有解決方法。
並不準確,但您可以在線程中輪詢GetCursorPos。

+0

這將是一個可接受的解決方案的調試版本,我認爲..不是一個「很好」的解決方法,但它會做的工作:) – lunatix

+0

...或者也許http://social.msdn.microsoft.com/Forums/ vstudio/en-US/d6d18a8e-5b2d-4fe3-bc80-6e6b61d256b1/vs2008-multithread-debug-keep-1-thread-running-while-stepping-through-other-thread help。我也不知道這是可能的,直到現在(如果這是正確的),感謝您提出這個話題:) – deviantfan

+0

接受這個答案,因爲它指出我在正確的方向。最終的解決方案是在每個由鉻創建的窗口上使用普通的鼠標鉤子(而不是低級別) - 使用給定MOUSEHOOKSTRUCTEX的HWND句柄(它是一個子窗口,因此只需查找它的父項)完成映射。奇蹟般有效。謝謝@all :) – lunatix

5

爲了說明這一點:當你攔截所有的鼠標移動事件時,它們都會在你的鉤子中結束,它可以修改或吞下它們。因此,系統會調用每個鼠標移動事件掛鉤並等待直到您的掛鉤例程完成它,直到它再次調用您的掛鉤以用於下一個掛起的鼠標移動事件。

猜猜當你在hook事件中進入調試器時會發生什麼?除非你已經通過你的鉤子程序,否則沒有更多的鼠標事件。通常情況下,你可以用這樣的中央掛鉤來降低整個系統。但幸運的是,Windows確實預料到了壞點。您會注意到系統在一段時間後會再次響應鼠標事件。我的猜測是,當Windows掛起一次時,Windows會簡單地刪除你的掛鉤。

現在關於調試:安全進入調試器的唯一方法是在進入鉤子後永遠不要觸摸鼠標。不太實際。唯一的出路是追蹤有趣的事情,並查看日誌文件中發生的事情。 如果你示例代碼如何連接鼠標和鍵盤事件後,你可以看看這裏:

http://etwcontroler.codeplex.com/SourceControl/latest#ETWControler/Hooking/Hooker.cs

+1

'Hooker.cs' - 經典! – CodeAngry

+0

感謝C#鏈接,我會牢記這一點.net開發:)哦,我沒有說只打破鉤本身,它是更普遍的 - 任何地方導致問題 - 就像你提到的一樣它,因爲我的方法停止回調隊列。我的應用程序運行多個線程,所以也許可能只是停止應用程序線程,而不是掛鉤線程(就像上面發佈的@deviantfan)。 – lunatix