Is there a way to hook mouse events for a specific button in a windows form

后端 未结 2 576
北荒
北荒 2021-01-21 05:18

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 Fin

相关标签:
2条回答
  • 2021-01-21 05:47

    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

    0 讨论(0)
  • 2021-01-21 06:07

    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

    0 讨论(0)
提交回复
热议问题