Understanding the
AppWizard and ClassWizard in Visual C++ Version 6.x
by Marshall Brain
Understanding
the Document/View Paradigm
The framework
that the AppWizard generates revolves around a concept called
the Document/View Paradigm. If you understand this paradigm
then it is much easier to understand the files that the AppWizard
generates, and it also makes it much easier for you to fit your
code into the AppWizard framework. This tutorial describes the
paradigm so that you completely understand its purpose and intent.
The App Wizard takes a document-centric approach to application design. The MFC class hierarchy contains two classes that help to support this approach: CDocument and CView. The AppWizard and MFC use this approach because most Windows applications work this way. Built into any framework generated by the AppWizard is the assumption that your application will want to load and work with multiple documents, and that each document will have one or more views open at a time. This approach makes it extremely easy to create both Single Document Interface(SDI) and Multiple Document Interface(MDI) applications. All applications can be thought of in terms of documents and views.
It is easiest to understand the document/view paradigm if you think about a typical MDI word processor like Microsoft Word. At any given time you can have one or more documents open. A document represents a single open file. The user generally has one view open on each document. The view shows the user a part of the document in an MDI window, and lets the user edit the document. However, Microsoft Word allows the user to split a window into multiple frames so that the user can have two or more views on the same document if desired. When the user edits in one of the views, it changes the data in the document associated with the view. If a document has multiple views open and the user changes data in one of the views, the document and all other related views should reflect the change. When the user saves the document, it is that data held by the document that gets saved to disk.
Many applications allow the user to open just one type of document. Microsoft Word, for example, works only with Microsoft Word documents. It may allow you to open other types of documents, but it first filters them to turn them into Word documents. Other applications open several different types of documents and can display all of them simultaneously in its MDI framework. Visual C++ is an example of this type of application. The most common type of document Visual C++ works with is a text file that contains code. However, you can open resources in the different resource editors as different types of documents in the MDI framework. Microsoft Works is similar. It can open word processing documents, but it can also open spreadsheet and database documents. Each of these documents has a completely unique view in the MDI frame, but all of the different views live there in harmony with one another. In addition, database documents in Works can be viewed both in a spreadsheet-like list, or in a customizable form that shows one complete record at a time.
Therefore, in the most general case, an application may be able to open several different types of documents simultaneously. Each type of document can have a unique viewing window. Any document may have multiple views open at once. In fact, a document might have more than one way of viewing its data, and those different views on a single document might be open simultaneously. Each document stores its data on disk. The views give the user a way to view and edit that data.
At a code level, the document and view classes separate functionality. Since this arrangement is typical of most applications, the framework generated by the AppWizard supports this structure implicitly. The document class is responsible for data. It reads the data from a file on disk and holds it in memory. The view class is responsible for presentation. The view takes data from the document class and presents it to the user in a view. The multiple views for a single document synchronize themselves through the data in the document. The MFC class hierarchy contains classes - CDocument and CView - that make this structure easy to create. The AppWizard derives new classes from the existing document and view classes and you build your application within those derived classes.
The goal of the document class is to completely encapsulate the data for one open document. It holds the data for the document in a data structure in memory and knows how to load the data from the disk and save it to the disk. The view class uses and manipulates the data in the document based on user events. The view class is responsible for letting the user view the contents of the document. (Note - The document class does not necessarily have to hold its data in memory. In certain types of applications it can act instead as a pipe to a binary file that remains on disk, or to a database.)
The relationship between the document and view classes is summarized in the figure below. When you are designing your own applications, you want the document class to completely encapsulate the data, and you want the view class to display information to the user. There should be a clear and obvious way for the view to interact with the document through member functions that you create if you want to properly encapsulate the data in the document.
When you create your own application, you typically will create
some sort of data structure in the document class to hold the
document's data. MFC contains a number of collection classes that
you can use for this purpose, or you can create any other data
structure that you like. The document class will be called when
the data in the data structure needs to be loaded from disk or
saved to disk. This is most commonly done through the document
class's Serialize function. You will then add your own
member functions to the class to encapsulate the data structure
and allow the view class to manipulate the data held by the data
structure. The view class contains the code to handle user events
and draw to the screen.