Delphi如何在MainForm中访问MDI Child的组件?

How to access MDI Child's component in MainForm in Delphi?

我使用 Delphi 编写代码。
当我按下按钮时,它会创建一个新的 MDI 子窗体。
所以,程序有多个MDI子窗体,我想在MainForm中访问每个子窗体的组件(例如定时器)。
MainForm是fsMDIForm,ChildForm是fsMDIChild。

这是我试过的代码。但它不起作用,因为 TChildForm 和 TForm 不兼容。

procedure TMainForm.Start1Click(Sender: TObject);
var   
i : Integer;
begin
  for i := MainForm.MDIChildCount-1 to 0 do
  begin
    ChildForm := MainForm.MDIChildren[i];   //Incompatible types -> Can't Run
    ChildForm.Timer1.Enabled := True;
  end;
end;

unit MDIChildForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ToolWin, ActnMan, ActnCtrls, ComCtrls, Buttons,
  ExtCtrls;

type
  TChildForm = class(TForm)
    ToolBar1: TToolBar;
    ListView1: TListView;
    ToolButton1: TToolButton;
    Splitter1: TSplitter;
    Memo1: TMemo;
    ToolButton2: TToolButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure ToolButton1Click(Sender: TObject);
    procedure ToolButton2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ChildForm: TChildForm;
  value1: Integer = 1;

implementation

{$R *.dfm}

procedure TChildForm.FormCreate(Sender: TObject);
begin
  {
    itm := ListView1.Items.Add;
    itm.Caption := 'item ' + IntToStr(value1);
    itm.SubItems.Add('subItem1 ' + IntToStr(value1));
    itm.SubItems.Add('subItem2 ' + IntToStr(value1));
  }
  Timer1.Enabled := False;
  {
    ChildForm.Caption := 'ChildForm' + IntToStr(value1);
    Inc(value1);
  }
end;
procedure TChildForm.ToolButton1Click(Sender: TObject);
begin
  ToolButton1.Show;
  value1 := value1 + 10;
end;

procedure TChildForm.ToolButton2Click(Sender: TObject);
begin
  //ListView1.Items.Item[0] := 'Index';
end;

procedure TChildForm.Timer1Timer(Sender: TObject);
var
  itm : TListItem;
  i : Integer;
begin
  for i:= value1 to value1+10 do
  begin
    itm := ListView1.Items.Add;
    itm.Caption := 'item ' + IntToStr(i);
  end;
  value1 := i;
end;

end.

如何以子形式访问组件?

您需要使用这样的转换:

procedure TMainForm.Start1Click(Sender: TObject);
var   
  i : Integer;
begin
  for i := MainForm.MDIChildCount-1 downto 0 do
    (MainForm.MDIChildren[i] as TChildForm).Timer1.Enabled := True;
end;

另请注意,我在 for 循环中使用了 downto,因为您想向后遍历子列表。