深入理解Delphi的消息机制

http://tech.ddvip.com   2006年07月31日    社区交流

本文详细介绍深入理解Delphi的消息机制

  鼠标在 Form 上点击,产生两个消息 WM_LBUTTONDOWN/WM_LBUTTONUP,但我们只截获 WM_LBUTTONDOWN。产生的 WM_LBUTTONDOWN 经过一系列的消息传递到达 TObject.Dispatch,通过查询动态方法表在 TForm 的父类 TControl 中找到了 Handler -- TControl.WMLButtonDown,在 TControl.WMLButtonDown 中又经过 TControl.DoMouseDown、TControl.MouseDown 一系列方法调用,最终调用到 FOnMouseDown,FOnMouseDown 被赋值为 TForm1.FormMouseDown,调用 FOnMouseDown 即调用 TForm1.FormMouseDown。

  讲了一大堆消息实现过程,那么在实际中到底有哪些应用?

  四、消息的实际应用

  如果你是共享软件作者,经常会为你的软件被 Crack 掉所烦恼,你能做的就是要加强你的软件的 Anti-Crack 功能,今天就交你一招。

  如果你用过 Delphi 的专用反汇编工具 DEDE,那么你肯定知道像 Button1Click 这种 Event Handler 的方法入口地址 极容易被定位,其原理是根据TForm 的 RTTI 信息获取的(通过分析 dfm 资源文件就可以获得地址),其实 VCL 窗体只有 published 过的类成员才会生成 RTTI 信息。知道这个关键点加上对 VCL 消息机制的深入了解你就可以防止这一切发生。

  1. Anti-Crack

  新建一个 Application,在 Form1 上放两个 Button,命名为 btnRegister、btnCancel,双击这两个按钮,分别生成TForm1.btnCancelClick、TForm1.btnRegisterClick 两个 Event Handler 骨架代码,然后在对象查看器中取消 btnRegister.OnClick 与 TForm1.btnRegisterClick 的关联, 随后将 TForm1.btnCancelClick 的声明放入 TForms1 声明的 private 区段。再按照下面的代码 内容加入其他部分:

  unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btnRegister: TButton;
btnCancel: TButton;
procedure btnCancelClick(Sender: TObject);
private
procedure btnRegisterClick(Sender: TObject);
procedure WMCommand(var Message: TWMCommand); message WM_COMMAND;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnCancelClick(Sender: TObject);
begin
Close;
end;
procedure TForm1.btnRegisterClick(Sender: TObject);
begin
ShowMessage('Thx for ur registration.');
end;
procedure TForm1.WMCommand(var Message: TWMCommand);
begin
if Message.NotifyCode = BN_CLICKED then
if FindControl(Message.Ctl) = btnRegister then
begin
btnRegisterClick(Self);
Exit;
end;
inherited;
end;
end.

  这个方法的本质就是截获 TForm1 的 WM_COMMAND 消息并自己处理,请自行分析代码,我就不多说了。编译完后你可以用 DEDE 反汇编一下,看看还能不能那么容易地找到 TForm1.btnRegisterClick 的入口地址。

  结束语

  VCL 消息机制你理解了吗?是不是感到特别复杂?一个消息往往要经过10几个方法才能传到 Event Handler,别看消息传递经过这么漫长的路途,但是 VCL 消息机制的效率还是非常高的,因为很多关键的代码都是用汇编直接写成的,每一个中途站花费的时间也非常少,因此需要处理的消息还是能很快地到达目的地。

  我最开始学 Windows 编程是从 SDK 开始学起的,那时候会写了基本的 Windows 程序,一段时间内总认为会 SDK 比会用 Delphi 牛X,现在想起来真傻,比起直来直去的 SDK 编程,VCL 消息机制要复杂得多得多,看完 VCL 源码后最大感受就是觉得以前跟没学过编程似的,但不可否认的是,只有在你掌握了 OOP/ASM/SDK 这些基础知识后,你才有看懂 VCL 源码的资本,这些基础知识你都掌握了吗?

作者:NoteXPad    责编:豆豆技术应用

正在加载评论...