终于懂了:Delphi消息的Result完全是生造出来的,不是Windows消息自带的(Delphi对Windows编程体系的改造越大,学习收获就越大)
2016-02-05 22:35
477 查看
Windows中,消息使用统一的结构体(MSG)来存放信息,其中message表明消息的具体的类型,
而wParam,lParam是其最灵活的两个变量,为不同的消息类型时,存放数据的含义也不一样。
time表示产生消息的时间,pt表示产生消息时鼠标的位置。
里面没有Result的选项。然后我用VC2008实测MSG结构的大小:
结果等于28
结果等于4
结果等于4
-------------------------------------------------------------
再来看Delphi里的定义,它也有原模原样的定义,只不过一般情况下用不到:
经过测试,它的大小当然也是28:
再看Delphi真正使用的消息结构,注意它包括了Result:
测试它的大小:
结果等于16
-------------------------------------------------------------
再测试消息本身的大小:
结果等于2
结果等于1
-------------------------------------------------------------
再来看Delphi定义的消息结构体:
测试Delphi消息结构体的大小:
怎么测都是16字节大小。。。
------------------------------------------------------------------------
最后,忽然想起来,Delphi消息结构这个的Result的作用,很像QT里中止信号的Q_UNUSED,例如 :
而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 0: ( WParam: Longint; LParam: Longint; Result: Longint); 1: ( 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字节大小。。。
------------------------------------------------------------------------
最后,忽然想起来,Delphi消息结构这个的Result的作用,很像QT里中止信号的Q_UNUSED,例如 :
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); // ... }
相关文章推荐
- 终于懂了:Delphi重定义消息结构随心所欲,只需要前4个字节是消息编号就行了,跟Windows消息虽然尽量保持一致,但其实相互没有特别大的关系。有了这个,就有了主动,带不带句柄完全看需要。
- WM_PAINT在微软官方定义中,wParam和lParam都没有使用,所以就被Delphi给重定义了这个消息,还增加了DC(Delphi可任意改写消息的结构,只需要保持前4个字节是消息即可,另外要携带微软定义的所有必要信息就行了)
- WM_PAINT中应该用BeginPaint与EndPaint这两个api,它们的功能正是使无效区域恢复(所以WM_PAINT里即使什么都不做,也必须写上BeginPaint与EndPaint)——Delphi里WM_PAINT消息的三个走向都做到了这一点
- Delphi和C++数据类型对照表
- Delphi中如何获得光标
- 利用Delphi编写Socket通信程序
- (delphi)DbgridEh排序
- ListView 百分比进度条(delphi版)
- Delphi的RTTI还分为对类和对象的判断,以及对普通属性的判断——相比之下,C++的RTTI实在太弱!
- 终于懂了:TWinControl主要是Delphi官方用来封装Windows的官方控件,开发者还是应该是有TCustomControl来开发三方控件
- C++能在三个地方创造对象,而Delphi只有一个地方
- delphi 怎么获取工程版本号
- Delphi 10 Seattle不支持intel atom?
- 不是什么时候都可以用栈来声明对象并使用(自动释放)——Delphi里到处都是编译器魔法,并且自动帮助实例化界面元素指针
- Delphi XE7下如何创建一个Android模拟器调试
- DelphiXE Android的所有权限按照分类总结说明
- DelphiXE8怎么使用调试模式(朱建强)
- delphi使用ado连接Excel
- 与java兼容的delphi xe实现des算法单元
- DelphiXE8怎么使用调试模式