有没有一种方法可以钩取 Windows 窗体中特定按钮的鼠标事件?

3
我想要钩取特定窗口内特定按钮的WM_MOUSEDOWN和WM_MOUSEUP事件。我想使用SetWindowsHookEx来钩取所需的消息,并使用FindWindowEx来找到我想要捕获这些事件的窗口句柄。
我不知道如何让它给我指定窗口句柄的事件,或者如何确定消息应该发送到哪个句柄。
如果有其他经验丰富的人可以提供帮助,我将非常感激。
编辑:
或者提供一个用C#编写的Spy++工具代码,或者一个ManagedSpy的可工作副本,类似的东西也可以。我想学习如何浏览窗口句柄层次结构并从中钩取窗口事件。

你使用 WH_MOUSE,我仍在研究它,但据我所知,你不能使用 WH_MOUSE_LL 来获取本地信息(你要查找的 hwnd)。从我现在的理解来看,唯一的方法是创建一个 .dll 文件。 - Mark Aven
2个回答

1

你无法让 SetWindowsHookEx 只返回单个窗口句柄的事件,但你可以自行过滤。 如果你使用 WH_CALLWNDPROCWH_CALLWNDPROCRET(你需要使用它们来获取你感兴趣的鼠标消息),CallWndProcCallWndRetProclParam 值是一个包含处理消息的控件的窗口句柄的结构体。

所以在你的 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也基本适用相同的逻辑。


lparam 总是 CWPSTRUCT 吗? - The Lazy Coder
仅适用于 WH_CALLWNDPROC 钩子,是的。WH_CALLWNDPROCRET 钩子使用 CWPRETSTRUCT - Remy Lebeau

1

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

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 中获取 按钮名称矩形坐标热键等信息。


那么现在你的每个答案都有竞争结构...这些是相同的结构吗? - The Lazy Coder
@VolureDarkAngel:这是两种不同的方法,一种是使用WH_MOUSE钩子捕获所有鼠标事件,另一种是捕获发送到窗口的所有Windows消息事件。 - sri
你知道哪里可以获取有关低级钩子的更多信息吗?最佳实践、方法等方面的内容? - The Lazy Coder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接