When a user chooses the New command on the File menu in an AppWizard-generated application, the default framework behavior is as follows.
1. Checks whether the current document has been modified and, if so, prompts the user to save it. Saves the current document if the user says yes.
2. Removes the contents of the old document.
3. Creates a new document.
Virtual Functions to Manage Document Creation
The CDocument class provides two virtual functions that can be overridden to provide for handling the document-creation process.
CDocument::OnNewDocument is called by the framework as part of the New command. The default implementation of this function calls DeleteContents to empty the document, and then marks the document as clean.
You can override this function to do per-document initialization instead of placing this code in the constructor for your document class.
CDocument::DeleteContents empties the document without destroying the document object itself. The default implementation of this function does nothing. Commonly, this function is overridden to delete dynamically allocated objects in your document, rather than using the destructor.
MDI vs. SDI
Because SDI applications use only a single document object, CDocument::DeleteContents is used to reuse the single document object whenever the user creates another document. No constructor or destructor for the associated document object is called on subsequent New operations.
In an MDI application, opening a new file causes a new document object to be created with its attendant views. The function CDocument::OnNewDocument is called for the document after it is constructed.
Opening an Existing File
When a user chooses the Open command on the File menu in an AppWizard-generated application, the default behavior is as follows:
1. Checks whether the current document has been modified and, if so, prompts the user to save it. Saves the current document if the user says yes.
2. Displays the Open common dialog box and accept the user's file selection.
3. Removes the contents of the old document.
4. Loads the new document by deserializing its data.
Internally, the process is much more complicated, but most of the details are encapsulated into the application framework. In fact, in most cases, you need concern yourself only with specifying which data to serialize and in what order. The application framework manages the opening and closing of files, and the instantiation of the document and view objects.
Virtual Functions for Special FileOpen Situations
The CDocument class provides two virtual functions that can be overridden to provide for the handling of special FileOpen operations:
® CDocument::OnOpenDocument provides a place to do per-document initialization when an existing file is opened. The framework calls OnOpenDocument as part of the file-opening process. The default implementation of this function opens the specified file, calls DeleteContents to empty the document, calls Serialize to read the file contents, and then marks the document as clean.
It is more rare to override OnOpenDocument than it is to override OnNewDocument, since serialization is usually sufficient to initialize the document when opening an existing file.
® CDocument::DeleteContents empties the document without destroying the document object itself. The default implementation of this function does nothing.
SDI vs. MDI
Because SDI applications use only a single document object for the duration of the application, CDocument::DeleteContents is used to reuse the single document object whenever the user opens another document. No constructor or destructor for the associated document object is called during FileOpen operations.
In an MDI application, opening an existing file causes a new document object and its attendant views to be created. The CDocument::OnNewDocument function is called for the document after it is constructed.
Saving or Closing a File
Saving a file involves having the document store its data and objects by calling its Serialize function.
Before closing a document, the framework calls CDocument::IsModified to determine if the document data has changed. If data has changed, the framework displays a dialog box to ask the user whether or not the modified data should be saved.
Marking a Document as Modified
It is the developer's responsibility to ensure that the modified flag is set when the document data has changed. In general, the program should call CDocument::SetModifiedFlag whenever a document's data has changed. This guarantees that no changed document will be closed without first asking the user if the data should be saved.
MDI vs. SDI
In an MDI application, when a document is closed, CDocument::DeleteContents is called before the destructor for the associated document object.
Because an SDI application must have exactly one document open at a time, the Close command is not usually available on the File menu.
If you generate a nondatabase application, AppWizard overrides CDocument::Serialize for your application's document class. However, AppWizard supplies only an almost empty implementation for this member function. It is your responsibility to add the proper implementation code to the Serialize function based upon the details of your application's document class. The following example code shows a typical Serialize function that is generated by AppWizard:
void CMyDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
Serialization Helper Functions
MFC serialization is responsible for both storing and loading data. To allow the Serialize function to handle both cases, two adjunct functions exist: CArchive::IsLoading returns TRUE if reading from the file; CArchive::IsStoring returns TRUE if writing to the file.
Note The order in which members are loaded and stored must match exactly, or the data in the document will be corrupted. Neither the Visual C++ compiler nor the application framework can check this for you.
Serializing Built-in Data Types
Similar to the standard Visual C++ iostream class library, CArchive provides overloaded insertion (<<) and extraction (>>) operators for data insertion and extraction in the following portable Visual C++ and Microsoft Windows simple built-in data types.
CTime and CTimeSpan SIZE and CSize float
WORD CString POINT and CPoint
DWORD BYTE RECT and CRect
double LONG COLORREF
BOOL
Nonportable data types, such as int, do not have corresponding overloaded CArchive serialization operators. If the document class contains members of these nonportable data types, the developer can cast them to their equivalent portable types for serialization.
To see sample code that serializes document class members that are built-in data types, click this icon.
class CSerialDocumentDoc : public CDocument
{
...
CString m_phrase;
CPoint m_location;
COLORREF m_color;
...
};
// Class definition
void CSerialDocumentDoc::Serialize(CArchive& ar)
{//
if (ar.IsStoring())
ar << m_phrase << m_location << m_color;
else
ar >> m_phrase >> m_location >> m_color;
}
No comments:
Post a Comment