我正在尝试编写一个返回两个 TForm
之一的函数实例,根据用户设置的配置:
function TfrmMain.GetCurrentRamEditFrm: TForm;
{ Get the RAM Editor Form instance according to currenttly-set protocol. }
begin
if frmSetup.GetCurrentProtocol() = FooBus then
result := RAM_Editor_FooBus.frmRAM_Editor_FooBus
else
result := RAM_Editor_SXcp.frmRAM_Editor_SXcp;
end;
我需要这个函数,因为这个单元 (
Main.pas
) 在 RAM 编辑器表单中读取/写入大量变量。编译器在以下行中出错:
GetCurrentRamEditFrm().StatusBar1.Panels[1].Text := get_text(96);
带有错误消息:
Undeclared identifier 'StatusBar1'
如果我明确提供 TForm 实例,则没有错误:
RAM_Editor_SXcp.frmRAM_Editor_SXcp.StatusBar1.Panels[1].Text := get_text(96);
StatusBar
在两种形式中都这样声明:type
TfrmRAM_Editor_SXcp = class(TForm)
StatusBar1: TStatusBar; // i.e. the scope is "published"
...
有趣的是,编译器不介意以下内容:
GetCurrentRamEditFrm().show();
最佳答案
您的函数将实例返回为 TForm
对StatusBar1
一无所知的人您已在 TfrmRAM_Editor_SXcp
中声明.GetCurrentRamEditFrm().show();
之所以有效,是因为 TForm
类有方法Show
.
您必须创建基本表单类型来声明要使用的所有变量和方法,或者声明两个表单将共享的接口(interface)。
解决方案一:
type
TBaseForm = class(TForm)
StatusBar1: TStatusBar;
type
TfrmRAM_Editor_SXcp = class(TBaseForm)
// this type will automatically inherit StatusBar1
function TfrmMain.GetCurrentRamEditFrm: TBaseForm;
{ Get the RAM Editor Form instance according to currenttly-set protocol. }
begin
if frmSetup.GetCurrentProtocol() = FooBus then
result := RAM_Editor_FooBus.frmRAM_Editor_FooBus
else
result := RAM_Editor_SXcp.frmRAM_Editor_SXcp;
end;
方案二:
type
IBaseForm = interface
procedure SetStatus(const s: string);
end;
type
TfrmRAM_Editor_SXcp = class(TForm, IBaseForm)
StatusBar1: TStatusBar; // i.e. the scope is "published"
...
procedure SetStatus(const s: string);
procedure TfrmRAM_Editor_SXcp.SetStatus(const s: string);
begin
StatusBar1.Panels[1].Text := s;
end;
function TfrmMain.GetCurrentRamEditFrm: IBaseForm;
{ Get the RAM Editor Form instance according to currenttly-set protocol. }
begin
if frmSetup.GetCurrentProtocol() = FooBus then
result := RAM_Editor_FooBus.frmRAM_Editor_FooBus
else
result := RAM_Editor_SXcp.frmRAM_Editor_SXcp;
end;
然后你可以像这样使用它:
GetCurrentRamEditFrm().SetStatus(get_text(96));
当然,即使您不使用接口(interface)解决方案,也最好为您需要的功能引入方法,而不是像
StatusBar
这样抓取 UI 元素。直接地。如果有一天你确实需要使用接口(interface)而不是通用基类,如果你已经有了方法,那么引入接口(interface)将非常容易。
关于delphi - 如何编写在运行时返回现有 TForm 实例的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27224439/