当我键入此问题时,我意识到可能应该这样做。
将表单停靠到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/