在活动 window 发生变化时收到通知
Getting notification when active window changes
我试图让我的程序在焦点改变时获取当前活动的 window 标题。我有以下回调:
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);
也许我只是太笨了,但它没有按预期工作,有人知道为什么吗?
编辑:
程序似乎根本没有检测到 window 更改,我尝试将代码更改为此无济于事:
LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS)
cout << "TEST";
return(CallNextHookEx(NULL, nCode, wParam, lParam));
}
您没有检查 SetWindowsHookEx
中的 return 值!
windowChangeHook
需要在 DLL 中,其 HMODULE
在 hMod
参数中。
在nCode
参数中传递了HCBT_*
值!
您也可以尝试使用 SetWinEventHook
代替...
您没有正确处理 WH_CBT
回调。
根据 CBTProc callback function 文档:
nCode [in]
Type: int
The code that the hook procedure uses to determine how to process the message. If nCode
is less than zero, the hook procedure must pass the message to the CallNextHookEx
function without further processing and should return the value returned by CallNextHookEx
. This parameter can be one of the following values.
...
HCBT_SETFOCUS
9
A window is about to receive the keyboard focus.
wParam [in]
Type: WPARAM
Depends on the nCode
parameter. For details, see the following Remarks section.
lParam [in]
Type: LPARAM
Depends on the nCode
parameter. For details, see the following Remarks section.
The following table describes the wParam
and lParam
parameters for each HCBT_
hook code.
...
HCBT_SETFOCUS
wParam: Specifies the handle to the window gaining the keyboard focus.
lParam: Specifies the handle to the window losing the keyboard focus.
您在错误的参数中查找 HCBT_SETFOCUS
值。您还检索了错误的标题 window,因为输入焦点尚未实际切换 windows。
您的回调应该看起来更像这样(假设您的回调是在 DLL 中实现的,这是检测全局事件所必需的,这也意味着您需要在 64 位系统上使用单独的 32 位和 64 位 DLL。这在中进行了解释SetWindowsHookEx()
文档):
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);
}
也就是说,您应该考虑改用 SetWinEventHook()
,如果您使用挂钩 "out-of-context":
,它就没有 DLL 要求
The callback function is not mapped into the address space of the process that generates the event. Because the hook function is called across process boundaries, the system must queue events. Although this method is asynchronous, events are guaranteed to be in sequential order. For more information, see Out-of-Context Hook Functions.
EVENT_OBJECT_FOCUS
0x8005
An object has received the keyboard focus. The system sends this event for the following user interface elements: list-view control, menu bar, pop-up menu, switch window, tab control, tree view control, and window object. Server applications send this event for their accessible objects.
The hwnd
parameter of the WinEventProc
callback function identifies the window that receives the keyboard focus.
例如:
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);
我试图让我的程序在焦点改变时获取当前活动的 window 标题。我有以下回调:
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);
也许我只是太笨了,但它没有按预期工作,有人知道为什么吗?
编辑: 程序似乎根本没有检测到 window 更改,我尝试将代码更改为此无济于事:
LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS)
cout << "TEST";
return(CallNextHookEx(NULL, nCode, wParam, lParam));
}
您没有检查
SetWindowsHookEx
中的 return 值!windowChangeHook
需要在 DLL 中,其HMODULE
在hMod
参数中。在
nCode
参数中传递了HCBT_*
值!
您也可以尝试使用 SetWinEventHook
代替...
您没有正确处理 WH_CBT
回调。
根据 CBTProc callback function 文档:
nCode [in]
Type: intThe code that the hook procedure uses to determine how to process the message. If
nCode
is less than zero, the hook procedure must pass the message to theCallNextHookEx
function without further processing and should return the value returned byCallNextHookEx
. This parameter can be one of the following values....
HCBT_SETFOCUS
9
A window is about to receive the keyboard focus.
wParam [in]
Type: WPARAMDepends on the
nCode
parameter. For details, see the following Remarks section.
lParam [in]
Type: LPARAMDepends on the
nCode
parameter. For details, see the following Remarks section.
The following table describes the
wParam
andlParam
parameters for eachHCBT_
hook code....
HCBT_SETFOCUS
wParam: Specifies the handle to the window gaining the keyboard focus.
lParam: Specifies the handle to the window losing the keyboard focus.
您在错误的参数中查找 HCBT_SETFOCUS
值。您还检索了错误的标题 window,因为输入焦点尚未实际切换 windows。
您的回调应该看起来更像这样(假设您的回调是在 DLL 中实现的,这是检测全局事件所必需的,这也意味着您需要在 64 位系统上使用单独的 32 位和 64 位 DLL。这在中进行了解释SetWindowsHookEx()
文档):
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);
}
也就是说,您应该考虑改用 SetWinEventHook()
,如果您使用挂钩 "out-of-context":
The callback function is not mapped into the address space of the process that generates the event. Because the hook function is called across process boundaries, the system must queue events. Although this method is asynchronous, events are guaranteed to be in sequential order. For more information, see Out-of-Context Hook Functions.
EVENT_OBJECT_FOCUS
0x8005An object has received the keyboard focus. The system sends this event for the following user interface elements: list-view control, menu bar, pop-up menu, switch window, tab control, tree view control, and window object. Server applications send this event for their accessible objects.
The
hwnd
parameter of theWinEventProc
callback function identifies the window that receives the keyboard focus.
例如:
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);