Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Simple Document / View Architecture for WTL

0.00/5 (No votes)
6 Aug 2007 1  
Simple Document / View Architecture for WTL

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);

// TODO: add code to initialize document

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)
            // your message map here.

        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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here