Reputation: 2411
I am trying to get my program to get the current active window title when the focus is changed. I have the following 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));
}
And I am trying to hook WH_CBT as follows:
HHOOK hhkWindowChange = SetWindowsHookEx(WH_CBT, windowChangeHook, 0, 0);
Maybe I am just stupid but it isn't working as intended, anyone have an idea why?
EDIT: It doesn't seem like the program is detecting the window changes at all, I have tried changing the code to this to no avail:
LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS)
cout << "TEST";
return(CallNextHookEx(NULL, nCode, wParam, lParam));
}
Upvotes: 0
Views: 2549
Reputation: 101764
You are not checking the return value from SetWindowsHookEx
!
windowChangeHook
needs to be in a DLL with its HMODULE
in the hMod
parameter.
The HCBT_*
values are passed in the nCode
parameter!
You could also try using SetWinEventHook
instead...
Upvotes: 3
Reputation: 598289
You are not handling the WH_CBT
callback correctly.
Per the CBTProc callback function documentation:
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.
You are looking for the HCBT_SETFOCUS
value in the wrong parameter. You are also retrieving the title of the wrong window, since the input focus has not actually switched windows yet.
Your callback should look more like this instead (assuming your callback is implemented in a DLL, which is required to detect global events, which also means you need separate 32bit and 64bit DLLs on a 64bit system. This is explained in the SetWindowsHookEx()
documentation):
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);
}
That being said, you should consider using SetWinEventHook()
instead, which does not have the DLL requirement if you use the hook "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.
For example:
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);
Upvotes: 0