Rob
Rob

Reputation: 78758

WM_SETFOCUS, get app that just lost focus

When my WTL C++ application is activated or gets the keyboard focus I need to determine the window handle of the application that was previously activated/had focus. However, the window handles (LPARAM) of both the WM_SETFOCUS and WM_ACTIVATE messages are both NULL (XP, 32 bit).

How can I determine the application that just lost focus when my application is activated? Is there a simple way to do this or will I need to roll a special CBT hook?

Upvotes: 1

Views: 2785

Answers (1)

Cody Gray
Cody Gray

Reputation: 244981

An easy way to see exactly what messages are being sent and what their parameters are is to fire up Spy++ and set it to Log Messages while you Alt+Tab to another window.

Consistent with what you've discovered, the lParam for both WM_SETFOCUS and WM_ACTIVATE will be NULL when the previously active window (or the window being active) is not in the same thread.

You might have more luck with WM_ACTIVATEAPP, as David suggested. Once you get the thread identifier, you can try calling the GetGUIThreadInfo function to determine the active window for that thread. This function will work even if the active window is not owned by the calling process.

If your app is anything other than a small utility that the user is not expected to keep open and running for very long, I would shy away from using a CBT hook if at all possible, given the potential performance implications. Unfortunately, interaction like this across process boundaries is difficult.

If you're not afraid of using things that may break with future versions of Windows, you could investigate the RegisterShellHookWindow function. I can't tell you much about it, having never used it myself, but it's an easier way to get the shell messages you would otherwise only receive by installing a hook.
It was around as far back as Windows 2000, but wasn't included in the SDK until XP SP1. It still exists in Windows Vista and 7, as far as I can tell.

Upvotes: 4

Related Questions