DELPHI中的消息处理机制


======================================================
注:本文源代码点此下载
======================================================

delphi中的消息处理机制

delphi是borland公司提供的一种全新的windows编程开发工具.由于它采用了具有弹性的和可重用的面向对象pascal(object-oriented pascal)语言,并有强大的数据库引擎(bde),快速的代码编译器,同时又提供了众多出色的构件.受到广大编程人员的青睐.在众多的编程语言(如vb,powerbuilder,powerpoint等)中脱颖而出.

其中一个delphi强于其他编程语言(如vb4.0)的地方就是在delphi中可自定义消息,并可直接处理消息.这对于那些希望编写自己的构件(component),或者希望截获.过滤消息的用户来说是必不可少的.因为编写构件一般要对相应的消息进行处理.下面就对delphi中消息处理机制进行一下介绍。

一.delphivcl中消息的传递

delphi中每一个vcl(visual component library)构件(如tbutton,tedit等)都有一内在的消息处理机制,其基本点就是构件类接收到某些消息并把它们发送给适当的处理方法,如果没有特定的处理方法,则调用缺省的消息处理句柄。

其中mainwndproc是定义在twincontrol类中的一个静态方法,不能被重载(override)。它不直接处理消息,而是交由wndproc方法处理,并为wndproc方法提供一个异常处理模块。mainwndproc方法声明如下:

procedure mainwndproc(var message: tmessage);

wndproc是在tcontrol类中定义的一个虚拟方法,由它调用dispatch方法来进行消息的分配,wndproc方法声明如下:

procedure wndproc(var message: tmessage); virtual;

dispatch方法是在tobject根类中定义的,其声明如下:

procedure tobject.dispatch(var message);传递给dispatch的消息参数必须是一个记录类型,且这个记录中第一个入点必须是一个cardinal类型的域(field),它包含了要分配的消息的消息号码.例如:

type

tmessage=record

msg:cardinal;

wparam:word;

lparam:longint; .

result:longint;

end;

而dispatch方法会根据消息号码调用构件的最后代类中处理此消息的句柄方法.如果此构件和它的祖先类中都没有对应此消息的处理句柄,dispatch方法便会调用defaulthandler方法.defaulthandler方法是定义于tobject中的虚拟方法,其声明如下:

procedure defaulthandler(var message);virtual;

tobject类中的defaulthandler方法只是实现简单的返回而不对消息进行任何的处理.我们可以通过对此虚拟方法的重载,在子类中实现对消息的缺省处理.对于vcl中的构件而言,其defaulthandler方法会启动windowsapi函数defwindowproc对消息进行处理.

二.delphi中的消息处理句柄

在delphi中用户可以自定义消息及消息处理句柄.消息处理句柄的定义有如下几个原则:

消息处理句柄方法必须是一个过程,且只能传递一个tmessage型变量参数.

方法声明后要有一个message命令,后接一个在0到32767之间的消息标号(整型常数).

消息处理句柄方法不需要用override命令来显式指明重载祖先的一个消息处理句柄,另外它一般声明在构件的protected或private区.

在消息处理句柄中一般先是用户自己对消息的处理,最后用inherited命令调用祖先类中对应此消息的处理句柄(有些情况下可能正相反).由于可能对祖先类中对此消息的处理句柄的名字和参数类型不清楚,而调用命令inherited可以避免此麻烦,同样如果祖先类中没有对应此消息的处理句柄,inherited就会自动调用defaulthandler方法.(当然如果要屏蔽掉此消息,就不用inherited命令了)。

消息处理句柄方法声明为:

procedure mymsgmethod(var message:tmessage); message msgtype;

同样用户也可以定义自己的消息,用户自定义消息应从wm_user开始.

自定义消息及消息处理句柄举例如下:

const my_paint=wm_user+1;

type

tmypaint=record

msgid:cardinal;

msize:word;

mcolor:longint;

msgresult:longint;

end;

type

tmycontrol=class(tcustomcontrol)

protected

procedure change(var message:tmypaint); message my_paint;

.....

end;

......

procedure tmycontrol.change(var message:tmypaint);

begin

size:=message.msize;{设置tmybutton尺寸属性}

color:=message.mcolor;{设置tmybutton颜色属性}

{do something else}

inherited; { 交 由tcustomcontrol 处 理}

end;

三.过滤消息

过滤消息又称消息陷阱。在一定情况下,用户可能需要屏蔽某些消息.或者截获某些消息进行处理。由以上介绍可以看出过滤消息一般有三种途径:(1).重载构件继承的虚拟方法wndproc.(2).针对某

消息编写消息处理句柄.(3).重载构件继承的虚拟方法defhandler,在其中对消息进行处理。其中常用的方法是方法(2),在上节中已介绍过了,方法(1)与方法(3)相似,这里只简单介绍一下方法(1)。

重 载 虚 拟 方 法wndproc 的 一 般 过 程 如 下:

procedure tmyobject.wndproc(var message:tmessage);

begin

{...判断此消息是否该处理..}

inheritedwndproc(message);

{未处理的消息交由父辈wndproc方法处理}

end;

由此可以看出在wndproc方法中处理消息的优势是可以过滤整个范围内的消息,而不必为每个消息指定一个处理句柄,事实上tcontrol构件中就是利用它来过滤并处理所有的鼠标消息的(从wm_mousefirst到wm_mouselast,如下代码示).同样利用它也可以阻止某些消息被发送给处理句柄。

procedure tcontrol.wndproc(var message: tmessage);

begin

if (message.msg>=wm_mousefirst) and (message.msg 关注我收藏该文与我联系


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值