Redrawing the View
When the view, or some part of it, must be redrawn, the framework calls the override of the OnDraw
member function that AppWizard generated. In this topic you’ll add Scribble-specific code for OnDraw
to the ScribbleView.cpp file.
To add implementation code for the view’s OnDraw member function
Use WizardBar to jump to the starter
OnDraw
member function of classCScribbleView
.Replace the //TODO comments, after the
ASSERT_VALID(pDoc)
line, with the following code:// The view delegates the drawing of individual strokes to // CStroke::DrawStroke( ). CTypedPtrList<CObList, CStroke*>& strokeList = pDoc->m_strokeList; POSITION pos = strokeList.GetHeadPosition( ); while (pos != NULL) { CStroke* pStroke = strokeList.GetNext(pos); pStroke->DrawStroke( pDC ); }
The view uses the pointer to iterate through the stroke list, telling each stroke to draw itself. When OnDraw
calls DrawStroke
for a given stroke object, it passes along the device-context object it received as a parameter. (Having the data draw itself is only one possible strategy.)
To complete Scribble’s drawing, you must also add the DrawStroke
member function definition to class CStroke
.
To add drawing code for strokes
Add the
DrawStroke
member function definition to ScribbleDoc.cpp as shown, right after theSerialize
function. (Recall that you added its declaration when you added theCStroke
class to ScribbleDoc.h.)BOOL CStroke::DrawStroke( CDC* pDC ) { CPen penStroke; if( !penStroke.CreatePen(PS_SOLID, m_nPenWidth, RGB(0,0,0))) return FALSE; CPen* pOldPen = pDC->SelectObject( &penStroke ); pDC->MoveTo( m_pointArray[0] ); for( int i=1; i < m_pointArray.GetSize(); i++ ) { pDC->LineTo( m_pointArray[i] ); } pDC->SelectObject( pOldPen ); return TRUE; }
This code passes DrawStroke
a pointer to an object of class CDC, which encapsulates a Windows device context (DC).
Note In programs written with MFC, all graphics calls are made through a device-context object of class CDC or one of its derived classes.
DrawStroke
:
Calls CDC member functions — SelectObject, MoveTo, LineTo — through the pointer to select a graphic device interface (GDI) pen into the device context and to move the pen and draw.
Constructs a new CPen object and initializes it with the current properties by calling the pen’s CreatePen member function.
Note This two-stage construction is typical of framework objects.
Calls SelectObject to select the pen into the device context (saving the existing pen as
pOldPen
).Calls MoveTo to position the pen to the first point.
Iterates through the array of points.
Calls the device context’s LineTo member function to connect the previous point with the next point.
Restores the device context to its previous condition by reinstalling its old pen.
Important Always restore the device context to its original state before releasing it to Windows. To do so, save the state before you change it. Storing the old pen in DrawStroke
is an example of how to do this.
The addition of DrawStroke
completes Scribble’s code for drawing in response to update requests from the framework. However, Scribble also draws in response to mouse actions, as discussed in the next topic, Handling Windows Messages in the View.