有没有办法为Windows窗体中的特定按钮挂钩鼠标事件

我想从特定窗口内的特定按钮挂钩WM_MOUSEDOWN和WM_MOUSEUP事件。 我在想SetWindowsHookEx将挂钩我想要的消息。 和FindWindowEx将帮助我找到我想从中捕获这些事件的窗口句柄。

我只是不知道如何让它从特定的窗口句柄给我事件。 或者如何确定消息应该处理的句柄。

任何有这方面经验的人都会非常感谢

编辑

或者,使用C#中的Spy ++工具代码或ManagedSpy的工作副本或类似代码。 我想学习导航窗口句柄层次结构并从那些钩子窗口事件。

你不能让SetWindowsHookEx只为你提供来自单个窗口句柄的事件,但你可以自己过滤它。 如果您正在使用WH_CALLWNDPROCWH_CALLWNDPROCRET (您需要使用它来获取您感兴趣的鼠标消息),则CallWndProc和CallWndRetProc的lParam值是一个结构,其中包含处理消息的控件的窗口句柄。

因此,在您的SetWindowsHookEx回调中,您只需要检查该消息是否适用于您要过滤的窗口。

例如:

 static HWND s_hWndButton; ..... SetWindowsHookEx(WH_CALLWNDPROC, ButtonHookProc, ....); ..... LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode >= 0) { CWPSTRUCT* cp = (CWPSTRUCT*)lParam; if (cp->hWnd == s_hWndButton) { if (cp->Msg == WM_MOUSEUP || cp->Msg == WM_MOUSEDOWN) { // Your logic goes here } } } Return CallNextHookEx(NULL, nCode, wParam, lParam); } 

几乎相同的逻辑适用于WH_CALLWNDPROCRET

SetWindowsHookEx可用于挂钩特定线程或所有线程。 你不能钩住一个特定的句柄。 您可以获取Windows窗体应用程序的特定线程或所有线程并将它们挂钩,但它不能解决您的问题,这只是性能考虑因素。

MouseProc的回调中,您可以使用wParam过滤事件WM_LBUTTONDOWNWM_LBUTTONUP

您可以从lParam处理此鼠标事件所在的窗口

 MOUSEHOOKSTRUCT * pMouseHookStruct = (MOUSEHOOKSTRUCT *) lParam; HWMD hWnd = pMouseHookStruct->hwnd; 

hwnd你可以获得窗口的所有细节,你可以检查它是否是相同的窗体窗口。

如果您只想要特定按钮的鼠标事件,可以从鼠标单击的点获取UI对象详细信息并相应地过滤事件(使用UIAutomation

 CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation); pAutomation->ElementFromPoint(*pPoint, &pIUIAutomationElement); 

您可以从IUIAutomationElement获取button namerect coordinateshot keys