- 浏览: 15833 次
- 性别:
- 来自: 成都
最新评论
1、命令消息(WM_COMMAND)
所有派生自 CCmdTarget 的类都有资格接受WM_COMMAND。
2、Window消息(WM_xxx)
所有派生自 CWnd 的类都有资格接受 WM_xxx。
3、控件消息(WM_NOTIFY)
控件向其父窗口通知消息。
消息处理
1、WM_xxx 消息处理
窗口类(自身)处理→基类处理→CWnd∷DefWindowProc()处理;
其所对应的宏一般为在消息 WM_ 前面加上 ON_。
2、命令消息处理
命令消息来自命令用户接口对象(菜单、加速键或工具栏按钮)发出的WM_COMMAND消息;
㈠、WM_COMMAND消息
其所包含的类型和对应的宏如下:
①、ON_COMMAND(ID,pfn)
标准的命令消息;
②、ON_COMMAND_EX(ID,pfn)
多个对象对同一个命令 ID 的处理;
其函数的原型如下:
afx_msg BOOL pfn(UINT nID)
说明:
当返回 TRUE 时表示已经处理,不用在消息处理链中继续处理该命令;为 FALSE 时表示继续在消息处理链中处理该命令。
注意:
其一:在多对象处理中一定要使用该宏;
其二:pfn(UINT nID)(消息处理函数)返回值将其类型void改成BOOL,而且必须为FALSE;
其三:多个对象的处理是由高层向低层的过程:即视图类→主框架窗口类→应用程序类;
③、ON_COMMAND_RANGE(nID,nLastID,pfn)
多个命令 ID 提供相同的处理;
注意:
其一:确保nID、nLastID的值在 Resource.h 中是连续的。
其二:一般在函数 pfn(UINT nID) 中加入参数,用来确定那一个按钮点击。
㈡、CN_UPDATE_COMMAND_UI消息
当菜单项、工具栏按钮等[命令用户接口对象]要更新其状态时所对应的消息,它所包含的类型和对应的宏如下:
①、ON_UPDATE_COMMAND_UI(ID,pfn)
其中函数的原型如下:
afx_msg void pfn(CCmdUI* pCmdUI)
②、ON_UPDATE_COMMAND_UI_RANGE(nID,nLastID,pfn)
该函数可以处理一组[命令用户接口对象]的外观;
其中函数的原型如下:
afx_msg void pfn(CCmdUI* pCmdUI)
重要:
CCmdUI 中的 m_nID 成员表示不同的 ID,因此可以利用它来进行区别处理。
3、控件的通知消息
从控件和子窗口发送到父窗口的WM_COMMAND通知消息(即在发送命令消息中加入控件的通知码)。
注意:在 Window9x 新控件中不再传送WM_COMMAND通知消息,而是发送 WM_NOTIFY 消息,但为了兼容,旧有的控件还是传送WM_COMMAND消息。
例如:
CEdit控件向父窗口发送 EN_CHANGE 通知代码的WM_COMMAND消息。
注意:框架像传送其它 WM_ 消息一样传送通知消息,但有一个例外,即由 [按钮] 控件发送的 BN_CLICKED 通知消息,被作为命令消息特别处理。
㈠、WM_COMMAND 其所对应的宏如下:
①、ON_CONTROL(通知码, nID,fn)
②、ON_CONTROL_RANGE(通知码, nFirstID,nEndID,fn)
注意:
这两个宏的应用和 ON_COMMAND、ON_COMMAND_RANGE相同,所不同的是在宏前面加入[通知码]。
注意:可以根据不同的控件的[通知码]派生出特定的宏,其所派生的宏一般为在 [通知码] 前面加上 ON_。
㈡、WM_NOTIFY 其所对应的宏如下:
①、ON_NOTIFY(通知码, nID,fn)
其中函数的原型如下:
afx_msg void fn(NMHDR* pNotifyStruct,LRESULT* result)
其中结构:
typedef struct tagNMHDR {
HWND hwndFrom; //发送通知消息的控件的句柄;
UINT idFrom; //发送通知消息的控件的 ID;
UINT code; //通知码;
} NMHDR;
②、ON_NOTIFY_EX(通知码, nID,fn)
表示一个消息在多个对象的成员函数中进行处理。
其中函数的原型如下:
afx_msg BOOL fn(UINT nID,NMHDR* pNotifyStruct,LRESULT* result)
说明:
它必须返回 BOOL 类型的数值,其意义和 ON_COMMAND_EX 相同。
③、ON_NOTIFY_RANGE(通知码, nFirstID,nEnd,fn)
表示多个控件的通知消息在同一个函数中进行处理。
其中函数的原型如下:
afx_msg void fn(UINT nID,NMHDR* pNotifyStruct,LRESULT* result)
说明:
其意义和ON_COMMAND_RANGE相同。
4、反射消息处理
父窗口在处理控件窗口的通知消息WM_CTLCOLOR、WM_COMMAND、WM_NOTIFY时,会把该消息转化为反射消息,并转交给控件子窗口处理,只有在控件子窗体不处理该消息时,父窗口才有机会处理。
注意:在类的属性对话框中的消息页面可查反射消息(前面有"="标志)
①、WM_CTLCOLOR_REFLECT反射消息
其所对应的宏如下:
ON_WM_CTLCOLOR_REFLECT()
反射消息函数的原型:
HBRUSH class_name∷CtlColor(CDC* pDC,UINT nCtlColor)
{
return NULL;
}
该函数用来重置控件的顔色;注意:必须 return CBrush才有效。
5、自定义的窗口消息
自定义窗口消息的消息标志都大于WM_USER(至少是WM_USER+100,因为许多控件都使用这一范围的WM_USER消息)
使用自定义的消息分为二步:
①、在 Resource.h 中定义消息标记
#define WM_MYMSG (WM_USER+1000)
②、在消息映射表中加入消息映射宏
BEGIN_MESSAGE_MAP()
ON_MESSAGE(WM_MYMSG,fn)
END_MESSAGE_MAP()
说明:
其对应的宏为 ON_MESSAGE(),其成员函数的原型为:
afx_msg LRESULT fn(WPARAM,LPARAM)
6、登记消息
①、在系统中注册并获取一个登记消息的消息标记
UINT RegisterWindowMessage(LPCTSTR)
说明:
通过 API 函数来注册消息标记,其中 LPCTSTR 为用户的任意字符串。例如:
UINT WM_MYMSG=RegisterWindowMessage("MYMSG");
其中 WM_MYMSG 是自定义无符号整型的消息标记。
②、在消息映射表中加入消息映射宏
BEGIN_MESSAGE_MAP()
ON_REGISTERED_MESSAGE(WM_MYMSG,fn)
END_MESSAGE_MAP()
说明:
其对应的宏为 ON_REGISTERED_MESSAGE(),其成员函数的原型为:
afx_msg LRESULT fn(WPARAM,LPARAM)
注意:登记消息可以实现跨进程的数据通讯。
7、线程消息
只有继承自CWinThread类才能允许处理线程消息。
①、定义线程的消息标记
有两种方法:
(1)、使用自定义的消息标记,即:WM_USER;
(2)、使用登记的消息标记,即:RegisterWindowMessage;
②、在CWinThread继承类的消息映射表中添加宏
ON_THREAD_MESSAGE(消息标记,fn) //自定义的消息;
ON_REGISTERED_THREAD_MESSAGE(消息标记,fn) //登记的 //消息
③、其函数的原型如下:
afx_msg void fn(WPARAM wPARAM,LPARAM lParam)
④、引发线程消息
线程消息的引发必须调用 CWinThread 类的PostThreadMessage将消息投递到线程消息队列中。
注意:可以通过 AfxGetApp() 函数获取一个全局的应用对象。
PostThreadMessage(UINT,WPARAM,LPARAM)
8、WM_COPYDATA
操作系统维护一块内存来管理 WM_COPYDATA 消息,该消息主要用于跨进程传递数据,传递的数据量达到 232。
①、定义一个 COPYDATASTRUCT 数据结构
typedef struct tagCOPYDATASTRUCT {
DWORD dwData; //自定义的特殊数据;
DWORD cbData; //以字节为单位的 lpData 的大小;
PVOID lpData; //传送的数据内存块的指针;
} COPYDATASTRUCT;
②、其所对应的宏
ON_WM_COPYDATA()
③、其所对应的函数的原型
afx_msg BOOL OnCopyData(CWnd*,COPYDATASTRUCT*)
说明:
CWnd*:发送该消息的窗口的指针;
9、投递和发送消息
通过向一个窗体投递或发送消息,可以间接地驱动窗体的消息过程。
投递(PostMessage):将消息放到线程的消息队列中,然后不等线程处理该消息就直接返回到调用方。
发送(SendMessage):当一个线程向目标线程发送消息时,该线程要一直等待,直到目标线程处理了该消息为止。
①、投递消息
BOOL CWnd∷PostMessage(UINT,WPARAM=0,LPARAM=0)
说明:
CWnd:目标窗口;
该函数将一条消息放入到应用程序的消息队列,然后不等窗口处理就直接返回。
②、发送消息
LRESULT CWnd∷SendMessage(UINT,WPARAM=0,LPARAM=0)
说明:
CWnd:目标窗口;
该函数将一条消息放入到应用程序的消息队列,等待窗口处理后才返回。
为了避免线程陷入永久等待状态,可以用SendMessageTimeout代替SendMessage:
LRESULT SendMessageTimeout(HWND,UINT,WPARAM,LPARAM,UINT,UINT,PDWORD_PTR)
说明:
HWND:窗口句柄;
UINT:消息发送的选项,为SMTO_BLOCK时,可以防止线程无 限等待,即根据一定的超时值返回。
UINT:超时,以毫秒为单位;
PDWORD_PTR:返回值;
注意:CWnd没有对该函数的包装。
③、投递和发送消息
BOOL CWnd∷SendNotifyMessage(UINT,WPARAM,LPARAM)
说明:
CWnd:目标窗口;
该消息具有SendMessage和PostMessage两种功能:
当目标窗口和发送窗口为同一个线程时,则相当于SendMessage的功能;否则当不为同一个线程时,则为PostMessage的功能。
6-1、投递和发送 WM_XXX 消息
在发送标准的 WINDOW 消息时,只要将该消息的 ID、wParam、lParam参数放在 SendMessage()和PostMessage()函数的相应位置即可。
6-2、投递和发送命令消息和控件的通知消息
在投递和发送命令消息时,消息的 ID为 WM_COMMADN,而对于不同的菜单项、加速键、控件则wParam、lParam的取值不同。
wParam分成低、高两部分,低部分为菜单项、加速键、控件的ID。高部分则:
菜单项:0;加速键:1;控件:通知码
lParam:当控件时是控件的句柄,否则为 NULL。
对于wParam参数可以采用自定义宏:
WPARAM MAKEWPARAM(WORD wLow,WORD wHigh)
6-3、投递和发送自定义的窗口消息
在投递和发送自定义的窗口消息时,参数 wParam、lParam 没有特别的涵义,只和普通函数的形参一样进行数据的传递。
注意:
PostMessage 和 SendMessage 是不同的,前者投递后就返回,而后者必须等到消息处理后再返回;所以在参数是 [局部] 或 [临时]时,使用PostMessage函数会引发错误(除非参数使用 指针,则可避免错误),而必须使用SendMessage函数。
6-4、投递和发送注册的窗口消息
和 6-3 基本一样,但它要特别注意的问题是:在跨进程的处理消息时,如果将消息PostMessage、SendMessage到某个进程 A,则必须在进程 B 中获取进程 A 的窗口类名,并通过窗口类名获取窗口的指针,最后再根据指针调用 PostMessage、SendMessage 函数。
注意:在获取窗口的指针时,可以根据窗口类名或窗口的标题。
6-5、投递和发送WM_COPYDATA消息
SendMessage(消息标记,WPARAM,LPARAM)
其中:
消息标记:WM_COPYDATA;
WPARAM:发送该消息的窗口句柄;
LPARAM:COPYDATASTRUCT结构的指针,先通过(LPVOID)进行转换,再通过(LPARAM)进行转换,如下形式:
(LPARAM)(LPVOID)&cds
转自:http://blogold.chinaunix.net/u/28371/showart_425070.html
发表评论
-
Visual C++ 2010(2008)创建Ribbon界面
2011-07-01 22:28 1055http://hayyoungsue.blog.163.com ... -
C++0x FAQ中文版
2011-06-27 21:47 801http://space.itpub.net/trackbac ... -
Windows用户模式与内核模式
2011-06-01 09:18 960从Intel80386开始,出于安 ... -
Windows用户模式与内核模式
2011-06-01 09:18 11从Intel80386开始,出于安 ... -
Css处理负数需要position的配合【及IE6CSS负数遮挡处理】
2010-12-30 22:25 1421有8个像素是负数,在IE6下会被遮挡,因此这个时候,必须用po ... -
NHibernate之旅系列文章导航
2010-12-10 22:35 723http://www.cnblogs.com/lyj/arch ... -
NUnit2.0详细使用方法 (二)
2010-12-10 22:33 895TestFixtureSetUp/TestFixtureTea ... -
NUnit2.0详细使用方法 (一)
2010-12-10 22:24 8021. TDD的简介 首先什么是TDD呢?Kent Beck ... -
JAVA基础:Hibernate外键关联与HQL语法
2010-12-05 23:22 851例如对于TUser类 1.实体查询 String hql ... -
对象生死劫 - 构造函数和析构函数的异常
2010-11-19 08:40 880构造函数和析构函数分 ... -
Fck编辑器的完整详解
2010-11-17 15:07 922javascript调用方式: --------------- ... -
java抽象类和接口和继承之间关系
2010-11-09 14:52 1411有时候,我们可能想要构造一个很抽象的父类对象,它可能仅仅代表一 ...
相关推荐
MFC的消息类型主要包括命令消息、Window消息和控件消息,它们都是通过消息映射机制进行处理的。 1. 命令消息(WM_COMMAND) 命令消息通常由用户界面元素(如菜单、快捷键或工具栏按钮)生成,用于传递用户操作到...
在深入探讨MFC消息循环和消息泵之前,我们首先要理解MFC(Microsoft Foundation Classes)是一个C++库,它为开发Windows应用程序提供了一种抽象层。MFC的消息循环和消息泵是Windows应用程序的基础,它们处理应用程序...
这个压缩包“模拟MFC消息循环.rar”可能包含了作者根据侯老师的讲解创建的一个简单的MFC控制台程序,用于演示和理解消息循环的工作原理。 首先,我们需要理解MFC中的消息映射(Message Map)。消息映射是MFC框架...
MFC的消息映射表包含不同类型的消息处理,如控件消息、命令消息、更新命令消息等。`nMessage`字段存储Windows消息ID,`nCode`和`nID`通常用于控制代码和控件ID。`nLastID`用于指定范围内的控件ID,`nSig`定义消息的...
MFC 消息机制完全解读 MFC(Microsoft Foundation Classes)是 Windows 下最流行的一套类库,它提供了许多便捷的功能使程序员更方便地开发 Windows 程序。但是,MFC 的消息映射机制对初学者来说可能比较难以理解和...
1. **MFC消息框简介** MFC提供了CMessageBox类,它是CDialog派生的,用于创建弹出式对话框,通常用于向用户显示简短的信息或请求简单的确认。消息框通常包含一个标题、消息文本以及一组按钮,如“确定”、“取消”...
消息是一个结构体,包含了消息的类型标识符、窗口句柄、参数、时间和鼠标位置等信息。 Window 消息循环: 消息循环是 Windows 应用程序存在的根本,应用程序通过消息循环获取各种消息,并通过相应的窗口函数,对...
总的来说,MFC消息机制是构建用户界面和处理用户交互的基础。通过消息映射和`SendMessage`等函数,我们可以精确地控制应用程序的响应行为,使得程序更加灵活和健壮。理解并熟练运用这些概念,对于开发高效、稳定的...
PreTranslateMessage函数的参数是一个MSG结构体的指针,该结构体包含了消息的详细信息,例如消息类型、参数等。我们可以在PreTranslateMessage函数中使用这些信息来拦截和处理特定的消息。例如,我们可以使用(pMsg->...
#### 一、MFC消息处理机制概览 在Microsoft Foundation Classes (MFC)框架中,消息处理是应用程序的核心部分,尤其对于对话框程序而言,如何有效地处理键盘消息成为了一个关键点。MFC中的对话框程序通常会在程序...
MFC消息响应机制是其核心功能之一,它允许开发者通过面向对象的方式来处理Windows操作系统中的消息。 一、MFC消息响应机制概述 MFC将Windows API中的消息处理封装在类库中,提供了一种更加高效和方便的方式来处理...
当你调用`PostMessage`时,需要提供目标窗口的句柄(HWND)、消息类型(如WM_COMMAND、WM_PAINT等)以及任何相关的参数。 例如,假设我们有一个简单的MFC对话框应用程序,我们想要从一个按钮的点击事件中发送一个...
自定义消息是Windows操作系统中除标准消息(如WM_PAINT、WM_CREATE等)之外,由开发者自行定义的消息类型。它们通常以WM_USER作为起始值,并通过增量来创建唯一的消息ID,以避免与系统消息冲突。 二、在MFC中声明...
开发者需要在窗口过程中解析消息类型并编写相应的处理代码,这种方法较为繁琐。 **MFC中的消息映射机制** MFC的消息映射机制是通过宏定义实现的,它创建了一个消息映射表格,当消息发生时,框架会根据表格找到相应...
TranslateMessage函数用于将键盘消息转换为相应的消息类型。DispatchMessage函数则将消息传递给相应的窗口函数,进行处理。 二、窗口函数 窗口函数是一种特殊的回调函数,用于处理来自操作系统的消息。窗口函数的...
MFC消息响应顺序涉及从消息的产生、传递到最终处理的整个流程。以下将详细阐述这个过程。 首先,当Windows系统接收到用户操作,如点击按钮或键盘输入,这些事件会被转化为消息(如WM_COMMAND或WM_KEYDOWN)。MFC...
为了处理自定义消息,MFC提供了一个强大的宏`ON_MESSAGE()`,允许开发者定义自己的消息类型,并将其与特定的处理函数关联起来。 1. **头文件中的自定义消息定义** ```cpp #define WM_MYMESSAGE WM_USER + 1 afx...