I have a global WH_CBT
32bit hook that I am using to determine when a window is about to be activated using HCBT_ACTIVATE
.
How can I determine when the window is about to be deactivated?
There is the CBTACTIVATESTRUCT
which has hWndActive
, but that is sometimes 0x0
and it wont work when switching to a 64bit window.
There is no HCBT_DEACTIVATE
.
As@Remy Lebeau mentioned, you can use WM_ACTIVATE
message. This message is sent both when the window is activated or deactivated.
Set a WH_CALLWNDPROC
hook to capture the deactivated message, it will get the messages before the system sends them to the destination window procedure.
For more detail:
Use a function in a DLL for a non-local hook:
#include <Windows.h>
#include <stdio.h>
LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
HWND hwnd;
//...
DWORD threadID = GetWindowThreadProcessId(hwnd, NULL);
HINSTANCE hinstDLL = LoadLibrary(TEXT("..\\Debug\\ProcHookDLL.dll"));
void (*AttachHookProc)(DWORD);
AttachHookProc = (void (*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook");
AttachHookProc(threadID);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
//...
};
Here is the code for the DLL:
#include <Windows.h>
#include <stdio.h>
HMODULE thisModule;
HHOOK hook;
LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam);
#ifdef __cplusplus // If used by C++ code,
extern "C" { // we need to export the C interface
#endif
__declspec(dllexport) void AttachHook(DWORD threadID) {
hook = SetWindowsHookEx(WH_CALLWNDPROC, LaunchListener, thisModule, threadID);
}
#ifdef __cplusplus
}
#endif
LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam) {
// process event here
if (nCode >= 0) {
CWPSTRUCT* cwp = (CWPSTRUCT*)lParam;
if (cwp->message == WM_ACTIVATE) {
if (LOWORD(cwp->wParam) == WA_INACTIVE)
{
//the window being deactivated
}
else
{
//the window being activated
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}