我正在尝试让我的程序在焦点更改时获取当前活动窗口标题。我有以下CALLBACK:
LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (wParam == HCBT_SETFOCUS || lParam == HCBT_SETFOCUS)
cout << GetActiveWindowTitle();
return(CallNextHookEx(NULL, nCode, wParam, lParam));
}
我正试图按如下方式挂钩WH_CBT:
HHOOK hhkWindowChange = SetWindowsHookEx(WH_CBT, windowChangeHook, 0, 0);
也许我只是愚蠢但是没有按预期工作,任何人都知道为什么?
修改 似乎程序根本没有检测到窗口的变化,我尝试将代码更改为此无效:
LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS)
cout << "TEST";
return(CallNextHookEx(NULL, nCode, wParam, lParam));
}
答案 0 :(得分:3)
您没有检查SetWindowsHookEx
的返回值!
windowChangeHook
需要位于HMODULE
参数中hMod
的DLL中。
HCBT_*
参数传递nCode
值!
您也可以尝试使用SetWinEventHook
代替...
答案 1 :(得分:0)
您没有正确处理WH_CBT
回调。
根据CBTProc callback function文档:
nCode [in]
键入:int钩子过程用于确定如何处理消息的代码。如果
nCode
小于零,则钩子过程必须将消息传递给CallNextHookEx
函数没有进一步处理,应返回CallNextHookEx
返回的值。此参数可以是以下值之一。...
HCBT_SETFOCUS
9
窗口即将接收键盘焦点。
wParam [in]
键入:WPARAM取决于
nCode
参数。有关详细信息,请参阅以下备注部分。
lParam [in]
键入:LPARAM取决于
nCode
参数。有关详细信息,请参阅以下备注部分。
下表介绍了每个
wParam
挂钩代码的lParam
和HCBT_
参数。...
HCBT_SETFOCUS
wParam:指定获得键盘焦点的窗口的句柄 lParam:指定失去键盘焦点的窗口的句柄。
您正在寻找错误参数中的HCBT_SETFOCUS
值。您还在检索错误窗口的标题,因为输入焦点尚未实际切换窗口。
你的回调应该看起来更像这样(假设你的回调是在DLL中实现的,这是检测全局事件所必需的,这也意味着你需要在64位系统上使用单独的32位和64位DLL。这在{ {3}}文档):
LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_SETFOCUS)
{
HWND hwnd = (HWND) wParam;
// retreive and use the title of hwnd as needed...
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
话虽如此,你应该考虑使用SetWindowsHookEx()
代替,如果你使用钩子“out-of-context”,它没有DLL要求:
回调函数未映射到生成事件的进程的地址空间。由于跨函数边界调用钩子函数,因此系统必须对事件进行排队。虽然此方法是异步的,但事件保证按顺序排列。有关详细信息,请参阅
SetWinEventHook()
。
EVENT_OBJECT_FOCUS
0x8005对象已获得键盘焦点。系统为以下用户界面元素发送此事件:列表视图控件,菜单栏,弹出菜单,切换窗口,选项卡控件,树视图控件和窗口对象。服务器应用程序为其可访问对象发送此事件。
hwnd
回调函数的WinEventProc
参数标识了获得键盘焦点的窗口。
例如:
void CALLBACK windowChangeHook(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
// retreive and use the title of hwnd as needed...
}
HWINEVENTHOOK hEventHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, NULL, &windowChangeHook, 0, 0, WINEVENT_OUTOFCONTEXT);
...
UnhookWinEvent(hEventHook);