Advanced MFC Programming
Advanced MFC Programming Advanced MFC Programming
Chapter 8. DC, Pen, Brush and Palette } nMode=dc.SetROP2(R2_XORPEN); if(m_bNeedErase == TRUE) { dc.Rectangle(m_rectDraw); } else m_bNeedErase=TRUE; m_rectDraw.right=point.x; m_rectDraw.bottom=point.y; dc.Rectangle(m_rectDraw); dc.SetROP2(nMode); dc.SelectObject(ptrBrushOld); brush.Detach(); dc.SelectObject(ptrPenOld); } CView::OnMouseMove(nFlags, point); Also, function CGDIView::OnDraw(…) is modified as follows: void CGDIView::OnDraw(CDC* pDC) { CPen pen; CPen *ptrPenOld; CBrush brush; CBrush *ptrBrushOld; int nMode; int nNumOfRects; int i; CGDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); } pen.CreatePen(PS_SOLID, 1, RGB(0, 255, 0)); ptrPenOld=pDC->SelectObject(&pen); brush.CreateSolidBrush(RGB(255, 0, 255)); ptrBrushOld=pDC->SelectObject(&brush); nMode=pDC->SetROP2(R2_COPYPEN); nNumOfRects=pDoc->GetNumOfRects(); for(i=0; iRectangle(pDoc->GetRect(i)); } pDC->SetROP2(nMode); pDC->SelectObject(ptrBrushOld); pDC->SelectObject(ptrPenOld); With the above implementation, the application will be able to let the user draw rectangles. With only minor modifications we can let the application draw ellipses. Sample 8.2-2\GDI demonstrates how to implement interactive ellipse drawing. It is based on sample 8.2-1\GDI. To draw an ellipse, we need to call function CDC::Ellipse(…)and pass a CRect type value to it. This is exactly the same with calling function CDC::Rectangle(…). So in the previous sample, if we change all the “Rectangle” keywords to “Ellipse”, the application will be implemented to draw ellipses instead of rectangles. In sample 8.2-2\GDI, function CDC::Ellipse(…) is called within CGDIView::OnMouseMove(…) and CGDIView::OnDraw(…). The following shows the modified portion of two functions: …… void CGDIView::OnMouseMove(UINT nFlags, CPoint point) { if(m_bNeedErase == TRUE) { dc.Ellipse(m_rectDraw); } else m_bNeedErase=TRUE; m_rectDraw.right=point.x; m_rectDraw.bottom=point.y; 210
Chapter 8. DC, Pen, Brush and Palette …… } dc.Ellipse(m_rectDraw); …… …… void CGDIView::OnDraw(CDC* pDC) { } ptrPenOld=pDC->SelectObject(&pen); brush.CreateHatchBrush(HS_CROSS, RGB(255, 0, 255)); ptrBrushOld=pDC->SelectObject(&brush); nMode=pDC->SetROP2(R2_COPYPEN); nNumOfRects=pDoc->GetNumOfRects(); for(i=0; iEllipse(pDoc->GetRect(i)); } In CGDIView::OnDraw(…), function CBrush::CreateSolidBrush(…) is also changed to CBrush:: CreateHatchBrush(…). By doing this, a different brush will be used to fill the interior of ellipse. 8.3 Curve We can call function CDC::PolyBezier(…) to draw curves. This function has two parameters: BOOL CDC::PolyBezier(const POINT* lpPoints, int nCount); The first parameter lpPoints is a pointer to an array of points, which specify the control points that can be used for drawing a curve. The second parameter nCount specifies how many control points are included in the array. We need at least four control points to draw a curve, although the last three points could be the same (In this case, a straight line will be drawn). Sample 8.3\GDI demonstrates how to implement an interactive environment that can let the user draw curves. It is a standard SDI application generated by Application Wizard. First new variable and functions are declared in the document, which will be used to store the data of curves: …… …… …… class CGDIDoc : public CDocument { public: void AddPoint(CPoint pt){m_dwaPts.Add(pt.x); m_dwaPts.Add(pt.y);} int GetNumOfPts(){return m_dwaPts.GetSize()/2;} CPoint GetOnePt(int nID) { return CPoint(m_dwaPts.GetAt(nID*2), m_dwaPts.GetAt(nID*2+1)); } protected: CDWordArray m_dwaPts; }; We use a CDWordArray type variable m_dwaPts to record control points, this class can be used to record DWORD type value, which is 32-bit integer. Because a point contains two integers, we need two DWORD type variables to store one point. So in CGDIDoc::AddPoint(…), function CDWordArray::Add(…) is called twice to add both x and y coordinates to the array. Function CGDIDoc::GetNumOfPts() returns the number of control points, which is obtained through dividing the size of the array by 2. Function CGDIDoc::GetOnePt() returns a specified control point, which is obtained from two consecutive elements contained in array m_dwaPts. Curve drawing is implemented in function CGDIView::OnDraw(…) as follows: 211
- Page 175 and 176: Chapter 6. Dialog Box } TOOLTIPTEXT
- Page 177 and 178: Chapter 6. Dialog Box ) { } if ( )
- Page 179 and 180: Chapter 6. Dialog Box pWndCtrl=GetW
- Page 181 and 182: Chapter 6. Dialog Box Sample 6.8-2\
- Page 183 and 184: Chapter 6. Dialog Box } // handle t
- Page 185 and 186: Chapter 6. Dialog Box 1) Tracking s
- Page 187 and 188: Chapter 7. Common Dialog Boxes DWOR
- Page 189 and 190: Chapter 7. Common Dialog Boxes } {
- Page 191 and 192: Chapter 7. Common Dialog Boxes } }
- Page 193 and 194: Chapter 7. Common Dialog Boxes dial
- Page 195 and 196: Chapter 7. Common Dialog Boxes Alth
- Page 197 and 198: Chapter 7. Common Dialog Boxes } NU
- Page 199 and 200: Chapter 7. Common Dialog Boxes Stc3
- Page 201 and 202: Chapter 7. Common Dialog Boxes DWOR
- Page 203 and 204: Chapter 7. Common Dialog Boxes the
- Page 205 and 206: Chapter 7. Common Dialog Boxes Comm
- Page 207 and 208: Chapter 7. Common Dialog Boxes Retr
- Page 209 and 210: Chapter 7. Common Dialog Boxes 7.9
- Page 211 and 212: Chapter 7. Common Dialog Boxes } }
- Page 213 and 214: Chapter 7. Common Dialog Boxes …
- Page 215 and 216: Chapter 7. Common Dialog Boxes …
- Page 217 and 218: Chapter 8. DC, Pen, Brush and Palet
- Page 219 and 220: Chapter 8. DC, Pen, Brush and Palet
- Page 221 and 222: Chapter 8. DC, Pen, Brush and Palet
- Page 223 and 224: Chapter 8. DC, Pen, Brush and Palet
- Page 225: Chapter 8. DC, Pen, Brush and Palet
- Page 229 and 230: Chapter 8. DC, Pen, Brush and Palet
- Page 231 and 232: Chapter 8. DC, Pen, Brush and Palet
- Page 233 and 234: Chapter 8. DC, Pen, Brush and Palet
- Page 235 and 236: Chapter 8. DC, Pen, Brush and Palet
- Page 237 and 238: Chapter 8. DC, Pen, Brush and Palet
- Page 239 and 240: Chapter 8. DC, Pen, Brush and Palet
- Page 241 and 242: Chapter 8. DC, Pen, Brush and Palet
- Page 243 and 244: Chapter 8. DC, Pen, Brush and Palet
- Page 245 and 246: Chapter 8. DC, Pen, Brush and Palet
- Page 247 and 248: Chapter 8. DC, Pen, Brush and Palet
- Page 249 and 250: Chapter 8. DC, Pen, Brush and Palet
- Page 251 and 252: Chapter 8. DC, Pen, Brush and Palet
- Page 253 and 254: Chapter 9. Font Here, member lfFace
- Page 255 and 256: Chapter 9. Font } dlg.m_bBgdStyle=m
- Page 257 and 258: Chapter 9. Font The first element o
- Page 259 and 260: Chapter 9. Font int CALLBACK EnumFo
- Page 261 and 262: Chapter 9. Font for(i=0; iGetSafeHa
- Page 263 and 264: Chapter 9. Font }; Variable m_nRang
- Page 265 and 266: Chapter 9. Font Frame border is gra
- Page 267 and 268: Chapter 9. Font CFont *ptrFont; if(
- Page 269 and 270: Chapter 9. Font POINT pt; CClientDC
- Page 271 and 272: Chapter 9. Font } if(dlg.DoModal()
- Page 273 and 274: Chapter 9. Font In this function, W
- Page 275 and 276: Chapter 9. Font } CScrollView::OnKe
Chapter 8. DC, Pen, Brush and Palette<br />
……<br />
}<br />
dc.Ellipse(m_rectDraw);<br />
……<br />
……<br />
void CGDIView::OnDraw(CDC* pDC)<br />
{<br />
}<br />
ptrPenOld=pDC->SelectObject(&pen);<br />
brush.CreateHatchBrush(HS_CROSS, RGB(255, 0, 255));<br />
ptrBrushOld=pDC->SelectObject(&brush);<br />
nMode=pDC->SetROP2(R2_COPYPEN);<br />
nNumOfRects=pDoc->GetNumOfRects();<br />
for(i=0; iEllipse(pDoc->GetRect(i));<br />
}<br />
In CGDIView::OnDraw(…), function CBrush::CreateSolidBrush(…) is also changed to CBrush::<br />
CreateHatchBrush(…). By doing this, a different brush will be used to fill the interior of ellipse.<br />
8.3 Curve<br />
We can call function CDC::PolyBezier(…) to draw curves. This function has two parameters:<br />
BOOL CDC::PolyBezier(const POINT* lpPoints, int nCount);<br />
The first parameter lpPoints is a pointer to an array of points, which specify the control points that<br />
can be used for drawing a curve. The second parameter nCount specifies how many control points are<br />
included in the array. We need at least four control points to draw a curve, although the last three points<br />
could be the same (In this case, a straight line will be drawn).<br />
Sample 8.3\GDI demonstrates how to implement an interactive environment that can let the user draw<br />
curves. It is a standard SDI application generated by Application Wizard. First new variable and functions<br />
are declared in the document, which will be used to store the data of curves:<br />
……<br />
……<br />
……<br />
class CGDIDoc : public CDocument<br />
{<br />
public:<br />
void AddPoint(CPoint pt){m_dwaPts.Add(pt.x); m_dwaPts.Add(pt.y);}<br />
int GetNumOfPts(){return m_dwaPts.GetSize()/2;}<br />
CPoint GetOnePt(int nID)<br />
{<br />
return CPoint(m_dwaPts.GetAt(nID*2), m_dwaPts.GetAt(nID*2+1));<br />
}<br />
protected:<br />
CDWordArray m_dwaPts;<br />
};<br />
We use a CDWordArray type variable m_dwaPts to record control points, this class can be used to record<br />
DWORD type value, which is 32-bit integer. Because a point contains two integers, we need two DWORD type<br />
variables to store one point. So in CGDIDoc::AddPoint(…), function CDWordArray::Add(…) is called twice<br />
to add both x and y coordinates to the array. Function CGDIDoc::GetNumOfPts() returns the number of<br />
control points, which is obtained through dividing the size of the array by 2. Function<br />
CGDIDoc::GetOnePt() returns a specified control point, which is obtained from two consecutive elements<br />
contained in array m_dwaPts.<br />
Curve drawing is implemented in function CGDIView::OnDraw(…) as follows:<br />
211