是否有方法为窗口窗体中的特定按钮挂钩鼠标事件

本文关键字:按钮 事件 鼠标 有方法 窗口 窗体 是否 | 更新日期: 2023-09-27 18:11:25

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

我只是不知道如何使它从特定的窗口句柄给我事件。或者如何确定消息应该发送到哪个句柄。

任何有这方面经验的人,我将非常感激。

编辑

或者代码到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_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等。