delphi - TForm.ManualDock 应该调用 onFormShow 吗?

标签 delphi events event-handling docking

当我输入这个问题时,我意识到它可能应该如此。

当调用 form.Create() 和调用 form.ManualDock(pagecontrol,pagecontrol.alClient) 时,将表单停靠到 TPageControl 会调用 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/

相关文章:

javascript - 您可以安全地将 addEventListener 与 SVG 元素一起使用吗?

cocoa - 如何在 NSViewController 的子类中处理键盘事件?

memory-leaks - 内存泄漏 JQuery - 所有浏览器

c# - 如何在 C# 的 delphi dll 中调用此函数

VCL 的 Delphi TExpander 等效项

delphi - 将应用程序转换为 BPL,现在应用程序在 Application.Initialize 之前终止

jquery - 仅允许 onclick 一次

delphi - 如何安装Delphi 10.2 Tokyo命令行编译器

WPF 过多的 PropertyChanged 事件

linux - 我如何知道/dev/input/eventX (X=0..7) 中的哪个有 Linux 输入流?