有没有办法为Windows窗体中的特定按钮挂钩鼠标事件
我想从特定窗口内的特定按钮挂钩WM_MOUSEDOWN和WM_MOUSEUP事件。 我在想SetWindowsHookEx将挂钩我想要的消息。 和FindWindowEx将帮助我找到我想从中捕获这些事件的窗口句柄。
我只是不知道如何让它从特定的窗口句柄给我事件。 或者如何确定消息应该处理的句柄。
任何有这方面经验的人都会非常感谢
编辑
或者,使用C#中的Spy ++工具代码或ManagedSpy的工作副本或类似代码。 我想学习导航窗口句柄层次结构并从那些钩子窗口事件。
你不能让SetWindowsHookEx只为你提供来自单个窗口句柄的事件,但你可以自己过滤它。 如果您正在使用WH_CALLWNDPROC
或WH_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_LBUTTONDOWN
, WM_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 name
, rect coordinates
, hot keys
等