定义一个消息需要两个步骤:
1.声明一个消息标识符
2.声明一个消息记录类型
一个消息标识符是一个整数大小的常数。windows自用低于1024的消息,所以当你声明你自己的消息,你应该开始高于这一数字。
常数wm_app代表了用户定义的消息开始编号。当定义消息标识符,你应该基于wm_app它们。(这是因为wm_user所代表1024以后的消息编号,有一些已经被windows标准组件占用了,为了避免冲突,使用wm_app)
如果你想给你的消息一个有用的参数名,你需要声明该消息的消息记录类型。消息记录是传递给消息处理方法的参数类型。如果你不使用消息的参数,或者如果你想使用旧风格的参数表示法(wparam参数,lparam参数,等等),你可以使用默认的消息记录,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;
要声明一个消息记录类型,请按照下列约定:
1.命名消息记录类型,以t开头
2.第一个字段为msg,为对应的消息
3.定义接下来的两个字节对应word参数,接下来的两个字节为未使用。
或
接下来的四个字节定义对应于longint型参数。
4.最后字段添加一个类型为longint型的result。
如delphi源码里面:
twmchartoitem = packed record
key: word;
caretpos: word;
listbox: hwnd;
result: longint;
twmcompacting = packed record
compactratio: longint;
unused: longint;
有不同的方式来发送一个windows消息,经常使用的是sendmessage和postmessage,它们原型如下:
function sendmessage(hwnd: hwnd; msg: uint; wparam: wparam; lparam: lparam): lresult; stdcall;
function postmessage(hwnd: hwnd; msg: uint; wparam: wparam; lparam: lparam): bool; stdcall
其中wparam和lparam都是longint。这两个函数参数一样,返回值不同。sendmessage()返回被处理的消息的结果值,但是postmessage()返回的只是一个布尔值,表示是否该消息被放入到目标窗口队列中。另外一个方面,sendmessage()是同步调用的,postmessage()是异步调用的。
下面一个例子来说明,如何自定义消息。示例功能为应用程序调用计算器类,当计算器类计算完毕,就发带计算结果的消息给应用程序:
1.新建delphi 7应用程序,单击菜单栏→file→new→unit,在弹出的单元文件,输入以下代码:
unit unit2;
interface
uses
classes, windows, messages;
const
wm_calcok = wm_app + 100; //定义消息
type
tcalc = class(tobject)
private
fformhandle: hwnd; //接受者的句柄
fone,fanother: integer;
public
constructor create(ahandle: hwnd;aone,aanother: integer);
procedure startcalc;
implementation
constructor tcalc.create(ahandle: hwnd;aone,aanother: integer);
begin
inherited create;
fformhandle := ahandle;
fone := aone;
fanother := aanother;
end;
procedure tcalc.startcalc;
var
s: string;
s := '计算结果:';
sendmessage(fformhandle,wm_calcok,fone + fanother,longint(s)); //进程内发送字符串
//postmessage(fformhandle,wm_calcok,fone + fanother,0); //不可发送字符串
end.
2.主窗体上放置2个编辑框和一个按钮,主单元文件代码如下:
unit unit1;
windows, messages, sysutils, variants, classes, graphics, controls, forms,
dialogs, stdctrls, unit2;
wm_calcok = wm_app + 100;
tform1 = class(tform)
btn1: tbutton;
edt1: tedit;
edt2: tedit;
procedure btn1click(sender: tobject);
fcalc: tcalc;
procedure calcok( var msg: tmessage); message wm_calcok;
{ public declarations }
form1: tform1;
{$r *.dfm}
procedure tform1.btn1click(sender: tobject);
fcalc := tcalc.create(self.handle,strtoint(edt1.text),strtoint(edt2.text));
try
fcalc.startcalc;
finally
fcalc.free;
procedure tform1.calcok( var msg: tmessage);
showmessage( string(msg.lparam) + inttostr(msg.wparam));
3.运行程序,结果如下所示: