我有2个MDI ChildForm,而Child1有一个TButton来打开Child2。我同时打开它没有任何问题,请禁用TButton,以防止Child2使用TButton重新创建。
现在,当我希望在关闭Child2时将Child1的TButton重新设置为“启用”时,挑战就来了。
执行这些代码时出现访问错误:
procedure TfrmChild2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
child1_u.frmChild1.btnOpenChild2Form.Enabled := True;
Action := caFree;
end;
我知道在处理MDI时有某种不同的方法。我在下面的运行时打开期间执行禁用TButton的代码时就知道了:
procedure TfrmMain.btnOpenChild2(Sender: TObject);
begin
TfrmChild2.Create(frmMain);
btnOpenChild2.Enabled := False;
end;
但是要在关闭Child2窗体时重新启用它是一个挑战。
我试图在MainForm(所有者)中创建一个过程以触发在Child1中启用TButton:
procedure TfrmMain.EnableButtonAtChild1();
begin
child1_u.frmChild1.btnOpenChild1Form.Enabled := True;
end;
并在运行期间在Child2的OnClose期间调用:
procedure TfrmChild2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
EnableButtonAtChild1();
end;
我是MDI的新手,我需要了解在这种简单情况下访问组件的工作方式。在这里,我将不胜感激。
我将采用另一种方法-当第一个孩子创建第二个孩子时,动态分配第二个孩子的OnClose
事件。不要让第二个孩子尝试直接找到并访问第一个孩子:
procedure TfrmChild1.btnOpenChild2FormClick(Sender: TObject);
var
child: TfrmChild2;
begin
child := TfrmChild2.Create(Application.MainForm);
child.OnClose := Child2Closed;
btnOpenChild2Form.Enabled := False;
end;
procedure TfrmChild1.Child2Closed(Sender: TObject; var Action: TCloseAction);
begin
btnOpenChild2.Enabled := True;
Action := caFree;
end;
请确保在释放第一个孩子之前始终关闭第二个孩子,否则会遇到麻烦。如果需要,可以这样解决:
procedure TfrmChild1.FormDestroy(Sender: TObject);
var
I: Integer;
child: TForm;
event: TCloseEvent;
begin
for I := 0 to Application.MainForm.MDIChildCount-1 do
begin
child := Application.MainForm.MDIChildren[I];
event := child.OnClose;
if Assigned(event) and (TMethod(event).Data = Self) then
child.OnClose := nil;
end;
end;