Включить TButton MDI ChildForm после закрытия другой MDI ChildForm - PullRequest
0 голосов
/ 17 января 2020

У меня есть 2 MDI ChildForms, а Child1 имеет TButton, чтобы открыть Child2. У меня нет никаких проблем, открывая его, в то же время отключите TButton, чтобы предотвратить повторное воссоздание Child2 с помощью TButton.

Теперь проблема возникает, когда я хочу, чтобы TButton of Child1 снова включился, когда я закрыл Child2.

Я получаю ошибку доступа при выполнении этого кода:

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 закрыта, - задача.

I попытался создать процедуру в MainForm (Владелец), чтобы вызвать включение TButton в Child1:

procedure TfrmMain.EnableButtonAtChild1();
begin
  child1_u.frmChild1.btnOpenChild1Form.Enabled := True;  
end;

и вызвал во время выполнения во время OnClose of Child2:

procedure TfrmChild2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  EnableButtonAtChild1();
end;

Я новичок в MDI, и мне нужно понять, как работает доступ к компонентам, особенно в этом простом случае. Я буду признателен за любую помощь здесь.

1 Ответ

1 голос
/ 17 января 2020

Я бы выбрал другой подход - динамически назначать событие 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;
...