第二章 使用MFC消息机制
mfc消息机制原理

MFC(Microsoft Foundation Classes)是一种用于开发Windows应用程序的C++类库,它建立在Win32 API之上,并提供了更高层次的抽象和封装。
在MFC中,消息机制是实现应用程序与用户交互和事件处理的基础。
MFC消息机制的原理如下:1.消息映射表:在MFC应用程序中,每个窗口类(如对话框类、视图类等)通常都有一个消息映射表(message map),用于将消息与相应的处理函数关联起来。
消息映射表是一个静态数据结构,通过DECLARE_MESSAGE_MAP宏进行声明,并在类的实现文件中使用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏定义映射表的内容。
2.消息处理函数:每个消息映射表项将消息的ID(或者命令ID)与相应的消息处理函数绑定在一起。
消息处理函数是成员函数,由开发人员根据需要自行定义。
当相应的消息被触发时,系统会自动调用与该消息对应的处理函数。
3.消息循环:MFC应用程序在运行时通过消息循环(message loop)不断接收和分发消息。
消息循环负责从操作系统获取消息,并将消息派发给目标窗口的消息处理函数进行处理。
消息循环可以使用Run函数或AfxGetApp()->Run函数启动。
4.分发消息:当系统从消息队列中获取到一个消息后,会根据消息的目标窗口通过HWND来查找对应的CWnd对象,并调用该窗口的响应函数(如PreTranslateMessage、OnCmdMsg等)进行消息处理。
如果消息在目标窗口的消息映射表中找到了对应的处理函数,则将该消息转发给对应的处理函数进行处理。
5.消息处理:消息处理函数执行相应的逻辑,可以进行界面更新、控件操作、数据处理等操作。
处理函数的返回值通常是布尔型,表示是否终止消息的传递。
通过这种消息机制,MFC应用程序可以实现用户交互和事件处理的功能,使开发人员可以方便地处理窗口消息,响应用户操作,以及完成界面和数据之间的交互。
mfc 消息机制

mfc消息机制
MFC(Microsoft Foundation Class)是微软开发的一种面向对象的C++框架,用于Windows操作系统的应用程序开发。
MFC消息机制是MFC框架的核心之一,其基本原理是在窗口、控件等对象之间传递消息,以便处理事件和交互。
具体而言,MFC消息机制包括以下几个方面:1.消息循环:MFC使用一个消息循环来接受和处理Windows操作系统发送的Windows消息,处理完消息后将处理结果反馈给Windows操作系统。
2.消息映射:MFC中的控件和窗口都有一个关联的消息映射表,用于将Windows消息映射到应用程序代码中的相应处理函数上。
当某个控件或窗口收到消息后,根据消息类型在相应的消息映射表中查找对应的消息处理函数,并调用相应的处理函数处理消息。
3.消息类型:MFC处理的Windows消息类型包括键盘和鼠标消息、定时器消息、系统负载消息、窗口大小变化消息等等,具体的消息类型可以在MFC框架的文档中查找。
4.消息处理函数:MFC中的消息处理函数是C++成员函数,定义为afx_msg 修饰的函数,Windows消息处理函数命名时需要遵循一定的命名规则,例如OnPaint()函数用于处理绘图事件。
需要注意的是,MFC消息机制是针对Windows操作系统设计的,其他操作系统可能具有不同的消息机制。
此外,MFC框架已经不是微软推荐的最先进的应用程序开发框架,已经逐渐被其他框架和技术所取代,例如.NET Framework,WPF,UWP等。
MFC使用教程范文

MFC使用教程范文MFC(Microsoft Foundation Classes)是微软的一套C++类库,用于开发Windows桌面应用程序。
本教程将向您介绍MFC的基本概念和使用方法。
一、MFC简介MFC是基于面向对象的设计思想,为开发Windows应用程序提供了一套强大的工具和框架。
它提供了诸如窗口、对话框、菜单等常见界面元素的类,并且封装了底层的Windows API,简化了程序的编写过程。
二、MFC应用程序的创建要创建一个MFC应用程序,您可以使用Visual Studio进行操作。
首先,打开Visual Studio,并选择“新建项目”,然后选择“MFC应用程序”模板。
在创建项目的向导中,您可以指定应用程序的名称、位置和其他选项。
接下来,您可以选择所需的特性和模板。
例如,如果需要创建一个对话框应用程序,则可以选择“对话框”模板。
创建完成后,Visual Studio将自动为您生成一个基本的MFC应用程序框架,包括一个主窗口、一个菜单栏、一个工具栏和一个状态栏。
三、MFC界面元素的创建和使用1. 窗口(CWnd类):MFC提供了多种窗口类,如CFrameWnd、CView 等,您可以根据需要选择合适的窗口类来创建窗口。
4. 菜单(CMenu类):MFC通过CMenu类来管理菜单。
您可以创建菜单项并将其添加到菜单中,然后将菜单与窗口相关联。
5. 工具栏(CToolBar类):工具栏是一种常见的界面元素,用于提供快速访问常用命令的按钮。
您可以通过CToolBar类创建和管理工具栏,并将其与窗口相关联。
四、MFC消息机制在MFC中,程序通过消息来进行事件处理。
消息是由操作系统发送给应用程序的,应用程序通过重载消息响应函数来处理不同类型的消息。
在MFC中,您可以通过添加消息映射宏(BEGIN_MESSAGE_MAP和END_MESSAGE_MAP)和消息处理函数(OnXxx系列函数)来处理消息。
MFC消息映射机制过程

MFC消息映射机制过程1:windows OS事件驱动策略基于3种消息。
标准消息、通告消息、命令消息。
2:“事件”就是“消息”,事件是有形形象的,是站在⼈类能理解的⾓度来定义的。
消息是⽆形抽象的,是站在OS能理解的⾓度来定义的。
3:我把按下⿏标左键这⼀事件转换成WM_LBUTOONDOWN消息来告诉OS我做了按下⿏标左键这了件事情。
现在OS知道了我做了按下⿏标左键这了件事情了,那么OS怎么处理呢?3.1:消息响应函数原型//{{AFX_MSG(CMyView)afx_msg void OnLButtonDown(UINT nFlags,CPoint point);//}}AFX_MSGDECLARE_MESSAGE_MAP()3.2:ON_WM_LBUTTONDOWN消息映射宏BEGIN_MESSAGE_MAP(CMyView, CView)//{{AFX_MSG_MAP(CMyView)ON_WM_LBUTTONDOWN()//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()3.3:消息响应函数的定义void CMyView::OnLButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultMessageBox("WM_LBUTTONDOWN");CView::OnLButtonDown(nFlags, point);}4:⾄此,我们从按下⿏标左键到看到如下图的效果,OS完成了对事件做出的反应。
mfc 信息机制

mfc 信息机制MFC信息机制MFC(Microsoft Foundation Class)是微软公司推出的一套用于Windows操作系统的C++类库,它为开发者提供了丰富的工具和组件,用于快速构建Windows应用程序。
在MFC中,信息机制是其重要特性之一,它提供了一种方便的方式来管理和传递应用程序中的消息。
一、消息机制的基本概念在MFC中,消息是指应用程序中发生的各种事件,比如鼠标点击、键盘输入、窗口关闭等。
消息机制是指MFC框架中的一套机制,用于处理和分发这些消息。
消息的处理过程包括两个关键组件:消息映射和消息处理函数。
1. 消息映射消息映射是指将消息和消息处理函数进行关联的过程。
通过在类的消息映射表中添加相应的消息和处理函数的映射关系,可以告诉MFC框架在收到某个消息时应该调用哪个函数进行处理。
消息映射表一般定义在类的声明中,使用宏来声明消息映射表的内容。
2. 消息处理函数消息处理函数是指用于处理特定消息的函数。
当MFC框架收到某个消息时,会根据消息映射表中的映射关系调用相应的消息处理函数。
消息处理函数可以是类的成员函数,也可以是全局函数,具体取决于消息映射表中的声明方式。
二、消息机制的应用场景消息机制在MFC中广泛应用于用户界面的交互和事件响应。
通过消息机制,开发者可以方便地处理用户的操作和系统的事件,实现各种功能和交互效果。
1. UI事件响应在MFC应用程序中,用户通过与界面上的控件进行交互来触发各种事件,比如按钮点击、菜单选择等。
通过消息机制,我们可以将这些事件与相应的处理函数进行关联,当用户触发某个事件时,可以执行相应的处理逻辑。
2. 窗口消息处理MFC中的窗口是指用户界面上的各种窗口元素,比如对话框、窗口、视图等。
窗口消息是指与窗口相关的各种事件,比如窗口创建、大小改变、关闭等。
通过消息机制,我们可以对窗口消息进行处理,实现窗口的初始化、布局、关闭等功能。
3. 自定义消息除了系统定义的消息类型,MFC还支持自定义消息。
MFC消息机制

MFC消息机制⼀、消息的分类1、队列消息、⾮队列消息l队列消息:windows为每个应⽤程序都建⽴⼀个消息队列,那么通过消息队列,进⾏传送的消息都属于队列消息;⼀般来说,由⿏标、键盘产⽣的消息都属于队列消息。
(为什么呢?想想,⿏标、键盘事件都是由系统捕获的,系统捕获后要传递给应⽤程序,就⼀定的通过消息队列);l⾮队列消息:除了队列消息,剩下的⾃然⽽然就是⾮队列消息了;u队列消息是通过PostMessage()的⽅式投递消息的,这样的消息发送也叫“寄送”,该函数寄送消息即可返回,不需要等待程序处理结果;u⾮队列消息是通过SendMessage()的⽅式进⾏的,这样的消息发送叫“发送”;消息不需要进⼊窗⼝的消息队列,然⽽不管是队列消息,还是⾮队列消息,消息处理的起点都是AfxWndProc。
不同的是队列消息,是操作系统把消息投放到消息队列,应⽤程序空闲是,通过⼀个消息循环,搜索消息队列,不停的从消息队列抓取消息,并处理。
⼤致流程是:CwinThread->PumpMessage->CWnd->PreTranslateMessage->…………..->USER32内核->AfxWndProcBase->AfxWndProc->…….(继续处理)⽽⾮队列消息呢(即通过SendMessage⽅式发送的消息)?它是直接进⼊了USER32内核,然后处理的流程和队列消息⼀样了。
注意,不管是队列消息,还是⾮队列消息,都是从USER32内核开始,转到了AfxWndProcBase(有时候不经过这⾥),再到AfxWndProc,所以可以认为AfxWndProc是消息传递与处理的起点!出来后,不管是队列消息,还是⾮队列消息,应该由Windosw系统发往各个窗⼝的消息处理函数(这个处理函数是DefWindowProc,这是很直觉的想法,⽽且传统的SDK程序确实是这样的,但是MFC程序⽐传统的SDK多了document/view,如果如果某个消息是做⽂档处理,那么就让这个消息直接流到document中去不是更好吗?所以才有了MFC命令传递机制、MFC消息映射的出现),但是为什么都统⼀到了AfxWndProc这⾥呢?这⾥⽤到了钩⼦技术。
MFC对话框向主窗体传递消息机制

对话框向主窗体传递消息,在视图中显示现举例说明对话框向主窗体传递消息,以及主窗体响应消息的过程。
我们拿单文档来说明,我们要实现下列功能:通过对话框,在文本框中输入字符串,在视图中显示刚才输入的字符串。
1、在应用程序向导中选择单个文档,然后完成。
我这里的项目名称为mybook2、在资源视图中,插入一对话框,对话框名称为dlg_wzm。
3、在刚才生成的对话框中插入一文本框,设置好相应的类和变量。
为确认按钮生成响应函数。
同时在mybook.cpp的BOOL CMyBookApp::InitInstance()函数中让该对话框启动,也就是加入CDlg_wzm dlg; dlg.DoModal();两行程序,当然在前面的要加入#include "dlg_wzm.h"。
(详细过程略)4、下面重点在于点击该对话框的确认按钮向主窗体发送消息。
要现定义一个消息名称。
在stdafx.h文件中加入一行:#define WM_MYMESSAGE WM_USER+1005、在CMainFrame的pulic申明中加入一变量CString wzmstr。
目的是为了保存对话框中的字符串的值。
在对话框的Onok()函数中:void CDlg_wzm::OnOK(){// TODO: Add extra validation herethis->UpdateData(true);CMainFrame* pWnd=(CMainFrame*)AfxGetMainWnd(); //得到父窗体的指针pWnd->wzmstr=this->m_input_edit;ASSERT(pWnd!=NULL);::SendMessage(pWnd->GetSafeHwnd(), WM_MYMESSAGE,0,0); //发送消息//注意WM_MYMESSAGE就是我们前面定义的消息。
//CDialog::OnOK();}6、下面我们看看主窗体怎么接受消息。
[工程科技]MFC的消息机制的实现原理和消息处理的过程
![[工程科技]MFC的消息机制的实现原理和消息处理的过程](https://img.taocdn.com/s3/m/d293c7e80b4c2e3f5627636f.png)
[工程科技]MFC的消息机制的实现原理和消息处理的过程下面几节将分析MFC的消息机制的实现原理和消息处理的过程。
为此,首先要分析ClassWizard实现消息映射的内幕,然后讨论MFC的窗口过程,分析MFC窗口过程是如何实现消息处理的。
1. 消息映射的定义和实现1. MFC处理的三类消息根据处理函数和处理过程的不同,MFC主要处理三类消息:, Windows消息,前缀以“WM_”打头,WM_COMMAND例外。
Windows消息直接送给MFC窗口过程处理,窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
, 控制通知消息,是控制子窗口送给父窗口的WM_COMMAND通知消息。
窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
需要指出的是,Win32使用新的WM_NOFITY来处理复杂的通知消息。
WM_COMMAND类型的通知消息仅仅能传递一个控制窗口句柄(lparam)、控制窗ID和通知代码(wparam)。
WM_NOTIFY能传递任意复杂的信息。
, 命令消息,这是来自菜单、工具条按钮、加速键等用户接口对象的WM_COMMAND通知消息,属于应用程序自己定义的消息。
通过消息映射机制,MFC框架把命令按一定的路径分发给多种类型的对象(具备消息处理能力)处理,如文档、窗口、应用程序、文档模板等对象。
能处理消息映射的类必须从CCmdTarget类派生。
在讨论了消息的分类之后,应该是讨论各类消息如何处理的时候了。
但是,要知道怎么处理消息,首先要知道如何映射消息。
1. MFC消息映射的实现方法MFC使用ClassWizard帮助实现消息映射,它在源码中添加一些消息映射的内容,并声明和实现消息处理函数。
现在来分析这些被添加的内容。
在类的定义(头文件)里,它增加了消息处理函数声明,并添加一行声明消息映射的宏DECLARE_MESSAGE_MAP。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
•
在生成的消息函数中加入一些代码,并运行查看结果 – 例如,在OnLButtonDown函数中输入代码查看点击位置。
– – – CString str; str.Format("x=%d,y=%d",point.x,point.y); AfxMessageBox(str);
•
删除消息映射函数 – 打开ClassWizard选择OnLButtonDown成员函数,再点删除函数按钮。 – 查看删除消息函数后的代码,消息映射宏和头文件中的函数声明已经 被删除,一般ClassWizard会保留函数体中的代码,以备开发者保存。
第二章 使用MFC消息机制
学习目标
1 2 3 4
MFC的六大关键技术 的六大关键技术
使用系统消息
建立自定义消息
开发WIN32应用程序 应用程序 开发
MFC的六大关键技术
MFC的六大关键技术,是六大黑箱技术。使开发者只要做简单的局部修改,即 可处理大部分窗口事物。其他复杂处理过程被完美的封装起来,这样的技术 使程序员不需要懂太多,即可进行窗口软件的开发。 • 具体的MFC的六大技术,包括: • (1)MFC程序的初始化过程: – 建立一个最简单的MFC程序只用两步。从CWinApp派生一个应用程序类 (CMyApp),然后建立对象(theApp)。之后整个程序的编写,就只需 要改写一个InitInstance()函数。 • (2)运行时类型识别(RTTI) – 运行时类型识别(RTTI)即是程序执行过程中知道某个对象属于某个类, 参见CRuntimeClass类。 • (3)动态创建: – 动态创建就是运行时创建指定类的对象,而创建的对象在MFC内部能够被 动态识别。在MFC中大量使用。如框架窗口对象、视对象,还有文档对象 等等。参见CFrameWnd,CView和CDocument等类,按F12查阅相关的宏定 义,例如:DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE。 •
• •
•
SendMessage和PostMessage
• 如果在不同线程内,SendMessage 发送消息到目标窗口所属线程的消息队列 ,然后发送消息的线程在 USER32.DLL 模块内监视和等待消息处理,直到目 标窗口处理完返回。SendMessage 在返回前还做了很多工作,比如,响应别 的线程向它 SendMessage。Post 到别的线程时,最好用 PostThreadMessage 代替 PostMessage,PostMessage 的 hWnd 参数可以是 NULL,等效于 PostThreadMessage + GetCurrentThreadId。Post WM_QUIT 时,应使用 PostQuitMessage 代替。 4、系统只整编(marshal)系统消息(0 到 WM_USER 之间的消息),发送 用户消息(WM_USER 以上)到别的进程时,需要自己做整编。 用 PostMessage、SendNotifyMessage、SendMessageCallback 等异步函 数发送系统消息时,参数里不可以使用指针,因为发送者并不等待消息的处 理就返回,接受者还没处理指针就已经被释放了。 5、在 Windows 2000/XP 里,每个消息队列最多只能存放 10,000 个 Post 的消息,超过的还没被处理的将不会被处理,直接丢掉。这个值可以改得更 大:[HKEY_LOCAosoft\Windows NT\CurrentVersion\Windows] USERPostMessageLimit,最小可以是 4000。
关闭时的系统消息
• 点击标题栏上的关闭按钮,或者系统菜单中的关闭菜单时,系统内会触发多 种与关闭有关的系统消息。例如: – WM_SYSCOMMAND:该消息不只支持处理关闭消息,而且支持最大化、最小 化、移动、拉伸以及系统菜单等多种消息。在对应的消息函数中参数nID 代表系统消息的种类,例如:SC_CLOSE, SC_MINIMIZE等。参见 CWnd::OnSysCommand函数。 – WM_CLOSE:相当于WM_SYSCOMMAND关于SC_CLOSE类型的专用处理。 – WM_DESTROY:通用于任何窗口在摧毁时发出的消息。 – WM_NCDESTROY:通用于窗口在摧毁时,发出的最后一个消息。 • 在对话框窗口中,在WM_CLOSE消息之后还会发出WM_COMMAND消息,调用 OnCancel函数。但是在点击取消按钮(IDCANCEL)后,并不会发出 WM_SYSCOMMAND消息和WM_CLOSE消息。
建立自定义消息
从消息的来源来看,可以分为:系统定义的消息和应用程序定义的消息。 – 系统消息ID的范围是从0到WM_USER-1,或0X80000到0XBFFFF – 应用程序消息从 WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFFFF,范 围内的消息由应用程序自己使用; • 在MFC窗口类中定义消息成员函数: – 函数的格式:LRESULT MsgProc(WPARAM wParam,LPARAM lParam) – 定义消息映射宏:在BEGIN_MESSAGE_MAP下面加入 ON_MESSAGE(WM_USER+1,MsgProc) • 在其他函数中发送自定义消息: – SendMessage(WM_USER+1,3,9); – 或者PostMessage(WM_USER+1,22,11); • 在MsgProc消息函数中设置断点,运行并调试:
MFC系统消息分类
• 一般程序员在做2-3年的VC开发后,会自动进入阅读MFC源代码以及剖析以 上VC内部技术。但是对于初学者我们建议,应该重点放在使用MFC提供的 关键技术。 • Windows提供了大量的窗口消息,开发者可以在对应的消息函数下,编写 代码来修饰窗口的属性。常用的窗口消息如下: • (1)键盘消息: – WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP和WM_CHAR等 • (2)鼠标消息: – 左:WM_LBUTTONDOWN、WM_LBUTTONUP和WM_LBUTTONDBLCLK – 中:WM_MBUTTONDOWN、WM_MBUTTONUP和WM_MBUTTONDBLCLK – 右:WM_RBUTTONDOWN、WM_RBUTTONUP和WM_RBUTTONDBLCLK • (3)窗口创建和摧毁: – 普通窗口:WM_CREATE、WM_DESTROY和WM_CLOSE – MDI窗口:WM_MDICREATE、WM_MDIDESTROY – 对话框:WM_INITDIALOG
– 查看是否接收到该消息
•
SendMessage和PostMessage
• 1、首先是返回值意义的区别,我们先看一下 MSDN 里的声明: – LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); – WBOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); 其中 4 个参数的意义是一样的,返回值类型不同(其实从数据上看他们一样 是一个 32 位的数,只是意义不一样),LRESULT 表示的是消息被处理后的 返回值,BOOL 表示的是消息是不是 Post 成功。 2、PostMessage 是异步的,SendMessage 是同步的。 PostMessage 只 把消息放入队列,不管消息是否被处理就返回,消息可能不被处理;而 SendMessage 等待消息被处理完了之后才返回,如果消息不被处理,发送消 息的线程将一直被阻塞。 3、如果在同一个线程内,SendMessage 发送消息时,由 USER32.DLL 模块 调用目标窗口的消息处理程序,并将结果返回。SendMessage 在同一线程中 发送消息并不入线程消息队列。PostMessage 发送消息时,消息要先放入线 程的消息队列,然后通过消息循环分派到目标窗口(DispatchMessage)。
MFC系统消息分类
• • • (4)客户区消息: – WM_PAINT、WM_ERASEBKGND、WM_CTLCOLOR、WM_CTLCOLORBTN和WM_SIZE 等 (5)非客户区消息: – WM_NCPAINT、WM_NCCREATE和WM_NCLBUTTONDOWN等 (6)事件消息: – WM_COMMAND、WM_SYSCOMMAND、WM_TIMER和WM_HOTKEY等
• • •
建立一个简单的Win32工程
• 使用AppWizard建立基于Win32的应用程序
建立一个简单的Win32工程
• 选择第2项A simple Win32 application.
编辑Win32项目资源
• 生成的代码只有一个空的WinMain函数: – 在Workspace中只有ClassView和FileView,没有ResourceView。 – 也就说明目前的工程中没有任何资源。 为了生成基于对话框的Windows应用程序,我们需要在工程中添加一个资源文件 – 从主菜单中选择File->New,打开新建文件向导。 – 选择Resource Script,并在Add to project上打钩。 – 填入与工程相同的名字,例如Test,再按确定。 – 在Workspace中出现了ResouceView的选项卡页面。 点关闭按钮,关闭编辑器中的Test.rc,以便在Resource View中编辑。 – 如果Test.rc处于打开状态,点击ResourceView中的资源会提示