Working with Palettes (Windows Embedded CE 6.0)

1/6/2010

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 Embedded CE has no standard color palette and creates a default palette each time you create a device context. Windows Embedded 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 Embedded CE–defined colors. Printer devices might use other default colors. If you specify a pen or text color not in the default palette, Windows Embedded CE approximates the display color with the closest color in the palette. When displaying bitmaps, Windows Embedded CE assigns colors to a bitmap based on the bitmap's associated color table. If an image has no color table, Windows Embedded 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 Embedded 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 Embedded CE supports both palletized and non-palletized color display devices. Palletized devices have a color palette coded directly into their display card. Non-palletized 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.

To create a logical color palette

  1. Assign values to the members of a LOGPALETTE structure and pass a pointer to the structure to the CreatePalette function.

    The function returns a handle to a logical palette with the values specified in the LOGPALETTE structure.

  2. Call the SelectPalette function to select the palette into the current device context.

  3. Call the RealizePalette function to make the system palette the same as the palette in the current device context.

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 Embedded 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 Embedded 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.

Note

To make the following code example easier to read, error checking is not included. Do not use this code example in a release configuration unless you have modified it to include secure error handling.

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;
}

See Also

Concepts

Graphics Device Interface (GDI)