消息的基本概念

一、消息的基本概念

消息(Message)指的就是Windows操作系统发给应用程序的一个通告,它告诉应用程序某个特定的事件发生了。比如,用户单击鼠标或按键都会引发Windows系统发送相应的消息。最终处理消息的是应用程序的窗口函数,如果程序不负责处理的话系统将会作出默认处理。

从数据结构的角度来说,消息是一个结构体,它包含了消息的类型标识符以及其他的一些附加信息。比如对于鼠标单击产生的消息而言,它就包含了窗口句柄、此消息的常量标识符、鼠标的位置坐标等相关信息。

Windows系统定义了许多消息常量,包括标准的Windows消息、通知消息、命令消息等等。这些消息常量通常具有XX_YYYY的形式,其他XX通常代表消息的类型,而后面的YYYY通常是这个消息所对应事件的英文缩写。比如WM_LBUTTONDOWN代表的事件就是按下了鼠标左键。

二、Windows的消息系统

Windows的消息系统由3个部分组成:
消息队列。Windows操作系统本身维护了一个系统消息队列,而对于每一个正在执行的Windows应用程序,系统会为其建立一个应用程序消息队列。应用程序可以从这个消息队列中获取消息,然后分派给对应的窗口。
消息循环。Windows应用程序中都包含了一段称作“消息循环(也称消息泵)”的代码,用来从消息队列中检索消息并把他们分发到相应的窗口函数中。正是这个消息循环使得一个应用程序能够响应外部的各种事件,所以消息循环往往是一个Windows应用程序的核心部分。
窗口函数。最终为了处理各种消息,Windows应用程序所创建的每个窗口(广义,包括实际窗口、控件等诸如此类的的内容)都会在系统中注册一个相应的窗口函数,此窗口函数从形式上看一个巨大的switch语句,用以处理由消息循环发送到该窗口的各种消息。窗口函数是一种回调函数(Callback Function),也就是说,它是由Windows操作系统负责调用的,而应用程序本身不能调用它。

Windows操作系统中的消息从发生到被处理一般有5个步骤:
(1)系统发生了一个事件。
(2)Windows系统把事件翻译为对应的消息,并把它放到消息队列中。
(3)应用程序从消息队列中获取消息,然后把它封装在TMsg结构中。
(4)应用程序通过消息循环把消息分派给对应的窗口函数。
(5)窗口函数负责最终处理这个消息。
它在Windows单元中是这样声明的:
type
TMsg 
= packed record
hwnd: HWND; 
/ /窗口句柄
message: UINT; 
/ /消息常量标识符
wParam: WPARAM ; 
// 32位消息的特定附加信息
lParam: LPARAM ; 
// 32位消息的特定附加信息
time: DWORD; 
/ /消息创建时的时间
pt: TPoint; 
/ /消息创建时的鼠标位置
end;

hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。
message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。
wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。
lParam 通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m和P o i n t e r都是3 2位的,
因此,它们之间可以相互转换。

一些常用的消息常量:
WM_Create = &H0001;
应用程序创建一个窗口
WM_DESTROY = &H0002;
一个窗口被销毁
WM_MOVE = &H0003;
移动一个窗口
WM_SIZE = &H0005;
改变一个窗口的大小
WM_ACTIVATE = &H0006;
一个窗口被激活或失去激活状态;
WM_SETFOCUS = &H0007;
获得焦点后
WM_KILLFOCUS = &H0008;
失去焦点
WM_ENABLE = &H000A;
改变enable状态

WM_PAINT = &H000F;
要求一个窗口重画自己
WM_CLOSE = &H0010;
当一个窗口或应用程序要关闭时发送一个信号
WM_COPYDATA = &H004A;
当一个应用程序传递数据给另一个应用程序时发送此消息

WM_NCCreate = &H0081;
当某个窗口第一次被创建时,此消息在WM_Create消息发送前发送;
WM_NCDESTROY = &H0082;
此消息通知某个窗口,非客户区正在销毁
WM_NCCALCSIZE = &H0083;
当某个窗口的客户区域必须被核算时发送此消息
WM_NCHITTEST = &H0084;//移动鼠标,按住或释放鼠标时发生
WM_NCPAINT = &H0085;
程序发送此消息给某个窗口当它(窗口)的框架必须被绘制时;
WM_NCACTIVATE = &H0086;
此消息发送给某个窗口 仅当它的非客户区需要被改变来显示是激活还是非激活状态;
WM_NCLBUTTONDOWN = &H00A1;
当光标在一个窗口的非客户区同时按下鼠标左键时提交此消息
WM_NCLBUTTONUP = &H00A2;
当用户释放鼠标左键同时光标某个窗口在非客户区十发送此消息;
WM_NCLBUTTONDBLCLK = &H00A3;
当用户双击鼠标左键同时光标某个窗口在非客户区十发送此消息
WM_NCRBUTTONDOWN = &H00A4;
当用户按下鼠标右键同时光标又在窗口的非客户区时发送此消息
WM_NCRBUTTONUP = &H00A5;
当用户释放鼠标右键同时光标又在窗口的非客户区时发送此消息
WM_NCRBUTTONDBLCLK = &H00A6;
当用户双击鼠标右键同时光标某个窗口在非客户区十发送此消息
WM_NCMBUTTONDOWN = &H00A7;
当用户按下鼠标中键同时光标又在窗口的非客户区时发送此消息
WM_NCMBUTTONUP = &H00A8;
当用户释放鼠标中键同时光标又在窗口的非客户区时发送此消息
WM_NCMBUTTONDBLCLK = &H00A9;
当用户双击鼠标中键同时光标又在窗口的非客户区时发送此消息
WM_KEYFIRST = &H0100;
WM_KEYDOWN = &H0100;
//按下一个键
WM_KEYUP = &H0101;
WM_HSCROLL = &H0114;
当一个窗口标准水平滚动条产生一个滚动事件时发送此消息给那个窗口,也发送给拥有它的控件
WM_VSCROLL = &H0115;
当一个窗口标准垂直滚动条产生一个滚动事件时发送此消息给那个窗口也,发送给拥有它的控件
WM_MOUSEFIRST = &H0200;
WM_MOUSEMOVE = &H0200;
// 移动鼠标
WM_LBUTTONDOWN = &H0201;
//按下鼠标左键
WM_LBUTTONUP = &H0202;
//释放鼠标左键
WM_LBUTTONDBLCLK = &H0203;
//双击鼠标左键
WM_RBUTTONDOWN = &H0204;
//按下鼠标右键
WM_RBUTTONUP = &H0205;
//释放鼠标右键
WM_RBUTTONDBLCLK = &H0206;
//双击鼠标右键
WM_MBUTTONDOWN = &H0207;
//按下鼠标中键
WM_MBUTTONUP = &H0208;
//释放鼠标中键
WM_MBUTTONDBLCLK = &H0209;
//双击鼠标中键
WM_MOUSEWHEEL = &H020A;
当鼠标轮子转动时发送此消息个当前有焦点的控件


原文地址:https://www.cnblogs.com/samsonleung/p/1234193.html