19.6.2 Responding to the WM_PALETTECHANGED Message

Windows sends the WM_PALETTECHANGED message to all overlapped and pop-up windows when any window changes the system palette by realizing its logical palette. The wParam parameter of this message contains the handle of the window that realized its palette. If your window responds to this message by realizing its own palette, to avoid creating a loop you should first determine that this handle is not the handle of your window.

When an inactive window receives the WM_PALETTECHANGED message, it has three options:

It can do nothing. In this case, the colors displayed in the window's client area potentially will be incorrect until the window updates its client area. Consider this option only if color quality is unimportant to your application when its windows are inactive or if your application does not use a palette.

It can realize its logical palette and redraw its client area. This option ensures that the colors displayed in the window's client area will be as correct as possible, because Windows updates the colors in the client area by using the window's logical palette. This accuracy does increase the time required to redraw the client area, however. So if the quality of the colors displayed by your inactive window is crucial to your application, or if the image contained in your window's client area can be redrawn quickly, choose this option.

It can realize its logical palette and directly update the colors in its client area. This option provides a reasonable compromise between performance and color quality. A window directly updates the colors in its client area by realizing its palette and then calling the UpdateColors function. When an application calls UpdateColors, Windows quickly updates the client area by matching the current colors in the client area pixel by pixel to the system palette. Since the match is made based on the color of the pixel before the system palette changed rather than on the contents of the window's logical palette, the accuracy of the match decreases each time the window calls UpdateColors. Consequently, if color accuracy is of any importance to your application when your windows are inactive, limit the number of times the application calls UpdateColors for a window before repainting the window's client area.

The following demonstrates how ShowDIB updates its client area in response to the WM_PALETTECHANGED message:

case WM_PALETTECHANGED:

        /*
         * If SHOWDIB was not responsible for palette
         * change and if palette realization causes a
         * palette change, redraw.
         */

         if (wParam != (WPARAM) hWnd) {
            if (fLegitDraw) {
                hDC = GetDC(hWnd);
                hOldPal = SelectPalette(hDC, hpalCurrent, 0);

                i = RealizePalette(hDC);





                if (i) {
                    if (fUpdateColors) {
                        UpdateColors(hDC);
                        UpdateCount++;
                    }
                    else
                        InvalidateRect(hWnd, (RECT FAR*) NULL, 1);
                }

                SelectPalette(hDC, hOldPal, 0);
                ReleaseDC(hWnd, hDC);
            }
        }
        break;

When ShowDIB receives the WM_PALETTECHANGED message, it first determines whether the wParam parameter contains its own window handle. This would indicate that it was the window that had realized its logical palette and so no response is needed. After selecting and realizing its logical palette, the window determines whether a flag was set indicating that the user had chosen the Update Colors command from the Options menu. If the user had done so, the window calls UpdateColors to update its client area and sets a flag to indicate that it has directly updated its colors. Otherwise, the window invalidates its client area, forcing it to be redrawn.