附加或挂钩所有组件的事件

时间:2013-12-03 10:37:38

标签: delphi events hook

我有一个小问题。 我需要创建一个组件来捕获特定类型的组件独立建议的一些事件。 示例:每次调用事件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,我打算这样做并实现此组件。

我没有准备好代码,因为我仍然不知道该怎么做!

谢谢。

2 个答案:

答案 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.