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;
我怕注册一个新的组件编辑器后,旧的编辑器丢失了... ...
经过一些实验,我发现了这个。
创建一个现有的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.