第三课——MFC编程

摘要:
因此,stdafx仍然保留在MFC应用程序向导创建的程序中。h头文件包含。它是每个应用程序所必需的预编译头文件。包含程序使用的语句的Visual C++头文件通常添加到此文件中。

一、MFC概述

1. MFC简述

  MFC不仅仅是一套基础类库,更是一种编程方式

2. MFC由来

  1987年微软公司推出了第一代Windows产品,并为应用程序设计者提供了Win16(16位Windows操作系统)API,在此基础上推出了Windows GUI(图形用户界面),然后采用面向对象技术对API进行封装

  1992年推出应用程序框架产品AFX(Application Frameworks),并在AFX的基础上进一步发展为MFC产品。故在用MFC应用程序向导创建的程序中仍然保留stdafx.h头文件包含,它是每个应用程序所必有的预编译头文件,程序所用到的Visual C++头文件包含语句一般均添加到这个文件中。

3. MFC类的基本层次结构

  图示:

       第三课——MFC编程第1张

  CObject类是MFC提供的绝大多数类的基类。该类完成动态空间的分配与回收,支持一般的诊断、出错信息处理和文档序列化等。

  CCmdTarget类主要负责将系统事件(消息)和窗口事件(消息)发送给响应这些事件的对象,完成消息发送、等待和派遣(调度)等工作,实现应用程序的对象之间协调运行。

  CWinApp类是应用程序的主线程类,它是从CWinThread类派生而来。CWinThread类用来完成对线程的控制,包括线程的创建、运行、终止和挂起等。

  CDocument类是文档类,包含了应用程序在运行期间所用到的数据。

  CWnd类是一个通用的窗口类,用来提供Windows 中的所有通用特性、对话框和控件。

  CFrameWnd 类是从 CWnd 继承来的,并实现了标准的框架应用程序。

  CDialog 类用来控制对话框窗口。

  CView 是用于让用户通过窗口来访问文档以及负责文档内容的显示。

  CMDIFrameWnd和CMDIChildWnd类分别用来多文档应用程序的主框架窗口和文档子窗口的显示和管理。

  CMiniFrameWnd类是一种简化的框架窗口,它没有最大化和最小化窗口按钮,也没有窗口系统菜单,一般很少用到它。

4. MFC的优势

  读到本文最后,可得出如下结论:使用MFC

  ①可减少Windows应用程序的代码量;

  ②通过消息映射机制使消息处理更为方便;

  ③能很好地体现面向对象编程的优点。

二、MFC程序框架

——写在理解MFC机制之前

下面是一个MFC应用程序:

#include <afxwin.h>						// MFC头文件
class CHelloApp : public CWinApp		// 声明应用程序类
{
public:		
	virtual BOOL InitInstance();
};
CHelloApp theApp; 						// 建立应用程序类的实例
class CMainFrame: public CFrameWnd		// 声明主窗口类
{
public:
	CMainFrame()
	{	
		// 创建主窗口
		Create(NULL, "我的窗口", WS_OVERLAPPEDWINDOW, CRect(0, 0, 480, 320));
	}
protected:
	afx_msg void OnPaint();
	DECLARE_MESSAGE_MAP()
};
// 消息映射入口
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_PAINT()						// 绘制消息宏
END_MESSAGE_MAP()

//定义消息映射函数
void CMainFrame::OnPaint() 
{
	CPaintDC		dc(this);
	CRect			rc;
	GetClientRect(&rc);
	dc.DrawText(_T("Hello MFC!"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}
// 每当应用程序首次执行时都要调用的初始化函数
BOOL CHelloApp::InitInstance()
{
       m_pMainWnd = new CMainFrame();
       m_pMainWnd->ShowWindow(m_nCmdShow);
       m_pMainWnd->UpdateWindow();
       return TRUE;
}

三、程序运行机制

0. 上面程序中的关系梳理

  • 应用程序类:CHelloApp(公有继承自CWinApp)
  • 应用程序类的实例:theApp
  • 主窗口类:CMainFrame(公有继承自CFrameWnd)

1. MFC使用afxwin.h来代替头文件windows.h,在此程序中看不到Windows应用程序所必须的入口函数WinMain,这是因为MFC将它隐藏在应用程序框架内部了。

2. 当用户运行应用程序时,Windows会自动调用应用程序框架内部的WinMain函数,并自动查找应用程序类CHelloApp(从CWinApp派生)的全局变量theApp,然后自动调用CHelloApp的虚函数InitInstance,该函数会进一步调用相应的函数来完成主窗口的构造和显示工作

  • 重点:运行应用程序→WinMain+theApp→InitInstance(Create/ShowWindow/UpdateWindow)

3. 上面程序中InitInstance的执行过程(创建窗口+显示窗口+更新窗口)如下:

  ① m_pMainWnd = new CMainFrame();

  该语句的作用:创建从CFrameWnd类派生而来的用户框架窗口CMainFrame类对象,继而调用该类的构造函数,使得Create函数被调用,完成窗口创建工作。

  ② m_pMainWnd->ShowWindow(m_nCmdShow);

       m_pMainWnd->UpdateWindow();

  此两条语句的作用:用作窗口的显示和更新

  ③ 返回TRUE,表示窗口创建成功

4. InitInstance完成初始化工作之后,接下来就是调用CWinApp的成员函数Run,执行应用程序的消息循环,即重复执行接收消息并转发消息的工作。

笔记:InitInstance之后是Run,Run是用来处理消息的。

当Run检查到消息队列为空时,将调用基类CWinApp的成员函数OnIdle进行空闲时的后台处理工作。若消息队列为空且又没有后台工作要处理时,则应用程序一直处于等待状态,一直等到有消息为止。

5. 当程序结束后,调用基类CWinApp的成员函数ExitInstance,完成终止应用程序的收尾工作。

6. 尚待考究:既然MFC方式使用消息映射机制,那为何还要使用Run来处理消息?

四、消息映射

1. 区别于之前的消息处理机制

  在MFC中,不再使用消息循环代码以及在窗口过程函数中的switch结构来处理Win32的消息,而是使用独特的消息映射机制。

2. 何为消息映射

  所谓消息映射(Message Map)机制,就是将MFC类中的消息与消息处理函数一一对应起来的机制。

  在MFC中,任何一个从CCmdTarget派生的类理论上均可处理消息,且都有相应的消息映射函数。(即每个类都有相应的消息映射函数)

3. 映射一个消息的过程

  ① 在处理消息的类中,使用消息宏DECLARE_MESSAGE_MAP()声明对消息映射的支持,并在该宏之前声明消息处理函数。

  举例:

protected:
	afx_msg void OnPaint();
	DECLARE_MESSAGE_MAP()

  ② 使用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏在类声明之后的地方定义该类支持的消息映射入口点,所有消息映射宏都添加在这里,当然不同的消息MFC都会有不同的消息映射宏。

  举例:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	...
END_MESSAGE_MAP()

  其中,BEGIN_MESSAGE_MAP带有两个参数。第一个参数:用来指定需要支持消息映射的用户派生类;第二个参数:指定该类的基类

  ③ 定义消息处理函数(此例中OnPaint为消息处理函数

void CMainFrame::OnPaint() 
{
	CPaintDC		dc(this);
	CRect			rc;
	GetClientRect(&rc);
	dc.DrawText(_T("Hello MFC!"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}

  注意:为了使该消息能被其他对象接收并处理,在函数中常常需要调用基类中的相关消息处理函数。

补充:

应用程序类:继承自CWinApp类

消息映射机制:将消息与消息处理函数相对应的机制

消息宏:DECLARE_MESSAGE_MAP(),使用它声明对消息映射的支持

消息映射入口点:由BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏在类声明之后定义入口点,而所有消息映射宏都添加在此

消息映射宏:不同的消息MFC都有不同的消息映射宏,如ON_WM_PAINT

消息处理函数:如OnPaint,该函数的声明必须在消息宏之前

彩蛋:

在Visual C++ 6.0中不需要输入上述程序代码(其实不需要输入任何代码),就能创建所需要的应用程序!!

这就是MFC应用程序向导(MFC AppWizard)的功能。

上面只是拓宽你的视野!!!

具体MFC对应用程序项目的管理方式见下一课。

免责声明:文章转载自《第三课——MFC编程》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇DNS(BIND)服务搭建JPS 命令详解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

windows下IPv6组播(C++、MFC)

Server #include <stdio.h>#include <Ws2tcpip.h>#include <winsock2.h> #pragma comment(lib,"ws2_32.lib")​ #define PORT 6060 #define IP "ff02::2" #define...

HOOK自绘原理

做“HOOK文件打开/保存对话框”的过程中,我首先研究了界面库的相关知识。界面库一般都是由C/C++这种中低级语言编码,这是因为在Windows下的界面库实现技术大都以直接操作控制Windows的消息和调用Windows的API为主,这就是这种中低级语言的优势了。无论何种界面库,最为根本的原理就是获得或者截获窗口的某些消息,按照自己的需要处理这些消息,画出...

MFC中UpdateData函数解析

当你使用了ClassWizard(类向导)建立了控件和变量之间的联系后: 当你修改了变量的值,而希望对话框控件更新显示,就应该在修改变量后调用 UpdateData(FALSE); 如果你希望知道用户在对话框中到底输入了什么,就应该在访问变量前调用UpdateData(TRUE)。 用处: 主要控制ddx_data 把控件中的值和变量进行交换。 比如你有个...

MFC 学习之 鼠标移动到Toolbar按钮上显示提示信息(tooltip),状态栏也随之改变

1.在ResourceView里加入Toolbar资源,命名IDR_TOOLBAR1 2、在主程序的.h文件中加入变量:           CToolBar m_toolbar;CImageList img; 3、在主程序中.h文件中的BEGIN_MESSAGE_MAP(CDetectorDlg,CDialog)函数中加入:         ON_NOT...

VS2015配置OpenCV,使用mfc摄像头程序测试

转自:https://blog.csdn.net/Lee_Dk/article/details/80466523 这只是介绍了如何加入OpenCV,怎么查找OpenCV请看出处。  新建一个项目。找到属性管理器,debug-win32。后4个是原本就有的。Micross.Cpp.Win32.user是vs的默认属性表,如果在这个表中配置了,以后的项目都不用...

Visual C++ MFC/ATL开发-提高篇

MFC简单打印方法通过MFC来完成打印作业有很多的方法,应用场合也有所不同。我们通常是利用视图框架在MFC基础之上按照OnPreparePrinting() à OnBeginPrinting() ? à OnPreprareDC() à OnPrinting () à OnEndPrinting()的顺序来编程的。对于我们使用单文档或者多文档的视图框架...