带有自定义数据的 SetWinEventHook [英] SetWinEventHook with custom data

查看:19
本文介绍了带有自定义数据的 SetWinEventHook的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using SetWinEventHook hook to detect the selection of Edit Controls. In the event hook callback function, is there a way to specify custom data? In my case the custom data would be the VKeyboard instance.

请查看代码以更好地描述我想要实现的目标.

Please see the code for a better description of what I am trying to achieve.

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

推荐答案

由于您的钩子回调是作为 脱离上下文钩子,它总是在调用SetWinEventHook()的线程的上下文中被调用,即使在钩子其他进程的事件时也是如此.因此,您可以使用 线程本地存储,或甚至只是一个全局变量,用于存储您的 VKeyboard 对象指针.前提是你只需要VKeyboard的一个实例,即

Since your hook callback is implemented as an Out of Context hook, it is always called in the context of the thread that calls SetWinEventHook(), even when hooking events of other processes. As such, you can use Thread Local Storage, or even just a global variable, to store your VKeyboard object pointer. Provided you only need one instance of VKeyboard, that is.

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

这篇关于带有自定义数据的 SetWinEventHook的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆