用习惯了 Delphi 、 VB 、 Windows Form ( Visual C# )等称之为 RAD ( Rapid Application Development )的开发工具进行项目开发的都会很满足这些工具和平台提供的快速界面开发的功效:你可以很容易就可以实现一个 MIS 系统的管理界面,提供一个主框架,点击主框架上的某一个菜单项就打开一个处理事务的窗口,这些窗口可以重叠,可以最大 / 小化,一切看起来都像那么回事。但是当你在 VC 中进行开发的时候,发现整个世界都变了,虽然 VC 提供了 MDI 支持多文档视图的框架,但是每次你点击“打开” / “新建”菜单项的时候,你会发现新打开的窗口千孔一面,都是同一个样式,根本就不能满足项目的开发。这就需要你能够为不同的业务逻辑提供不同的显示 / 操作界面。这里给出一个模版,供大家参考:
Step 1 :使用 VC 6.0 新建一个 Project ,命名为: MIS 。除选择单文档属性外,一切使用“默认”方式。于是你可以获得五个类: CMainFrame , CMISApp , CMISDoc , CMISView ,和 CAboutDlg ;
Step 2 :新建一套新的 Doc/View/Frame :添加新类 CNewDoc ,基类为 CDocument (方法: Insert —— >New Class ( Class Type : MFC Class ),基类选择 CDocument )。添加新的框架类 CNewChildFrame ,基类为 CMDIChildWnd ,添加方法同上。添加新的视图类 CNewView ,方法: Insert —— >New Form ,对话框中的文档类选择为 CNewDoc (默认也是)。
Step 3 :将菜单资源 IDR_MAINFRAME 中添加菜单项“功能”,并添加菜单子项“功能 1 ” 和“功能 2 ” ,分别对应项目开发中的不同的业务逻辑。为了保证整个过程中菜单项的一致性,在 IDR_MAINFRAME 上 Ctrl + C ,然后 Ctrl +V 两次生成和 IDR_MAINFRAME 一样的菜单两个,然后将这两个菜单分别改名为 IDR_MISTYPE 和 IDR_VIEW2_TMPL (注意:先将后两个菜单名字 Copy 再删除它们,然后再改名,这里菜单的名字可以换,但是为了简单就直接使用系统生成的默认菜单名字,如果改变了名字要在 New CMultiDocTemplate 时刻修改相应项)。
Step 4 :在 CMISApp 中添加变量记录这两个框架类,为简单起见就声明为 public (方便后面的访问,也就懒得管面向对象的设计原则了,因为仅仅是示例而已):
public : CMultiDocTemplate* m_pDocTemplate1; CMultiDocTemplate* m_pDocTemplate2; |
并将 BOOL CMISApp::InitInstance() 函数中由 VC 自动生成的代码作如下改变:
{ // BLOCK: doc template registration // Register the document template. Document templates serve // as the connection between documents, frame windows and views. // Attach this form to another document or frame window by changing // the document or frame class in the constructor below. CMultiDocTemplate* m_pDocTemplate2 = new CMultiDocTemplate( IDR_VIEW2_TMPL, // 这里就是菜单项目 RUNTIME_CLASS(CNewDoc), // document class RUNTIME_CLASS(CMDIChildWnd), // frame class RUNTIME_CLASS(CNewView)); // view class AddDocTemplate(m_pDocTemplate2); } |
改为 : 1 )(注意将 CMultiDocTemplate* 去掉,否则你是新建了一个 CMultiDocTemplate* 的对 象) 2 )如果不是选用 New Form 则没有生成以上代码,则直接添加以下代码。 |
m_pDocTemplate2 = new CMultiDocTemplate( IDR_VIEW2_TMPL, RUNTIME_CLASS(CNewDoc), // document class RUNTIME_CLASS(CNewChildFrame), // frame class RUNTIME_CLASS(CNewView)); // view class AddDocTemplate(m_pDocTemplate2); |
以及:
CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MISTYPE, RUNTIME_CLASS(CMISDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CMISView)); AddDocTemplate(pDocTemplate);*/ |
改为 :(注意将 CMultiDocTemplate* 去掉,否则你是新建了一个 CMultiDocTemplate* 的对象) |
m_pDocTemplate1 = new CMultiDocTemplate( IDR_MISTYPE, RUNTIME_CLASS(CMISDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CMISView)); AddDocTemplate(m_pDocTemplate1); |
Step 5 :在 MainFrm.h 中添加两个文档类变量记录这里的两个不同的 Document ,为简单起见就声明为 public :
public : CMISDoc* m_pDoc1; CNewDoc* m_pDoc2 |
注意:在 CMainFrame 构造函数 中将上面两个变量置为 NULL (否则:))。 并响应 IDR_MAINFRAME 的两个菜单项目“功能 1 ”和“功能 2 ”消息,在各自的响应菜单中分别添加响应函数:
// TODO: Add your command handler code here if (m_pDoc1 != NULL) // 已经打开则激活 { POSITION pos;
pos =m_pDoc1->GetFirstViewPosition();
CView* pView = m_pDoc1->GetNextView(pos);
pView->GetParentFrame()->ActivateFrame(); } else { CMISApp* pApp = (CMISApp*)AfxGetApp();
m_pDoc1 = (CMISDoc*)(pApp->m_pDocTemplate1->OpenDocumentFile(NULL)); } |
和:
// TODO: Add your command handler code here if (m_pDoc2 != NULL) { POSITION pos;
pos =m_pDoc2->GetFirstViewPosition();
CView* pView = m_pDoc2->GetNextView(pos);
pView->GetParentFrame()->ActivateFrame(); } else { CMISApp* pApp = (CMISApp*)AfxGetApp();
m_pDoc2 = (CNewDoc*)(pApp->m_pDocTemplate2->OpenDocumentFile(NULL)); } |
至此就完成了整个工作,需要说明的是:
1) 实现中由于使用到相关的类,因此在必要的地方要 include 相关的头文件,这里省略(编译有错误的时候添加就是了:));
2) 这里给出的是一个示例代码,实际开发中可以通过参考实现获得自己想要实现的具体应用情况(例如视图类的不同、数量不同,更重要的还有业务逻辑的不同实现等);