MFC深入浅出读书笔记第二部分1
第六章 MFC程序的生死因果
MFC学习过程,这个方法不错,条例清晰。

1、CWinApp -- 取代WinMain地位
WinMain函数的功能由CWinApp的三个函数实现
virtual BOOL InitApplication();
virtual BOOL InitInstance();
virtual int Run();
在CWinThread类中定义m_pMainWnd
CWnd* m_pMainWnd; // 记录主窗口的句柄
2、CFrameWnd --- 取代WndProc的地位
通过消息映射来实现消息与函数的关联,宏DECLARE_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
ON_WM_PAINT()
ON_COMMAND(IDM_ABOUT, OnAbout)
END_MESSAGE_MAP()
3、运行过程
1 Ctest7App theApp;//全局对象
2 AfxWinInit(...) 在头文件afxwin.h中定义的AfxWinInit(....),这个函数的参数和WndProc()的一样。
1 BOOL AFXAPI AfxWinInit( HINSTANCE hInstance, HINSTANCE hPrevInstance, //在CWind中被引用为友元函数
LPTSTR lpCmdLine, int nCmdShow);
//在这个函数中 的主要动作之一 CWinApp* pApp = AfxGetApp();//导致CWinApp::InitApplication()的调用
// 之二 AfxInitThread();//初始化线程
3 CWinApp::InitApplication(); //初始化应用
4 BOOL Ctest7App::InitInstance();//自己定义的类
注意:
应用程序一定要改写虚拟函数InitInstance,因为它在CWinApp 中只是个空函数,没有任何内建(预设)动作。
5 CFrameWnd::Create()产生窗口(并先注册窗口类别)
BOOL Create( LPCTSTR lpszClassName,//窗口类别
LPCTSTR lpszWindowName,//窗口标题
DWORD dwStyle = WS_OVERLAPPEDWINDOW,//窗口样式
const RECT& rect = rectDefault,//窗口位置和大小
CWnd* pParentWnd = NULL,//父窗口
LPCTSTR lpszMenuName = NULL,//指定菜单
DWORD dwExStyle = ,//附加样式
CCreateContext* pContext = NULL );//在文档/视图中会用到,这里为默认值NULL
在Create()中调用PreCreateWindow();//虚函数
然后在PreCreateWindow()中调用宏AfxDeferRegisterClass();
6 窗口的更新与显示
m_pMainWnd->ShowWindow(m_nCmdShow);//显示窗口
m_pMainWnd->UpdateWindow();//发送WM_PAINT消息
7 CWinApp::Run() ---- 程序的活水源头
Run()内部有一个GetMessage/DispatchMesage 循环
函数接收到WM_PAINT消息,通过消息映射跳转到OnPaint()函数
整个运行机制看起来很复杂,但是只要多看几遍,必然能熟记于心中,为以后的程序书写打下基础。总结如下:
程序的诞生:
Application object 产生,内存于是获得配置,初值亦设立了。
Afx WinMain 执行AfxWinInit,后者又调用AfxInitThread,把消息队列尽量加大到96。
Afx WinMain 执行InitApplication。这是CWinApp 的虚拟函数,但我们通常不改写它。
AfxWinMain 执行InitInstance。这是CWinApp 的虚拟函数,我们必须改写它。
CMyWinApp::InitInstance 'new' 了一个CMyFrameWnd 对象。
CMyFrameWnd 构造式调用Create,产生主窗口。我们在Create 参数中指定的窗口类别是NULL, 于是MFC 根据窗口种类, 自行为我们注册一个名为"AfxFrameOrView42d" 的窗口类别。
回到InitInstance 中继续执行ShowWindow,显示窗口。
执行UpdateWindow,于是发出WM_PAINT。
回到AfxWinMain,执行Run,进入消息循环。
程序开始运作:
程序获得WM_PAINT 消息(藉由CWinApp::Run 中的::GetMessage 循环)。
WM_PAINT 经由::DispatchMessage 送到窗口函数CWnd::DefWindowProc 中。
CWnd::DefWindowProc 将消息绕行过消息映射表格(Message Map)。
绕行过程中发现有吻合项目,于是调用项目中对应的函数。此函数是应用程序利用BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP 之间的宏设立起来的。
标准消息的处理例程亦有标准命名,例如WM_PAINT 必然由OnPaint 处理。程序的死亡:
使用者选按【File/Close】,于是发出WM_CLOSE。
CMyFrameWnd 并没有设置WM_CLOSE 处理例程,于是交给预设之处理例程。
预设函数对于WM_CLOSE 的处理方式是调用::DestroyWindow, 并因而发出WM_DESTROY。
预设之WM_DESTROY 处理方式是调用::PostQuitMessage,因此发出WM_QUIT。
CWinApp::Run 收到WM_QUIT 后会结束其内部之消息循环, 然后调用ExitInstance,这是CWinApp 的一个虚拟函数。
如果CMyWinApp 改写了ExitInstance , 那么CWinApp::Run 所调用的就是CMyWinApp::ExitInstance,否则就是CWinApp::ExitInstance。
最后回到AfxWinMain,执行AfxWinTerm,结束程序。
4、Callback函数-----全局函数 或者 static 函数
定义:凡是由你设计而却由Windows 系统调用的函数,统称为callback 函数。这些函数都有一定的类型,以配合Windows的调用动作。
注意:如果类别的成员函数是一个callback 函数, 你必须声明它为"static",才能把C++ 编译器加诸于函数的一个隐藏参数this 去掉。
5、 空闲时间(idle time)的处理:OnIdle
如果你的MFC 程序也想处理idle time,只要改写CWinApp 衍生类别的OnIdle 函数即可 virtual BOOL OnIdle(LONG lCount);
6、Dialog 与 Control
MFC中的对话框的创建与打开使用CDialog类。下面是一些常用的对话框:
类别 类型
CCommonDialog 以下各类别的父类别
CFileDialog File 对话框(Open 或Save As)
CPrintDialog Print 对话框
CFindReplaceDialog Find and Replace 对话框
CColorDialog Color 对话框
CFontDialog Font 对话框
CPageSetupDialog Page Setup 对话框(MFC 4.0 新增)
COleDialog Ole 相关对话框
派生关系如图:
具体使用方法参考MSDN
MFC深入浅出读书笔记第二部分1的更多相关文章
- MFC深入浅出读书笔记第二部分2
第七章 MFC骨干程序 所谓骨干程序就是指有AppWizard生成的MFC程序.如下图的层次关系是程序中常用的几个类,一定要熟记于心. 1 Document/View应用程序 CDocument存放 ...
- MFC深入浅出读书笔记第一部分
最近看侯捷的MFC深入浅出,简单总结一下. 第一章首先就是先了解一下windows程序设计的基础知识,包括win32程序开发基础,什么*.lib,*.h,*.cpp的,程序入口点WinMain函数,窗 ...
- MFC深入浅出读书笔记第三部分1
第八章 Document-View 深入探讨(总结) 1.Document Document 在MFC 的CDocument 里头被具体化.CDocument 本身并无任何具体数据,它只是提供一个空壳 ...
- 《javascript权威指南》读书笔记——第二篇
<javascript权威指南>读书笔记——第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字 ...
- STL源码分析读书笔记--第二章--空间配置器(allocator)
声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...
- Getting Started With Hazelcast 读书笔记(第二章、第三章)
第二章 起步 本章就相当简单粗暴了,用一个个例子说明hazelcast怎么用. 1.map,set,list这些集合类都是开箱即用的,只要从Hazelcast的实例中获取一份就行. 2.增加了Mult ...
- Java Concurrency in Practice 读书笔记 第二章
第二章的思维导图(代码迟点补上):
- 《疯狂Java:突破程序员基本功的16课》读书笔记-第二章 对象与内存控制
Java内存管理分为两个方面:内存分配和内存回收.这里的内存分配特指创建Java对象时JVM为该对象在堆内存中所分配的内存空间.内存回收指的是当该Java对象失去引用,变成垃圾时,JVM的垃圾回收机制 ...
- Spring 3.x 实践 第一个例子(Spring 3.x 企业应用开发实战读书笔记第二章)
前言:工作之后一直在搞android,现在需要更多和后台的人员交涉,技术栈不一样,难免鸡同鸭讲,所以稍稍学习下. 这个例子取自于<Spring 3.x 企业应用开发实战>一书中的第二章,I ...
随机推荐
- mysql用户权限操作
mysql用户权限操作1.创建用户mysql -urootcreate database zabbix default charset utf8;grant all on zabbix.* to za ...
- webstorm下载激活汉化
下载 官方下载地址:https://www.jetbrains.com/webstorm/ 激活 参考http://blog.csdn.net/it_talk/article/details/5244 ...
- LeetCode Reverse Words in a String 将串中的字翻转
class Solution { public: void reverseWords(string &s) { string end="",tem="" ...
- dac verilog ad5601
首先从官网下载数据手册.DAC有串行有并行,ad5601是串行,(需要好多时钟沿的移位内部转换为并行在输出). 按照手册的时序编写程序, 关注下芯片的波特率范围 看看手册的数据传输那些事有效的数据位 ...
- php:生成的时间与本地电脑的时间不匹配
如题,在php中我发现在数据库中的时间跟电脑上的时间没有同步 本地时间: 数据库中,生成的时间: 很明显,时分秒是对应不上去的,那么我们只要在php.ini中找到 这里被注释掉了,那我们就改成这样: ...
- pta 编程题15 列出连通集
其它pta数据结构编程题请参见:pta 题目 题目要求分别以深度优先搜索和广度优先搜索输出图的连通集. 广度优先搜索要用到队列,先回顾一下循环队列: struct QNode { int* Data; ...
- ABAP Netweaver和Cloud Foundry上的环境变量Environment Variable
Netweaver 更准确的说应该是系统变量:结构体sy 设一个断点,调试器里看这些字段的值就能知道每个字段是用来做什么的. sy-dbsys sy-sysid sy-opsys sy-saprl s ...
- PHP:is_string()字符串函数
is_string() is_string() - 检测变量是否是字符串. 描述:bool is_string( mixed $var ) 如果var是sring则返回TRUE,否则返回FALSE.m ...
- iOS内存探秘
http://www.cocoachina.com/ios/20170216/18689.html iOS 内存机制特点 有限的可用内存 iPhone 设备的 RAM 一直非常紧缺,iPhone 一代 ...
- 【HDU4473】Exam(数学题)
点此看题面 大致题意: 设\(f(x)=\sum[(a*b)|x]\),求\(\sum_{x=1}^nf(x)\). 转化题意 将题意进行转换,我们就可以发现,我们要求的\(ans\)就是满足\(x* ...