2

如何在 Delphi 或 C++Builder 中控制 MDI 子窗口 (FormStyle := fsMDIChild) 的位置?我知道我可以设置 Left、Top、Position 等,但特别是对于 MDI 子项,这些在窗口已经创建并显示在其默认位置之后才会生效。结果是一次创建和定位多个窗口会导致相当多的闪烁,因为窗口是在默认位置创建的,然后立即移动和调整大小。

通过深入研究 VCL 源代码,我能够找到的唯一解决方案是覆盖 TCustomForm 的 CreateParams 方法并更改 Params 参数的 X、Y、Width 和 Height 字段,但这感觉就像一个 hack。有更清洁的方法吗?

4

2 回答 2

2

您可以将WM_SETREDRAW消息发送到 MainForm 的 ClientHandle,其中一个 wParam 设置为 False,然后稍后将 wParam 设置为 True,以避免在设置 MDI 子窗口时闪烁,例如:

德尔福:

SendMessage(Application.MainForm.ClientHandle, WM_SETREDRAW, False, 0);
try
  Child := TChildForm.Create(Self);
  Child.Left := ...;
  Child.Top := ...;
  Child.Show;
finally
  SendMessage(Application.MainForm.ClientHandle, WM_SETREDRAW, True, 0);
  InvalidateRect(Application.MainForm.ClientHandle, nil, True);
end;

C++:

SendMessage(Application->MainForm->ClientHandle, WM_SETREDRAW, FALSE, 0);
try
{
  Child = new TChildForm(this);
  Child->Left = ...;
  Child->Top = ...;
  Child->Show();
}
__finally
{
  SendMessage(Application->MainForm->ClientHandle, WM_SETREDRAW, TRUE, 0);
  InvalidateRect(Application->MainForm->ClientHandle, NULL, TRUE);
}
于 2010-08-18T01:00:06.417 回答
1

我观察到根本没有闪烁,但这可能是因为我的计算机速度太快,或者可能是 Windows 7 对减少闪烁的改进。

我在 FormShow 中设置了 MDI 子窗口位置:

procedure TForm2.FormShow(Sender: TObject);
begin
  Top := 200;
  Left := 400;
end;
于 2010-08-17T21:37:47.407 回答