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
Use WizardBar to jump to the starter definition for
InitDocument
(in classCScribbleDoc
) 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.Use WizardBar to jump to the override of
OnNewDocument
created by AppWizard and replace the //TODO comments with the call toInitDocument
. The completed handler looks like this:BOOL CScribbleDoc::OnNewDocument() { if(!CDocument::OnNewDocument()) return FALSE; InitDocument(); return TRUE; }
Finally, use WizardBar jump to the starter version of
OnOpenDocument
and replace the //TODO comments with another call toInitDocument
. The completed handler looks like this:BOOL CScribbleDoc::OnOpenDocument(LPCTSTR lpszPathName) { if( !CDocument::OnOpenDocument( lpszPathName ) ) return FALSE; InitDocument( ); return TRUE; }
The overrides of
OnNewDocument
andOnOpenDocument
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.