定義一個消息需要兩個步驟:
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.運作程式,結果如下所示: