当前位置:主页>销售管理软件> 列表

如何重定义事件

仓库管理软件版1楼: 比如继承TreeView的控件,我要重新定义OnChanging事件,如何处理,请高手们指点一下!

2楼: OnChanging事件是自己写的呀,VCL只是定义了实现了事件获取的方式而已.是个事件指针而已.
至于你所说的继承,可以通过方法覆盖来实现. 如记账软件

3楼: 大哥,能不能详细一点,最好有一点点代码,求你了!

4楼: 你可以直接给它的事件一个地址,当然最好的方法是在赋值前保存原来的事件处理地址。例如:
if assigned(xxx.OnChanging) then
tmpevent:=xxx.OnChanging
else
tmpevent:=nil;
xxx.OnChanging:=youevent;//youevent就是你的事件处理方法。

procedure xxx.OnChanging;
begin
if assigned(tmpevent) then
tmpevent();
//下面就是你自己的处理方法了
end;

5楼: 对不起,我的基础实在太差,您能不能直接在我的代码上修改,小生感激不尽!

type
TTreeViewCheckBox = class(TTreeView)
private
{ Private declarations }
FOnChanging:TTVChangingEvent;
procedure DoOnChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);


protected
{ Protected declarations }
procedure Changing(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);dynamic;
end;

procedure Register;

implementation
begin
if Assigned(FOnChanging) then
FOnChanging(Sender,Node,AllowChange);
end;
procedure TTreeViewCheckBox.DoOnChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);
var
SQL: string;
ps: integer;
begin
...;
end;

6楼: tmpevent是什么,需要声明吗,第一部分的代码放在哪里呢。教教我吧!:)

仓库管理软件版7楼: 我是直接在一个现成的工程中新建一个Component的,F12也看不到控件界面,麻烦,如果在事件声明后使用OverRide关键字,则提示没有该基类,怎么做啊,大哥!

8楼: http://www.delphibbs.com/keylife/images/u196832/TXTreeView20050805.jpg

9楼: type
TTreeViewCheckBox = class(TTreeView)
private
{ Private declarations }
FOnChanging:TTVChangingEvent;
procedure DoOnChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);
protected


{ Protected declarations }
[red]procedure Changing(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);dynamic;//这不是个保护方法麻?他是动态的,你可以继承下来修改[/red]end;

10楼: type
TXTreeView = class(TTreeView)
private
{ Private declarations }
FChildChecked: Boolean;
FOnChecked: TXTreeViewCheckedEvent;
FOnUnChecked: TXTreeViewCheckedEvent;
function GetChildChecked: Boolean;
procedure SetChildChecked(const Value: Boolean);
protected
{ Protected declarations }
procedure MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); override;
procedure CreateParams(var Params: TCreateParams); override;
[red]procedure Changing(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);override;[/red]
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property XChildChecked: Boolean read GetChildChecked write SetChildChecked;


property OnChecked: TXTreeViewCheckedEvent read FOnChecked write FOnChecked;
property OnUnChecked: TXTreeViewCheckedEvent read FOnUnChecked write FOnUnChecked;
end;


........
[blue]procedure TXTreeView.Changing(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);
begin
//首先做你的处理,do you want to do
//然后调用父类方法触发事件
Inherited Changing(Sender, Node, AllowChange);
end;[/blue]

11楼: 另外,我用的是delphi6.0,这有关系吗?
以下语句:
procedure Changing(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);override;
编译时系统会提示:Method ''Changing'' not found in base class

12楼: 鄙人确实菜,希望大家不会厌烦我和我的问题,再次谢谢大家了! 如仓库管理软件

13楼: 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;

一些想法,仅供参考。

仓库管理软件版14楼: jfyes的代码非常棒,解决了CheckBox的问题,我还以为要加ImageList(我更没有把握),Jonson_sunshine老师的话让我明白了很多原理,非常感谢,能不能有个简单的控件生成的代码,包括能够显示在Object Inspector属性窗口的属性,显示在该属性窗口的自定义Event,类似Changing事件在控件内部可以进行部分预处理的事件,如何生成dpk文件以便安装,免得每次都要打开该文件。对不起要求似乎太高了,不过为了表示我的敬意,我愿意倾囊所有,把剩下的分数送给我的大救星。

15楼: [:D]基本上解决问题了,再次感谢大家,有机会的话希望能够更直接的请教![:D]