The dangers of messing with activation when handling a WM_ACTIVATE message


This is basically the same thing as The dangers of playing focus games when handling a WM_KILLFOCUS message, just with activation in place of focus. One developer discovered the hard way that if you mess with activation inside your WM_ACTIVATE handler, things get weird. The author noted that if he posted a message and did the work from the posted message, then everything came out okay.

A follow-up to the original message noted that passing the SWP_NOACTIVATE flag to the SetWindowPos function solves the problem. Do you understand why?

Comments (5)
  1. Chump says:

    Hmmm let me see….

    When the messagebox receives WM_ACTIVATE it sends a WM_ACTIVATE message back to it’s parent (setting wParam==WA_INACTIVE).

    The parent therefore re-enters the WM_ACTIVATE handler, and…’oh look I’ve been sent WA_INACTIVE, I’d better reposition the messagebox’….and on and on.

    Is this correct?

  2. David says:

    The poster notes that he doesn’t experience the problem in Windows ME. Do you have any idea why this is the case?

    I always imagined that things like the order of messages sent etc would be the same on 9x and NT-based versions of Windows – that the Win32 layer would expose the same behaviour, in other words, regardless of what was underneath. But if this problem doesn’t occur on ME it implies something’s quite different about what happens under the hood.

    It’s not important, but I’m curious. Any insights?

  3. Norman Diamond says:

    Various bugs in controls have had different behaviours in different versions of Windows 9x, 2000, etc., AND have had different behaviours depending on which version of Internet Explorer is installed. So it doesn’t surprise me a bit that the Win32 layers don’t expose the same behaviour in this kind of situation either.

    I often have to put code in some kinds of handlers in order to check if an unwanted event is occuring due to some other known action, and do nothing and exit immediately if so. The same handler might or might not be reentered, but either way it has to be programmed to avoid interfering with the intended actions.

  4. Tom West says:

    This is apropros to my current programming assignment. I’m trying to make a window modal to several other (but not all) application windows. I have window A that is always supposed to be above window B (although there may be other windows above both of them). if the user clicks on B to activate it, I want A to come to the foreground with B right behind it.

    My understanding is that when the user clicks on B, I will receive a WM_SETWINDOWPOSCHANGING message, where I could change the WINDOWPOS structure to place B behind A and have it not activate.

    My question is could I also call SetForegroundWindow on A while handling B’s WM_SETWINDOWPOSCHANGING message, or will it, as I suspect, occasionally blow up? Is there a message I could post to A to make it activate later?

  5. Nekto2 says:

    Thanks for the article. I have some strange crashes on WinCE after messing with Activate and focus messages.

    Still I can’t see why my background windows (all of them are modal dialog 8-) could just activate/deactivate even if I will not show them. I think this article will help me find out why it is.

    But this lead me to the questions:

    1. Why there is no integrated messages debugger? The one which will show both current messages in progress (and handler are reentered) and message queue of unprocessed messages and history with timeline of messages (with starting and ending processing time and overlaps if there are any).

    2. Why there is no list of "this action sould be done in that handler" for common actions. Example is – "when should I update data in controls of a dialog, which is not recreated every time it is used?".

    –answer?–

    MSDN: SWP_NOACTIVATE Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or the nontopmost group, depending on the setting of the pWndInsertAfter parameter.

    So there is reenterance.

    But the questions is: If I set SWP_HIDEWINDOW flag without SWP_NOACTIVATE will that set window to Active before it hides it? :)

Comments are closed.

Skip to main content