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 ...
随机推荐
- 新增自定义聚合函数StrJoin
1.添加程序集Microsoft.SqlServer.Types CREATE ASSEMBLY [Microsoft.SqlServer.Types] AUTHORIZATION [sys] FRO ...
- LeetCode Single Number III (xor)
题意: 给一个数组,其中仅有两个元素是出现1次的,且其他元素均出现2次.求这两个特殊的元素? 思路: 跟查找单个特殊的那道题是差不多的,只是这次出现了两个特殊的.将数组扫一遍求全部元素的异或和 x,结 ...
- LeetCode Sort List 链表排序(规定 O(nlogn) )
Status: AcceptedRuntime: 66 ms 题意:根据给出的单链表,用O(nlogn)的时间复杂度来排序.由时间复杂度想到快排.归并这两种排序.本次用的是归并排序.递归将链表的规模不 ...
- hbase查询基于标准sql规范中间件Phoenix
Phoenix是个很好的hbase 查询工具,在hbase中安装也很简单,可以按照 http://www.cnblogs.com/laov/p/4137136.html 这个连接中进行配置客户端和服务 ...
- Spark的基本概念及工作原理
Spark作业的基本概念 -Application:用户自定义的Spark程序,用户提交后,Spark为App分配资源将程序转换并执行. -Driver Program:运行Application的m ...
- vuejs课程简介及框架简介
vuejs准备知识: 1.前端开发基础 html css js 2.前端模块化基础 3.对es6有初步的了解 vuejs是一种轻量级的MVM框架,他吸收了react和angular的优点,强调re ...
- 【DBA-Oracle】更改Oracle数据字符集_转为常用的ZHS16GBK
A.oracle server 端 字符集查询 select userenv('language') from dual 其中NLS_CHARACTERSET 为server端字符集 NLS_LAN ...
- nginx installl
参考http://jingyan.baidu.com/album/4b07be3cbbb54848b380f322.html?picindex=5 安装nginx需要的依赖包 wget 下载 编译安装 ...
- ARC机制中的Strong和weak
什么是ARC Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入的最大的变革和最激动人心的变化.ARC是新的LLVM 3.0编译 ...
- 爬虫学习(八)——带cookie的网页进行爬取
# 前提:# # 通常,很多网站需要登录才能进行浏览,所以在爬取这些网站时,也需要进行登录,并拿取登录时的cookie# # 登录网页,服务器会给客户端一个牌子cookie# # 访问登录页面时,带着 ...