Introduction
When I used the wizard in the VC++ and
created a MDI application, the first impression that I got was where is the
document class? So I did a little search
in the internet and found some articles about the Document / View Architecture
for WTL, and found that they are much more complete than I need.
Intention
I would like to be able to create a simple Document/View application for WTL with a minimum change to the code that generated by the wizard.
Requirement
Some knowledge of WTL, MFC and VC++ IDE are
required.
Background
To build a Doc/View application, I know I would need a document class, but
where do I instantiate it? For the SDI
application, it would make sense to put the document object and a central area
such as the global area and make it accessible through-out the rest of the
application. However, we are talking
about multiply document objects. The
next central area that makes sense to hold the documents is the main frame
class and we will need some kind of mechanism to keep track the documents as
well. DocManager class is the one that
does the job.
The next question I have is when should I
instantiate the document, before the creation of view object or after? Usually, it is possible for a document have
many views associate to it, but not the other way around. So logically saying, it will make more sense
to create the document object before the view object, but this will require a
modification of the CChildFrame's constructor.
This might violate my goal to make it simple. Therefore, you will see I create the document
object after the child frame and view are created. This shouldn't stop you to create the
document object first, if you feel comfortable to modify the child frame's
constructor.
With these thoughts in mind, it should be easy to follow the steps to build your own Doc/View application.
Using the code - the Steps
1.
Go ahead to create a MDI
application with the wizard and name the project as MDIApp.
2.
Copy the source files into the
project directory and then add them into the project.
3.
Create your own document class (e.g.
CMyDoc). Derived it from the CDocument
class and create a constructor like the following.
i.e.
class CMyDoc : public CDocument {
...
CMyDoc(CView* pView, CUpdateUIBase* pUpdateUI):
CDocument(pView, pUpdateUI) { }
...
4.
In the MDIAppview.h add
the following code.
#include "MyDoc.h"
#include "DocView\View.h"
class CMDIAppView : public CWindowImpl<CMDIAppView>, public CView
{
5. Add the CDocManager class into
the mainfrm .h files.
#include "DocView\DocManager.h"
class CMainFrame : public CMDIFrameWindowImpl<CMainFrame>,
public CUpdateUI<CMainFrame>, public CMessageFilter,
public CIdleHandler, public CDocManager
6. Create the document in the OnFileNew method in mainfrm.cpp right after the creation of the child frame.
CChildFrame* pChild = new CChildFrame;
pChild->CreateEx(m_hWndClient);
AddDocument (new CMyDoc ((CView*) &pChild->m_view, (CUpdateUIBase*) this));
7. Up to this point we are almost done, except we need to find a way to send message to the document class. Here is how.
In mainfrm.h add "CHAIN_MDI_CHILD_COMMANDS()" to the message map block.
In ChildFrm.h add "CHAIN_CLIENT_COMMANDS()" to the message map block.
In MDIAppview.h add "CHAIN_MSG_MAP_DYNAMIC (1)" to the message map block.
In MyDoc.h create your own message map block.
i.e. BEGIN_MSG_MAP(CMyDoc)
END_MSG_MAP()
The Demo
Besides the Document/View, I also demonstrated a little on how you can manipulate the toolbar buttons in the mainframe, document and view classes. You should be able to put such coding in any where you think it will make the most sense to you. General speaking, I would say to put the code in the document class will make the most sense.
The other thing I would like to mention is the way this demo closes the documents. It only closes the documents all at once while the application is being terminated. If you need to close a document while a view is being closed, call the CDocManager::RemoveDocument (pDoc) to do such job. To make my sample simple, let me leave this to you as your homework.
Conclusion
This Document/View architecture could become as powerful and flexible as you want it to be, because it is simple. As long as you understand the idea, it is not difficult to add more building blocks into the foundation. Hope this article can provide enough kicking-start for your own Document/View application.