好文档 - 专业文书写作范文服务资料分享网站

MFC教程

天下 分享 时间: 加入收藏 我要投稿 点赞

四、主应用程序类做什么

主应用程序类是程序的入口,其它各个类都是在这儿集成的。这个类除构造函数之外,唯一要注意的就是初始化函数。这个类一般不修改。

单文档 Ctest2App() 构造函数 对话框 Ctest2App() 构造函数 初始化成InitInstance() 初始化成员函数 InitInstance() 员函数 OnAppAbout() 由菜单发出的消息 处理函数 单文档 BOOL Ctest2App::InitInstance() { InitCommonControls(); CWinApp::InitInstance(); if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } { 对话框 BOOL Ctest3App::InitInstance() InitCommonControls(); CWinApp::InitInstance(); AfxEnableControlContainer(); SetRegistryKey(_T(\应用程序向导生成的本地应用程序\)); //加载标准 INI 文件选项(包括 AfxEnableControlContainer(); SetRegistryKey(_T(\应用程序向导生成的本地应用程序\)); //上面内容不用太关注,以下是重MRU) LoadStdProfileSettings(4); //上面内容不用太关注,以下是重点 点 //注册应用程序的文档模板。文档模 Ctest3Dlg dlg; m_pMainWnd = &dlg; 板 //将用作文档、框架窗口和视图之间 INT_PTR nResponse = dlg.DoModal(); 的连接 //下面的程序注意:对话框窗口已 CSingleDocTemplate* pDocTemplate; 经被关闭 pDocTemplate = new CSingleDocTemplate( if (nResponse == IDOK) IDR_MAINFRAME, RUNTIME_CLASS(Ctest2Doc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(Ctest2View)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); { // TODO: 在此放置处理何时用“确定”来关闭 //对话框的代码 } else if (nResponse == IDCANCEL) { //分析标准外壳命令、DDE、打开文件 // TODO: 在此放置处理何时用操作的命令行 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); “取消”来关闭 //对话框的代码 } //调度在命令行中指定的命令。如果 //用 /RegServer、/Register、 // 由于对话框已关闭,所以将返回 /Unregserver FALSE 以便退出应用程序, //或 /Unregister 启动应用程序, // 而不是启动应用程序的消息则返回 FALSE。 泵。 if (!ProcessShellCommand(cmdInfo)) return FALSE; } return FALSE; //唯一的一个窗口已初始化,因此显 示它并对其进行更新 m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->UpdateWindow(); //仅当存在后缀时才调用 DragAcceptFiles, //在 SDI 应用程序中,这应在 ProcessShellCommand //之后发生 return TRUE; } 04章 程序的执行流程

一、WinMain()函数在哪儿

因为看不到WinMain()函数,许多初学者不知道程序究竟从哪儿开始,编程从哪儿下手,编写的代码何时运行等等,另外,还有很多看不懂的语句,最大的困难恐怕还是MFC的编程思想不太理解。各位既然选择小雅的教程来学习MFC,小雅就有责任将每一个你不明白的地方剖析清楚,因为小雅自己也曾为此而烦恼了几年。不过,饭还得一口一口地吃,最好的办法是先照葫芦画瓢,从容易的入手,再一步一步地深入。

MFC把千篇一律的WinMain()函数写在①crtexec.c中,在编译完后链接时才组装到你的exe程序中。运行时,这个WinMain()函数调用MFC的全局函数AfxWinMain(),这个全局函数AfxWinMain()是写在②appmodul.cpp中的。在AfxWinMain()函数中做三件事,③注册窗口类、④调用应用程序类的初始化函数InitInstance()、⑤调用应用程序类的Run()函数(实际上是父类的父类CWinThread的Run()成员函数)。

上面这个Run()函数中包含消息循环,而InitInstance()函数又将框架类、文档类、视图类结合在一起,于是所有的类全部集成起来了。编程的重点在文档类和视图类,什么样的消息,执行什么样的处理函数,这样就有效地将数据和控制分离开来。

二、消息处理

消息处理的回调函数在mfc70d.dll中的CWnd::WindowProc(...),由上面讲的Run()函数调用,然后在主应用程序类、框架类、文档类、视图类里面接受这些消息并处理。问题是:某一消息究竟在哪个类里面处理?

与窗口有关的消息(即以“WM_”开头的消息),只能在框架类和视图类中处理;来自菜单或工具条的命令事件,则框架类、视图类、主应用程序类、文档类全部可以处理,究竟在哪个类中处理,根据具体情况再决定在哪个类中处理。这其中有优先级别高低的问题,一个类接受到命令消息时,先传给比自己级别高的类,如果未处理再自己处理。如果自己也不处理,则传给比自己级别低的类。

这个优先级别是:视图类>文档类>文档模板类>框架类>主应用程序类。例如,框架类收到“编辑”菜单的“Clear All”命令消息时,首先传给视图类,如果视图类处理便结束,否则就传给文档类。如果文档类处理便结束,否则就传给文档模板类。如果文档模板类处理则结束,否则就回到了框架类。如果框架类处理则结束,否则就传给主应用程序类。如果主应用程序类还不处理,就回到MFC缺省的处理程序中。

三、添加、删除消息处理

添加一个消息处理,一般要改动三个地方,以

WM_LBUTTONDOWN消息为例,①在视图类的定义(test2View.h)

中添加一个成员函数,②在视图类(test2View.c)中添加一条消息映射,③在视图类(test2View.c)中实现消息处理的成员函数。

// test2View.h : Ctest2View 类的接口 ......(省略) // 生成的消息映射函数 protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnLButtonDown(UINT nFlags, CPoint point); }; ......(省略) // test2View.cpp : Ctest2View 类的实现 // #include \ #include \ #include \ #include \ #include \ #ifdef _DEBUG #define new DEBUG_NEW #endif // Ctest2View IMPLEMENT_DYNCREATE(Ctest2View, CView) BEGIN_MESSAGE_MAP(Ctest2View, CView) // 标准打印命令 ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() ......(省略) // Ctest2View 消息处理程序 void Ctest2View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 AfxMessageBox(\劝学网 http://www.quanxue.cn/\, MB_OK); CView::OnLButtonDown(nFlags, point); } 上面虽然很简单,但不建议手动添加,应该在“类视图”中选中“Ctest2View”,再在“属性”工具中选择“WM_LBUTTONDOWN”消息,同时选上“OnLButtonDown”后回车就可以了。

用同样方法在“属性”工具中删除“WM_LBUTTONDOWN”消息时,前面添加的三处代码将被用“//”注释在那儿,成了“垃圾”代码。这时最好手动删除一下这三处“垃圾”代码。

四、程序的入口

学过C++语言或Java语言的人都明白,类相当于自定义的数据类型,如果没有实例,自身是不会运行的。那么,上面一直在解说这4个类,当前生成的5个.cpp文件中,WinMain启动后究竟先运行什么语句,后运行什么语句?

要明白MFC的细节,除了C++的基础之外,最好学一点SDK编程,了解Win32编程中的基本内容。小雅在SDK教程中的第1章到第3章的内容请参考。MFC生成的4个类中,主应用程序类是从CWinApp类继承的,作用相当于WinMain程序;CMainFrame是从CFrameWnd类继承的,其作用相当于WndProc程序。也就是说,消息首先由框架类接受,然后按优先顺序传给其它的类。文档类和视图类由消息来驱动(视图类的PreCreateWindow()除外)。

主应用程序类的程序test2.cpp中,跳过消息映射以及类的构造函数、成员函数后,实际只剩下1条语句,即“Ctest2App theApp;”,这便是整个应用程序的总入口。MFC的crtexec.c的WinMain()函数调用test2.cpp中的“Ctest2App theApp;”。theApp是类的实例,自然也是必然要调用主应用程序类的构造函数,包括父类的构造函数,

MFC教程

四、主应用程序类做什么主应用程序类是程序的入口,其它各个类都是在这儿集成的。这个类除构造函数之外,唯一要注意的就是初始化函数。这个类一般不修改。单文档Ctest2App()构造函数对话框Ctest2App()构造函数初始化成InitInstance()初始化成员函数InitInstance()员函数OnAppAbout()
推荐度:
点击下载文档文档为doc格式
65d4x6qtdf553972zwtu
领取福利

微信扫码领取福利

微信扫码分享