MFC消息机制
mfc的原理、机制与开发实例
mfc的原理、机制与开发实例MFC(Microsoft Foundation Class)是微软公司开发的一套面向对象的应用程序框架,用于简化Windows操作系统上的图形用户界面(GUI)应用程序的开发。
MFC提供了一系列的类和函数,使开发者能够更加方便地创建、管理和操作窗口、对话框、控件等GUI元素。
MFC的原理和机制主要基于C++语言和Windows操作系统的API (Application Programming Interface)。
MFC的核心类是CObject类,所有的MFC类都是从CObject类派生而来的。
MFC使用了一种称为消息映射(Message Mapping)的机制来处理用户界面的事件和消息。
当用户进行操作时,例如点击按钮、输入文本等,Windows操作系统会生成相应的消息,并将其发送给应用程序。
MFC通过消息映射将这些消息与相应的处理函数关联起来,从而实现对用户操作的响应。
MFC的开发实例可以通过一个简单的计算器程序来说明。
首先,我们需要创建一个对话框,用于显示计算器的界面。
在MFC中,可以使用CDialog类来创建对话框。
然后,我们需要在对话框中添加一些控件,例如按钮、文本框等,用于用户输入和显示计算结果。
在MFC中,可以使用CButton、CEdit等类来创建这些控件。
接下来,我们需要处理用户的操作。
例如,当用户点击按钮时,我们需要执行相应的计算操作。
在MFC中,可以通过消息映射来实现。
首先,我们需要在对话框类中添加一个消息映射函数,用于处理按钮的点击事件。
然后,我们需要在消息映射函数中编写相应的代码,例如获取用户输入的数字、进行计算等。
最后,我们需要将消息映射函数与按钮关联起来,以便在用户点击按钮时调用相应的函数。
除了处理用户的操作,MFC还提供了许多其他功能,例如文件操作、数据库访问、图形绘制等。
开发者可以根据自己的需求选择相应的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消息映射机制过程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的消息机制的实现原理和消息处理的过程
下面几节将分析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。
MFC六大核心机制
MFC六大核心机制1.消息映射机制:MFC使用明确的消息映射机制来处理用户界面和系统事件。
应用程序通过重写消息映射函数来处理不同的消息事件,如鼠标点击、按键操作等。
消息映射机制使得开发者可以方便地响应和处理不同的用户交互动作。
2. 文档视图(Doc/View)体系:MFC采用了文档视图体系,将应用程序数据(文档)和用户界面(视图)分离。
文档表示应用程序的数据,视图代表用户界面,通过文档视图模式可以实现多视图的显示和操作。
开发者可以自定义文档类和视图类,通过它们来管理和展示数据。
3.对象序列化机制:对象序列化是指将对象的状态转换为可以存储或传输的格式,以便于在不同的环境中恢复对象的状态。
MFC提供了强大的对象序列化支持,可以方便地对应用程序的数据进行存储和加载。
开发者只需将需要序列化的成员变量标记为可序列化,并实现相关的序列化函数即可实现数据的持久化。
4.多线程支持:MFC提供了多线程支持,使得应用程序可以在多个线程中同时执行任务。
开发者可以使用MFC提供的线程类来创建和管理线程,并通过消息机制进行线程间的通信。
多线程支持有助于提高应用程序的性能和响应能力。
MFC的运行时类是一组用于封装常用功能的类,包括字符串操作、容器类、文件I/O等。
这些类提供了方便、高效的操作接口,减少了开发者对底层操作的依赖。
开发者可以直接使用MFC提供的运行时类来简化开发过程。
6.扩展性:MFC提供了丰富的扩展性机制,包括自定义控件、自定义对话框、自定义视图等。
开发者可以通过派生已有的MFC类来创建自定义的控件或界面,以满足特定的应用程序需求。
扩展性机制使得开发者可以充分发挥自己的创造力和想象力,实现更加个性化的应用程序。
总结:MFC六大核心机制为开发者提供了丰富的类和功能,使得开发Windows图形界面应用程序更加简单和高效。
通过消息映射机制、文档视图体系、对象序列化机制、多线程支持、运行时类和扩展性机制,开发者可以轻松地实现各种应用程序的需求,并提供更好的用户体验。
MFC消息机制详解
消息映射的实现Windows消息概述Windows应用程序的输入由Windows系统以消息的形式发送给应用程序的窗口。
这些窗口通过窗口过程来接收和处理消息,然后把控制返还给Windows。
消息的分类队列消息和非队列消息从消息的发送途径上看,消息分两种:队列消息和非队列消息。
队列消息送到系统消息队列,然后到线程消息队列;非队列消息直接送给目的窗口过程。
这里,对消息队列阐述如下:Windows维护一个系统消息队列(System message queue),每个GUI线程有一个线程消息队列(Thread message queue)。
鼠标、键盘事件由鼠标或键盘驱动程序转换成输入消息并把消息放进系统消息队列,例如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR等等。
Windows 每次从系统消息队列移走一个消息,确定它是送给哪个窗口的和这个窗口是由哪个线程创建的,然后,把它放进窗口创建线程的线程消息队列。
线程消息队列接收送给该线程所创建窗口的消息。
线程从消息队列取出消息,通过Windows把它送给适当的窗口过程来处理。
除了键盘、鼠标消息以外,队列消息还有WM_PAINT、WM_TIMER和WM_QUIT。
这些队列消息以外的绝大多数消息是非队列消息。
系统消息和应用程序消息从消息的来源来看,可以分为:系统定义的消息和应用程序定义的消息。
系统消息ID的范围是从0到WM_USER-1,或0X80000到0XBFFFF;应用程序消息从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到0X7FFF范围的消息由应用程序自己使用;0XC000到0XFFFF范围的消息用来和其他应用程序通信,为了ID的唯一性,使用::RegisterWindowMessage来得到该范围的消息ID。
消息结构和消息处理消息的结构为了从消息队列获取消息信息,需要使用MSG结构。
MFC的消息循环
MFC的消息循环MFC的消息循环消息分为队列消息(进⼊线程的消息队列)和⾮队列消息(不进⼊线程的消息队列)。
对于队列消息,最常见的是⿏标和键盘触发的消息,例如WM_MOUSERMOVE,WM_CHAR等消息;还有例如:WM_PAINT、WM_TIMER和WM_QUIT。
当⿏标、键盘事件被触发后,相应的⿏标或键盘驱动程序就会把这些事件转换成相应的消息,然后输送到系统消息队列,由Windows系统负责把消息加⼊到相应线程的消息队列中,于是就有了消息循环(从消息队列中读取并派送消息)。
还有⼀种是⾮队列消息,他绕过系统队列和消息队列,直接将消息发送到窗⼝过程。
例如,当⽤户激活⼀个窗⼝系统发送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。
创建窗⼝时发送WM_CREATE消息。
在后⾯你将看到,MS这么设计是很有道理的,以及他的整套实现机制。
这⾥讲述MFC的消息循环,消息泵。
先看看程序启动时,怎么进⼊消息循环的:_tWinMain ->AfxWinMain ->AfxWinInit ->CWinThread::InitApplication ->CWinThread::InitInstance ->CWinThread::Run ⾮对话框程序的消息循环的事情都从这CWinThread的⼀Run开始... 第⼀部分:⾮对话框程序的消息循环机制//thrdcore.cpp// main running routine until thread exitsint CWinThread::Run(){ ASSERT_VALID(this); // for tracking the idle time state BOOL bIdle = TRUE; LONG lIdleCount = 0; // acquire and dispatch messages until a WM_QUIT message is received. for (;;) { // phase1: check to see if we can do idle work while (bIdle && !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)) { // call OnIdle while in bIdle state if (!OnIdle(lIdleCount++)) bIdle = FALSE; // assume "no idle" state } // phase2: pump messages while available do { // pump message, but quit on WM_QUIT if (!PumpMessage()) return ExitInstance(); // reset "no idle" state after pumping "normal" message if (IsIdleMessage(&m_msgCur)) { bIdle = TRUE; lIdleCount = 0; } } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)); } //⽆限循环,退出条件是收到WM_QUIT消息。
MFC框架原理以及消息运行机制
MFC框架原理以及消息运行机制MFC(Microsoft Foundation Classes)是微软公司开发的一种基于面向对象的软件框架,用于开发Windows平台的应用程序。
MFC框架的主要原理是消息驱动机制。
消息驱动机制是一种事件驱动的编程模型,即程序中的操作通过消息的方式进行通知和处理。
MFC框架使用消息循环来处理应用程序的消息。
消息循环是一个无限循环,在每一次循环中,应用程序会不断地查询并处理消息队列中的消息。
消息的产生和处理是由Windows操作系统来完成的。
当发生一些特定的事件(例如鼠标点击、键盘输入等)时,Windows操作系统会将相应的消息放入消息队列中。
MFC框架通过调用Windows API函数来获取并处理消息队列中的消息。
1. 消息的类型(message type):表示消息的分类,例如鼠标消息、键盘消息等。
2. 消息的处理函数(message handler):用于处理特定类型的消息,根据消息类型的不同,消息处理函数也会有所不同。
3. 消息的参数(message parameters):包含了消息的具体信息,例如鼠标点击的坐标、键盘输入的字符等。
在MFC框架中,每个窗口控件都有一个与之相关联的消息处理函数。
当窗口控件接收到相应的消息时,该消息处理函数会被自动调用,从而完成消息的处理逻辑。
MFC框架中的消息机制是通过C++语言中的虚函数机制来实现的。
在MFC框架中,每个窗口对象都继承自CWnd类,并重载了CWnd类中的虚函数。
在消息循环中,通过调用窗口对象的成员函数来处理特定类型的消息。
MFC框架还提供了一些宏和宏函数来简化消息处理的代码。
例如,通过DECLARE_MESSAGE_MAP宏可以声明一个消息映射表,其中定义了窗口控件与消息处理函数之间的映射关系。
通过ON_MESSAGE宏可以将消息与消息处理函数进行绑定。
总结起来,MFC框架的消息机制是一种事件驱动的编程模型。
MFC框架原理以及消息运行机制
MFC框架原理以及消息运行机制(1)Windows程序内部运行机制1,windows程序设计是种事件驱动方式的程序设计,主要基于消息的。
当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。
2,消息结构:typedef struct tagMSG { // msgHWND hwnd; //接收消息的窗口句柄。
和哪个窗口相关联。
UINT message; //消息标识。
消息本身是什么。
WPARAM wParam; //消息的附加信息。
具体取决于消息本身。
LPARAM lParam;DWORD time; //消息投递时间。
POINT pt; //消息投递时,光标在屏幕上的位置。
} MSG;3,消息队列:每个应用程序OS都为它建立一个消息队列,消息队列是个先进先出的缓冲区,其中每个元素都是一个消息,OS将生成的每个消息按先后顺序放进消息队列中,应用程序总是取走当前消息队列中的第一条消息,应用程序取走消息后便知道用户的操作和程序的状态,然后对其处理即消息响应,消息响应通过编码实现。
4,使用VC编程除了良好的C基础外还需要掌握两方面:一,消息本身。
不同消息所代表的用户操作和应用程序的状态。
二,对于某个特定的消息来说,要让OS执行某个特定的功能去响应消息。
5,Window程序入口:int WINAPI WinMain(HINSTANCE hInstance, // 当前事例句柄。
HINSTANCE hPrevInstance, // 先前事例句柄。
LPSTR lpCmdLine, // 命令行指针int nCmdShow // (窗口)显示的状态);说明:WinMain函数是Windows程序入口点函数,由OS调用,当OS启动应用程序的时候,winmain函数的参数由OS传递的。
6,创建一个完整的窗口需要经过下面四个操作步骤:一,设计一个窗口类;如:WNDCLASS wndcls;二,注册窗口类;如:RegisterClass(&wndcls);三,创建窗口;如:CreateWindow(),CreateWindowEX();四,显示及更新窗口。
mfc消息响应机制
mfc消息响应机制MFC消息响应机制MFC(Microsoft Foundation Class)是微软公司为开发Windows应用程序而提供的一组C++类库。
在MFC中,消息响应机制是一种重要的编程方式,用于处理用户与应用程序之间的交互。
本文将详细介绍MFC消息响应机制的原理和使用方法。
一、消息处理函数在MFC中,消息处理函数是用于响应消息的函数。
当用户与应用程序进行交互时,系统会产生相应的消息,然后通过消息映射表找到对应的消息处理函数进行处理。
消息处理函数是类成员函数,其原型通常为:afx_msg LRESULT OnMessage(WPARAM wParam, LPARAM lParam);其中,afx_msg是MFC宏定义,LRESULT是消息处理函数的返回值类型,OnMessage是函数名,WPARAM和LPARAM是消息参数,用于传递消息的附加信息。
二、消息映射表消息映射表是一个包含消息处理函数与消息ID之间对应关系的表格。
在MFC应用程序的消息映射表中,每个消息ID都与一个消息处理函数相对应。
当收到某个消息时,系统会根据消息ID查找对应的消息处理函数,并调用该函数进行处理。
消息映射表通常定义在类的声明中,格式如下:BEGIN_MESSAGE_MAP(CMyClass, CBaseClass)ON_MESSAGE(messageID, memberFxn)// more message mappings...END_MESSAGE_MAP()其中,CMyClass是消息处理类的名称,CBaseClass是消息处理类的基类,messageID是消息ID,memberFxn是与该消息ID对应的消息处理函数。
三、消息处理函数的实现消息处理函数的实现步骤如下:1. 在类的声明中定义消息处理函数的原型。
2. 在类的实现文件中,使用宏定义IMPLEMENT_DYNAMIC或IMPLEMENT_DYNCREATE来实现运行时类型信息。
MFC消息映射机制剖析
一,消息映射机制1,消息响应函数:(例:在CDrawView类响应鼠标左键按下消息)1)在头文件(DrawView.h)中声明消息响应函数原型。
//{{AFX_MSG(CDrawView) //注释宏afx_msg void OnLButtonDown(UINT nFlags, CPoint point);//}}AFX_MSG //注释宏说明:在注释宏之间的声明在VC中灰色显示。
afx_msg宏表示声明的是一个消息响应函数。
2)在源文件(DrawView.cpp)中进行消息映射。
BEGIN_MESSAGE_MAP(CDrawView, CView)//{{AFX_MSG_MAP(CDrawView)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()说明:在宏BEGIN_MESSAGE_MAP()与END_MESSAGE_MAP()之间进行消息映射。
宏ON_WM_LBUTTONDOWN()把消息WM_LBUTTONDOWN与它的响应函数OnLButtonDown ()相关联。
这样一旦有消息的产生,就会自动调用相关联的消息响应函数去处理。
宏ON_WM_LBUTTONDOWN()定义如下:#define ON_WM_LBUTTONDOWN() \{ WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp, \(AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT,CPoint))&OnLButtonDown },3)源文件中进行消息响应函数处理。
mfc消息映射机制
mfc消息映射机制MFC消息映射机制是MFC框架中的一个重要机制,它是实现消息响应的关键。
在MFC中,消息是指Windows操作系统中的消息,例如鼠标点击、键盘输入、窗口大小改变等。
MFC消息映射机制是将消息与相应的处理函数关联起来的过程,使得程序能够响应用户的操作。
MFC消息映射机制的实现依赖于消息映射表。
消息映射表是一个数组,其中每个元素都是一个消息映射结构体。
消息映射结构体包含了消息的类型、消息的ID、消息的处理函数等信息。
当程序接收到一个消息时,MFC会根据消息的类型和ID在消息映射表中查找相应的处理函数,并将消息传递给该函数进行处理。
MFC消息映射机制的优点在于它能够将消息处理函数与消息的类型和ID进行关联,使得程序的代码更加清晰、易于维护。
此外,MFC 还提供了一些宏定义,例如DECLARE_MESSAGE_MAP和BEGIN_MESSAGE_MAP,使得消息映射表的定义更加简洁、易于理解。
MFC消息映射机制的使用方法如下:1. 在类的头文件中声明消息映射表,使用DECLARE_MESSAGE_MAP宏定义。
2. 在类的实现文件中定义消息映射表,使用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏定义。
3. 在消息映射表中添加消息映射结构体,使用ON_MESSAGE、ON_COMMAND等宏定义。
4. 在消息处理函数中编写相应的代码,处理消息。
例如,以下代码实现了一个响应鼠标点击消息的处理函数:afx_msg LRESULT CMyWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam){// 处理鼠标点击消息return 0;}BEGIN_MESSAGE_MAP(CMyWnd, CWnd)ON_WM_LBUTTONDOWN()END_MESSAGE_MAP()在上述代码中,CMyWnd是一个继承自CWnd的窗口类,OnLButtonDown是处理鼠标点击消息的函数。
MFC消息机制
MFC消息机制理解消息循环理解消息循环经及Windows程序整个的消息发送机制对于任何Windows程序都是非常重要也是最根本的.现在我们已经尝试了如何处理消息循环,我们有必要对这整个过程再深入一些.因为假如你不能理解消息循环具体是怎么一回事的话,那么以后你就会越来越糊涂.什么是消息?消息就是一个整型值.如果你查看一下你的头文件的话(当你去调查API的工作机制的话,这是一个非常好的也是大多数人都有的习惯)你就发现下面这些东西:#define WM_INITDIALOG 0x0110#define WM_COMMAND 0x0111#define WM_LBUTTONDOWN 0x0201...等等. 消息是用于底层这个层次上,窗口之间的通信.假如你希望窗口或是控件(其实也是一个特殊的窗口)做某个事情的话,你就发送给它一个消息. 假如有另一个窗口希望你做某个事情的话,它也送一个消息给你.假如有比如像用户敲击键盘,移动鼠标,点击按钮之类的事件发生的话,那么这些消息就由系统发送给那些受到影响的窗口.假如你的窗口是其中的一个的话,你就要处理这个消息,对这个消息做出相应的反应.每个窗口消息都有两个参数,wParam和lParam.最初wParam是16位的,lParam是32位,但是在WIN32中,它们都是32位的.不是每条消息都用到了这些参数,而且不同的消息对它们的使用是不同的.举个例子,WM_CLOSE消息就两个参数都没有用到,你可以把两个都忽略.WM_COMMAND消息就两个参数都用上了,wParam参数包含了两个值,一个是HIWORD(wParam),它是消息的通知码(如果可用的话),另一个是LOWORD(wParam),它是发送消息的控件或是菜单的标识符.lParam是发送消息的控件的HWND(HWND是一种数据类型,也就是窗口的句柄.控件的实质也是一个窗口,因此它也有句柄),当这个消息不是来自于一个控件或是窗口,lParam 的值就是NULL,.(比如当消息是由菜单产生时,lParam就是NULL)HIWORD()和LOWORD()是由windows定义的宏,它们的作用分别是取得一个32位的值的高两个字节(高字)和低两个字节(低字) ,(相当于是将一个双字分别去和0XFFFF0000以及0X0000FFFF作与运算,再分别向右和向左作相应16位位移后得到的结果) 在WIN32中,一个字是16位,一个双字也就是32位了.发送一个消息,你可以用函数PostMessage()或函数SendMessage(). 函数PostMessage()的作用是将消息送到消息队列中,然后立即返回.这意味着,一旦你调用了函数PostMessage()后,那么这个消息有没有得到处理就不一定了.函数 SendMessage()是将消息直接发送给窗口,然后要一直等窗口对这个消息的处理完成了,这个函数才会返回了.假如我们想关闭一个窗口的话,我们可以发送给这个窗口一个WM_CLOSE的消息,比如像这样做: PostMessage(hwnd, WM_CLOSE, 0, 0),那么这个你去点击窗口上方的关闭按钮的效果是一样的.请注意wParam 和 lParam 都是0.原因就正如我们已经谈到的那样,WM_CLOSE消息没有用到这两个参数对话框一旦你开始使用对话框,为了和对话框进行通信,你就会需要发送消息给对话框上的控件.为了做到这一点,你要么用函数GetDlgItem()加上控件的标识符来获得控件的句柄,然后呢,再用函数SendMessage();要么你就用函数SendDlgItemMessage(),这个函数把以上两步结合起来了. 你给这个函数一个窗口的句柄以及子窗口(也就是这个窗口上的控件)的标识符,你就可以获取标识符所对应的子窗口的句柄,接下来就是给子窗口发送消息了.函数SendDlgItemMessage()以及类似的API比如GetDlgItemMessage()可以工作在所有的窗口上,不仅仅是对话框.什么是消息队列让我们假设当你在忙于处理WM_PAINT消息时,突然用户在键盘上敲了一串键.这会发生什么事情呢?你到底是应该停下你的画画,对键盘作出响应,还是对敲下的这些键置之不理呢?显然两种方式都是不合理的.因此我们有了消息队列.当消息被送入消息队列后,你一个个的对它们进行处理,处理一个消息,就移除一个消息.(当然先来的消息先得到处理)这样可以确保存你不会错过哪条消息.当你对某条消息进行处理时,其它消息就等待在队列中,直到你来处理它们.什么是消息循环while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}消息循环调用函数GetMessage(),这个函数它会去察看你的消息队列.假如消息队列是空的(也就是没有任何消息),那么我们的程序就停在那里,等待消息的到来.当某一个导致消息被送到消息队列的事件发生时(举个例子,系统注册的鼠标点击,比如点击关闭按钮),函数GetMessage()就会返回一个正值,表明这里有一个需要得到处理的消息,而且这个消息的值被赋给了我们传递给函数GetMessage()的参数Msg,这个结构体中.如果这个消息是WM_QUIT,那么函数GetMessage()的返回值就是0.如果有错误产生的话,那么返回值就是负值.我们得到消息后(消息在结构体变量Msg中),接下来就可以把消息传递给函数TranslateMessage().这个函数对消息又多做了一步处理,它将虚拟键的消息翻译成字符消息.这一步事实上是可选的,但是如果没有这一步的话,某些事情就不会发生了.一旦这些做完以后,我们把消息传递给函数DispatchMessage(). 函数DispatchMessage()所做的事情就是检查消息是发送哪个窗口的,然后再去查看这个窗口的窗口过程.然后呢,它就会调用这个过程,将参数: 窗口的句柄,消息以及wParam和lParam,送给窗口过程.在你的窗口过程中,你就会检查消息和它的参数,然后根据消息和它的参数,你就可以做你想做的事情了!你不用对所有的消息都进行处理,对于你不想亲自去处理的消息,你就调用函数DefWindowProc()就是了.它会为你对那些没有处理的消息做一些默认的处理.(一般情况下,这个函数其实什么也没有做,也就是相当于将你没有处理的消息忽略掉了,等于那些消息从没有产生过,只是从消息队列中过了一遍.)一旦你做完对消息的处理之后,你的窗口过程就返回了,函数DispatchMessage()也返回了.我们又回到了整个循环的的开始.对于WINDOWS程序,这里有一个非常重要的概念.那就是你的窗口过程不是由系统调用的,事实上是你自己通过调用函数DispatchMessage()间接地调用的. 假如你想自己来调用窗口过程的话(不通过函数DispatchMessage()),你可以把接受消息的窗口,它的窗口句柄作为参数传递给函数GetWindowLong()(函数GetWindowLong()通过设置最后一个参数为GWL_WNDPROC,可以获得窗口过程的地址),这样直接得到窗口的窗口过程,然后再直接执行这个窗口过程!while(GetMessage(&Msg, NULL, 0, 0) > 0){WNDPROC fWndProc = (WNDPROC)GetWindowLong(Msg.hwnd, GWL_WNDPROC);fWndProc(Msg.hwnd, Msg.message, Msg.wParam, Msg.lParam);}我在前面的例程序中尝试了这种作法,而且它确实是可行的.但是这里有许多事情,比如Unicode/ANSI的转换,调用定时器返回等等就不行了,所以呢,你可以试一试,但是不要用在实际的应用中.请注意,我们用函数GetWindowLong()获得和这个窗口相关的窗口过程.为什么不直接调用我们的WndProc()呢?是这样的,我们的消息循环负责我们程序中的所有的窗口,这些窗口包括了比如按钮,列表框之类,它们都有各自的窗口过程.因此我们要确定对不同的窗口我们调用的是相应的窗口过程.因为多个窗口都可以使用相同的窗口过程,第一个参数(窗口的句柄)就用于告诉窗口过程,消息是送给哪个窗口的.正如你所看到的那样,你的应用程序花费了绝大多数的时间在消息循环中往往返返.你非常惬意地发送一条消息给运行得正开心的窗口处理.但是当你想你的窗口退出时,你该怎么做呢?因为我们用的是一个while()循环,假如函数GetMessage()的返回值是0(OK,0),这个循环就结束了.我们也就到达我们的WinMain()的终点了,从而退出程序.这些正是函数PostQuitMessage()完成的事情.它将WM_QUIT消息送到了队列中,和返回一个正值不同,函数GetMessage()填充了Msg结构体,然后返回一个0.在这里Msg结构体的成员wParam包含了你传递给函数PostQuitMessage()的值.你要么将这个值忽略掉,要么把它作为W inMain()的返回值.也就是这个过程终止时的退出码.重要之处: 函数GetMessage()将会返回-1假如它遇到了错误的话.你要记住这一点,不然的话,在某些时候你就会被它拖住的....即使这个函数是定义成返回一个布尔值,它也可以返回除了真或假以外的其它值,因为BOOL布尔型被定义成UINT(无符号整型).下面是例程序代码,它看起来可以运行,但是在某些情况下不能正确处理.while(GetMessage(&Msg, NULL, 0, 0))while(GetMessage(&Msg, NULL, 0, 0) != 0)while(GetMessage(&Msg, NULL, 0, 0) == TRUE)上面的全是错的!你也许注意到了在整个教程中我用的都是第一个,正如我所提到的那样,只要函数GetMessage()的调用不失败的话(前提是你的所有代码都是正确的),它还是可以工作得很好.然而我有一点没有考虑到,那就是当你看到我写的这些文字的时候,你的代码可能在绝大多数的情况下都有错误.还有一点就是函数GetMessage()本身也可能在某些情况下调用失败:) 我会全部检查一遍并且纠正这个错误,但是如果我漏掉了一些的话,就原谅我.while(GetMessage(&Msg, NULL, 0, 0) > 0)上面这个就是对的.要取得相同效果的代码也应该总是这个样子的.我希望你现在对窗口的消息循环有了一个更好的理解,假如不是这样的话,不要灰心,不要害怕,一旦你使用它们一段时间后,所有的事情都会明白的.。
MFC六大核心机制
MFC六大核心机制MFC(Microsoft Foundation Classes)是微软公司开发的一套基于C++语言的应用程序框架。
它提供了一系列类和函数库,方便开发人员构建Windows应用程序。
MFC框架包含了许多核心机制,下面将介绍其中的六大核心机制。
一、消息映射机制:消息映射机制是MFC框架的核心之一,它用于处理Windows消息。
Windows操作系统是事件驱动的,应用程序需要响应来自用户的输入或系统的消息。
通过消息映射机制,开发人员可以向MFC框架注册处理特定消息的函数,当该消息发生时,框架将自动调用相应的函数进行处理。
开发人员只需要在类的消息映射表中添加相应的消息与处理函数的映射关系,就可以实现消息的处理。
二、文档/视图机制:文档/视图机制是MFC框架中用来管理应用程序数据和图形界面显示的一种机制。
应用程序的数据和用户界面是相互独立的,通过文档/视图机制可以将二者进行分离。
开发人员可以创建一个或多个文档类来管理数据,同时可以创建一个或多个视图类来负责显示用户界面。
MFC框架会自动处理数据和界面之间的同步,例如当数据发生变化时,会自动更新界面;当用户修改界面时,会自动更新数据。
三、消息响应机制:消息响应机制是MFC框架中用来处理用户输入和系统消息的一种机制。
开发人员可以通过消息响应机制,将特定的消息与相应的处理函数进行关联,当该消息发生时,框架会自动调用相应的处理函数。
例如,开发人员可以通过响应鼠标点击消息来实现用户点击按钮的响应,或者通过响应键盘输入消息来实现用户输入的响应。
四、对象模型机制:对象模型机制是MFC框架中用来管理对象的一种机制。
MFC框架使用了一种轻量级的对象模型,对象之间的关系通过继承和组合来实现。
开发人员可以创建自己的类并继承自MFC提供的基类,以实现各种功能。
MFC框架提供了丰富的基类库,包括窗口类、对话框类、控件类等,开发人员可以通过继承这些基类来快速构建自己的应用程序。
第二章 使用MFC消息机制
建立自定义消息
从消息的来源来看,可以分为:系统定义的消息和应用程序定义的消息。 – 系统消息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消息函数中设置断点,运行并调试:
•
在生成的消息函数中加入一些代码,并运行查看结果 – 例如,在OnLButtonDown函数中输入代码查看点击位置。
– – – CString str; str.Format("x=%d,y=%d",point.x,point.y); AfxMessageBox(str);
•
删除消息映射函数 – 打开ClassWizard选择OnLButtonDown成员函数,再点删除函数按钮。 – 查看删除消息函数后的代码,消息映射宏和头文件中的函数声明已经 被删除,一般ClassWizard会保留函数体中的代码,以备开发者保存。
• •
•
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_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows] USERPostMessageLimit,最小可以是 4000。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
全面解析MFC应用程序中处理消息的顺序
1.AfxWndProc() 该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc
2.AfxCallWndProc() 该函数负责保存消息(保存的内容主要是消息标识符和消息参数)供应用程序以后使用,然后调用WindowProc()函数
3.WindowProc() 该函数负责发送消息到OnWndMsg()函数,如果未被处理,则调用DefWindowProc()函数
4.OnWndMsg() 该函数的功能首先按字节对消息进行排序,对于WM_COMMAND 消息,调用OnCommand()消息响应函数,对于WM_NOTIFY消息调用OnNotify()消息响应函数。
任何被遗漏的消息将是一个窗口消息。
OnWndMsg()函数搜索类的消息映像,以找到一个能处理任何窗口消息的处理函数。
如果OnWndMsg()函数不能找到这样的处理函数的话,则把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数
5.OnCommand() 该函数查看这是不是一个控件通知(lParam参数不为NULL,如果lParam参数为空的话,说明该消息不是控件通知),如果它是,OnCommand()函数会试图将消息映射到制造通知的控件;如果他不是一个控件通知(或者如果控件拒绝映射的消息)OnCommand()就会调用OnCmdMsg()函数
6.OnCmdMsg() 根据接收消息的类,OnCmdMsg()函数将在一个称为命令传递(Command Routing)的过程中潜在的传递命令消息和控件通知。
例如:如果拥有该窗口的类是一个框架类,则命令和通知消息也被传递到视图和文档类,并为该类寻找一个消息处理函数
MFC应用程序创建窗口的过程
1.PreCreateWindow() 该函数是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数(可以设置窗口风格等等)
2.PreSubclassWindow() 这也是一个重载函数,允许首先子分类一个窗口
3.OnGetMinMaxInfo() 该函数为消息响应函数,响应的是WM_GETMINMAXINFO消息,允许设置窗口的最大或者最小尺寸
4.OnNcCreate() 该函数也是一个消息响应函数,响应WM_NCCREATE消息,发送消息以告诉窗口的客户区即将被创建
5.OnNcCalcSize() 该函数也是消息响应函数,响应WM_NCCALCSIZE消息,作用是允许改变窗口客户区大小
6.OnCreate() 该函数也是一个消息响应函数,响应WM_CREATE消息,发送消息告
诉一个窗口已经被创建
7.OnSize() 该函数也是一个消息响应函数,响应WM_SIZE消息,发送该消息以告诉该窗口大小已经发生变化
8.OnMove() 消息响应函数,响应WM_MOVE消息,发送此消息说明窗口在移动
9.OnChildNotify() 该函数为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被创建
MFC应用程序关闭窗口的顺序(非模态窗口)
1.OnClose() 消息响应函数,响应窗口的WM_CLOSE消息,当关闭按钮被单击的时候发送此消息 [Page]
2.OnDestroy() 消息响应函数,响应窗口的WM_DESTROY消息,当一个窗口将被销毁时,发送此消息
3.OnNcDestroy() 消息响应函数,响应窗口的WM_NCDESTROY消息,当一个窗口被销毁后发送此消息
4.PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作,被CWnd调用
MFC应用程序中打开模式对话框的函数调用顺序
1.DoModal() 重载函数,重载DoModal()成员函数
2.PreSubclassWindow() 重载函数,允许首先子分类一个窗口
3.OnCreate() 消息响应函数,响应WM_CREATE消息,发送此消息以告诉一个窗口已经被创建
4.OnSize() 消息响应函数,响应WM_SIZE消息,发送此消息以告诉窗口大小发生变化
5.OnMove() 消息响应函数,响应WM_MOVE消息,发送此消息,以告诉窗口正在移动
6.OnSetFont() 消息响应函数,响应WM_SETFONT消息,发送此消息,以允许改变对话框中控件的字体
7.OnInitDialog() 消息响应函数,响应WM_INITDIALOG消息,发送此消息以允许初始化对话框中的控件,或者是创建新控件
8.OnShowWindow() 消息响应函数,响应WM_SHOWWINDOW消息,该函数被ShowWindow()函数调用
9.OnCtlColor() 消息响应函数,响应WM_CTLCOLOR消息,被父窗口发送已改变对话框或对话框上面控件的颜色
10. OnChildNotify() 重载函数,作为WM_CTLCOLOR消息的结果发送
MFC应用程序中关闭模式对话框的顺序
1.OnClose() 消息响应函数,响应WM_CLOSE消息,当\"关闭\"按钮被单击的时候,该函数被调用
2.OnKillFocus() 消息响应函数,响应WM_KILLFOCUS消息,当一个窗口即将失去键盘输入焦点以前被发送
3.OnDestroy() 消息响应函数,响应WM_DESTROY消息,当一个窗口即将被销毁时,被发送
4.OnNcDestroy() 消息响应函数,响应WM_NCDESTROY消息,当一个窗口被销毁以后被发送
5.PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作被CWnd调用。