SetWinEventHook包含自定义数据

时间:2016-05-08 02:46:09

标签: c++ winapi

我使用SetWinEventHook挂钩来检测编辑控件的选择。在事件钩子回调函数中,有没有办法指定自定义数据?在我的例子中,自定义数据将是VKeyboard实例。

请参阅代码以更好地描述我想要实现的目标。

class VKeyboard
{
public:
    static void CALLBACK winEventProc(HWINEVENTHOOK hWinEventHook, DWORD  event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
    {
        // Somehow access VKeyboard instance?
        VKeyboard* keyboard = ??;

        IAccessible* pAcc = NULL;
        VARIANT varChild;
        HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);

        if ((hr == S_OK) && (pAcc != NULL))
        {
            VARIANT varRole;
            hr = pAcc->get_accRole(varChild, &varRole);

            // if user selects a edit control: show window
            if ((hr == S_OK) && (varRole.vt == VT_I4) && (varRole.lVal == ROLE_SYSTEM_TEXT))
                ShowWindow(keyboard->mainHwnd, SW_SHOW);
            else ShowWindow(keyboard->mainHwnd, SW_HIDE);

            pAcc->Release();
        }
    }

    VKeyboard() 
    {
        SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, NULL, (WINEVENTPROC)&winEventProc, 0, 0, WINEVENT_SKIPOWNPROCESS);


        SetWindowLongPtr (mainHwnd, GWLP_USERDATA, (LONG_PTR)this);
    }

    HWND mainHwnd;
}

1 个答案:

答案 0 :(得分:2)

由于您的钩子回调是作为Out of Context hook实现的,因此它总是在调用VKeyboard的线程的上下文中调用,即使在挂钩其他进程的事件时也是如此。因此,您可以使用Thread Local Storage,甚至只使用全局变量来存储VKeyboard对象指针。如果您只需要class VKeyboard { private: HWINEVENTHOOK hHook; static VKeyboard *pKeyboard; static void CALLBACK winEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { IAccessible* pAcc = NULL; VARIANT varChild; HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild); if ((hr == S_OK) && (pAcc != NULL)) { VARIANT varRole; hr = pAcc->get_accRole(varChild, &varRole); // if user selects a edit control: show window if ((hr == S_OK) && (varRole.vt == VT_I4) && (varRole.lVal == ROLE_SYSTEM_TEXT)) ShowWindow(pKeyboard->mainHwnd, SW_SHOW); else ShowWindow(pKeyboard->mainHwnd, SW_HIDE); pAcc->Release(); } } VKeyboard() { hHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, NULL, &winEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); mainHwnd = ...; SetWindowLongPtr (mainHwnd, GWLP_USERDATA, (LONG_PTR)this); pKeyboard = this; } ~VKeyboard() { UnhookWinEvent(hHook); pKeyboard = NULL; } HWND mainHwnd; }; 的一个实例,那就是。

link