前言
MFC用来自己做个小Demo做测试还是可以的,如果是正儿八经做项目的朋友建议去换个别的界面工具吧,这玩意儿老掉牙了不好看还难用,Qt什么的比这个好多了。我是用occ的代码做测试,随便用用MFC做小测试
本文将基于VS2017创建的单文档MFC项目为例,主要介绍其目录结构,以及各模块(App、View、Doc等的相互调用方法)
一、目录结构
直接在VS2017中新建一个名叫mfcTest的单文档MFC项目后,其目录结构是这样的:

运行初始界面如下:

这些文件可以分为
1.预编译文件
2.应用程序架构文件
3.应用程序控件文件
4.资源文件
1.预编译文件:pch.h、framework.h
里面包含了需要用到的头文件,现在这里对他们进行一个预编译,也可以不用预编译去手动包含。framework我也给他归类到这里,因为里面也是包含一些文件、链接而已,没什么实质性作用的代码
2.应用程序架构文件:MainFrm.h、mfcTest.h、mfcTestDoc.h、mfcTestView.h
架构文件负责控制整个程序的运行流程
mfcTest.h/.cpp是程序的主文件,主要包含由CWinAppEx类派生的CmfcTestApp类的声明与实现,以及CmfcTestApp类的全局对象theApp的声明与定义。
MainFrm.h/.cpp:通过这两个文件从CFrameWndEx类派生出CMainFrame类,用于创建主框架、菜单栏、工具栏和状态栏等。(窗口最上方那些基础控件)
CmfcTestDoc.h/.cpp:这两个文件从CDocument类派生出文档类CmfcTestDoc,包含一些用来初始化文档、串行化(保存和装入)文档和调试的成员函数。
CmfcTestView.h/.cpp:它们从CView类派生出名为CmfcTestView的视图类,用来显示和打印文档数据,包含了一些绘图和用于调试的成员函数。(通过这个类生成的图像显示在中间的视图画布部分)
3.应用程序控件文件:classView.h、fileView.h、OutPutWnd.h、PropertiesWnd.h
这几个类比较直观,可以直接在界面上看到。
classView和fileView就是类视图的文件视图,在运行界面的左侧。
OutPutWnd就是输出打印栏,就在界面最下方。
PropertiesWnd就是属性框,在界面的右方。
这里主要讲一下应用程序架构文件:
这些文件的运行顺序为App->Doc->MainFrame->View
Doc和View类是息息相关的,他们只不过是MFC为了更好的让用户去在逻辑层面理解而创造的。顾名思义,Doc中主要负责数据相关信息的存储、更新等,View主要负责视图上显示。
App类就是这个SDI作为”程序”的入口,有点像c的Main函数,它不是从CWND中派生出来的。App表示应用程序本身。
另外App类和Doc类都是从CCmdTarget类派生而来,所以只能接收命令消息和控件通知消息,View类与Frame框架类都是从CWnd类派生所以能够接收命令消息和控件通知消息还有windows消息三种消息.对于三种消息,响应的顺序是这样的:
首先由框架类接收到该消息,框架类将该消息递交给其子窗口View,如果View没有对该消息进行响应,则由View递交给Doc,如果Doc也没有对该消息进行响应,那么它回再次将该消息回交给View,View再回交给Frame框架,框架检查自己是否对该消息有相应的处理函数,如果没有则递交给 App,如果App也没有则由Windows系统自己处理。
二、对象指针的相互调用
它们的指针相互调用方式如下:
App调用其他指针:
// Doc
CDocument *pDoc = ((CFrameWndEx *)m_pMainWnd)->GetActiveDocument();
// Main 成员变量m_pMainWnd
CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
// View
CView *pView = ((CFrameWndEx *)m_pMainWnd)->GetActiveView();
注意:App是最早创建的,不能在其构造函数中就试图去获取上述三种指针
Doc调用其他指针:
// App
CWinAppEx *pApp = (CWinAppEx *)AfxGetApp();
// Main
CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
// View
CView *pView= (CView *)pMain->GetActiveView();
POSITION pos = GetFirstViewPosition();
pView = GetNextView(pos);
注意:Doc创建早于Main和View,所以不能在Doc的构造函数里获取这两种指针
Main调用其他指针:
// App
CWinAppEx *pApp = (CWinAppEx *)AfxGetApp();
// Doc
CDocument *pDoc = (CDocument *)GetActiveDocument();
// View
CView *pView = (CView *)GetActiveView();
注意:Mian的构造函数里无法获取当前激活的Doc,另外Main创建早于View,也无法在构造函数中获取View
View调用其他指针:
// App
CWinAppEx *pApp = (CWinAppEx *)AfxGetApp();
// Doc
CDocument *pDoc = GetDocument();
// Main
CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
Tip:以上View、Doc等类在定义时最好都定义为指针形式,这样不管是后期通过get函数获取、在自建类中新建对象赋值为View或Doc类,还是通过有参函数来传递都十分方便。
在自创类中调用控件,可以先获取窗口对象
CMainFrame* pMain = (CMainFrame )(((CMFCApplicationApp)AfxGetApp())->m_pMainWnd);
在窗口对象MainFrm.h中public下定义各个控件的全局变量:

之后再通过窗口对象来调用各个控件对象乃至这些控件的变量,这里举例调用 窗口对象->类视图对象->视图树对象->方法1
pMain->m_wndClassView.m_wndClassView.method1();
参考文章
老张谋:https://blog.csdn.net/wgf5845201314/article/details/78148479
csdn_222:https://blog.csdn.net/csdn_222/article/details/79404507
坚定的水手:https://blog.csdn.net/liu6886/article/details/68946542
zbird1988:https://blog.csdn.net/zbird1988/article/details/12141135
本文以VS2017创建的单文档MFC项目为例,介绍其目录结构,包括预编译、应用程序架构、控件和资源文件,阐述架构文件运行顺序及消息响应顺序。还讲解了App、Doc、Main、View对象指针的相互调用方式,以及在自创类中调用控件的方法。
3491

被折叠的 条评论
为什么被折叠?



