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

  1. Use WizardBar to jump to the starter OnDraw member function of class CScribbleView.

  2. 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 the Serialize function. (Recall that you added its declaration when you added the CStroke 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:

  1. 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.

  2. 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.

  3. Calls SelectObject to select the pen into the device context (saving the existing pen as pOldPen).

  4. Calls MoveTo to position the pen to the first point.

  5. Iterates through the array of points.

  6. Calls the device context’s LineTo member function to connect the previous point with the next point.

  7. 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.