我使用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;
}
答案 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