[MFC.Windows程序设计(第2版) 第一章
1,windows编程模型如下图:

2, windows的消息有成百上千种,以下列举10个:

3,消息处理函数的四个参数:窗口句柄(表示消息属于哪个窗口,32值。该窗口句柄引用一个数据结构,数据结构存储窗口的大小,风格,在屏幕的位置等信息)、消息ID、wParam、lParam。后两个存储消息的信息。
4,m_开头表示成员变量。

5,API程序和MFC程序的区别:

6,MFC的文档/视图体系结构很重要,想要用MFC的高级特性就必须掌握这些。从第9章开始接触这个。
7,MFC类的分层结构:
CObject类是MFC的祖先类。主要提供三个特性:串行化、运行时类信息、诊断和调试。具体要后面慢慢熟悉。
8,并非所有的MFC函数都是成员函数。以Afx开头的函数是MFC提供的全局函数。部分如下图:

9,MFC的执行流程。非常关键,必须弄懂。
MFC程序执行,操作系统将程序加载到内存,执行AfxWinMain函数(相当于win32的WinMain函数)。这个函数会将操作系统传过来的hInstance、nCmdShow等参数传递给全局变量theApp(这个通常是这样命名的,也可以命名为其他)的数据成员。那有人会问,这个theApp是什么时候创建的。其实这个theApp是应用程序全局变量。会在程序一开始运行就在内存创建好。现在只是给他的数据成员赋值。赋值完成后,就调用theApp的InitInstance函数。这个函数就相当于是MFC的入口函数了。当然调用这个函数是不需要传递参数的。因为这个函数是theApp的成员函数,可以使用theApp的数据成员(之前已经赋值了,现在当然可以直接使用那些被赋值过的数据成员了)。这个函数做一些初始化工作后,要返回一个bool值给AfxWinMain函数。如果返回值是false,则程序结束。如果返回值是true,则AfxWinMain会调用pThread->run()函数。这个函数执行消息循环,并向应用程序窗口发送消息。消息循环重复执行,直到遇到WM_QUIT消息,run才跳出循环。然后调用ExitInstance函数(一些清理工作)。然后AfxWinMain执行return语句结束整个程序。
10,hello.h
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance ();
}; class CMainWindow : public CFrameWnd
{
public:
CMainWindow (); protected:
afx_msg void OnPaint ();
DECLARE_MESSAGE_MAP ()
};
hello.cpp
#include <afxwin.h>
#include "Hello.h" CMyApp myApp; /////////////////////////////////////////////////////////////////////////
// CMyApp member functions BOOL CMyApp::InitInstance ()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow (m_nCmdShow);
m_pMainWnd->UpdateWindow ();
return true;
} /////////////////////////////////////////////////////////////////////////
// CMainWindow message map and member functions BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
ON_WM_PAINT ()
END_MESSAGE_MAP () CMainWindow::CMainWindow ()
{
Create (NULL, _T ("The Hello Application"));
} void CMainWindow::OnPaint ()
{
CPaintDC dc (this); CRect rect;
GetClientRect (&rect); dc.DrawText (_T ("Hello, MFC"), -, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}
上面的代码中,重点讲下
m_pMainWnd->ShowWindow (m_nCmdShow);
m_pMainWnd->UpdateWindow ();
这里调用了showWindow后,主窗口按理说应该显示,事实上,是通过发送WM_PAINT消息给应用程序来响应消息的。当应用程序收到消息WM_PAINT,会调用消息处理函数OnPaint函数。
对于OnPaint函数,通过CPaintDC对象调用DrawText函数来绘制文本。CPaintDC是CDC的子类。CDC封装了windows的设备环境。在CPaintDC的构造函数会调用::BeginPaint()函数,在CPaintDC析构函数会调用::EndPaint()函数。这样做是为了能够将WM_PAINT消息从
消息队列中取出。因为不调用::BeginPaint()和::EndPaint()函数,WM_PAINT消息是不能从消息队列中取出的。CPaintDC对象dc可以设置字体,文本颜色等。此处没有使用这些功能。
GetClientRect方法获取窗口中客户区的坐标顶点位置并赋给rect对象。然后通过DrawText函数,就能找到窗口客户区的正中间绘制文本"Hello,MFC"。 11,消息映射的工作原理。非常重要,必须掌握。
hello.h中的声明: DECLARE_MESSAGE_MAP ()
hello.cpp中的定义:
BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
ON_WM_PAINT ()
END_MESSAGE_MAP () 这些宏就是实现消息映射的关键。 DECLARE_MESSAGE_MAP的声明给hello.h添加了三个数据成员:一个结构数组_messageEntries(包含消息及消息处理函数指针),一个静态结构messageMap(该结构包含两个指针,一个指向类中的_messageEntries数组的指针,一个指向父类messageMap结构的指针)。,一个名为
GetMessageMap的虚函数(该函数返回messageMap的指针)。 下图是BEGIN_MESSAGE_MAP的实现:(afxwin.h)
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
PTM_WARNING_DISABLE \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return GetThisMessageMap(); } \
const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
{ \
typedef theClass ThisClass; \
typedef baseClass TheBaseClass; \
static const AFX_MSGMAP_ENTRY _messageEntries[] = \
{
很明显,我们写在BEGIN_MESSAGE_MAP宏后面的代码会被添加到_messageEntries结构数组中。下面是END_MESSAGE_MAP宏的定义:(afxwin.h)
#define END_MESSAGE_MAP() \
{, , , , AfxSig_end, (AFX_PMSG) } \
}; \
static const AFX_MSGMAP messageMap = \
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[] }; \
return &messageMap; \
}
第一行的意思是添加一个NULL条目。表示结构数组的结束。
从上面这些可以看出:一旦应用程序收到窗口的消息,会先调用WindowProc函数(由Cwnd继承)。WindowProctor又会调用OnWndMsg。OnWndMsg又会调用GetMessageMap获取指向CMainWindow::messageMap指针。最终就能通过这个指针找到消息处理函数。如果在本类中没找到消息对应的消息处理函数,就会去通过CMainWindow::messageMap找到父类的messageMap指针,从而找到父类的消息映射表。从而一次一次往父类找。最终的查找过程见下图:

12,_T宏的作用:
如果不适用_T宏,将字符串常量编码为"Hello, MFC",编译器将使用ANSI字符组成该字符串,如果将字符串常量编码为L"Hello,MFC",编译器将使用Unicode字符组成该字符串。这样导致的问题就是编写的代码与字符集有关了,不适于跨平台性。因为不同的平台使用的字符集不同,就需要维护两套代码来分别支持ANSI字符集和Unicode字符集。
使用MFC的_T宏,可以使得编译器根据代码是否定义_UNICODE宏来确定使用什么字符集。如果定义了_UNICODE宏,就使用Unicode字符集,如果没有定义_UNICODE宏,就使用ANSI字符集。这样的代码是跨平台的。因为只需要维护一份代码。只需要编译的时候定义或者不定义_UNICODE宏就能产生不同平台的代码了。
当然也不是使用_T宏就可以一劳永逸了。这只是使得字符串常量支持跨平台。还有一些接口,一些变量类型都需要使用跨平台的类型,才能实现整个代码都是跨平台的。当然原理都和这个一样。下面看个例子。


[MFC.Windows程序设计(第2版) 第一章的更多相关文章
- javascript高级程序设计第3版——第一章概括
最近发现Xmind思维导图是个好东西,刚好开始看书,被用来归纳最好不过了
- MFC Windows程序设计源代码免费下载
本人近期在网上找到了<MFC Windows程序设计>第二版的书内程序的源代码,特意上传CSDN上面,供学习MFC的程序猿们免费下载. 源代码下载: http://download.csd ...
- 【翻译习作】 Windows Workflow Foundation程序开发-第一章02
1.2 Windows Workflow概览 微软的Windows Workflow Foundation(简称WF)是.NET框架3.0版的一部分..NET3.0其它主要部分是Window ...
- 《Windows程序设计第5版》学习进度备忘
书签:另外跳过的内容有待跟进 __________________学习资源: <Windows程序设计第5版珍藏版> __________________知识基础支持: _________ ...
- 【翻译习作】 Windows Workflow Foundation程序开发-第一章05
1.3 开发我们的第一个工作流 也许你曾经在这样的产品经理手下搞过开发:他总是在你身边转悠,并不时的问一句“你还没做完吗?”.在这一部分,我们将用一个简单的Windows Workflow程 ...
- 【翻译习作】 Windows Workflow Foundation程序开发-第一章04
1.2.3 Windows Workflow运行时 从Windows Workflow的角度看,可以将工作流活动当成是交给一个工作流处理器去执行的一系列指令或操作码.在Windows Workflo ...
- 【翻译习作】 Windows Workflow Foundation程序开发-第一章03
1.2.2.Visual Studio 2005扩展包 微软也为Windows Workflow开发者提供了Visual Studio 2005扩展包.扩展包将许多功能集成到Visual Studio ...
- Windows程序设计(第五版)学习:第一章 起步
第一章 起步 1,windows主要的三个动态库: kernel32.dll负责操作系统的传统工作,包括内存管理.文件输入以及任务管理等. user32.dll负责用户界面的操作,即所有窗口的管理 g ...
- Pro ASP.NET Core MVC 第6版 第一章
目录 第一章 ASP.NET Core MVC 的前世今生 ASP.NET Core MVC 是一个微软公司开发的Web应用程序开发框架,它结合了MVC架构的高效性和简洁性,敏捷开发的思想和技术和.N ...
随机推荐
- 数学概念的提出(一) —— 熵的定义式 H(x)=-log2(p(x))
h(x)=−log2p(x) 考虑一个离散型随机变量 x,当我们观测到该变量的一个特定值,问此时我们通过该值获得的关于该变量的信息量是多少? 信息量可视为"意外的程度"(degre ...
- SICP 锻炼 (1.40)解决摘要
SICP 锻炼1.40 是一个休闲的工作非常easy,但它看起来很复杂,单的一道题. 题目原题例如以下: 请定义一个过程cubic, 它和newtons-method过程一起使用在以下形式的表达式里: ...
- kendo ui gird温馨提示(使用本地数据) 一个
加入js引用 <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.common.min.css" r ...
- 介绍MFC参与设计模式框架(一个)
最近我读了一些相关MFC参与设计的花纹纸架,为了帮助您了解MFC在此框架总结,我们希望对大家有帮助. 简介设计模式 设计模式是一套被重复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计 ...
- 罚函数(penalty function)的设计
1. encourage sparsity ℓ0 范数: non-differentiable and difficult to optimize in general ℓ1 范数: 对数约束,log ...
- Matlab Tricks(二十二)—— 自定义函数
printme = @(txt) print('-dpdf', sprintf('figures/Example_%s',txt)); % 这里的 print 显然不是控制台输出一句话,而是图像的命名 ...
- WPF 悬浮键盘
原文:WPF 悬浮键盘 public class TouchScreenKeyboard : Window { #region Property & Variable & Constr ...
- QT如何编译出带调试信息的qtwebkit库
因为在编译QT的时候默认是不编译成带调试信息的qtwebkit库的,不论如何设置参数都是没有用的.后面在一博客中查找到相关信息 1.编译带debug 信息的webkit 库 注释或者删除qt-ev ...
- C# 事件详解
1.事件的本质是什么 答:事件是委托的包装器,就像属性是字段的包装器一样 2.为什么有了委托还有有事件 委托可以被访问就可以被执行,事件则只能在类的内部执行 3.事件要怎么声明 a.明一个委托 //委 ...
- ArcGIS数据生产与精细化制图之中国年降水量分布图的制作
原文:ArcGIS数据生产与精细化制图之中国年降水量分布图的制作 楼主按:在今年的Esri中国用户大会上,我听了几场关于ArcGIS用于制图方面的讲座,也在体验区与Esri中国的技术老师有一些交流.一 ...