A palette is a collection that contains the colors that can be displayed on an output device. Palettes are used by devices that can display only a subset of their potential colors at any specified time.
Windows CE has no standard color palette and creates a default palette each time you create a device context. Windows CE bases this palette on the device capabilities. Most devices have 256 colors. Display devices, for example, often use the 16 standard video graphics adapter (VGA) colors and 4 other Windows CE–defined colors. Printer devices might use other default colors. If you specify a pen or text color not in the default palette, Windows CE approximates the display color with the closest color in the palette. When displaying bitmaps, Windows CE assigns colors to a bitmap based on the bitmap's associated color table. If an image has no color table, Windows CE uses the color palette in the currently selected device context.
You cannot change the entries in the default palette. However, you can create your own logical palette and select the palette into a device context in place of the default palette. You can use logical palettes to define and use colors that meet your specific needs. Windows CE enables you to create multiple logical palettes. You can attach each logical palette to a unique device context or you can switch between multiple logical palettes in a single device context.
Windows CE supports both palettized and non-palettized color display devices. Palettized devices have a color palette coded directly into their display card. Non-palettized devices use pixel bit values in the video memory to directly define colors in terms of their RGB values. You can use the GetDeviceCaps function to determine if a device supports color palettes.
The function returns a handle to a logical palette with the values specified in the LOGPALETE structure.
Your logical palette should have just enough entries to represent the colors you need. You can call the GetDeviceCaps function with the SIZEPALETTE index to retrieve the maximum palette size associated with a device.
When working with palettes, you can change the colors in an existing logical palette as well as retrieve color values. The following table shows how to modify the color palette.
To |
Call |
Change the colors in an existing logical palette. | SetPaletteEntries |
Update the display after changing or creating a palette. | RealizePalette |
Retrieve the color values for a logical palette. | GetPaletteEntries |
Retrieve the value in a specified logical palette that most closely matches a specified color value. | GetNearestPaletteIndex |
Delete a logical palette. Be sure that the logical palette is not selected into a device context when you delete it. | DeleteObject |
Note The GetSystemPaletteEntries and RealizePalette functions will fail if the device associated with the selected device index does not have a palette that you can set. Call GetDeviceCaps to determine if the device has a palette that you can set.
Windows CE does not arbitrate between the palettes of the background and foreground applications. The application running in the foreground controls the system palette. Applications that use colors other than standard Windows colors might not display properly when they run in the background. Windows CE does not perform any color matching operations between the foreground and background applications; therefore, background applications cannot successfully call RealizePalette.
The following code example shows how to create color palettes.
HPALETTE CreateScalePalette (HDC hDC, int iColor)
{
HPALETTE hPalette = NULL; // Handle of the palette to be created
LPLOGPALETTE lpMem = NULL; // Buffer for the LOGPALETTE structure
// which defines the palette
int index, // An integer
iReserved, // Number of reserved entries in the
// system palette
iRasterCaps; // Raster capabilities of the display
// device context
// Retrieve the raster capabilities of the display device context.
// Check if it is capable of specifying a palette-based device, then
// determine the number of entries in the logical color palette.
iRasterCaps = GetDeviceCaps (hDC, RASTERCAPS);
iRasterCaps = (iRasterCaps & RC_PALETTE) ? TRUE : FALSE;
if (iRasterCaps)
{
iReserved = GetDeviceCaps (hDC, NUMRESERVED);
iPalSize = GetDeviceCaps (hDC, SIZEPALETTE) - iReserved;
}
else
iPalSize = GetDeviceCaps (hDC, NUMCOLORS);
// If there cannot be any entries in the logical color palette, exit.
if (iPalSize <= 0)
{
MessageBox (g_hwndMain,
TEXT("Palette can't be created, there can't be any")
TEXT("entries in it."),
TEXT("Info"),
MB_OK);
goto exit;
}
// Allocate a buffer for the LOGPALETTE structure.
if (!(lpMem = (LOGPALETTE *) LocalAlloc (LMEM_FIXED,
sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * iPalSize)))
goto exit;
lpMem->palNumEntries = (WORD) iPalSize;
lpMem->palVersion = (WORD) 0x0300;
switch(iColor)
{
case 0: // Red color component only
for (index = 0; index < iPalSize; index++)
{
lpMem->palPalEntry[index].peRed = (BYTE) index;
lpMem->palPalEntry[index].peGreen = 0;
lpMem->palPalEntry[index].peBlue = 0;
lpMem->palPalEntry[index].peFlags = 0;
}
break;
case 1: // Green color component only
for (index = 0; index < iPalSize; index++)
{
lpMem->palPalEntry[index].peRed = 0;
lpMem->palPalEntry[index].peGreen = (BYTE) index;
lpMem->palPalEntry[index].peBlue = 0;
lpMem->palPalEntry[index].peFlags = 0;
}
break;
case 2: // Blue color component only
for (index = 0; index < iPalSize; index++)
{
lpMem->palPalEntry[index].peRed = 0;
lpMem->palPalEntry[index].peGreen = 0;
lpMem->palPalEntry[index].peBlue = (BYTE) index;
lpMem->palPalEntry[index].peFlags = 0;
}
break;
case 3: // Grayscale palette
default:
for (index = 0; index < iPalSize; index++)
{
lpMem->palPalEntry[index].peRed = (BYTE) index;
lpMem->palPalEntry[index].peGreen = (BYTE) index;
lpMem->palPalEntry[index].peBlue = (BYTE) index;
lpMem->palPalEntry[index].peFlags = 0;
}
break;
}
// Create the palette.
hPalette = CreatePalette (lpMem);
// Free the memory object lpMem.
LocalFree ((HLOCAL) lpMem);
exit:
return hPalette;
}