VCl中的类型定义:
TTVChangingEvent = procedure(Sender: TObject; Node: TTreeNode;
var AllowChange: Boolean) of object;
首先说说 VCL 的 TTreeView 类的继承架构,看看VCL源代码,TTreeView只定义了一
些Published属性,而 TTreeView = class(TCustomTreeView),TTreeView是继承自
TCustomTreeView的,而 TCustomTreeView 里面并没有定义 Changing 方法,所以,
你直接 override 当然就会提示“Method 'Changing' not found in base class”
(TTreeView和基类TCustomTreeView都没有次方法)。再看看在 TCustomTreeView里,
OnChanging属性是怎么访问的:
OnChanging定义为一个 TTVChangingEvent 类型的属性,联系着私有成员 FOnChanging:
property OnChanging: TTVChangingEvent read FOnChanging write FOnChanging;
而在这个类的消息处理流程里,真正对FOnChanging 成员进行操作的方法是动态方法(函
数)CanChange:function CanChange(Node: TTreeNode): Boolean; dynamic;实现如下:
function TCustomTreeView.CanChange(Node: TTreeNode): Boolean;
begin
Result := True;
if Assigned(FOnChanging) then FOnChanging(Self, Node, Result);
end;
也就是处理消息过程中,当调用到CanChange动态方法处理消息时,实际上先判断
FOnChanging成员有没有被赋值(if Assigned(FOnChanging),就是FOnChanging成员有没
有挂上编程者自己编写的事件处理函数的函数指针),如果有,则通过FOnChanging保存的
函数指针访问到事件处理函数,在这里,VCL架构为FOnChanging指定属性OnChanging进行
读写,在可视化编程时,编程者双击对象查看器并定义下面的方法
procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
var AllowChange: Boolean);
begin
......
end;
架构实际上将此过程挂上了OnChanging(也就对FOnChanging赋了值):
OnChanging = TreeView1Changing
这样也方便了程序员编写程序(只需双击对象查看器中的方法并进行定义就行了)。
所以,你所谓要“重新定义OnChanging事件”,实际上
1)可以自己另写一个函数(与TTVChangingEvent兼容的方法),比如
procedure MyOnChanging(Sender: TObject; Node: TTreeNode;
var llowChange:Boolean);
begin
....//do something
end;
然后在适当时候将此方法赋值给OnChanging(或FOnChanging):
OnChanging :=MyOnChanging;
2)可以直接在VCL提供的方法中写处理过程:
procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
var AllowChange: Boolean);
begin
....//do something
end;
3)对应的,改写消息处理流程中的消息处理函数 CanChange :
function CanChange(Node: TTreeNode): Boolean; override; 实现之:
function TCustomTreeView.CanChange(Node: TTreeNode): Boolean;
begin
Result := True;
//if Assigned(FOnChanging) then FOnChanging(Self, Node, Result); 去掉此句
....do something
end;
一些想法,仅供参考。