Advanced MFC Programming

Advanced MFC Programming Advanced MFC Programming

math.hcmuns.edu.vn
from math.hcmuns.edu.vn More from this publisher
11.04.2014 Views

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

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

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

Saved successfully!

Ooh no, something went wrong!