`SetWindowLong()` function doesn't change window style even after calling `SetWindowPos()`

3.6k views Asked by At

normal static control sunken static control

I create the static control with the code below:

hWnd = CreateWindowExW( 0,
                        L"STATIC",
                        Content.c_str(),
                        SS_LEFT | WS_VISIBLE | WS_CHILD /*| SS_SUNKEN*/,
                        200,
                        120,
                        120,
                        40,
                        hWndParent,
                        NULL,
                        hInstance,
                        NULL);

If I enable the SS_SUNKEN style in the creation code above, the created static control appears sunken successfully.

But, what I'm trying to do is the change the control style after its creation.
I tried this:

void BaseWindowClass::AddStyle(DWORD NewStyle)
{
    // NewStyle     = 0x00001000 = SS_SUNKEN
    LONG oldstyle, changedstyle;
    oldstyle=SetWindowLongW(hWnd, GWL_STYLE, changedstyle=GetWindowLongW(hWnd, GWL_STYLE) | NewStyle);
    UpdateWindowStyles();
    // oldstyle     = 0x50000000
    // changedstyle = 0x50001000 (everything looks normal)
}
void BaseWindowClass::UpdateWindowStyles()
{
    BOOL success;
    success=SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    // success = 0x00000001 (non-zero: SetWindowPos sucseeded)
}

Documentation:
SetWindowLong()
SetWindowPos()

I call SetWindowPos() after calling SetWindowLongW() because in the documentation of SetWindowLong, it says:

Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function. Specifically, if you change any of the frame styles, you must call SetWindowPos with the SWP_FRAMECHANGED flag for the cache to be updated properly.

And, in the documentation of SetWindowPos, it says:

If you have changed certain window data using SetWindowLong, you must call SetWindowPos for the changes to take effect. Use the following combination for uFlags: SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED.

Even after changing SetWindowLongW() and SetWindowPos() the style of my static control does not change.

What am I doing wrong, or what am I missing?

2

There are 2 answers

0
Eric Brown On

SS_SUNKEN effectively sets WS_EX_STATICEDGE in the extended styles (GWL_EXSTYLE) window long, so you can update GWL_EXSTYLE appropriately and reposition as you're currently doing.

1
Jonathan Potter On

Even though SS_SUNKEN does affect the frame of a static control, it isn't one of the "frame styles" that note is referring to.

That note refers to generic frame styles that affect all windows like WS_BORDER or WS_EX_CLIENTEDGE - styles that require a recalculation of a window's non-client area when changed.

Many of the system controls cache their styles upon creation and don't update the cache even if you change the styles via SetWindowLong. I would guess that's what's happening here - if you don't create the static control with SS_SUNKEN, you can't add it later. Your best option would be to simply destroy and recreate the control with the new style.