Search code examples
cwindowswinapigdi

Meaning of the WM_SYSCOLORCHANGE message


From documentation:

WM_SYSCOLORCHANGE message is sent to all top-level windows when a change is made to a system color setting.

Applications that have brushes using the existing system colors should delete those brushes and re-create them using the new system colors.

Declare global variable

HBRUSH g_hBackground = NULL;

In WM_CREATE message handler create background brush

case WM_CREATE:
g_hBackground = (HBRUSH)(COLOR_3DFACE + 1);
break;

Use brush in paint message

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &rcClient, g_hBackground);
EndPaint(hwnd, &ps);
break;

Handle system color change

case WM_SYSCOLORCHANGE:
if (g_hBackground)
{
    DeleteObject(g_hBackground);
}

g_hBackground = (HBRUSH)(COLOR_3DFACE + 1);
break;

Now, I change system color in control panel, everything works, background is painted with new color.

Delete all WM_SYSCOLORCHANGE handler code, I change system color in control panel, everything works too, background is painted with new color.

So why I need this message?

THE QUESTION

What is the meaning this message for the top-level window?

Only forwarding this message to the child windows? Or I missed something?


Solution

  • This was important in the early days when displays could only display 256 colors. (Or if your system boots in Safe Mode when Windows can't access a native true color display mode.) A system color change meant a (potential) change in the palette, so applications would have to adjust which color index they would use to draw their windows.

    These days, if you change a color from (for example) green to blue, any window or control that uses that RGB color for drawing needs to be notified of the updated color so that it conform to the new color scheme. Brushes created from an index color like COLOR_3D_FACE or via a call to GetSysColorBrush() will automatically use the new color on the next redraw.

    If you call CreateSolidBrush based off of a system color (GetSysColor()), you'll need to update the brush (recreate it) when you receive the WM_SYSCOLORCHANGE message.