19.4.2 Indirectly Specifying Palette Colors

Using an index into a logical palette allows your application greater control over the colors displayed. This method becomes impractical, however, when dealing with a device that has 2^24 colors with no system palette. On a device capable of supporting full 24-bit color, this limits your application to displaying only the colors in your logical palette. By specifying palette colors indirectly, you can avoid this limitation.

You specify a palette color indirectly by using a palette-relative RGB COLORREF value instead of a palette index. A palette-relative RGB value is a 32-bit value that has the second bit in the high-order byte set to 1 and one-byte values for red, green, and blue in the remaining bytes. The PALETTERGB macro accepts three values that indicate the relative intensity of red, green, and blue, and returns a palette-relative RGB COLORREF value, which, like a palette-index COLORREF value, you can use in place of an explicit RGB COLORREF value for functions that require a color.

By specifying a palette-relative RGB value instead of a palette index, your application can draw to an output device by using palette colors, without having to determine first whether the device supports a system palette. The following table shows how Windows interprets a palette-relative RGB value.

Device supports
a system palette?

How Windows uses a palette-relative RGB value

Yes Windows matches the RGB information to the nearest color in the currently selected logical palette and uses that palette entry as though the application had directly specified the entry.
No Windows uses the RGB information as though the palette-relative RGB were an explicit RGB value.

For example, assume your application includes the following statements:

pLogPal->palPalEntry[5].pRed = 0xFF;
pLogPal->palPalEntry[5].pGreen = 0x00;
pLogPal->palPalEntry[5].pBlue = 0x00;
CreatePalette((LPSTR) &pa);
crRed = PALETTERGB(0xFF, 0x00, 0x00);

If the target output device supports a system palette, crRed would be equivalent to this:

crRed = PALETTEINDEX(5);

If the output device does not support a system palette, however, crRed would be equivalent to this:

crRed = RGB(0xFF, 0x00, 0x00);

Even when using a logical palette, an application can use an explicit RGB value to specify color. In such cases, Windows displays the color as it would for an application that does not use a color palette, by displaying the nearest color in the default palette. If an application creates a solid brush by using an explicit RGB value, Windows simulates the color by dithering—that is, producing a pattern of pixels made up of colors in the default palette.