Types of Palette Entries in Windowed Mode

Unlike full-screen exclusive mode applications, windowed applications must share the desktop palette with other applications. This imposes several restrictions on which palette entries you can safely modify and how you can modify them. The PALETTEENTRY structure you use when working with DirectDrawPalette objects and GDI contains a peFlags member to carry information that describes how the system should interpret the PALETTEENTRY structure.

The peFlags member describes three types of palette entries, discussed in this topic:

Windows static entries

In normal mode, Windows reserves palette entries 0 through 9 and 246 through 255 for system colors that it uses to display menu bars, menu text, window borders, and so on. In order to maintain a consistent look for your application and avoid damaging the appearance of other applications, you need to protect these entries in the palette you set to the primary surface. Often, developers retrieve the system palette entries by calling the GetSystemPaletteEntries Win32® function, then explicitly set the identical entries in a custom palette to match before assigning it to the primary surface. Duplicating the system palette entries in a custom palette will work initially, but it becomes invalid if the user changes the desktop color scheme.

To avoid having your palette look bad when the user changes color schemes, you can protect the appropriate entries by providing a reference into the system palette instead specifying a color value. This way, no matter what color the system is using for a given entry, your palette will always match and you won't need to do any updating. The PC_EXPLICIT flag, used in the peFlags member, makes it possible for you to directly refer to a system palette entry. When you use this flag, the system no longer assumes that the other structure members include color information. Rather, when you use PC_EXPLICIT, you set the value in the peRed member to the desired system palette index and set the other colors to zero.

For instance, if you want to ensure that the proper entries in your palette always match the system's color scheme, you could use the following code:

// Set the first and last 10 entries to match the system palette.
PALETTEENTRY pe[256];
ZeroMemory(pe, sizeof(pe));
for(int i=0;i<10;i++){
    pe[i].peFlags  = pe[i+246].peFlags = PC_EXPLICIT;
    pe[i].peRed = i;
    pe[i+246].peRed = i+246;
} 
 

You can force Windows to use only the first and last palette entry (0 and 255) by calling the SetSystemPaletteUse Win32 function. In this case, you should set only entries 0 and 255 of your PALETTEENTRY structure to PC_EXPLICIT.

Animated entries

You specify palette entries that you will be animating by using the PC_RESERVED flag in the corresponding PALETTEENTRY structure. Windows will not allow any other application to map its logical palette entry to that physical entry, thereby preventing other applications from cycling their colors when your application animates the palette.

Nonanimated entries

You specify normal, nonanimated palette entries by using the PC_NOCOLLAPSE flag in the corresponding PALETTEENTRY structure. The PC_NOCOLLAPSE flag informs Windows not to substitute some other already-allocated physical palette entry for that entry.