对ActiveX控件中实现文档视图结构的理解和补充

MFC的文档视图结构,通过文档管理数据,通过视图显示数据,实现数据管理与数据显示的分离,是一种强大且经典的结构模式。ActiveX控件基于COM的基础,实现功能的模块化。ActiveX本身不支持文档视图结构,如果能在ActiveX控件中实现文档视图结构,那么就可以做出功能非常强大的组件。

关于如何在ActiveX控件中实现文档视图结构,网上已经有了现成的方法,我只是想对这些方法做一些解释和补充。以下是网上的关于ActiveX控件中实现文档视图结构的实现方法的博客,方法其实都是同一方法,不过讲述的稍微有些不同,大家都可以参考一下:

1. Designing ActiveX Components with the MFC Document/View Model - 李昱成的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/l12345678/article/details/1711521

2. MFC Doc/View结构实现ActiveX控件_lyingbo_新浪博客
http://blog.sina.com.cn/s/blog_6f83fdb40101gpyk.html


3. 单文档/视图结构的ActiveX控件 - 快活鱼 - 博客园
http://www.cnblogs.com/rukeefan/archive/2007/09/05/31184.html

接下来对ActiveX控件中实现文档视图结构的方法做进一步的解释。

MFC中的文档视图结构并不只包括文档和视图,其结构为Document/View/Frame,通过Template来管理,见CWinApp的AddDocTemplate函数代码:

	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CTestTemplateDoc),
		RUNTIME_CLASS(CMainFrame),       // main SDI frame window
		RUNTIME_CLASS(CTestTemplateView));
	AddDocTemplate(pDocTemplate);

而模板类变量pDocTemplate通过文档管理器CDocManager* m_pDocManager变量管理:

void CWinApp::AddDocTemplate(CDocTemplate* pTemplate)
{
	if (m_pDocManager == NULL)
		m_pDocManager = new CDocManager;
	m_pDocManager->AddDocTemplate(pTemplate);
}

因此,在ActiveX控件中实现文档视图结构,必须要满足以下几个条件:

1. 有相应的文档、视图和框架对象

2. 以文档、视图和框架对象为基础创建模板类对象

3. 管理模板类对象

网上的方法主要是通过CActiveXDocTemplate和CActiveXDocControl两个类来实现文档视图框架,从这两个类的名字可以看出,CActiveXDocTemplate与模板有关,CActiveXDocControl与ActiveX控件有关,事实上,CActiveXDocTemplate是管理文档、视图和框架对象的模板类,CActiveXDocControl是控件类,我们用VC6.0或者VS2008新建的ActiveX控件工程里的控件类必须从CActiveXDocControl继承过来。以上第一和第二个条件的满足,见以下的实现代码:

	AddDocTemplate(new CActiveXDocTemplate(
        RUNTIME_CLASS(CAxAppDoc),
        RUNTIME_CLASS(CMainFrame),
        RUNTIME_CLASS(CAxAppView)));

这样一来,我们就有了模板类对象。至于第三个条件,如何管理模板类对象,CActiveXDocTemplate和CActiveXDocControl这两个类并没有提供类似MFC中的文档管理器m_pDocManager来管理模板类对象,而是为控件类CActiveXDocControl添加了一个CActiveXDocTemplate的指针成员变量,并且为模板类CActiveXDocTemplate实现了一些必要的函数,保证控件类CActiveXDocControl管理模板类CActiveXDocTemplate。只要我们按照方法上讲的来组织代码,改造ActiveX控件的结构,就能正确地在ActiveX控件中实现文档视图结构,而且不会陷入MFC本身文档视图结构复杂调用关系的漩涡中。

我要补充的,就是如何管理CActiveXDocTemplate模板类,正如上面讲的,MFC中是通过文档管理器m_pDocManager来进行管理;ActiveX控件中则是通过别的方式。

首先,CActiveXDocControl控件类中有一个CActiveXDocTemplate类的指针成员变量:

CActiveXDocTemplate* m_pDocTemplate;

然后,CActiveXDocTemplate类中实现了一些必要的函数:

    CFrameWnd* CreateDocViewFrame(CWnd* pParentWnd);
    void SaveDocumentFile();
    virtual CFrameWnd* CreateNewFrame(CDocument* pDoc,
        CFrameWnd* pOther);
    virtual CDocument* OpenDocumentFile(
        LPCTSTR lpszPathName, BOOL bVerifyExists = TRUE);
其中,SaveDocumentFile函数实现保存文档的功能,OpenDocumentFile函数实现打开和新建文档的功能。在MFC中,新建和打开文档是通过调用CWinApp的OnFileNew和OnFileOpen函数来实现的,而这两个函数都用到了文档管理器m_pDocManager:

// WinApp features for new and open

void CWinApp::OnFileNew()
{
	if (m_pDocManager != NULL)
		m_pDocManager->OnFileNew();
}

/

void CWinApp::OnFileOpen()
{
	ASSERT(m_pDocManager != NULL);
	m_pDocManager->OnFileOpen();
}
CActiveXDocTemplate类的OpenDocumentFile函数则绕过文档管理器m_pDocManager,实现文档新建及打开的功能:
CDocument* CActiveXDocTemplate::OpenDocumentFile(
    LPCTSTR lpszPathName, BOOL bVerifyExists)
{
    SaveDocumentFile();
    m_docFile = lpszPathName;

    if (bVerifyExists)
    {
        DWORD dwAttrib = GetFileAttributes(m_docFile);
        if (dwAttrib == 0xFFFFFFFF ||
            dwAttrib == FILE_ATTRIBUTE_DIRECTORY)
        {
            lpszPathName = NULL;
        }
    }

    return CSingleDocTemplate::OpenDocumentFile(
        lpszPathName, TRUE);
}

管理模板类中涉及到文档管理器m_pDocManager的部分都可以通过模板类自带的函数来实现,从而绕过了文档管理器。因此,MFC的文档视图结构中的绝大多数功能,都能在ActiveX控件中模拟出来。








  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在MFC,可以通过以下步骤在对话框创建一个视图: 1. 首先,打开MFC应用程序的代码。 2. 在对话框资源定义一个静态控件,该控件将用于容纳视图。 3. 在对话框类的头文件添加一个成员变量,用于表示视图对象。 4. 打开对话框类的源文件,并在OnInitDialog()函数进行如下操作: a. 调用基类的OnInitDialog()函数。 b. 创建视图对象,使用CreateView()函数并传入静态控件的ID和对话框指针。 c. 将视图对象指针保存到成员变量。 ```c++ BOOL CMyDialog::OnInitDialog() { CDialog::OnInitDialog(); // 创建视图对象 CRect rect; GetDlgItem(IDC_STATIC_VIEW)->GetWindowRect(&rect); ScreenToClient(&rect); m_pView = new CMyView(); m_pView->Create(NULL, NULL, WS_CHILD | WS_VISIBLE, rect, this, IDC_STATIC_VIEW); return TRUE; } ``` 5. 最后,别忘记在对话框类的析构函数删除视图对象。 ```c++ CMyDialog::~CMyDialog() { if (m_pView != nullptr) { delete m_pView; m_pView = nullptr; } } ``` 通过以上步骤,就可以在对话框成功创建一个视图对象,并将其显示在静态控件。这样就可以在对话框展示自定义的图形、数据等内容,并实现与用户的交互。 ### 回答2: 在MFC,在对话框创建一个视图有两种方法可以实现。 方法一:使用视图类(CView)和文档类(CDocument) 1. 创建一个新的MFC应用程序项目,选择“单文档”或“多文档”模式。 2. 在资源视图,打开对话框资源文件(.rc)。 3. 在对话框上选择插入->ActiveX 控件。 4. 在弹出的对话框,选择“Visual C++ 控件类”,然后点击“添加新控件类…”按钮。 5. 输入控件类名,选择CView作为基类,然后点击“完成”。 6. 给控件设置一个唯一的ID。 7. 在对话框类(CDialog)的代码文件,添加对CView类的成员变量。 8. 在OnInitDialog()函数,使用Create()函数创建视图。 方法二:使用静态控件(CStatic)和视图类(CView) 1. 创建一个新的MFC应用程序项目。 2. 在资源视图,打开对话框资源文件(.rc)。 3. 在对话框上选择插入->控件->静态文本。 4. 调整静态文本的大小和位置,使其占据你想要的视图区域。 5. 在对话框类(CDialog)的代码文件,添加对CView类的成员变量。 6. 在OnInitDialog()函数,使用Create()函数创建视图,并将其父窗口设置为静态文本的句柄。 无论使用哪种方法,创建视图后,需要在对话框类的OnSize()函数调整视图的大小和位置,以保证视图随着对话框的大小改变而调整。 总结:以上是两种在MFC对话框创建视图的方法。使用方法一可以使视图文档类关联,方便进行数据的读写和操作;而方法二则更加简单直接。根据项目需求以及个人偏好,选择合适的方法创建视图即可。 ### 回答3: 在MFC,我们可以在对话框创建一个视图,可以通过以下步骤实现: 1. 首先,在MFC应用程序的资源文件夹打开对话框编辑器,选择一个适当的对话框进行编辑。 2. 在对话框编辑器,将“工具箱”窗口的“控件”组件显示出来。 3. 在“控件”组件找到“ActiveX Control”(“ActiveX 控件”),并在对话框绘制一个合适大小的矩形。 4. 右键单击绘制的矩形,选择“添加变量”。 5. 在“添加变量”对话框,将控件名称设置为适当的名称,选择“值”类型为“Control”(“控件”),然后单击“完成”。 6. 在对话框的头文件,找到对控件变量的声明,并将其类型更改为“CWnd”。 7. 在对话框类的源文件(.cpp),找到OnInitDialog()函数。 8. 在OnInitDialog()函数添加以下代码: ``` // 获取控件指针 CWnd* pWnd = GetDlgItem(IDC_YOUR_CONTROL_ID); // 创建视图对象 CYourViewClass* pView = new CYourViewClass(); // 获取视图的矩形区域 CRect rect; pWnd->GetWindowRect(rect); ScreenToClient(rect); // 创建视图窗口 pView->Create(NULL, NULL, WS_VISIBLE | WS_CHILD | WS_BORDER, rect, this, IDC_YOUR_VIEW_ID); // 调整视图窗口的大小和位置 pView->MoveWindow(rect); ``` 注意:需要将“IDC_YOUR_CONTROL_ID”和“IDC_YOUR_VIEW_ID”替换为适当的控件视图ID。 9. 编译并运行应用程序,你翻看对话框时将会在指定的位置看到创建的视图。 在对话框创建视图可以实现为用户提供更丰富的交互功能,例如通过绘图或显示图形等。但也需要处理好视图的生命周期和内存管理,防止内存泄漏和其他问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值