2014-02-23 107 views
0

我想開發一個捕獲鼠標點擊的WPF C#應用程序,甚至(尤其是)如果它在後臺才能啓動另一個任務。WH_MOUSE可以捕捉全局事件嗎?

在MSDN文檔(http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx)我可以看到WH_MOUSE應該有全局或線程作用域。

我實例化我的鉤柄是這樣的:

hHook = SetWindowsHookEx(WH_MOUSE, 
         MouseHookProcedure, 
         (IntPtr)0, 
         AppDomain.GetCurrentThreadId()); 

其中MouseHookProcedure是我的回調函數和WH_MOUSE值的代表是7(以下Winuser.h中)。

該代碼有效,但它只能捕獲本地點擊(我只需要WM_LBUTTONDOWN消息),窗口內的點擊。我需要在窗口外面捕捉點擊,以及當窗口在背景中時。

我試着掛鉤到WH_MOUSE_LL(值爲14),但它不工作。

對於大多數情況下,我遵循這一點: http://support.microsoft.com/kb/318804 因爲我使用WPF而不是WinForms進行了一些更改。

關於鉤子的文檔有點混亂。 總而言之,我想知道:

  • WH_MOUSE WH_MOUSE可以全局檢測鼠標消息嗎?如果是的話,我做錯了什麼?
  • 我可以從.NET C#代碼掛鉤到WH_MOUSE_LL嗎?如果是,如何?

在此先感謝。

+0

你發佈了錯誤的代碼。你現在擁有的是完全正常的,你的鉤子只能看到到你窗口的鼠標消息。你確實需要WH_MOUSE_LL來抓住所有人。谷歌充滿了關於如何做到這一點的例子。 –

+0

我現在用WH_MOUSE_LL工作了。 以前我在google上使用Hooks的方式,因爲MSDN文檔聲明WH_MOUSE在Thread/Global上工作,我遵循他們的例子。當我嘗試在他們的示例中使用WH_MOUSE_LL時,它不再工作。所以我想了解我應該遵循的路線。雖然謝謝:) –

回答

0

從技術上講,您應該可以在C#中實現全局鼠標鉤子。然後,您將傳遞零作爲SetWindowsHookEx的最後一個參數,並且您的掛鉤過程必須駐留在DLL中,而不是EXE。這是因爲DLL將被注入到具有屬於與掛接應用程序相同桌面的窗口的每個進程中。出於同樣的原因,在.NET中編寫全局鉤子實際上並未被大多數人推薦,因爲它導致CLR被加載到每個桌面進程中,這可能帶來大量開銷。

1

這可能與WH_MOUSE_LL,你需要它。

在我的情況下,我開發了一個全球鍵盤,也許這可以幫助你。 我需要在第三個參數中調用LoadLibrary

[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)] 
private static extern IntPtr LoadLibrary(string fileName); 

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardProc lpfn, IntPtr hMod, uint dwThreadId); 

void MyFunction(){ 
    [...] 
    SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, LoadLibrary("user32.dll"), 0); 
}