Jump to content
  • Advertisement
Sign in to follow this  
JonW

WM_KILLFOCUS Not Getting Sent

This topic is 5090 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have some code like the following to create a top-level window: [In the window creation function] // Create the window, store in hWnd.... ShowWindow(hWnd, SW_SHOW); SetFocus(hWnd); [In the message handler] case WM_SETFOCUS: OutputDebugString("Got focus.\n"); break; case WM_KILLFOCUS: OutputDebugString("Lost focus.\n"); break; After the window is created, I get a WM_SETFOCUS message right away as I should. But then if I click on another application's window, such as Explorer, I don't receive the WM_KILLFOCUS message. The funny thing is, I can click on dozens of windows from other processes without receiving the message, and then when I click on my application's other top-level window I finally receive the WM_KILLFOCUS message. If I first click on the created window and then click on, say, Explorer, I will receive the WM_KILLFOCUS message as I should. I just won't receive it when the focus is set with the SetFocus call. I tried replacing it with SetActiveWindow and SetForegroundWindow, but the results are the same. Sorry if that sounds confusing... couldn't phrase it any more clearly. Thanks, Jon

Share this post


Link to post
Share on other sites
Advertisement
It's not a dialog. Here is the window class code:

WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(RGB(88, 87, 104));
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyClass";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

And the window creation:

hWnd = CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, "MyClass", NULL, WS_POPUP|WS_BORDER, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);

It would be ideally if I could know when just this window loses focus, such as to another window in the same process. Should I process both ACTIVATEAPP and KILLFOCUS?

Thanks,
Jon

Share this post


Link to post
Share on other sites
You need WM_KILLFOCUS for when focus changes inside your process (e.g. to another window of your program) and WM_ACTIVATEAPP (not APPACTIVATE, sorry) for when focus changes between processes (e.g. to a window in another program). See MSDN on WM_ACTIVATEAPP for some extra details.

Share this post


Link to post
Share on other sites
Even with WM_ACTIVATEAPP, it still does not work right.

Here's the code in my message handler (lets call this created window 'Window A'):

case WM_SETFOCUS:
OutputDebugString("Got focus.\n");
break;

case WM_KILLFOCUS:
OutputDebugString("Lost focus.\n");
break;

case WM_ACTIVATEAPP:
if ((BOOL)wParam)
OutputDebugString("Got app focus.\n");
else
OutputDebugString("Lost app focus.\n");
break;

And here's the output I get when Window A is initially opened:

Got app focus.
Got focus.

If I first click on another application's window, I don't receive either WM_ACTIVATEAPP or WM_KILLFOCUS.

If I click on Window A before clicking on another application's window, I get both outputs:

Lost app focus.
Lost focus.

And if I click on my other top level window (Window B), I get just this:

Lost focus.

So Window A does not receive WM_ACTIVATEAPP when I click on another app's window unless I initially click on Window A. However I can still receive WM_KILLFOCUS when I click on Window B.

I wish MS documented these messages better...

Share this post


Link to post
Share on other sites
Quote:
Original post by ApochPiQ
You need WM_KILLFOCUS for when focus changes inside your process (e.g. to another window of your program) and WM_ACTIVATEAPP (not APPACTIVATE, sorry) for when focus changes between processes (e.g. to a window in another program)...


Not really, WM_KILLFOCUS is sent right before the keyboard focus is transfered to another window (at the same process or another doesn't matter). Using WM_KILLFOCUS is sufficient in this case I think.

Did you try to create a toolbox window alone (a new app with only a toolbox) ?. I think the problem lay somewhere in your window procedure. CreateWindowEx () is fine, I suggest remove WS_POPUP however.

Share this post


Link to post
Share on other sites
Depends on how the message pump and wndprocs are set up in the code; some points will always see WM_ACTIVATEAPP while some points may not catch WM_KILLFOCUS. The messages will always be sent, but whether or not your code sees them depends on where the code is located and how things are set up.

JonWoyame, can you provide some extra details on how the message handling is set up in your app?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
WM_ACTIVATEAPP works for me. BTW, MSDN says you're supposed to return zero upon receiving this message. This message is sent both when your app receives focus, and when it relinquises focus. If wparam is TRUE, you're receiving focus, otherwise, you're losing focus.

I find that WM_KILLFOCUS is only sent when an apps main window reliquenches control to one of it's (child) controls.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
WM_ACTIVATEAPP works for me. BTW, MSDN says you're supposed to return zero upon receiving this message. This message is sent both when your app receives focus, and when it relinquises focus. If wparam is TRUE, you're receiving focus, otherwise, you're losing focus.

I find that WM_KILLFOCUS is only sent when an apps main window reliquenches control to one of it's (child) controls.


I'm not sure about 'only', you may try creating a plain window which alerts user when WM_KILLFOCUS is sent. Switching between windows in Windows Explorer will also generate this message.
It is weird I've never had troubles with WM_KILLFOCUS, I believe the problem arose from your window procedure (seconded ApochPiQ).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!