The last task is to take advantage of the hint so the other views can repaint themselves more efficiently. This involves modifying the CScribbleView
class by overriding the OnUpdate
function to respond to any hint it receives.
In Scribble Lesson 6, Binding Visual Objects to Code Using WizardBar, you saw how to use WizardBar to connect user-interface objects to their message-handler functions. You can also use WizardBar to override functions inherited from the base class, which are not attached to user-interface objects. The following procedure illustrates this point.
Note To use WizardBar to override OnUpdate
, file ScribbleView.cpp must be open in the text editor.
To add the OnUpdate function to Scribble
The New Virtual Override dialog box appears.
OnUpdate
. // The document has informed this view that some data has changed.
if (pHint != NULL)
{
if (pHint->IsKindOf(RUNTIME_CLASS(CStroke)))
{
// The hint is that a stroke has been added (or changed).
// So, invalidate its rectangle.
CStroke* pStroke = (CStroke*)pHint;
CRect rectInvalid = pStroke->GetBoundingRect();
InvalidateRect(&rectInvalid);
return;
}
}
// We can't interpret the hint, so assume that anything might
// have been updated.
Invalidate();
return;
Remember, this function is called by the UpdateAllViews
function of CScribbleDoc
, which passes it a hint. In this function, the view checks if the hint is a CStroke
object. If so, the view gets the bounding rectangle for the stroke and marks it as invalid. This rectangle marks the area that must be redrawn. If the hint isn’t a CStroke
object, the view doesn’t know what area was modified, so it invalidates the entire client area as a precaution.
After a region has been invalidated, Windows sends a WM_PAINT message. The OnPaint member function defined by CView handles this message by calling the virtual OnDraw
member function. Consequently, you must modify the OnDraw
function to take advantage of the invalidated rectangle when redrawing.
OnDraw
member function in class CScribbleView
, and add the following code just after the ASSERT_VALID(pDoc)
line:// Get the invalidated rectangle of the view, or in the case
// of printing, the clipping region of the printer DC.
CRect rectClip;
CRect rectStroke;
pDC->GetClipBox(&rectClip);
//Note: CScrollView::OnPaint() will have already adjusted the
//viewpoint origin before calling OnDraw(), to reflect the
//currently scrolled position.
CStroke* pStroke = strokeList.GetNext(pos)
line:rectStroke = pStroke->GetBoundingRect();
if (!rectStroke.IntersectRect(&rectStroke, &rectClip))
continue;
In the OnDraw
function, the view first calls the GetClipBox member function of CDC to get the invalidated portion of the client area. Then the view iterates through the list of strokes in the document, calling IntersectRect
for each to determine if any part of the stroke lies in the invalidated region. If so, the view asks the stroke to draw itself. Any strokes that don’t intersect the invalidated region don’t have to be redrawn.
Note This is a good point to compile your changes and test the window updating.
To test your update code