You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求TFDQuery原生TComponentEditor的类名与所在单元

自定义TFDQuery右键菜单保留原生编辑器功能的解决方法

我给自定义TFDQuery的右键菜单添加新选项时,按照常规方法实现自定义TComponentEditor后,发现原有Fields Editor、Query Editor等功能都无法访问了——因为自定义编辑器完全替换了TFDQuery的原生编辑器。我推测应该从FireDAC的原生TComponentEditor继承来扩展,但找不到原生编辑器的类和所在单元。后来通过代码获取到原生编辑器是FireDAC.dcl.Reg单元的TFDQueryEditor,但既没有这个单元的源码,也找不到FireDAC源码里的相关引用。

获取编辑器信息的代码

constructor TKpQuery.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  ShowMessage(  (GetComponentEditor(Self, NIL) as TObject).ClassName  );
  ShowMessage(  (GetComponentEditor(Self, NIL) as TObject).UnitName  );
end;

原自定义ComponentEditor代码

interface

uses System.Classes, DesignIntf, DesignEditors, FireDAC.Comp.Client;

type
{$REGION 'TKpQuery Editor Declaration'}
  TKpQueryEditor=class(TComponentEditor)
    function GetVerbCount: Integer; override;
    function GetVerb(Index: Integer): string; override;
    procedure ExecuteVerb(Index: Integer); override;
  end;
{$ENDREGION}

{$REGION 'TKpQuery Declaration'}
  ...
  ...
{$ENDREGION}

procedure Register;

implementation

uses
  Data.DB,
  System.Types,
  System.SysUtils,
  System.StrUtils,
  System.RegularExpressions;

procedure Register;
begin
  {$IFDEF WIN32}
  RegisterComponents('My Custom Data Access', [TKpQuery]);
  RegisterComponentEditor(TKpQuery, TKpQueryEditor);
  {$ENDIF}
end;

{$REGION 'TKpQuery Editor Implementation'}
procedure TKpQueryEditor.ExecuteVerb(Index: Integer);
begin
  inherited;
  case Index of
    0: (Component as TKpQuery).SetDisplayLabels;  
  end;
end;

function TKpQueryEditor.GetVerb(Index: Integer): string;
begin
  case Index of
    0: Result := 'Set DisplayLabels';  
  end;
end;

function TKpQueryEditor.GetVerbCount: Integer;
begin
  Result := 1;   
end;
{$ENDREGION}

解决方法

不需要直接继承FireDAC的私有编辑器类,而是通过委托原生编辑器的方式来扩展功能:

  1. 在自定义编辑器中保存原生编辑器的实例
  2. 重写GetVerbCount时,将自定义选项数量加上原生编辑器的动词数量
  3. 重写GetVerb时,索引小于自定义数量返回自定义动词,否则返回原生编辑器对应索引的动词
  4. 重写ExecuteVerb时,同理处理执行逻辑
  5. 重写Edit方法,调用原生编辑器的Edit方法以保留原有的编辑窗口

修改后的自定义编辑器代码示例:

interface

uses System.Classes, DesignIntf, DesignEditors, FireDAC.Comp.Client;

type
  TKpQueryEditor=class(TComponentEditor)
  private
    FOriginalEditor: TComponentEditor;
  public
    constructor Create(AComponent: TComponent; ADesigner: IDesigner); override;
    destructor Destroy; override;
    function GetVerbCount: Integer; override;
    function GetVerb(Index: Integer): string; override;
    procedure ExecuteVerb(Index: Integer); override;
    procedure Edit; override;
  end;

implementation

uses
  Data.DB, System.Types, System.SysUtils;

constructor TKpQueryEditor.Create(AComponent: TComponent; ADesigner: IDesigner);
begin
  inherited;
  // 创建原生编辑器实例
  FOriginalEditor := GetComponentEditor(AComponent, ADesigner) as TComponentEditor;
  if FOriginalEditor = nil then
    FOriginalEditor := inherited Create(AComponent, ADesigner);
end;

destructor TKpQueryEditor.Destroy;
begin
  FOriginalEditor.Free;
  inherited;
end;

function TKpQueryEditor.GetVerbCount: Integer;
begin
  // 自定义动词数 + 原生编辑器动词数
  Result := 1 + FOriginalEditor.GetVerbCount;
end;

function TKpQueryEditor.GetVerb(Index: Integer): string;
begin
  if Index = 0 then
    Result := 'Set DisplayLabels'
  else
    // 索引偏移,调用原生编辑器的GetVerb
    Result := FOriginalEditor.GetVerb(Index - 1);
end;

procedure TKpQueryEditor.ExecuteVerb(Index: Integer);
begin
  if Index = 0 then
    (Component as TKpQuery).SetDisplayLabels
  else
    // 索引偏移,调用原生编辑器的ExecuteVerb
    FOriginalEditor.ExecuteVerb(Index - 1);
end;

procedure TKpQueryEditor.Edit;
begin
  // 调用原生编辑器的Edit方法,保留原有的编辑功能
  FOriginalEditor.Edit;
end;

内容的提问来源于stack exchange,提问作者Marc Guillot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:05:13