I thought you could use SWP_FRAMECHANGED to force a control to recalculate its properties after a change in styles


Simon Cooke dug back into his memory and asked, "Doesn't calling Set­Window­Pos with SWP_FRAME­CHANGED cause a recreate and re-apply of the styles?"

The SWP_FRAME­CHANGED flag does not recreate anything, but it does reapply the styles, as far as it knows.

Recall that the bits in the window style break into two parts. There are the styles managed by the window manager, which are in the upper 16 bits, and there are the styles that are specific to each control, which are in the lower 16 bits.

The window manager knows about the styles that it manages, but it has no clue about the styles that are specific to each control. It has no idea that the MCIWNDF_NO­PLAY­BAR style controls the toolbar in an MCI window, or that the ES_RIGHT style controls the alignment of text in an edit control.

The SWP_FRAME­CHANGED flag tells the window manager, "Hey, I changed some styles that affect the non-client area of the window (the window frame). Could you go and re-read those styles and apply them to the window? Thanks." That's sort of implied in the name: "Frame changed."

If you want a control to re-inspect the window styles and adjust its behavior in response, you need to do something control-specific. The control might have a custom message you can send it to say, "Hey, I changed some styles that afect the client area of the window. Could you go and re-read those styles and apply them to the window? Thanks." Or there may be special messages specifically for changing styles, such as EM_SET­READ­ONLY. The fancier windows may do it automatically on receipt of the WM_STYLE­CHANGED messages.

Comments (7)
  1. Myria says:

    The complexity of the Windows GUI code makes me understand why Microsoft made the WinRT API, to throw it all away and make a better design.  Too bad it was wasted on Metro.  If WinRT could be used on desktop applications, it'd be awesome. =/

  2. Anon says:

    @Myria

    Don't worry, bad developers will have trashed WinRT soon enough!

  3. @Myria says:

    It really isn't that difficult. There's also .NET which simplifies it all. Plus you can use the Windows Runtime APIs from desktop applications.

  4. SimonRev says:

    @Myria — but there isn't a supported scenario to write a desktop application that uses the Metro UI which is what Myria was really wishing for.

    I really really want a supported method to use XAML directly from native C++ that can be used Win7 and above.

  5. mh says:

    @Myria: I'm not sure where you're seeing the complexity in this.  SWP_FRAMECHANGED is for use when the frame… has …changed.  Even the name is totally self-descriptive (compared to, say, something like SEEK_SET).

  6. alexcohn says:

    @mh: the question is why `Set­Window­Pos()` should be called at all to have a window redraw itself using changed styles? And all this trickery of styles in 16 higher bits and 16 lower bits – is this really as easy to understand and remember?

    [(1) Because the `WM_STYLECHANGED` message hadn't been invented yet. (2) Would you be happier if there were two different style values? Say, a 16-bit system-style field and a 16-bit application-style field. Hey, that's what it is! -Raymond]
  7. alexcohn says:

    @Raymond: my comment was by no means a complaint. I understand and accept a wide variety of constraints, including the unfortunate delay of time machine introduction. I only believe that the result is not what we would agree t call "clean and simple API".

Comments are closed.