Windows中,消息使用统一的结构体(MSG)来存放信息,其中message表明消息的具体的类型,

而wParam,lParam是其最灵活的两个变量,为不同的消息类型时,存放数据的含义也不一样。

time表示产生消息的时间,pt表示产生消息时鼠标的位置。

里面没有Result的选项。然后我用VC2008实测MSG结构的大小:

#include <afx.h>

void Cxe111Dlg::OnBnClickedButton1()
{
CString m_Str;
int ddd = sizeof(MSG);
m_Str.Format(_T("%d"), ddd);
AfxMessageBox(m_Str);
}

结果等于28

void Cxe111Dlg::OnBnClickedButton1()
{
CString m_Str;
int ddd = sizeof(WM_SIZE);
m_Str.Format(_T("%d"), ddd);
AfxMessageBox(m_Str);
}

结果等于4

void Cxe111Dlg::OnBnClickedButton1()
{
CString m_Str;
int ddd = sizeof(WM_CHAR);
m_Str.Format(_T("%d"), ddd);
AfxMessageBox(m_Str);
}

结果等于4

-------------------------------------------------------------

再来看Delphi里的定义,它也有原模原样的定义,只不过一般情况下用不到:

  PMsg = ^TMsg;
tagMSG = packed record
hwnd: HWND;
message: UINT;
wParam: WPARAM;
lParam: LPARAM;
time: DWORD;
pt: TPoint;
end; TMsg = tagMSG;
MSG = tagMSG;

经过测试,它的大小当然也是28:

procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage(IntToStr(sizeof(tagMSG)));
end;

再看Delphi真正使用的消息结构,注意它包括了Result:

  PMessage = ^TMessage;
TMessage = packed record
Msg: Cardinal;
case Integer of
: (
WParam: Longint;
LParam: Longint;
Result: Longint);
: (
WParamLo: Word;
WParamHi: Word;
LParamLo: Word;
LParamHi: Word;
ResultLo: Word;
ResultHi: Word);
end;

测试它的大小:

procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage(IntToStr(sizeof(TMessage)));
end;

结果等于16

-------------------------------------------------------------

再测试消息本身的大小:

procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage(IntToStr(sizeof(WM_CHAR)));
end;

结果等于2

procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage(IntToStr(sizeof(WM_SIZE)));
end;

结果等于1

-------------------------------------------------------------

再来看Delphi定义的消息结构体:

  TWMSize = packed record
Msg: Cardinal;
SizeType: Longint; { SIZE_MAXIMIZED, SIZE_MINIMIZED, SIZE_RESTORED,
SIZE_MAXHIDE, SIZE_MAXSHOW }
Width: Word;
Height: Word;
Result: Longint;
end; TWMKey = packed record
Msg: Cardinal;
CharCode: Word;
Unused: Word;
KeyData: Longint;
Result: Longint;
end; TWMChar = TWMKey; TWMPaint = packed record
Msg: Cardinal;
DC: HDC;
Unused: Longint;
Result: Longint;
end; TWMCommand = packed record
Msg: Cardinal;
ItemID: Word;
NotifyCode: Word;
Ctl: HWND;
Result: Longint;
end; TWMNotify = packed record
Msg: Cardinal;
IDCtrl: Longint;
NMHdr: PNMHdr;
Result: Longint;
end;

测试Delphi消息结构体的大小:

procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage(IntToStr(sizeof(TWMSize)));
ShowMessage(IntToStr(sizeof(TWMChar)));
ShowMessage(IntToStr(sizeof(TWMPaint)));
ShowMessage(IntToStr(sizeof(TWMCommand)));
ShowMessage(IntToStr(sizeof(TWMNotify)));
end;

怎么测都是16字节大小。。。

------------------------------------------------------------------------

一个使用例子:

  TWMContextMenu = packed record
Msg: Cardinal;
hWnd: HWND;
case Integer of
: (
XPos: Smallint;
YPos: Smallint);
: (
Pos: TSmallPoint;
Result: Longint);
end; procedure TControl.WMContextMenu(var Message: TWMContextMenu);
var
Pt, Temp: TPoint;
Handled: Boolean;
PopupMenu: TPopupMenu;
begin
if Message.Result <> 0 then Exit;
if csDesigning in ComponentState then
begin
inherited;
Exit;
end; Pt := SmallPointToPoint(Message.Pos);
if InvalidPoint(Pt) then
Temp := Pt
else
begin
Temp := ScreenToClient(Pt);
if not PtInRect(ClientRect, Temp) then
begin
inherited;
Exit;
end;
end; Handled := False;
DoContextPopup(Temp, Handled);
Message.Result := Ord(Handled);
if Handled then Exit; PopupMenu := GetPopupMenu;
if (PopupMenu <> nil) and PopupMenu.AutoPopup then
begin
SendCancelMode(nil);
PopupMenu.PopupComponent := Self;
if InvalidPoint(Pt) then
Pt := ClientToScreen(Point(, ));
PopupMenu.Popup(Pt.X, Pt.Y);
Message.Result := 1;
end; if Message.Result = 0 then
inherited;
end;

终于懂了:Delphi消息的Result完全是生造出来的,不是Windows消息自带的(Delphi对Windows编程体系的改造越大,学习收获就越大)——消息是否继续传递就看这个Result的更多相关文章

  1. 终于懂了:Delphi消息的Result域出现的原因——要代替回调函数的返回值!(MakeObjectInstance不会帮助处理(接收)消息回调函数的返回值)

    MakeObjectInstance应该不会帮助处理(接收)消息回调函数的返回值,可是有时候又确实需要这个返回值,这可怎么办呢?我是看到这段文字的时候,想到这个问题的: 当WM_PAINT不是由Inv ...

  2. 终于懂了:WM_PAINT中应该用BeginPaint与EndPaint这两个api,它们的功能正是使无效区域恢复(所以WM_PAINT里即使什么都不做,也必须写上BeginPaint与EndPaint)——Delphi里WM_PAINT消息的三个走向都做到了这一点 good

    程序本来是想实现鼠标单击改变背景颜色.可是,程序运行时,为什么没有任何消息触发,背景颜色就一直不断的改变了?WM_PAINT怎么被触发的 #include <windows.h> #inc ...

  3. Expo大作战(十四)--expo中消息推送的实现

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  4. rabbitmq学习(九) —— 关于消息队列的选型

    转自http://cmsblogs.com/?p=3846 在IM这种讲究高并发.高消息吞吐的互联网场景下,MQ消息中间件是个很重要的基础设施,它在IM系统的服务端架构中担当消息中转.消息削峰.消息交 ...

  5. ActiveMQ学习总结(8)——消息队列设计精要

    消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一. 当今市面上有很多主流的消息中间件,如老牌的Activ ...

  6. kafka学习笔记(一)消息队列和kafka入门

    概述 学习和使用kafka不知不觉已经将近5年了,觉得应该总结整理一下之前的知识更好,所以决定写一系列kafka学习笔记,在总结的基础上希望自己的知识更上一层楼.写的不对的地方请大家不吝指正,感激万分 ...

  7. 学习ActiveMQ(八):activemq消息的持久化

    1. 持久化方式介绍前面我们也简单提到了activemq提供的插件式的消息存储,在这里再提一下,主要有以下几种方式: AMQ消息存储-基于文件的存储方式,是activemq开始的版本默认的消息存储方式 ...

  8. 从零开始一起学习SLAM | 理解图优化,一步步带你看懂g2o代码

    首发于公众号:计算机视觉life 旗下知识星球「从零开始学习SLAM」 这可能是最清晰讲解g2o代码框架的文章 理解图优化,一步步带你看懂g2o框架 小白:师兄师兄,最近我在看SLAM的优化算法,有种 ...

  9. Win32汇编学习(6):键盘输入消息

    这次,我们将要学习WINDOWS程序是如何处理键盘消息的. 理论: 因为大多数的PC只有一个键盘,所以所有运行中的WINDOWS程序必须共用它.WINDOWS 将负责把击键消息送到具有输入焦点的那个应 ...

随机推荐

  1. 关于Ubuntu12.04下code::blocks不能使用debug解决方法

    问题描述:   系统:ubuntu 12.04   code::blocks版本:10.05   问题现象:debug->start        之后出现:warning: GDB: Fail ...

  2. 设计模式总结4--singleton pattern

    单例模式 保证每个类只有一个实例,并提供一个全局访问点 第一步 构造方法私有化第二步 公有化静态方法获取的实例 懒汉式  public class Bank{ private Bank(){} pri ...

  3. C 语言中的变量为什么不能以数字打头

    C 语言中的变量为什么不能以数字打头? C 语言中的变量为什么不能以数字打头? 不要告诉我编译原理书上有.我暂时看不懂. 除了下面的解释外, “假如变量名允许以数字开头的话,那么语法分析器在解析一个全 ...

  4. android软键盘enter键

    enter键,回车键,电脑键盘上enter键就有多种响应.android软键盘也不例外 你在EditText上输入以后,想在下一行输入框输入,可能需要去点击下一行输入框,让它获取焦点,也可能要隐藏软键 ...

  5. BitNami Redmine Stack

    BitNami Redmine Stack 是打包了 Redmine 的一键安装程序包,包括:Apache, MySQL, Ruby On Rails, and Subversion Redmine ...

  6. C++之字符串分割函数split

    c++之字符串分割: /* *c++之字符串分割: */ #include <iostream> #include <string> #include <vector&g ...

  7. TCP/IP之TCP连接的建立与中止状态分析

    TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做四次握手. 1.连接的建立: c端发起请求同步(用SYN段等于1的TCP报文),确认某个端口是否监听: s端应答(用ACK段等于1的TCP ...

  8. c# .net 读取json 字符串 与序列化和反序列化json字符串

    命名空间 using Newtonsoft.Json.Linq; JObject obj = JObject.Parse("json字符串");用 obj["" ...

  9. SGU 183. Painting the balls( dp )

    dp..dp(i, j)表示画两个点为i-j, i的最优答案. dp(i, j) = min{ dp(i-j, k) } + cost[i] (1≤k≤M-j) 令f(i, j) = min{dp(i ...

  10. Sprintf()的思考和引出的相关问题

    Sprintf()为什么不安全? 功能 把格式化的数据写入某个 字符串 缓冲区. 头文件 stdio.h 原型 int sprintf( char *buffer, const char *forma ...