Должен ли TForm.ManualDock вызывать onFormShow? - PullRequest
2 голосов
/ 07 декабря 2011

Когда я набрал этот вопрос, я понял, что, вероятно, должен.

Прикрепление формы к TPageControl вызывает FormShow при вызове form.Create () и при вызове form.ManualDock (pagecontrol, pagecontrol.alClient).

Отмена стыковки формы также вызывает show, и я предполагаю, что это происходит из-за того, что форма на самом деле «сбрасывается» при стыковке / отстыковке?

Если это так, как было задумано, я просто рефакторингкод, который я не хочу запускать в onCreate (если это не плохой дизайн).

1 Ответ

2 голосов
/ 08 декабря 2011

Если должен или нет, это более философский, чем технический вопрос. Событие TForm.OnShow вызывается выполнением управляющего сообщения CM_DOCKCLIENT, которое также используется функцией ManualDock. Внутренне это сообщение вызывает CM_SHOWINGCHANGED, которое вызывает само событие.

В следующем примере я буду использовать две формы: Form1 (с элементом управления страницей и кнопкой) и Form2 (пустой и закрепляемый). Я предполагаю, что оба они созданы автоматически.

Следующий код является доказательством того, что событие OnShow вызывается управляющим сообщением CM_DOCKCLIENT. При нажатии на кнопку появляется сообщение CM_DOCKCLIENT и запускается событие Form2 OnShow.

Код для формы 1

procedure TForm1.FormShow(Sender: TObject);
begin
  Form2.Show;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  DockObject: TDragDockObject;
begin
  DockObject := TDragDockObject.Create(Form2);
  try
    // sending the CM_DOCKCLIENT message internally performs also the
    // CM_SHOWINGCHANGED message which triggers the TForm.OnShow event
    PageControl1.Perform(CM_DOCKCLIENT, WPARAM(DockObject), LPARAM(SmallPoint(0, 0)));
  finally
    DockObject.Free;
  end;
end;

И у Form2 есть только обработчик событий OnShow

procedure TForm2.FormShow(Sender: TObject);
begin
  ShowMessage('FormShow');
end;

Простой обходной путь - не закреплять Form2 вручную самостоятельно (в событии OnShow), а прикреплять его создателем или, скажем, формой, которая его отображает. В моем предыдущем примере я отобразил Form2 в событии Form1.OnShow, поэтому я могу легко закрепить его там вручную.

procedure TForm1.FormShow(Sender: TObject);
begin
  Form2.Show;
  Form2.ManualDock(PageControl1);
end;

procedure TForm2.FormShow(Sender: TObject);
begin
  // no manual docking of this form by itself
end;
...