11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 11. Sample: Simple Paint<br />

case default function CBitmapButton::DrawItem(…) will be called). If we do not override this function, we<br />

will not be notified when buttons need to be updated.<br />

Since this sample is supposed to be used for palette device (Of course, it can be run on a non-palette<br />

device), we will let each button display a color contained in a different entry of the logical palette. In order<br />

to do this, we should let different button have a different index that represents a different entry of the<br />

logical palette. For this purpose, a variable m_nPalIndex and two functions (GetPaletteIndex() and<br />

SetPaletteIndex(…)) are added to class CColorButton. In function CColorButton::DrawItem(…), this<br />

value is used as the index to the application’s logical palette for button drawing:<br />

……<br />

……<br />

else<br />

{<br />

pDC=CDC::FromHandle(lpDrawItemStruct->hDC);<br />

pPalOld=pDC->SelectPalette(pPal, FALSE);<br />

pDC->RealizePalette();<br />

pDC->FillSolidRect<br />

(<br />

&lpDrawItemStruct->rcItem,<br />

PALETTEINDEX(m_nPalIndex)<br />

);<br />

pDC->SelectPalette(pPalOld, FALSE);<br />

}<br />

We use macro PALETTEINDEX to retrieve the actual color contained in the palette entry. As usual, before<br />

doing any drawing, we have to select the logical palette into the DC and realize it.<br />

Class CFBButton is similar. Two variables m_BgdIndex and m_FgdIndex are added to class CGDIDoc<br />

representing the currently selected foreground and background colors. Their values can be retrieved and set<br />

through calling functions CGDIDoc::GetBgdIndex(), CGDIDoc::GetFgdIndex(), CGDIDoc::<br />

SetBgdIndex(…), CGDIDoc::SetFgdIndex(…). Two variables are declared in the document class instead of<br />

color bar class because their values may need to be accessed from the view. Since the document is the<br />

center of the application, we should put the variables in the document so that they can be easily accessed<br />

from other classes.<br />

Function CFBButton::Drawitem(…) implements drawing a rectangle filled with current background<br />

color overlapped by another rectangle filled with current foreground color. Like class CColorButton, the<br />

color is retrieved from the logical palette contained in the document. The following code fragment shows<br />

how the background rectangle is drawn:<br />

……<br />

……<br />

brush.CreateSolidBrush(PALETTEINDEX(nBgdIndex));<br />

rect=lpDrawItemStruct->rcItem;<br />

rect.InflateRect(-2, -2);<br />

rect.left+=rect.Width()/4;<br />

rect.top+=rect.Height()/4;<br />

pBrOld=pDC->SelectObject(&brush);<br />

pDC->Rectangle(rect);<br />

pDC->DrawEdge(rect, EDGE_ETCHED, BF_RECT);<br />

pDC->SelectObject(pBrOld);<br />

Variable nBgdIndex is an index to the logical palette, the whole area that needs to be painted is<br />

specified by lpDrawItemStruct->rcItem (lpDrawItemStruct is the pointer passed to function<br />

DrawItem(…)). When drawing the rectangle, we see that a margin of 2 is left first (This is done through<br />

calling function CRect:: InflateRect(…)), then the width and height of the rectangle are set to ¾ of their<br />

original values. The foreground rectangle has the same dimension, but overlaps the background rectangle.<br />

To add more fluff to the application, the border of both rectangles has a 3D effect, which is implemented by<br />

calling function CDC::DrawEdge(…).<br />

340

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!