我正在使用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;
}
最佳答案
由于您的挂钩回调是通过Out of Context hook实现的,因此即使在挂钩其他进程的事件时,也总是在调用SetWinEventHook()
的线程的上下文中调用它。这样,您可以使用Thread Local Storage或什至仅使用全局变量来存储VKeyboard
对象指针。前提是您只需要一个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;
};