Initializing and Cleaning Up

Because a document can be created with either the New command or the Open command on the File menu, CScribbleDoc overrides both the OnNewDocument and OnOpenDocument member functions of CDocument to perform necessary document initialization. However, for Scribble, both initializations are the same, so both overrides call the member function InitDocument.

The framework automatically calls OnNewDocument when a new document is created or OnOpenDocument when a document is opened. AppWizard creates a starter version of OnNewDocument for you, and ClassWizard created a starter version for OnOpenDocument.

In the following procedure, you’ll define these functions for Scribble.

To implement initialization for Scribble’s documents

  1. Use WizardBar to jump to the starter definition for InitDocument (in class CScribbleDoc) and fill it in with the following code:

    m_nPenWidth = 2;  // Default 2-pixel pen width
    // Solid black pen
    m_penCur.CreatePen( PS_SOLID, m_nPenWidth, RGB(0,0,0) );
    

    InitDocument sets a default pen width and creates a pen object for drawing. Pen creation is done through the CPen object, m_penCur, by calling its CreatePen member function. The arguments specify a solid black pen 2 pixels wide.

  2. Use WizardBar to jump to the override of OnNewDocument created by AppWizard and replace the //TODO comments with the call to InitDocument. The completed handler looks like this:

    BOOL CScribbleDoc::OnNewDocument()
    {
    if(!CDocument::OnNewDocument())
    return FALSE;
    InitDocument();
    return TRUE;
    }
    
  3. Finally, use WizardBar jump to the starter version of OnOpenDocument and replace the //TODO comments with another call to InitDocument. The completed handler looks like this:

    BOOL CScribbleDoc::OnOpenDocument(LPCTSTR lpszPathName)
    {
    if( !CDocument::OnOpenDocument( lpszPathName ) )
    return FALSE;
    InitDocument( );
    return TRUE;
    }
    

    The overrides of OnNewDocument and OnOpenDocument call the base-class version of the function before performing application-specific initialization of the document.

The following procedure describes how to add the code that implements document cleanup for Scribble. You’ll replace the ClassWizard starter version of the DeleteContents member function of CDocument. Note that you are still working in ScribbleDoc.cpp.

To implement document cleanup

  • Use WizardBar to jump to the DeleteContents member function, and replace the //TODO comment with the following code:

    while( !m_strokeList.IsEmpty( ) )
    {
    delete m_strokeList.RemoveHead( );
    }
    

DeleteContents provides the best place to destroy a document’s data when you want to keep the document object around. The function is called automatically by the framework any time it’s necessary to delete only the document’s contents. It’s called in response to the Close command on the File menu, when the user closes the document’s last open window, and before creating or opening a document with the New and Open commands. This is all part of the base-class functionality of DeleteContents.

Scribble’s override of DeleteContents iterates through the stroke list. DeleteContents calls the CTypedPtrList member function RemoveHead, which removes the list object and returns a pointer to the removed object. DeleteContents then calls the delete operator on this pointer, destroying the stroke object.

Alternatively, this cleanup code could be placed in the destructor, but DeleteContents is reused later in other functions.