MFC初窥MFC运行机制孙鑫C++第三讲笔记整理.docx
- 文档编号:10717933
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:13
- 大小:183.89KB
MFC初窥MFC运行机制孙鑫C++第三讲笔记整理.docx
《MFC初窥MFC运行机制孙鑫C++第三讲笔记整理.docx》由会员分享,可在线阅读,更多相关《MFC初窥MFC运行机制孙鑫C++第三讲笔记整理.docx(13页珍藏版)》请在冰豆网上搜索。
MFC初窥MFC运行机制孙鑫C++第三讲笔记整理
有了一定的Windows32编程知识,就能学习MFC了。
在学习MFC之前,一定要弄明白Windows32编程中的消息循环是怎么回事。
MFC实际上就是对WindowsAPI函数的封装。
在Windows程序设计编程中,创建一个窗口要经历下面四个过程 (如有不懂,请看博客win32初窥)
1设计一个窗口类;
2注册窗口类;
3创建窗口;
4显示及更新窗口。
同样,MFC中也是一样的。
只是封装了而已,很多人认为MFC很难学,看着书本能编程序,但是却编写不了自己的程序,为什么呢?
因为还没有理解MFC的原理的机制。
市场上有很多有关VC++的书本,但是很少有将MFC原理讲得比较透彻的,引用孙鑫老师的话。
同样的,WinMain也是入口函数,具体的过程,请看孙鑫视频20讲之第三讲
其中,孙鑫老师开始提出的一个问题是:
在全局变量中,定义一个子类对象。
。
。
[html] viewplain copy
1.#include
2.#include
3.using namespace std;
4.
5.class Person
6.{
7.public:
8. Person *p;
9. Person()
10. {
11. p=this;//保存this指针
12. }
13. virtual void say()
14. {
15. cout<<"Person's say()"< 16. } 17. 18.}; 19. 20.class Student: public Person 21.{ 22.public: 23. 24. Student() 25. { 26. 27. } 28. void say() 29. { 30. cout<<"Student's say()"< 31. } 32. 33.}; 34. 35.Student s; 36. 37.int main() 38.{ 39. 40. s.p->say();//这里将调用子类的方法 41. return 0; 42.} 什么都不用做,直接用向导生成一个MFC窗口。 下面是结构图,有五个类 是这样命名的,开头的C表示Class,C+工程名+(App,Doc,View...) 其中CMainFrame表示一个窗口(主窗体,包括标题栏,菜单...),XXApp表示运用程序,XXDOC表示文档类(加载数据,实现数据的存储与操作分离),XXView也表示一个窗口(相当于Windows的客户区) 下面看看MFC中类的主要继承关系: 由于继承树太大,这里只罗列了CWnd的继承关系 API中CreateWindowEx和CreateWindow几乎是一样的,Ex表示扩展,多了一个参数 下面用API模拟CWnd just模拟 [html] viewplain copy 1.//下面是模仿封装API函数 2. 3.class CWnd 4.{ 5.public: 6. BOOL CreateEX( 7. DWORD dwExStyle, // extended window style 8. LPCTSTR lpClassName, // registered class name 9. LPCTSTR lpWindowName, // window name 10. DWORD dwStyle, // window style 11. int x, // horizontal position of window 12. int y, // vertical position of window 13. int nWidth, // window width 14. int nHeight, // window height 15. HWND hWndParent, // handle to parent or owner window 16. HMENU hMenu, // menu handle or child identifier 17. HINSTANCE hInstance, // handle to application instance 18. LPVOID lpParam // window-creation data 19. ); 20. 21. BOOL ShowWindow(int nCmdShow); 22. 23. BOOL UpdateWindow(); 24. 25.public: 26. HWND m_hWnd; 27.}; 28. 29.BOOL CWnd: : CreateEx( 30. DWORD dwExStyle, // extended window style 31. LPCTSTR lpClassName, // registered class name 32. LPCTSTR lpWindowName, // window name 33. DWORD dwStyle, // window style 34. int x, // horizontal position of window 35. int y, // vertical position of window 36. int nWidth, // window width 37. int nHeight, // window height 38. HWND hWndParent, // handle to parent or owner window 39. HMENU hMenu, // menu handle or child identifier 40. HINSTANCE hInstance, // handle to application instance 41. LPVOID lpParam // window-creation data 42. ); 43.{ 44. m_hWnd=: : CreateWindowEx(dwExstyle,lClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent, 45. hMenu,hInstance,lParam); 46. 47. if(m_hWnd! =NULL) 48. 49. return TRUE; 50. else 51. return FALSE; 52.} 53. 54.BOOL CWnd: : ShowWindow(int nCmdShow) 55.{ 56. return : : ShowWindow(m_hWnd,nCmdShow);//调用的是SDK全局函数,加个: : 说明是全局的 57.} 58. 59.BOOL CWnd: : UpdateWindow() 60.{ 61. return : : UpdateWindow(m_hWnd); 62.} 63. 64.int WINAPI WinMain( 65. HINSTANCE hInstance, // handle to current instance 66. HINSTANCE hPrevInstance, // handle to previous instance 67. LPSTR lpCmdLine, // command line 68. int nCmdShow // show state 69. ) 70.{ 71. WNDCLASS wndclass; 72. 73. wndclass.cbClsExtra=0; 74. wndclass.cbWndExtra=0; 75. wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); 76. wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); 77. wndclass.hIcon=LoadIcon(NULL,IDI_ERROR); 78. wndclass.hInstance=hInstance; 79. ... 80. 81. CWnd cwnd; 82. cwnd.CreateEx(dwExstyle,...,...); 83. 84. cwnd.ShowWindow(nCmdShow); 85. cwnd.UpdateWindow(); 86. 87. while(GetMessage(&msg,NULL,0,0)) 88. { 89. TranslateMessage(&msg); 90. DispatchMessage(&msg); 91. } 92. 93. ... 94.} 下面是重头戏(引用了某位仁兄的,太详细了) 重点: MFC运行机制 提示: 对于不想理解内部运行过程的,可以不看这一章,可以看了后面的界面设计再回头来看这一章,可能感觉更深刻。 这一次课和上一次的课的重点就是MFC的窗口类创建过程,而要反复说明的就是: MFC的程序和C语言的程序,从执行原理上说,是完全一致的。 抓住这一点,那么对于理解MFC程序的运行机制也就相对于简单了。 C中的main函数就相当于MFC中的WinMain函数。 感兴趣的可以利用VC的断点设置自己跟踪下面讲述的各个函数,就明白它的执行顺序了。 一、C语言程序执行步骤 在C语言中,大约的步骤如下: 1,全局变量内存分配 2,进入main函数 二、MFC程序的运行步骤(主要是初始化) 打开一个MFCAPPWizard(exe)工程,跟踪其执行步骤,可以发现,是以下顺序: 1)CXXApp中的全局变量定义 CXXApptheApp; 2)调用CXXApp构造函数 CXXApp: : CXXApp(){} 3)进入Winmain函数(_tWinMain为宏,值为WinMain) _tWinMain(){} 4)完成初始化工作: 包括窗口类注册、窗口产生、显示和更新 pThread->InitInstance() 对于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注册与创建、显示等要反复调用多次,一次对应一个窗口 (1)注册窗口类 AfxEndDeferRegisterClass (2)创建窗口 CMainFrame: : PreCreateWindow()//反复调用一次是给我们修改窗口属性的机会 CFrameWnd: : Create() (3)消息循环 PumpMessage() 补充1: 在MFC中,由于涉及到(窗口)类定义,所以定义全局变量的时候,需要进行更多的步骤。 全局变量涉及到类定义(类似于C中的类型定义)的话,那么需要遵循以下步骤(以MFC的窗口类为例) 1)设计一个窗口类 2)注册窗口类 3)创建窗口 4)显示及更新窗口 5)消息循环 补充2: 其他需要注意的几点 1,每一个MFC程序,有且只有一个从WinApp类派生的类(应用程序类),也只有一个从应用程序类所事例化的对象,表示应用程序本身。 在WIN32程序当中,表示应用程序是通过WINMAIN入口函数来表示的(通过一个应用程序的一个事例号这一个标识来表示的)。 在基于MFC应用程序中,是通过产生一个应用程序对象,用它来唯一的表示了应用程序。 2,_tWinMain函数中通过调用AfxWinMain()函数来完成它要完成的功能。 (Afx*前缀代表这是应用程序框架函数,是一些全局函数,应用程序框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成,我们可根据这些类函数来设计自己的应用程序)。 3,设计窗口类: 在MFC中事先设计好了几种缺省的窗口类,根据不同的应用程序的选择,调用AfxEndDeferRegisterClass()函数注册所选择的窗口类。 4,PreCreateWindow()是个虚函数,如果子类有则调用子类的。 5,CreateWindowEx()函数参数与CREATESTRUCT结构体成员完全一致,CreateWindowEx()函数与CREATESTRUCT结构体参数的对应关系,使我们在创建窗口之前通过可PreCreateWindow(cs)修改cs结构体成员来修改所要的窗口外观。 6,注意两个函数。 : : TranslateMessage(&m_msgCur)函数进行消息(如键盘消息)转换 : : DispatchMessage(&m_msgCur)函数分派消息到窗口的回调函数处理(实际上分派的消息经过消息映射,交由消息响应函数进行处理。 ) 7,可以认为View类窗口是CMainFram类窗口的子窗口。 DOCument类是文档类。 DOC-VIEW结构将数据本身与它的显示分离开。 文档类用于数据的存储,加载;视类用于数据的显示,修改 8,CTEApp: : InitInstance()函数中通过文档模板将文档类,视类,框架类的有机组织一起。 语句如下: CSingleDocTemplate*pDocTemplate; pDocTemplate=newCSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CTEDoc), RUNTIME_CLASS(CMainFrame),//mainSDIframewindow RUNTIME_CLASS(CTEView)); AddDocTemplate(pDocTemplate);//增加到模板 补充3: 本课涉及到MFC函数的源文件位置 根目录 找到您安装VC98下MFC的位置,比如我的机子上为: D: \ProgramFiles\MicrosoftVisualStudio\VC98\MFC。 下面提供的就是相对路径了。 CWinApp构造函数: MFC=>SRC=>APPCORE.CPP AfxWinMain: MFC=>SRC=>WINMAIN.CPP AfxEndDeferRegisterClass: MFC=>SRC=>APPCORE.CPP CFrameWnd: : PreCreateWindow()函数所在文件: MFC=>SRC=>WINFRM.CPP CFrameWnd: : Create()函数路径: MFC=>SRC=>WINFRM.CPP CWnd: : CreateEx()函数路径: MFC=>SRC=>WINCORE.CPP CWinThread: : Run()方法路径: MFC=>SRC=>THRDCORE.CPP 创建按钮 1在CMainFrame创建 双击CMainFrame,添加数据成员,CButtonm_btn 在OnCreate方法添加如下代码: [html] viewplain copy 1.m_btn.Create(TEXT("first Button"),BS_PUSHBUTTON|WS_CHILD,CRect(0,0,100,100),this,123); 2.m_btn.ShowWindow(SW_NORMAL); 2在CXXView创建 双击CXXView,添加数据成员,CButtonm_btn 在CXXView右键AddwindowsMessageHandler添加WM_CREATE消息处理,然后生成OnCreate函数 在OnCreate函数添加如下代码 [html] viewplain copy 1.m_btn.Create(TEXT("Button2"),BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE,CRect(0,0,100,100),this,123); 两个代码效果是等价的:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFC 初窥 运行机制 C+ 第三 笔记 整理