Window class properties apply to all windows that belong to the class


Window class properties apply to all windows that belong to the class. That's why they're called class properties. This seems like an obvious thing to say when put in so many words, but I see many "solutions" that lose sight of this simple fact.

All the properties that you set in the WNDCLASS (or WNDCLASSEX) are window class properties, as are the properties that you can access via Get/SetClassWord/Long/LongPtr. This means that when you change those properties, they affect the entire class. For example, if you write

SetClassLongPtr(hwnd, GCLP_HCURSOR, (LONG_PTR)hcurNew);

then you aren't just changing the cursor for the window specified by hwnd. You're changing the cursor for all windows of the same class as hwnd. For example, if hwnd is an edit control, then you changed the default cursor for all edit controls.

But what if you want to change a class property for just one particular window instead of for all windows of a class?

If you want to change the menu, background, cursor, or icon for a particular window, you can override the class default on a per-window basis:

Property Method
Menu SetMenu(hwnd, hmenuNew) + destroy the old menu
Background Override WM_ERASEBKGND
Cursor Override WM_SETCURSOR
Icon SendMessage(hwnd, WM_SETICON, iconSize, (LPARAM)hiconNew)
Comments (6)
  1. Yaron says:

    What about subclassing each individual window/control with a simple implementation that otherwise just passes everything to the previous class’ window procedure?

    [What about it? If that’s all it did, it seems like an awfully expensive nop. -Raymond]
  2. Ring Zero says:

    It would probably have been wiser for functions like SetClassLongPtr to take a WNDCLASS or an ATOM instead of an HWND. It makes more sense, and I bet nobody would’ve made the mistake of thinking the new value only applied to the one window.

  3. Norman Diamond says:

    Menu

    >SetMenu(hwnd, hmenuNew) + destroy the old menu

    It always makes me nervous, trying to figure out if an old menu (or font or whatever) should be destroyed.  If the old object belonged to a window class, and we destroy the old object, how do we know that other windows of the same class aren’t going to get in trouble?

  4. steveg says:

    I always liked the Set[Class|Window].* functions — so obviously additional memory allocated at the end of a C struct (at least to my way of thinking, could’ve been assembler originally). And definitely an interface designed by and for people of, dare I say, a bygone age.

    The other thing of note, is the lack of orthogonality in the ways the class defaults are overridden.

    I’m not saying these are bad, they’re simply not something anyone would design in 2006. Right?

  5. Yaron says:

    > What about it? If that’s all it did, it seems

    > like an awfully expensive nop.

    I think what I was trying to ask is *how much* really expensive is
    the overhead? Especially compared with the relative simplicity of then
    being able to use those class functions to change a parameter when
    needed, and, erm, let the OS worry about it?

    I agree it’s messier at runtime, but if some app requires multiple
    windows/controls like that, writing a single MakeNewClass function and
    a generic minimal window procedure for it can look more appealing then
    overriding specific messages per-control in several different window
    procedure of the application.

    BTW, off-topic, but your in-comment replies do not show up in
    comment feeds. You may want to raise a request to have a comment
    updated in the feeds when it’s edited. It’s a very safe assumption that
    your replies are important to everyone monitoring a post here, so when
    you do reply people shouldn’t see that there are no new comments on the
    post…

    [If you want to register one generic class and subclass it every time you create it, then you can do that. You can work out the overhead yourself (a few extra calls at window creation, plus a few more at every window message) – you get to decide if it’s worth it. Note of course that if you do this then anybody who tries to manipulate your program via FindWindow (e.g. your automated testing system) will be in for a surprise. If you want to request features for the blog software, you can raise them to the software vendor. -Raymond]
  6. testing123 says:

    Is automated testing systems incompatible with subclassed windows?

Comments are closed.