当我键入此问题时,我意识到可能应该这样做。

将表单停靠到TPageControl时,会在调用form.Create()以及调用form.ManualDock(pagecontrol,pagecontrol.alClient)时调用FormShow。

取消停靠表单也称为show,我认为这是因为停靠/取消停靠时表单实际上是“重置”的吗?

如果这是设计好的,我将重构我不想触发的代码到onCreate(除非这是不好的设计)。

最佳答案

是否应该比技术问题更具哲学性。通过执行控制消息TForm.OnShow触发CM_DOCKCLIENT事件,该消息也被ManualDock功能使用。在内部,此消息称为CM_SHOWINGCHANGED,它将触发事件本身。

在下面的示例中,我将使用两种形式:Form1(带有页面控件和按钮)和Form2(空和可停靠)。我认为两者都是自动创建的。

以下代码证明OnShow控制消息触发了CM_DOCKCLIENT事件。单击该按钮,将执行CM_DOCKCLIENT消息并触发Form2的OnShow事件。

Form1的代码

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事件中)手动将其停靠,而是由创建者或通过显示它的表单将其停靠。在我之前的示例中,我在Form1.OnShow事件中显示了Form2,因此我可以轻松地将其手动停靠在那里。

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;

关于delphi - TForm.ManualDock应该调用onFormShow吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8410574/

10-09 00:40