Add Scrolling to Scribble

The following procedures describe how to perform the first three tasks involved in adding scrolling to Scribble, as described in the previous topic, Basic Tasks for Adding Scrolling. In the topic, Working with GDI Coordinates, you’ll see how to perform the fourth task.

Suggested Reading in the Microsoft Foundation Class Reference

To add scrolling support to Scribble

  1. In ClassView, double-click CScribbleDoc.

    ScribbleDoc.h is displayed in the text editor.

  2. In the text editor, scroll to the //Attributes section and add the following code after public:
    protected:
    CSize m_sizeDoc;
    public:
    CSize GetDocSize() { return m_sizeDoc; }
    

    This defines the size of Scribble documents by having each document store its dimensions. The member variable m_sizeDoc stores the size of the document in a CSize object. This member is protected, so it cannot be accessed directly by the views attached to the document. To let the views retrieve the size of the document, you provide a public helper function named GetDocSize. The views base their scrolling limits on the document size.

    Jump to the Serialize member function in CScribbleDoc and add the following line of code after the if branch, in place of the //TODO comments for storing:

    ar << m_sizeDoc;
    
  3. Add the matching line just after the else branch:
    ar >> m_sizeDoc;
    

    The changes to the Serialize member function store and read the m_sizeDoc member variable.

  4. In ClassView, double-click the member function InitDocument.

    ScribbleDoc.cpp is displayed in the text editor.

  5. In the text editor, add the following code after the call to ReplacePen:
    // Default document size is 800 x 900 screen pixels.
    m_sizeDoc = CSize(800,900);
    

    The new code in the InitDocument member function initializes the m_sizeDoc member variable. Recall that you use this function whenever a new document is created or an existing document is opened. All Scribble documents are the same size: 800 logical units in width and 900 logical units in height. For simplicity’s sake, Scribble doesn’t support documents of varying size.

  6. In ClassView, double-click CScribbleView to return to the CScribbleView class definition and, in the text editor, specify that it be derived from class CScrollView (instead of class CView):
    class CScribbleView : public CScrollView
    

    Recall that MFC uses message maps as well as C++ inheritance. As a result, modifying the class definition in the header file isn’t enough to give CScribbleView all of CScrollView’s functionality. You also have to modify the message-map macros in the implementation file.

  7. In ScribbleView.cpp, change the reference to CView in the following lines to refer to CScrollView instead:
    IMPLEMENT_DYNCREATE( CScribbleView, CScrollView )
    
    BEGIN_MESSAGE_MAP( CScribbleView, CScrollView )
    

    In the message-map macro, referencing CScrollView instead of CView instructs the framework to search CScrollView’s message map if it can’t find the message handler it needs in CScribbleView’s message map.

  8. If you want to use the diagnostic features provided by MFC, change the implementations of the Dump and AssertValid member functions of CScribbleView. These functions simply call their base class versions; change them to call the CScrollView versions rather than the CView versions.

These changes set the document’s scrolling limits according to the size of the document. By changing the base class of CScribbleView from CView to CScrollView, you give CScribbleView scrolling functionality without having to implement scrolling yourself.

Since Scribble documents are fixed in size, there is no need to make any subsequent calls to SetScrollSizes. If your application supports documents of varying size, you should call SetScrollSizes immediately after the document’s size changes. (You can do this from the OnUpdate member function of your view class.)

In addition to the changes just made, the CScribbleView class will override the OnInitialUpdate member function, which is called when the view is first attached to the document. By overriding this function, you can inform the view of the document’s size as soon as possible.

The following procedure describes how to do this.

To override OnInitialUpdate

  1. Use WizardBar to open ScribbleView.cpp in the text editor.

  2. Click the arrow on the action button, located on the right end of WizardBar.

  3. On the menu, click Add Virtual Function.

    The New Virtual Override dialog box appears.

  4. From the New Virtual Functions list, select OnInitialUpdate.

  5. Click Add and Edit.

  6. Add the following line of code just before the call to the OnInitialUpdate function in the base class:
    SetScrollSizes( MM_TEXT, GetDocument()->GetDocSize() );
    

The SetScrollSizes member function is defined by CScrollView. Its first parameter is the mapping mode used to display the document. The current version of Scribble uses MM_TEXT as the mapping mode; in Lesson 9, Enhancing Printing, Scribble will use the MM_LOENGLISH mapping mode for better printing. (For more information on mapping modes, see Enlarge the Printed Image in Lesson 9.)

The second parameter is the total size of the document, which is needed to determine the scrolling limits. The view uses the value returned by the document’s GetDocSize member function for this parameter.

SetScrollSizes also has two other parameters for which Scribble uses the default values. These are CSize values that represent the size of one “page” and one “line,” the distances to be scrolled if the user clicks the scroll bar or a scroll arrow. The default values are 1/10th and 1/100th of the document size, respectively.