我有一个小问题。 我需要创建一个组件来捕获特定类型的组件独立建议的一些事件。 示例:每次调用事件TIBDatabase时,我需要活动组件(Palette Interbase)在运行事件代码的组件激活之前自动配置组件的某些属性。 是自动执行此操作吗?示例:当我将组件放在表单上时,他会自动连接到事件? 非常感谢你。
注意:我无法重现(How can I dynamically inject code into event handlers in Delphi?)
的例子已编辑:
我正在尝试使用“Ritsaert Hornstra”的例子。接受答案的例子我必须扫描所有组件。
该示例仅在我激活要监视的事件组件时才有效。 示例:当我重现链接的示例不起作用时,“TIBQuery”组件具有“AfterOpen”事件。但是,如果我在组件实例运行中放入该事件中的任何内容。 他没有自动做。 我正在使用Delphi XE3。
已编辑2:
嗨Craig Young。 今天我有几个系统在积极生产。 我想要做的是实现在开发系统时没有完成的安全日志。 这将是Hercules的第13次劳动,在所有这些中手动完成。 我需要做什么。 当数据模块中的adiconado挂钩/附加InterBase数据库组件的某些事件时的组件。 我只需要一个有效的例子让我做其余的事情。我只想知道在完成任务时做了什么以及做了什么变量系统:g_s_user,g_s_date,g_s_sql。 由于几乎所有组件都连接到TDataset,我打算这样做并实现此组件。
我没有准备好代码,因为我仍然不知道该怎么做!
谢谢。
答案 0 :(得分:1)
在Delphi中添加事件处理程序programaticaly并不难。例如,假设您要添加一个事件处理程序来响应BeforeDelete
事件。你这样做:
interface
type
TMyDatasetHook = class
protected
TargetDataset: TDataset;
PreviousBeforeDelete: TDataSetNotifyEvent;
procedure DatasetBeforeDelete(aSender: TObject);
procedure CleanupHooks(aDataset: TDataset);
procedure SetupHooks(aDataset: TDataset);
public
constructor Create(aDataset: TDataset);
destructor Destroy; override;
end;
implementation
constructor TMyDatasetHook.Create(aDataset: TDataset);
begin
TargetDataset := aDataset;
SetupHooks(TargetDataset);
end;
destructor TMyDatasetHook.Destroy;
begin
CleanUpDataset(TargetDataset);
inherited;
end;
procedure TMyDatasetHook.DatasetBeforeDelete(aSender: TObject);
begin
// Here goes your code to handler BeforeDelete
if Assigned(PreviousBeforeDelete) then
PreviousBeforeDelete(aSender); // Here we call the existing handler
end;
procedure TMyDatasetHook.CleanupHooks(aDataset: TDataset);
begin
aDataset.BeforeDelete := PreviousBeforeDelete;
end;
procedure TMyDatasetHook.SetupHooks(aDataset: TDataset);
begin
PreviousBeforeDelete := aDataset.BeforeDelete; // Here we save the existing handler
aDataset.BeforeDelete := DatasetBeforeDelete;
end;
您现在需要做的是实例化该类将目标数据集传递给其构造函数
var
myDatasetHook: TMyDatasetHook;
begin
myDatasetHook := TMyDatasetHook.Create(someTargetDataset);
end;
您现在需要的是调整上述课程以满足您的特定需求。
答案 1 :(得分:0)
AlexSC
老兄,谢谢你的回复。 我实际上已经解决了这个问题。它不漂亮。但它奏效了。 很高兴知道有像你这样的人愿意提供帮助并提出建设性意见。与我们高贵的朋友克雷格不同。除了没有帮助我的问题变得消极。 如果我来到stackoverflow,因为我真的很难做到。想象一下解释我想要的东西。但那没关系。我非常感谢所有以某种方式帮助我解决问题的人。 关于你AlexSC我会发布我做过的事情: PS:我会冒昧地用示例来增强我的代码吗?
unit Sample;
interface
uses
System.SysUtils, System.Classes, Dialogs, IBDatabase, Data.DB, System.Win.Registry, Winapi.Windows;
type
TSample = class(TComponent)
private
FBanco: TIBDatabase;
FDataSet: TDataSet;
L_FBeforeScroll: TDataSetNotifyEvent;
L_FBeforeRefresh: TDataSetNotifyEvent;
Procedure OnRefresh(DataSet: TDataSet);
Procedure OnScroll(DataSet: TDataSet);
Procedure SetBanco(Value: TIBDatabase);
public
{ Public declarations }
constructor Create(AOwner : TComponent); override;
destructor Destroy;override;
published
{ Published declarations }
property Database: TIBDatabase read FBanco write SetBanco;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('DataXML', [TSample]);
end;
constructor TSample.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TSample.Destroy;
begin
inherited;
end;
procedure TSample.OnRefresh(DataSet: TDataSet);
begin
if Assigned(L_FBeforeRefresh) then
L_FBeforeRefresh(FDataSet);
end;
procedure TSample.OnScroll(DataSet: TDataSet);
begin
if Assigned(L_FBeforeScroll) then
L_FBeforeScroll(FDataSet);
end;
procedure TSample.SetBanco(Value: TIBDatabase);
begin
FBanco := Value;
FDataSet := FBanco.DataSets[0];
L_FBeforeScroll := FDataSet.BeforeScroll;
L_FBeforeRefresh := FDataSet.BeforeScroll;
FDataSet.BeforeScroll:=OnScroll;
FDataSet.BeforeScroll:=OnRefresh;
end;
end.