一、开篇引论
熟悉Win32开发的朋友,应该非常了解它的基本组成和流程
1. WinMain:书写窗口类(WNDCLASS) -> 注册窗口类 -> 创建窗口 -> 显示窗口和更新窗口 -> 消息循环
2. WndProc(回调函数):消息处理函数,由windows操作系统自行调用
而MFC呢,就是用c++面向对象的编程思想将这些主要成分封装到各个基本类中,由于封装得很隐蔽,所以学习它的难度就大大增加了。今儿,我就带着大家一起来剖析一下MFC的来龙去脉
在看后面两点之前,先上一份剖析MFC最简单的代码(MFC版的Hello):
1. Hello.h:
只有CMyApp和CMainWindow两个类,它们分别是CWinApp、CFrameWnd的子类,这两个基类有分别封装了WinMain和消息映射机制(相当于WndProc的消息处理)
//Hello.h
//封装了Win32的WinMain函数的处理过程
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance ();
};
//实现了MFC的消息机制
class CMainWindow : public CFrameWnd
{
public:
CMainWindow ();
protected:
afx_msg void OnPaint ();
DECLARE_MESSAGE_MAP ()//消息映射的声明
};
2. Hello.cpp
//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"), -1, &rect, DT_SINGLELINE |DT_CENTER | DT_VCENTER);
}
今天主要利用这两份源代码来剖析MFC的"WinMain"和消息机制,下面进入主题(我就不说什么F话了,直接切入^_^)
二、MFC的"WinMain函数"跑哪儿去了呢?
要想找到它,我给大家介绍一种很有效的方式:
1. 如果你是VC++6.0,就用"Call Stack"(下图红色框圈住的按钮)
2. 如果是VS2008,就用"堆栈帧"(在调试模式下,会出现)
我这里使用的是vc++6.0:
1. 先在OnPaint函数(处理WM_PAINT消息)那儿设置一个端点
2. 键入F5进入调试模式,然后点击"Call Stack",得到的结果如下:
接下来需要做的工作就是一一跟踪这些函数,跟踪一会儿你就能很快了解到MFC中关于Win32的各个实现细节
在这里,由于篇幅的限制,我就直接明述跟踪结果(你可以自行按照上述方法跟踪,这样才有助于深入理解):
1. 全局变量CMyApp myApp;
2. _tWinMain
3. 全局变量myApp的InitInstance()函数
4. 窗口类的注册
5. 创建窗口
6. 显示、更新窗口(还是调用myApp的InitInstance()函数)
7. 进入WndProc,处理消息响应
这里我仅仅将大致的过程贴出来,给你一个大致思路,具体的需要你自己去调试、探究,这样的难度应该就小很多了
三、MFC的消息映射机制
这是MFC的精华所在,它将Win32的消息处理(以WM_开头的消息)过程 映射为 类函数成员函数的处理过程,这样才能符合面向对象的编程思想。其实,它就是使用一大堆宏来实现一种类似于c++的多态机制,因此,要想深入了解这个消息机制,我们必须剖析这些宏:
DECLARE_MESSAGE_MAP ()//消息映射的声明
//消息映射
BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
ON_WM_PAINT ()
END_MESSAGE_MAP ()
下面我们一一展开这些宏:(方法很简单,就是在IDE(集成编译环境 就是编译器)中右键对应的宏,然后选择" Go To Definition Of *** " )
1. 首先展开DECLARE_MESSAGE_MAP
1)未展开的
2)展开后
2. 展开
{
BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
ON_WM_PAINT ()
END_MESSAGE_MAP ()
}
1)未展开的
2)展开后
看到这里,你也许有一点儿蒙,为此,我自行绘制了一张图,它能很好的诠释消息机制的流程关系
好了,现在你应该能明白了吧,可能你还会有一个问题:
MFC本身使用c++封装的,又用一些宏来实现一个类似c++多态的消息映射机制,这不是有些多余吗?
表面上看似是这么回事儿,其实,据我了解到,当时微软的MFC的架构师们测试过,如果用c++的多态性实现,基本上每一个类的对象的储存空间要多那么几十到几百K,它们觉得这样很浪费内存,所以想出了这么一个类似于多态的消息消息映射机制
分享到:
相关推荐
AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC程序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对...
Vc++实现方程求根的程序以及源代码,有MFC的窗口函数#include<windows.h> #include<stdio.h> #include<math.h> //声明窗口函数 LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE ...
main和WinMain函数到底是怎么回事,以及QT是怎么创建窗口和消息循环的,我们已经非常清楚了
什么是句柄?...也就是说MFC都是让我们采用默认的窗口过程函数,这并不是说我们因此就不能使用自己的窗口过程函数实现个性化的消息处理了,MFC采用了一种基于消息映射的机制完成了消息个性化处理。...
#include<windows.h> #include<stdlib.h> #include<string.h> #include<stdio.h> #include<math.h> #define Pi 3.1415926 int lCenterX,lCenterY,lRidous=135; long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT ...
更深入地了解MFC序列化中那些没有文档记录的方面和一些没有文档记录的类,例如CPreview、CPreviewDC、CMirrorFile以及CDockBar等等;最后理解MFC 和OLE是如何共同运作的,以及OLE控悠扬是如何实现的;积累技巧,学会...
此程序为本人在学习了孙鑫老师vc视频教程后,深彻领悟MFC编程原理和对比了Win32 SDK编程开发流程,经过本人不屑的努力,最终写成的,本人不断反思,探索思考而得,属于100%原创作品。 程序中隐藏WinMain函数,当成...
SDL使用实例,该实例运行于PocketPC2002,窗口不停的显示彩色条纹。
AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC程序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对...
利用<windows.h>,<conio.h>,<stdlib.h>这三个库,实现窗口的创建,以及窗口显示区画图。 使用的是控制台创建窗口的方式(main()作为入口),没有利用WinMain()作为入口。 该资源包含图形库与利用该图形库实现的...
和消息动向,然而这些重要的动线在MFC 应用程序中却隐晦不明,因为它们被Application Framework 包起来了。这一章主要目的除了解释MFC 应用程序的长像,也要从MFC 源代 码中检验出一个Windows 程序原本该有的程序...
Custom AppWizard的基本操作 剖析AppWizard Components Dialog Templates和Dialog classes Macros Directives 动手修改Top Studio AppWizard 利用资源编辑器修改IDD_CUSTOM1对话框画面 利用ClassWizard修改IDD_...
#include <string> #include <iostream> #include <windows.h> #include <shellapi.h> #include <gl/gl.h> #include <gl/glext.h> #include "SOIL.h" LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); ...
深入浅出MFC(第二版) 目录 第0章 你一定要知道(导读) 这本书适合谁 你需要什么技术基础 你需要什么软硬件环境 让我们使用同一种语言 本书符号习惯 本书例程的取得 范例程序说明 与前版本之差异 如何联络作者 第...
第1章 MFC概述 1 1.1 MFC是一个编程框架 1 1.1.1 封装 1 1.1.2 继承 2 1.1.3 虚拟函数和动态约束 2 1.1.4 MFC的宏观框架体系 2 1.2 MDI应用程序的构成 3 1.2.1 构成应用程序的对象 3 1.2.2 构成应用程序的对象之间的...
1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用程序的窗口函数。而在MFC程序当中我们不在能...
operator<< 和 operator>> / 532 效率考量/ 536 自定 SERIAL 巨集給抽象類別使用/ 537 在 CObList ㆗加入 CStroke 以外的類別/ 537 Document 與 View 交流 - 為 Scribble Step4 做準備/ 543 第9章 訊息映射與命令繞...
第1章 MFC应用程序概述 1 1.1 Windows应用程序概述 2 1.2 消息 2 1.2.1 消息结构 3 1.2.2 消息类型 3 1.2.3 消息队列 4 1.2.4 消息循环 6 1.3 程序的进入点——WinMain函数 6 1.4 窗口的诞生 7 ...
深入浅出MFC(第二版) 目录 第0章 你一定要知道(导读) 这本书适合谁 你需要什么技术基础 你需要什么软硬件环境 让我们使用同一种语言 本书符号习惯 本书例程的取得 范例程序说明 与前版本之差异 如何联络作者 第...