偷梁换柱---事件的替换与还原(100分)

  • 主题发起人 主题发起人 smokingroom
  • 开始时间 开始时间
S

smokingroom

Unregistered / Unconfirmed
GUEST, unregistred user!
你是否为许多控件的事件处理代码相同而烦恼? 虽然有许多方法可以解决代码的重写,比如构建子类,比如窗体继承,比如Frame等等...
以下的代码,从一个简单的实例,来说明了另外一种方法来实现,或许你会不屑一顾,如许你会受益良多...
我觉得该类的名称应该叫事件捕捉器,当然,它只实现了捕捉Click事件,还有其实的事件都可以实现,它的优点,你只要创建一个实例,指定要捕捉的对像就可以了,所指定的对像,它的原有事件处理器不会受到任何影响.

type
TButtonCatcher=class
private
FButton:TButton;
FOnClick:TNotifyEvent;
procedure InternalClick(Sender:TObject);
procedure SetButton(Value: TButton);
public
constructor Create(AButton:TButton);
destructor Destroy;override;
property Button:TButton read FButton write SetButton;
end;

implementation

constructor TButtonCatcher.Create(AButton:TButton);
begin
Button:=AButton;
end;

destructor TButtonCatcher.Destroy;
begin
Button:=nil;
end;

procedure TButtonCatcher.SetButton(Value:TButton);
begin
if Value = FButton then Exit;
if FButton <> nil then
FButton.OnClick:=FOnClick;
if Value <> nil then
begin
if Assigned(Value.OnClick) then
FOnClick:=Value.OnClick
else
FOnClick:=nil;
Value.OnClick:=InternalClick;
end else
begin
FOnClick:=nil;
end;
FButton:=Value;
end;

procedure TButtonCatcher.InternalClick(Sender:TObject);
begin
//特定的处理代码...
if Assigned(FOnClick) then FOnClick(Sender);
end;
 
好像很複雜的....
 
看起来很复杂,其实原理很简单:
将需要捕捉的事件原有的处理器保存(Value.OnClick),再指定特定的事件处理过程(InternalClick),这样,当事件触发后,将进入指定的事件处理过程(InternalClick),指定的处理过程完毕之后,再调用原有的处理过程(Value.OnClick).
 
呵呵,这个方法弊端也很明显
Win9X/2K子类化就是这种方法。而WinXP的子类化已经象一个链表一个,可以随时子类化和撤销子类化。dotNET的事件委托可以有多个处理函数,那才是正途.
 
收藏一下,希望帖子不要沉了。
 
我一般是用变量将事件保存,执行完特定操作后,再将事件恢复,如:
DataSetBeforeScroll:=ADOQuery1.AfterScroll;
。。。你的特定操作
ADOQuery1.AfterScroll:=DataSetBeforeScroll;
 
后退
顶部