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

发布于 2024-12-09 21:32:55 字数 293 浏览 1 评论 0原文

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

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

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

编辑

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

I want to hook the WM_MOUSEDOWN and WM_MOUSEUP events from a specific button inside a specific window. I am thinking that SetWindowsHookEx will hook the messages I want. and FindWindowEx will help me find the window handle that I want to trap these events from.

I just don't know how to make it give me the Events from specific window handles. Or how to Determine what handle the message is supposed to be going to.

Anyone else with experience in this I would greatly appreciate some good

EDIT

Alternatively the code to a Spy++ tool in C# or a working copy of ManagedSpy or something similar. I want to learn to navigate the Window Handle Hierarchy and hook windows events from those.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

堇年纸鸢 2024-12-16 21:32:55

您无法进行 SetWindowsHookEx< /a> 只为您提供来自单个窗口句柄的事件,但您可以自己过滤它。如果您使用 WH_CALLWNDPROCWH_CALLWNDPROCRET(您需要使用它们来获取您感兴趣的鼠标消息),则 lParamCallWndProcCallWndRetProc 是一个包含处理消息的控件的窗口句柄的结构。

因此,在 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

You can't make SetWindowsHookEx only give you thew events from a single window handle, but you can filter it yourself. If you are using the WH_CALLWNDPROC or WH_CALLWNDPROCRET (which you need to use to get the mouse messages you are interested in), the lParam value of CallWndProc and CallWndRetProc are a structure that contain the window handle of the control processing the message.

So in your SetWindowsHookEx call back you only need to check that the message is for the window you are filtering.

For example:

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);
}

Pretty much the same logic would apply for WH_CALLWNDPROCRET

中性美 2024-12-16 21:32:55

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

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

您可以从hwnd中的lParam中获取此鼠标事件所要到达的窗口的句柄,

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

您可以获取该窗口的所有详细信息,并且可以检查它是否相同windows 窗体窗口。

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

CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);

pAutomation->ElementFromPoint(*pPoint, &pIUIAutomationElement);

您可以从以下位置获取按钮名称矩形坐标热键IUIAutomationElement

SetWindowsHookEx can be used to hook a specific thread or all threads. You cant hook a specific handle. You can get the specific thread or all threads of the windows forms application & hook them, but it doesn't solve your problem, this is just a performance consideration.

In the callback of the MouseProc you can filter the events WM_LBUTTONDOWN, WM_LBUTTONUP using wParam.

You can get handle to the window to which this mouse event is going from lParam

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

from hwnd you can get all details of the window, and you can check if it is the same windows forms window.

If you want mouse events of only a specific button, you can get the UI Object details from the mouse clicked point & filter the events accordingly (using UIAutomation)

CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);

pAutomation->ElementFromPoint(*pPoint, &pIUIAutomationElement);

You can get the button name, rect coordinates, hot keys etc from IUIAutomationElement

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文