Open GL Super Bible

Previous Table of Contents Next

Listing 21-2 CPalette creation and initialization code

// Initializes the CPalette object
void CMfcglView::InitializePalette(void)
        PIXELFORMATDESCRIPTOR pfd;   // Pixel format descriptor
        LOGPALETTE *pPal;            // Pointer to memory for logical
        int nPixelFormat;            // Pixel format index
        int nColors;                 // Number of entries in palette
        int i;                       // Counting variable

        BYTE RedRange,GreenRange,BlueRange;
                               // Range for each color entry (7,7,and 3)

        // Get the pixel format index and retrieve the pixel format
        nPixelFormat = GetPixelFormat(m_hDC);
        DescribePixelFormat(m_hDC, nPixelFormat,
        sizeof(PIXELFORMATDESCRIPTOR), &pfd);

        // Does this pixel format require a palette?  If not, do not
           create a
        // palette and just return NULL
        if(!(pfd.dwFlags & PFD_NEED_PALETTE))

        // Number of entries in palette.  8-bit yields 256 entries
        nColors = 1 << pfd.cColorBits;

        // Allocate space for a logical palette structure plus all the
        // palette entries
        pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE)

        // Fill in palette header
        pPal->palVersion = 0x300;        // Windows 3.0
        pPal->palNumEntries = nColors;   // table size

        // Build mask of all 1's.  This creates a number represented
           by having
        // the low-order x bits set, where x = pfd.cRedBits,
        // and pfd.cBlueBits.
        RedRange = (1 << pfd.cRedBits) - 1;
        GreenRange = (1 << pfd.cGreenBits) - 1;
        BlueRange = (1 << pfd.cBlueBits) - 1;

        // Loop through all the palette entries
        for(i = 0; i < nColors; i++)
                // Fill in the 8-bit equivalents for each component
                pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) &
                pPal->palPalEntry[i].peRed = (unsigned char)(
                        (double) pPal->palPalEntry[i].peRed * 255.0 /

                pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) &
                pPal->palPalEntry[i].peGreen = (unsigned char)(
                        (double)pPal->palPalEntry[i].peGreen * 255.0/

                pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) &
                pPal->palPalEntry[i].peBlue = (unsigned char)(
                        (double)pPal->palPalEntry[i].peBlue * 255.0 /

                pPal->palPalEntry[i].peFlags = (unsigned char) NULL;

// Create the palette

// Go ahead and select and realize the palette for this device context

// Free the memory used for the logical palette structure

Using the Class Wizard again to add message response functions for WM_QUERYNEWPALETTE and WM_PALETTECHANGED, our code to realize the palette is shown in Listing 21-3.

Listing 21-3 Code to realize CPalette for the view class

BOOL CMfcglView::OnQueryNewPalette()
        // If the palette was created.
                int nRet;

                // Selects the palette into the current device context
                SelectPalette(m_hDC, (HPALETTE)m_GLPalette, FALSE);

                // Map entries from the currently selected palette to
                // the system palette.  The return value is the number
                // of palette entries modified.
                nRet = RealizePalette(m_hDC);

                // Repaint, forces remap of palette in current window
                return nRet;

        return CView::OnQueryNewPalette();

void CMfcglView::OnPaletteChanged(CWnd* pFocusWnd)
        if(((HPALETTE)m_GLPalette != NULL) && (pFocusWnd != this))
               // Select the palette into the device context

        // Map entries to system palette

        // Remap the current colors to the newly realized palette


This code to realize the palette is very much like that in Chapter 8. Here, though, Windows does not send these messages to the CView-derived class directly, but rather to the application’s CMainFrame class. This is because Windows only sends palette messages to the application’s main window; it is this window’s responsibility to route the messages to any child windows that need to be notified.

Previous Table of Contents Next