我可以在Firemonkey中为组件添加第二个组件编辑器吗?

问题描述 投票:0回答:1

Delphi IDE有一个TLang组件的组件编辑器(Language Designer),我为TLang写了一个自定义组件编辑器,以帮助完成本地化任务。我在设计时间包中注册了它。

  RegisterComponentEditor(TLang, TMyLangComponentEditor);

这样就可以工作了。现在,当我双击该组件时,我得到了华丽的组件编辑器。但它隐藏了原来的TLang编辑器。如何才能在右键菜单中同时访问两个编辑器?

例如:在我的组件编辑器中,我有。

function TMyLangComponentEditor.GetVerb(Index: Integer): string;
begin
  case Index of
    0: Result := '&Show IDE Lang Designer';
    1: Result := '&Show My Lang Editor';
  else
    raise ENotImplemented.Create('verb not supported');
  end;
end;

procedure TMyLangComponentEditor.ExecuteVerb(Index: Integer);
begin
  case Index of
    0: ;                //  <---  what goes here to open the IDE Language designer ?
    1: ShowMyLangForm;
  else
    raise ENotImplemented.Create('verb not supported.');
  end;
end;

我怕注册一个新的组件编辑器后,旧的编辑器丢失了... ...

delphi localization firemonkey
1个回答
0
投票

经过一些实验,我发现了这个。

创建一个现有的ComponentEditor(TFDQuery)的后裔。

这对我来说是可行的。但我不得不调整代码,因为IDE TLang组件编辑器没有实现动词,所以调用ExecuteVerb(0)无法工作。但它确实实现了编辑方法。

感谢Uwe Raabe指出的解决方案。

这是代码。

unit LangToolEditor; // LangTool alternative TLang component editor

interface

uses
  System.SysUtils,System.UITypes,System.Classes,
  FMX.Dialogs,
  FMX.Types,     // TLang
  DesignEditors,
  DesignIntf;

type
  TLangToolComponentEditor = class(TComponentEditor)
  private
    fOldEditor: TComponentEditor;
    procedure ShowLangToolForm;
  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;
  end;

procedure Register;

implementation  //---------------------------------

uses
  fTLangTool; //  TFormTLangTool  - LangTool editor form

// see https://stackoverflow.com/questions/33547929/create-a-descendant-of-a-existing-componenteditor-tfdquery
VAR
  PrevEditorClass:TComponentEditorClass=NIL;   //save class of original IDE TLang Editor

constructor TLangToolComponentEditor.Create(AComponent: TComponent; ADesigner: IDesigner);
begin
  inherited Create(AComponent, ADesigner);

  IF Assigned(PrevEditorClass) THEN BEGIN  //must be
    fOldEditor := TComponentEditor(PrevEditorClass.Create(AComponent, ADesigner));
  END;
end;

destructor TLangToolComponentEditor.Destroy;
begin
  inherited;
end;

function TLangToolComponentEditor.GetVerbCount: Integer;
begin
  Result := 2;
end;

function TLangToolComponentEditor.GetVerb(Index: Integer): string;
begin
  case Index of
    0: Result := 'Show &LangTool Editor..';
    1: IF Assigned(fOldEditor) THEN Result := 'Show IDE Lang Designer..'
         else Result := 'Old editor not found';
  end;
end;

procedure TLangToolComponentEditor.ExecuteVerb(Index: Integer);
begin
  case Index of
    0: ShowLangToolForm;
    1: IF Assigned(FOldEditor) THEN FOldEditor.Edit
       else MessageDlg('Old editor not found', TMsgDlgType.mtInformation,
         [TMsgDlgBtn.mbOk], 0);
  end;
end;

procedure AssignTLang(aLangSrc,aLangDest:TLang);  // TLang --> TLang    same as aLangDest.Assign(aLangSrc)
var i:integer; aLang:String; aStrs1,aStrs2:TStrings;
begin
  aLangDest.Lang := aLangSrc.Lang;  //original
  aLangDest.Original.Assign(aLangSrc.Original); //ok
  // TODO: dispose Resources?
  aLangDest.Resources.Clear;
  for i:= 0 to aLangSrc.Resources.Count-1 do
    begin
      aLang  := aLangSrc.Resources.Strings[i];
      aStrs1 := TStrings(aLangSrc.Resources.Objects[i]);
      aLangDest.AddLang(aLang);
      aStrs2 := aLangDest.LangStr[aLang];  //get access to strings
      aStrs2.Assign(aStrs1);              //copy strings
    end;
end;

procedure TLangToolComponentEditor.ShowLangToolForm;
var  DesignerForm: TFormTLangTool; aLangSrc,aLangDest:TLang;
begin
  DesignerForm := TFormTLangTool.Create(nil);
  try
    // Set curent value to designer form
    aLangSrc  := (Component as TLang);
    aLangDest := DesignerForm.Lang1;
    AssignTLang(aLangSrc,aLangDest);         // Componemnt --> LangTool.Lang1
    DesignerForm.populateGridWithLanguages;  // Lang1 --> grid
    // Show ModalForm, and then take result
    if DesignerForm.ShowModal = mrOK then     // modal
      begin
        DesignerForm.copyGridToLang1;
        aLangSrc := DesignerForm.Lang1;
        aLangDest:= (Component as TLang);
        AssignTLang(aLangSrc,aLangDest);         // as in aLangDest.Assign( aLangSrc );
      end;
    Designer.Modified;
  finally
    DesignerForm.Free;
  end;
end;

procedure Register;
VAR
  aLang: TLang;
  Editor: IComponentEditor;
BEGIN
  aLang := TLang.Create(NIL);
  TRY
    Editor := GetComponentEditor(aLang, NIL);
    IF Assigned(Editor) THEN BEGIN
      PrevEditorClass := TComponentEditorClass((Editor AS TObject).ClassType);
    END;
  FINALLY
    Editor := NIL;
    aLang.Free;
  END;
  RegisterComponentEditor(TLang, TLangToolComponentEditor);
END;

end.
© www.soinside.com 2019 - 2024. All rights reserved.