深入解析MFC -- CWinApp

一个Windows应用程序至少由两部分组成:消息处理和窗口过程。在MFC中,由CWinApp和CWnd来分别处理这些操作。
CWinApp负责初始化,创建一个或多个窗口。CWinApp由CWinThread派生。CWinThread的成员函数Run,维护GetMessage() ... DispatchMessage()等消息循环。
每个MFC模块都必须写一个类CYourApp,这个类从CWinApp派生,它具体实现了此模块要做的事情。
每个模块都拥有一个CYourApp的实例,但是CYourApp的实例theApp不是_tWinMain中被创建的。在进入主程序之前,实例就已经创建出来。MFC中有非常多的全局变量,theApp就是一个全局变量。为什么theApp会成为全局变量呢?我想是微软希望掩盖_tWinMain函数的细节,那么_tWinMain自然不会知道每个项目的CWinApp的派生类的名称,也就无从生成此对象的实例了。

其实,在MFC中,最大、最重要的一个全局变量是一个无文档说明的_afxBaseModuleState,其类型是结构体_AFX_BASE_MODULE_STATE。_AFX_BASE_MODULE_STATE的所有秘密在于其基类AFX_MODULE_STATE。AFX_MODULE_STATE包括很多关于模块的核心信息,比如模块实例句柄,资源模块实例,CYourApp的指针、应用程序的名字、指向应用程序的运行时类信息结构链表中的第一个节点的指针。当theApp被生成后,就会被记录到AFX_MODULE_STATE中。当然,做为MFC的使用者,是不需要了解AFX_MODULE_STATE的具体细节的。MFC很体贴的提供了很多AfxXXX的全局函数,通过这些全局函数,我们就能获得AFX_MODULE_STATE中的小秘密了。比如AfxGetApp()可以获得theApp实例,AfxGetInstanceHandle获得模块实例句柄等。

CYourApp(即CWinApp)被创建后,将在_tWinMain中被初始化。_tWinMain首先会调用CWinApp的InitApplication,在此函数中初始化CWinApp的某些成员变量,比如CDocManager对象等。然后调用InitInstance,通常CYourApp会重载这些函数,在此函数中我们会初始化COM环境等东西,然后创建文档视图模型,创建并显示主窗口。最后会调用CWinApp的Run,开始我们的消息之旅。当用户选择退出应用程序后,程序控制权从Run中返回到_tWinMain中,函数会做一些对象清理之类的工作,最后成功退出。


http://blog.sina.com.cn/s/blog_660ca10d0100lg0z.html


---------------------------------------------------------------------------------------------------------------------------------------

基本信息

  CWinApp为应用程序类 
  MFC 中的主应用程序类封装用于 Windows 操作系统的应用程序的初始化、运行和终止。基于  框架 生成的应用程序必须有且仅有一个从 CWinApp 派生的类的对象。在创建窗口之前先构造该对象。 
  CWinApp 是从  CWinThread  派生的,后者表示可能具有一个或多个线程的应用程序的主执行线程。在最新版本的 MFC 中,InitInstance、Run、ExitInstance 和 OnIdle 成员函数实际位于 CWinThread 类中。此处将这些函数作为 CWinApp 成员来探讨,因为探讨所关心的是对象作为应用程序对象而不是  主线程 的角色。

注意

  应用程序类构成应用程序的主执行线程。使用 Win32 API 函数还可以创建辅助执行线程。这些线程可以使用 MFC 库。有关更多信息,请参见多线程编程。 
  与用于 Windows 操作系统的任何程序一样,框架应用程序也具有 WinMain 函数。但在框架应用程序中不必编写 WinMain。它由类库提供,并在应用程序启动时调用。WinMain 执行注册  窗口类 等标准服务。然后它调用应用程序对象的成员函数来初始化和运行应用程序。(可通过重写由 WinMain 调用的 CWinApp 成员函数来自定义 WinMain。) 
  为初始化应用程序,WinMain 调用应用程序对象的 InitApplication 和 InitInstance 成员函数。为运行应用程序的  消息循环 ,WinMain 调用 Run 成员函数。在终止时,WinMain 调用应用程序对象的 ExitInstance 成员函数。下图显示了框架应用程序中的执行顺序。

CWinApp - 执行顺序

  注意 本文中以粗体显示的名称指示由 Microsoft 基础类库和 Visual C++ 提供的元素。以 monospaced 类型显示的名称指示您创建或重写的元素。 
  基于MFC的应用程序有一个  应用对象 ,它是CWinApp派生类的对象,该对象代表了应用进程的  主线程 。当线程执行完并退出线程时,由于进程中没有其他线程存在,进程自动结束。类CWinApp从CWinThread派生出来,CWinThread是  用户接口 线程的基本类。我们在编写用户接口线程时,需要从CWinThread派生我们自己的线程类,ClassWizard可以帮助我们完成这个工作。 
  先用ClassWizard派生一个新的类,设置  基类 为CwinThread。注意:类的 DECLARE_DYNCREATE IMPLEMENT_DYNCREATE 宏是必需的,因为创建线程时需要动态创建类的对象。根据需要可将初始化和结束代码分别放在类的InitInstance和ExitInstance函数中。如果需要创建窗口,则可在InitInstance函数中完成。然后创建线程并启动线程。可以用两种方法来创建用户接口线程,MFC提供了两个版本的 AfxBeginThread 函数,其中一个用于创建用户接口线程。第二种方法分为两步进行:首先,调用线程类的  构造函数 创建一个线程对象;其次,调用CWinThread::CreateThread函数来创建该线程。线程建立并启动后,在线程函数执行过程中一直有效。如果是线程对象,则在对象删除之前,先结束线程。CWinThread已经为我们完成了线程结束的工作。

CWinApp - CWinApp类成员

数据成员

  
m_pszAppName指定了应用程序的名字
  
m_hInstance标识了应用程序的当前实例
m_hPrevInstance在32位应用程序中被设为NULL
m_lpCmdLine指向一个以null结尾的字符串,指定了应用程序的命令行
m_nCmdShow指定最初如何显示窗口
m_bHelpMode指明用户是否处于Help上下文模式(通常用SHIFT+F1激活)
m_pActiveWnd当一个OLE服务器是现场可激活时,它指向容器应用程序的主窗口
m_pszExeName应用程序的模块名字
m_pszHelpFilePath应用程序的帮助文件的路径
m_pszProfileName应用程序的。INI文件名
m_pszRegistryKey用于确定保存应用程序主要设置的完整的注册表键
m_pDocManager用于保存文档模板管理类的指针(MSDN中没有这个数据成员)

构造函数

  CWinApp 构造一个CWinApp对象

操作符

  
LoadCursor载入光标资源
LoadStandardCursor载入WINDOWS.H中IDC_常量所指定的Windows预定义光标
LoadOEMCursor载入WINDOWS.H中OCR_常量所指定的WindowsOEM预定义光标
LoadIcon载入图标资源
LoadStandardIcon载入WINDOWS.H中IDI_常量所指定的Windows预定义图标
LoadOEMIcon载入WINDOWS.H中OIC_常量所指定的WindowsOEM预定义图标
RunAutomated检查应用程序的命令行是否指定/Automation选项。已不用。应当在调用ParseCommandLine之后使用CCommandLineInfo::m_bRunEmbedded中的值
RunEmbedded检查应用程序的命令行是否指定/Embedding选项。已不用。应当在调用ParseCommandLine之后使用CCommandLineInfo::m_bRunEmbedded中的值
ParseCommandLine解析命令行中的每个参数和标志
ProcessShellCommand处理命令行参数和标志
GetProfileInt从应用程序的。INI文件的一个入口中获取一个整数
WriteProfileInt将一个整数写到应用程序的。INI文件的入口
GetProfileString从应用程序的。INI文件的一个入口中获取一个字符串
WriteProfileString将一个字符串写到应用程序的。INI文件的入口
AddDocTemplate将一个文档模板加到应用程序的可用文档模板列表中
GetFirstDocTemplatePosition获取第一个文档模板的位置
GetNextDocTemplate获得文档模板的位置。可以递归调用
OpenDocumentFile由框架调用,用以从文件打开一个文档
AddToRecentFileList将一个文件名加入最近使用(MRU)的文件列表
SelectPrinter选择先前由用户在打印对话框中指定的打印机
CreatePrinterDC创建一个打印机设备环境
GetPrinterDeviceDefaults获得缺省的打印机设备

可重载的函数

  
InitInstance可被重载以执行Windows的实例初始化,比如创建窗口对象
Run运行缺省的消息循环。可被重载以定制消息循环
OnIdle可被重载以执行应用程序指定的空闲时处理
ExitInstance可被重载以在应用程序结束时执行清除操作
HideApplication在关闭所有的文档之前隐藏应用程序
CloseAllDocuments关闭所有打开的文档
PreTranslateMessage在消息被分派到Windows函数::TranslateMessage和::DispatchMessage之前过滤消息
SaveAllModified提示用户保存所有改变了的文档
DoMessageBox为应用程序实现AfxMessageBox
ProcessMessageFilter在消息到达应用程序之前截取特定的消息
ProcessWndProcException截取应用程序的消息和命令处理函数抛出的未被处理的异常
DoWaitCursor打开或关闭等待光标
OnDDECommand框架调用这个函数以响应动态数据交换(DDE)执行命令
WinHelp调用Windows的WinHelp函数

初始化

  
LoadStdProfileSettings载入标准的。INI文件设置并允许MRU文件列表特性
SetDialogBkColor设置对话框和消息框的缺省背景颜色
SetRegistryKey使应用程序的设置保存在注册表中,而不是。INI文件中
EnableShellOpen允许用户通过Windows的文件管理器打开数据文件
RegisterShellFileTypes在Windows的文件管理器中注册所有的应用程序文档类型
Enable3dControls使控件具有三维外观(动态库)
Enable3dControlsStatic使控件具有三维外观(静态库)

命令操作

  
OnFileNew实现ID_FILE_NEW命令
OnFileOpen实现ID_FILE_NEW命令
OnFilePrintSetup实现ID_FILE_PRINT_SETUP命令
OnContextHelp处理应用程序内的SHIFT+F1命令
OnHelp处理应用程序内的F1帮助命令(使用当前的上下文)
OnHelpIndex处理ID_HELP_INDEX命令,提供缺省的帮助主题
OnHelpFinder处理ID_HELP_FINDER和ID_DEFAULT_HELP命令
OnHelpUsing处理ID_HELP_USING命令
http://www.baike.com/wiki/CWinApp


  • 11
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值