delphi - 如何编写在运行时返回现有 TForm 实例的函数?

标签 delphi delphi-7

我正在尝试编写一个返回两个 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();

最佳答案

您的函数将实例返回为 TFormStatusBar1一无所知的人您已在 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/

相关文章:

delphi - 如何创建从其他几个组件继承的Delphi组件?

delphi - 我需要在派生类的构造函数声明之后放置重载或覆盖字吗?

delphi - 如果我知道数据库中的行 ID,则在 TdbGrid 中选择一行

windows - 我怎样才能释放一个 Tpanel 有一个 TbitBtn 调用释放 Tpanel

c++ - 德尔福泛型 : E2037: Declaration of 'XXX' differs from previous declaration

delphi - 如何对具有子属性的属性进行编码? (还原)

delphi - idHttpServer 上的 OnDisconnect 事件

Delphi 7 tguid 比较

sql-server - 如何检查数据库是否存在?

Delphi 7启动时打开cmd