Windows NT Systems Programming

[ Home | Syllabus |Course Notes]


Palettes, Bitmaps (Chapter 12)


Video Images

Ditial Motion Video has many simlarities with digital audio,
but also significant technological, physiological and psychological difference

 


BitMapped Displays

Display Technology and Video Drivers.


The Color Dimension


Color Palettes


Mapping onto the Palette.

Pens: Map COLORREF to nearest static color

Brushes: COLORREF is dithered using static colors

How to Access the other 236 colors? (Given that it is shared among all applications?)


Logical Palettes


Creating Custom Logical Palettes

First fill in the LOGPALETTE data structures.

typedef struct tagLOGPALETTE {
    WORD         palVersion; 
    WORD         palNumEntries; 
    PALETTEENTRY palPalEntry[1]; 
} LOGPALETTE; 
and
typedef struct tagPALETTEENTRY { // pe 
    BYTE peRed; 
    BYTE peGreen; 
    BYTE peBlue; 
    BYTE peFlags; 
} PALETTEENTRY;
struct {
   LOGPALETTE lp;
   PALETTEENTRY ape[31];
} pal;
LOGPALETTE* pLP = (LOGPALETTE*) &pal;
pLP->palVersion = 0x300;
pLP->palNumEntries = 32;
// would allocate 32 colors in this palette
// after setting values for all 32 entries, create a palette with
m_palette.CreatePalette(pLP);

Realizing a Palatte


Drawing with a Logical Palette


WM_QUERYPALETTE and WM_PALETTECHANGED

Two Messages sent about palettes:

In either case, the normal response is to realize the palette and repaint.


Palette Demo

class CMainWindow : public CFrameWnd
{
private:
    CPalette m_palette;

    void DoGradientFill (CDC*, CRect*);
    void DoDrawText (CDC*, CRect*);

public:
    CMainWindow ();

protected:
    afx_msg int OnCreate (LPCREATESTRUCT);
    afx_msg BOOL OnEraseBkgnd (CDC*);
    afx_msg void OnPaint ();
    afx_msg BOOL OnQueryNewPalette ();
    afx_msg void OnPaletteChanged (CWnd*);

    DECLARE_MESSAGE_MAP ()
};

rainbow.gif (2243 bytes)


Implementation

 


#define FONTHEIGHT 72

int CMainWindow::OnCreate (LPCREATESTRUCT lpcs)
{
    if (CFrameWnd::OnCreate (lpcs) == -1)
        return -1;

    CClientDC dc (this);
    if (dc.GetDeviceCaps (RASTERCAPS) & RC_PALETTE) {
        struct {
            LOGPALETTE lp;
            PALETTEENTRY ape[63]; // 64 shades of blue
        } pal;

        LOGPALETTE* pLP = (LOGPALETTE*) &pal;
        pLP->palVersion = 0x300;
        pLP->palNumEntries = 64;

        for (int i=0; i<64; i++) {
            pLP->palPalEntry[i].peRed = 0;
            pLP->palPalEntry[i].peGreen = 0;
            pLP->palPalEntry[i].peBlue = 255 - (i * 4); // From Black to Blue
            pLP->palPalEntry[i].peFlags = 0;
        }
        m_palette.CreatePalette (pLP); // Create this blue palette
    }
    return 0;
}

BOOL CMainWindow::OnEraseBkgnd (CDC* pDC)
{
    CRect rect;
    GetClientRect (&rect);
// return true; // this returns without painting a new background - so you get a transparent window - try it
    CPalette* pOldPalette;
    if ((HPALETTE) m_palette != NULL) {
        pOldPalette = pDC->SelectPalette (&m_palette, FALSE);
        pDC->RealizePalette ();
    }

    DoGradientFill (pDC, &rect);

    if ((HPALETTE) m_palette != NULL)
        pDC->SelectPalette (pOldPalette, FALSE);
    return TRUE;
}

void CMainWindow::OnPaint ()
{
    CRect rect;
    GetClientRect (&rect);

    CPaintDC dc (this);
    DoDrawText (&dc, &rect);
}

BOOL CMainWindow::OnQueryNewPalette ()
{
    if ((HPALETTE) m_palette == NULL)   // Shouldn't happen, but
        return 0;                       // let's be sure

    CClientDC dc (this);
    CPalette* pOldPalette = dc.SelectPalette (&m_palette, FALSE);

    UINT nCount;
    if (nCount = dc.RealizePalette ())
        Invalidate ();

    dc.SelectPalette (pOldPalette, FALSE);
    return nCount;
}

void CMainWindow::OnPaletteChanged (CWnd* pFocusWnd)
{
    if ((HPALETTE) m_palette == NULL)   // Shouldn't happen, but
        return;                         // let's be sure

    if (pFocusWnd != this) {
        CClientDC dc (this);
        CPalette* pOldPalette = dc.SelectPalette (&m_palette, FALSE);
        if (dc.RealizePalette ())
            Invalidate ();
        dc.SelectPalette (pOldPalette, FALSE);
    }
}

void CMainWindow::DoGradientFill (CDC* pDC, CRect* pRect)
{
    CBrush* pBrush[64];
    for (int i=0; i<64; i++) // Create 64 blue brushes
        pBrush[i] = new CBrush (PALETTERGB (0, 0, 255 - (i * 4)));
// This requests many shades of blue brushes, but logical palette created before must have them assigned

    int nWidth = pRect->Width ();
    int nHeight = pRect->Height ();
    CRect rect;

    for (i=0; i<nHeight; i++) {
        rect.SetRect (0, i, nWidth, i + 1); // rectangle = one line
        pDC->FillRect (&rect, pBrush[(i * 63) / nHeight]); // fill with nearest blue brush
    }

    for (i=0; i<64; i++)
        delete pBrush[i]; // prevent memory leaks
}

void CMainWindow::DoDrawText (CDC* pDC, CRect* pRect)
{
    CFont font;
    int nHeight = -((pDC->GetDeviceCaps (LOGPIXELSY) * FONTHEIGHT) / 72);

    font.CreateFont (nHeight, 0, 0, 0, FW_BOLD, TRUE, 0, 0,
        DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
        DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Times New Roman");

    pDC->SetBkMode (TRANSPARENT);
	//pDC->SetBkColor(RGB(255,0,255)); // use this to change background around text object
    pDC->SetTextColor (RGB (255, 255, 255)); // Display white text
	
    CFont* pOldFont = pDC->SelectObject (&font);
    pDC->DrawText ("Hello, MFC", -1, pRect, DT_SINGLELINE | DT_CENTER |
        DT_VCENTER);

    pDC->SelectObject (pOldFont);
}

rainbow.gif (2243 bytes)


BitMaps

 


DDB and CBitmap Class

CClientDC dcScreen (this);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dcScreen, 100, 100);
CDC dcMem;
dcMem.CreateCompatibleDC(&dcScreen);
CBrush brush(RGB(0,0,255));
CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);
dcMem.FillRect(CRect(0,0,100,100), &brush);
dcMem.SelectObject(pOldBitmap);

 

rainbow.gif (2243 bytes)


BLITting

Need to block transfer bitmaps
Can't simply select a bit map into a screen (nonmemory) DC

Can get properties of a bitmap by calling the GetObject function.

typedef struct tagBITMAP {
	LONG bmType;	// always 0
	LONG bmWidth;	// in PIXELs
	LONG bmHeight;
	LONG bmWidthBytes; // length in bytes of one line
	WORD bmPlanes;  // number of color planes
	WORD bmBitsPixel; // number of bits for each color
	LPVOID bmBits;	// pointer to actual bits NULL if DDB
} BITMAP;

Loading Bitmap Resources


Copyright chris wild 1997.
For problems or questions regarding this web contact [Dr. Wild].
Last updated: November 10, 1997.