65.9K
CodeProject 正在变化。 阅读更多。
Home

WTL 的简单文档/视图架构

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (3投票s)

2007年8月6日

3分钟阅读

viewsIcon

26373

downloadIcon

564

WTL 的简单文档/视图架构

引言

当我使用 VC++ 中的向导创建 MDI 应用程序时,我得到的第一个印象是文档类在哪里?因此,我在互联网上进行了一些搜索,找到了关于 WTL 的文档/视图架构的一些文章,并发现它们比我需要的要完整得多。

意图

我希望能够为 WTL 创建一个简单的文档/视图应用程序,只需对向导生成的代码进行最少的更改。

要求

需要一些 WTL、MFC 和 VC++ IDE 的知识。

背景

要构建一个 Doc/View 应用程序,我知道我需要一个文档类,但我在哪里实例化它?对于 SDI 应用程序,将文档对象和一个中央区域(例如全局区域)放在一起,并通过应用程序的其余部分访问它是有意义的。但是,我们谈论的是多个文档对象。下一个有意义的中央区域是主框架类,我们需要某种机制来跟踪文档。DocManager 类就是做这项工作的类。

我遇到的下一个问题是我应该在创建视图对象之前还是之后实例化文档?通常,一个文档可以有许多与之关联的视图,但反过来则不行。因此,从逻辑上讲,在视图对象之前创建文档对象会更有意义,但这将需要修改 CChildFrame 的构造函数。这可能会违背我使其简单的目标。因此,您将看到我在创建子框架和视图之后创建文档对象。如果您乐于修改子框架的构造函数,这不应该阻止您首先创建文档对象。

考虑到这些想法,遵循构建您自己的 Doc/View 应用程序的步骤应该很容易。

使用代码 - 步骤

1. 继续使用向导创建一个 MDI 应用程序,并将项目命名为 MDIApp。

2. 将源文件复制到项目目录中,然后将它们添加到项目中。

3. 创建您自己的文档类(例如 CMyDoc)。从 CDocument 类派生它,并创建一个如下所示的构造函数。

i.e.
class CMyDoc : public CDocument {
    ... 

    CMyDoc(CView* pView, CUpdateUIBase* pUpdateUI): 
        CDocument(pView, pUpdateUI)   { }

    ...

4. 在 MDIAppview.h 中添加以下代码。

#include "MyDoc.h"
#include "DocView\View.h"

class CMDIAppView : public CWindowImpl<CMDIAppView>, public CView 
{ 
5. 将 CDocManager 类添加到 mainfrm .h 文件中。
#include "DocView\DocManager.h"

class CMainFrame : public CMDIFrameWindowImpl<CMainFrame>, 
    public CUpdateUI<CMainFrame>, public CMessageFilter, 
    public CIdleHandler, public CDocManager
6. 在 mainfrm.cpp 的 OnFileNew 方法中,在创建子框架之后立即创建文档。
CChildFrame* pChild = new CChildFrame;
pChild->CreateEx(m_hWndClient);

// TODO: add code to initialize document
AddDocument (new CMyDoc ((CView*) &pChild->m_view, (CUpdateUIBase*) this));
7. 到目前为止,我们几乎完成了,除了我们需要找到一种方法将消息发送到文档类。这是方法。
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()

演示

除了文档/视图,我还演示了一点关于如何在主框架、文档和视图类中操作工具栏按钮。您应该能够将此类编码放在您认为最有意义的任何地方。一般来说,我会说将代码放在文档类中会更有意义。

我想提到的另一件事是此演示关闭文档的方式。它仅在应用程序终止时一次性关闭所有文档。如果您需要在关闭视图时关闭文档,请调用 CDocManager::RemoveDocument (pDoc) 来完成此任务。为了使我的示例简单,让我将其留给您作为您的家庭作业。

结论

这种文档/视图架构可以变得像您希望的那样强大和灵活,因为它很简单。只要您理解这个想法,添加更多的构建块到基础中并不难。希望这篇文章能为您的文档/视图应用程序提供足够的启动。

© . All rights reserved.