Delphi中对消息的处理

来源:互联网 发布:上海软件培训 编辑:程序博客网 时间:2024/05/16 00:36
 在Delphi中处理Windows预定义的消息通常叫覆盖消息,另一类是自定义消息。Windows在消息处理过程中为每一个消息确定了一个消息索引号,其范围是1~49151。Windows保留了1~1024范围。所以,覆盖消息的索引号在1~1024范围内,而自定义的消息就不要与预定义的消息发生冲突。下面对两类消息的处理方法做一说明。
2.1 覆盖消息
覆盖消息是将Windows预定义的消息进行覆盖。覆盖消息的原理是通过给新的消息处理方法赋予原消息索引号。这样,当某个事件产生消息的发生事件时,根据其索引号得到新的消息处理方法。覆盖消息的处理步骤:
1)确定所需处理的消息
确定消息是确定覆盖的系统消息,不同的事件有不同的消息,例如:鼠标单击窗口中的标题栏(窗口中的蓝色彩条)所产生的消息是WM_SYSCOMMAND。
2)在程序中声明所处理的消息(覆盖原消息)
在派生类的protected部分声明消息处理方法,此方法必须是过程:例如:
Procedure mymessage(var msg:Tmessage);
message WM_messageindex;
在protected中声明主要是在该类的封装时将其私有化(只允许该类使用),mymessage为此消息的过程名,用关键字message将WM_messageindex的索引号分配给mymessage,即覆盖WM_messageindex消息。WM_messageindex可以是前面提到的WM_SYSCOMMAND消息。
3)编写消息处理过程
在程序的implementation部分编写消息的实现代码。具体如下:
Procedure mymessage(var msg:Tmessage);
Begin
//所要执行的具体内容。
End;
2.2 自定义消息
自定义消息是声明Windows没有预定义的消息,因为不是预定义的消息,所以要编写程序,发送消息。而且用户可以定义一些本消息自带的参数。通过自定义消息,作者可以编写具有特色的应用程序。
自定义消息的步骤:
1)声明消息的索引号
前面已经提到了消息索引号的范围以及分配情况。在Delphi中常量WM_USER=1024可以用做自定义消息索引号的起始值,如:
const
WM_mymessage=WM_USER+100;
但要注意的是一些Windows的标准组件已经占用了1024以外的索引号,为了避免这样的冲突,在Delphi中有另处一个常量WM_APP=32768,建议自定义消息的索引号以WM_APP为起点
,如:
const
WM_mymessage=WM_APP+100
2)定义消息记录类型
在定义完消息的索引号后,还需要定义消息的记录类型。消息记录类型是传送给消息处理方法的参数结构类型。整个消息记录类型共128bits。定义消息记录类型时记录大小不能超出此范围。下面是一个消息记录类型的例子:
Type
TWMmymessage=record
Msg:Cardinal;//该记录对应的消息。
Name:DWORD;//对应参数wParam
Time:DWORD;//对应参数1Param;
Result:Longint;
end;
3)在程序中声明所处理的消息
声明消息的方法和声明覆盖消息的方法是相同的,使用规则也是一样的。
4)编写消息处理过程
和前面提到的覆盖消息处理过程方法一样,可以参考前面的例子进行编写。
5)发送自定义消息
自定义消息不是通过系统发生的某一件事所产生,而是需要我们自己发送到消息队列中。这就涉及到消息的发送问题,在用户发送消息时可以使用下面两个Windows的API函数:
① LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM 1Param);
② BOOL PostMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM 1Param);
3. 应用程序设计

3.1 程序实例
下面是该程序的部分代码:
unit Unit1;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,
shellapi,StdCtrls;//因为要用到Windows//API函数所以在此声明Shellapi
//定义消息索引号
const
WM_mymessage=WM_USER+100;
//定义消息类型
Type
TWMmymessage=record
Msg:Cardinal;//该记录对应的消息。
Name:DWORD;//对应参数wParam
Time:DWORD;//对应参数1Param;
Result:Longint;
end;
type
TForm1=class(TForm)
Label1:TLabel;
label2:TLabel;
wp:TLabel;
lp:TLabel;
Button1:TButton;
Button2:TButton;
Edit1:TEdit;
Edit2:TEdit;
Procedure Button1Click(Sender:TObject);
Procedure Button2Click(Sender:TObject);
private
{Private declarations}
procedure mytitlemessage(var msg:TWmsyscommand);message
WM_SYSCOMMAND;
Procedure myownermessage(var msg:tWMmymessage);message
WM_mymessage);message
WM_mymessage;
public
{Public declarations}
end;
var
Form1:TForm1;
implementation
{R*.DFM}
//覆盖消息的处理过程
procedure Tform1.mytitlemessage(var msg:TWmsyscommand);
begin
//得到消息的参数
case msg.CmdType of
SC_CLOSE:showmessage (您单击了关闭按扭);//按了关闭按扭
SC_MAXIMIZE:showmessage (您单击了最大化按扭);//按了最大化按扭
SC_MINIMIZE:showmessage (您单击了最小化按扭);//按了最小化按扭
end;
inherited;
end;
//自定义消息处理
procedure Tform1.myownermessage(var msg:TWMmymessage);
begin
//得到消息的参数
wp.Caption:=inttostr(msg.name);
lp.caption:=inttostr(msg.time);
end;
//用sendmessage函数发送消息
procedure TForm1.Button1Click(Sender:TObject);
var
hwn:hwnd;
begin
//得到当前窗口的句柄
hwn:=findwindow(`tform1',`消息处理');
//其中edit1.text、edit2.text为所要传递
//消息的参数
Sendmessage(hwn,cardinal(WM_mymessage),
strtoint(edit1.text),strtoint(edit2.text);
end;
//用postmessage函数传递消息
procedure Tform1.Button2Click(Sender:TObject);
var
hwn:hwnd;
begin
//得到当前窗口的句柄
hwn:=findwindow('tform1','消息处理');
//其中edit1.text、edit2.text为所要传递//消息的参数
postmessage(hwn,cardinal(WM_mymessage)),
strtoint(edit1.text),strtoint(edit2.text);
end;
end.
原创粉丝点击