MFC无文档多视应用程序框架

本文介绍了如何在MFC中创建一个无文档多视图应用程序,通过删除不必要的MDI组件,添加自定义的管理工具栏窗口,并实现树形控件与FormView之间的交互。步骤包括移除默认框架、添加DialogBar对话框、插入多个FormView资源、建立树形控件及处理点击事件,最后讨论了资源管理以优化性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

///

//Author:  aaashun

//Date:    23/2/2009

//Email:   aaashun@gmail.com

///

大多数情况下MFC的MDI模板为开发多窗口或多文档应用程序提供了很大的方便,但有时MFC向导生成的框架并非是我们需要的,怎么办?对MFC生成的框架动手术吧。本文以多视(无文档)为例说明手术的关键部分,讲的有点乱,如果需要源码请来邮件索要。

 

最终效果图:


 

1.选择MDI类型,去掉文档视图关联支持


2.一路next,子窗口类型样式选择最大化

 

3.去掉CChildView类

删除ChildView.h和ChildView.cpp两个文件,去掉CChildFrame里的几个重写(Dump等)、几个消息响应(WM_CREATE等)和一个事件响应(IDC_FILE_CLOSE等)。

4.去掉IDC_FILE_NEW在App类中响应

5.增加ShunStdAfx.h头文件并在stdafx.h里 include一下,我会把自定义的一些东西放在这个文件里。

 

至此已经把VC生成的框架程序删减的差不多了,保证编译通过再进行下边的工作--开始添加。

二、接下来开始做左边的管理工具栏窗口。

1.增加DialogBar类型对话框,并为之增加类CManageBar,从CDialog派生(因为找不到CDialogBar)

2.替换ManageBar.h和ManageBar.cpp文件里的CDialog为CDialogBar

修改构造函数如下:

      CManageBar::CManageBar(CWnd* pParent /*=NULL*/)

                  : CDialogBar()

3.为CMainFrame添加成员CManageBar m_wndManageBar,并在OnCreate中添加相应代码创建并把它show出来:

    if (!m_wndManageBar.Create(this, IDD_DIALOGBAR,

        CBRS_LEFT | CBRS_SIZE_DYNAMIC, AFX_IDW_DIALOGBAR))

    {

        TRACE0("Failed to create dialogbar/n");

        return -1;

    }

    m_wndManageBar.EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(&m_wndManageBar);

编译运行 报错 winfrm2.cpp 92 行,看提示

// assert fails when initial CBRS_ of bar does not

// match available docking sites, as set by EnableDocking()

原来是窗口不允许停靠,这样在停靠ManageBar的代码前面得加一句让窗口允许停靠。

    EnableDocking(CBRS_ALIGN_LEFT);

三、添加三个FormView资源

1.添加三个FormView资源并添加相应类分别为:

IDD_FORMVIEW_ADMIN,     CAdminView

IDD_FORMVIEW_CONSUMER, CConsumerView

IDD_FORMVIEW_GROUP,     CGroupView

注意这三个类都是从CFormView类里派生出来

四、在ManageBar上添加树形控件

1.添加树形控件ID为IDC_TREE_MANAGEBAR,关联一个成员变量m_tree

2.为CManageBar添加成员函数InitTreeCtrl,完成控件的初始化工作

HRESULT CManageBar::InitTreeCtrl(

摘要:本文通过一个程序实例描述了在VC++6.0下如何在单文档程序中通过菜单动态控制 个窗体的切换。    一、 引言    我们在编制程序中根据需求的不同会在程序风格上选择文档、单文档或是对话框模式 ,对于单文档模式可能是我们使用比较的,但有时我们想采用单文档的形式显示个不同 的窗体,如作为数据库前台应用程序就会遇到此类问题,数据库由大量的表单组成,而同常 一个窗体内只用来显示一个表单,所以要显示其他的表单时就要用到切换窗体的技术了,下 面就通过一个程序说明该技术的实现方法。    二、 实现技术    新建一个基于CFormView的单文档应用程序,再添加一个窗体和与之对应的基于 CFormView的新类,然后通过在主框架类里添加控制代码和菜单控制实现这两个窗体的动态 切换,下面就是具体的实现过程:    (一) 用"MFC AppWizard(exe)"建立一个新项目"SwitchForm",并在第二步的创建类型上选 择为"Single documnet"单文档模式,第三、四、五、六步均取确省状态,最后一步选择 "CFormView"作为类的基类。点按"完成"按钮,生成了初始工程"SwitchForm"。    (二) 点选菜单"Insert"、"Resource…",在弹出的"Insert Resource"对话框中"Dialog"树 里的"IDD_FORMVIEW",点击"New"按钮,生成了一个新的窗体,将其ID号改为"IDD_NEXTFORM"。 在原有的窗体上加一个静态框"这是第一个窗体";在新建的窗体上也添加一个静态框"这是第二 个窗体"。    (三) 在菜单资源的"IDR_MAINFRAME"上添加一级菜单"窗体切换",及其二级菜单"第一个窗 体"、"第二个窗体",其标识号分别为"ID_FIRSTFORM"和"ID_SECONDFORM"。修该"第一个窗体" 的属性为"Checked",表明程序初始时显示的是第一个窗体。    (四) 在"ClassView"属性页里的"SwitchForm classes"上右键,在弹出菜单上选择 "New Class…",弹出"New Class"对话框,选择"Dialog ID:"为我们刚添加的新窗体 "IDD_NEXTFORM",选择"Base class:"为"CFormView",类名取为"CNextFormView",这样就把第 二个窗体对应的视图类添加到了工程。 (五) 在框架类里添加函数SwitchToForm(): void CMainFrame::SwitchToForm(int nForm) { file://获取原来的活动窗体的视图句柄 CView* pOldActiveView = GetActiveView(); file://获取由"nForm"标识的窗体所对应的视图句柄 CView* pNewActiveView = (CView*) GetDlgItem(nForm); file://若视图句柄为空,则创建一新的。 if (pNewActiveView == NULL) { if (nForm == IDD_SW99vCHFORM_FORM) pNewActiveView = (CView*)new CSwitchFormView; if (nForm == IDD_NEXTFORM) pNewActiveView = (CView*)new CNextFormView; CCreateContext context; context.m_pCurrentDoc = pOldActiveView->GetDocument(); pNewActiveView->Create(NULL,NULL,0L, CFrameWnd::rectDefault, this,nForm,&context); pNewActiveView->OnInitialUpdate(); } file://选择pNewActiveView为活动窗体 SetActiveView(pNewActiveView); file://显示活动窗体,隐藏活动窗体 pNewActiveView->ShowWindow(SW_SHOW); pOldActiveView->ShowWindow(SW_HIDE); int ID; if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CSwitchFormView)) ID=IDD_SW99vCHFORM_FORM; if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CNextFormView)) ID=IDD_NEXTFORM; file://设置窗体的ID号 pOldActiveView->SetDlgCtrlID(ID); pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST); RecalcLayout(); }    (六)添加两个菜单相对应的命令响应函数和更新函数如下: void CMainFrame::OnFirstform() { file://通过IsKindOf函数确定当前活动窗口是否是第一个窗口,如是,则无须切换, file://否则将通过SwitchToForm函数将当前活动窗口切换到"IDD_SW99vCHFORM_FORM" file://标识的第二个窗体。 if (GetActiveView()->IsKindOf(RUNTIME_CLASS(CSwitchFormView))) return; SwitchToForm(IDD_SW99vCHFORM_FORM); } void CMainFrame::OnUpdateFirstform(CCmdUI* pCmdUI) { file://通过IsKindOf函数判断当前活动窗口是否是第一个窗体,如是则将其选中。 pCmdUI->SetCheck(GetActiveView()->IsKindOf(RUNTIME_CLASS(CSwitchFormView))); } void CMainFrame::OnSecondform() { if (GetActiveView()->IsKindOf(RUNTIME_CLASS(CNextFormView))) return; SwitchToForm(IDD_NEXTFORM); } void CMainFrame::OnUpdateSecondform(CCmdUI* pCmdUI) { pCmdUI->SetCheck(GetActiveView()->IsKindOf(RUNTIME_CLASS(CNextFormView))); }    然后再在该文件开始处添加对两个视图类的引用: #include "SwitchFormDoc.h" #include "SwitchFormView.h" #include "NextFormView.h"    在此须注意:应在两个类的引用之前添加对文档类的引用,否则会引起编译错误。另外,由于 类的构造函数在声明时都确省的声明为保护型的,在框架类中无法引用,所以还要将两个类的类 声明改动如下: class CNextFormView : public CFormView { public: file://将protected 改为public. CNextFormView(); …… }; class CSwitchFormView : public CFormView { public: file://将protected 改为public. CSwitchFormView(); …… };    三、 编译运行    编译运行程序,开始时的窗体上有"这是第一个窗体的字样",菜单也只有"第一个窗体"是被选中的, 当前的活动窗体是第一个窗体;点击菜单"第二个窗体",视图中的窗体上的字样变成了"这是第二 个 窗体",同时选中的菜单也由"第一个窗体"变成了"第二个窗体",实现了通过菜单将窗体进行动态切换。    总结:此程序中关键的是SwitchToView函数,在此函数中,程序搜索所有当前文档的显示窗口来查找与CruntimeClass变量匹配的视图类。如果找到,该窗口被激活。通过与之类似的方法,还可以实现在文档模式下的单档(文档视图),通过不同的视图以不同的方式显示来自同一份文档的数据,以更好的满足程序的需要。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值