在Delphi中控制fsMDIChild窗口的位置

在Delphi中控制fsMDIChild窗口的位置,delphi,c++builder,mdi,mdichild,Delphi,C++builder,Mdi,Mdichild,如何在Delphi或C++Builder中控制MDI子窗口(FormStyle:=fsMDIChild)的位置?我知道我可以设置Left、Top、Position等等,但对于MDI子级来说,这些设置只有在创建窗口并显示在其默认位置后才会生效。结果是,一次创建和定位多个窗口会导致相当多的闪烁,因为窗口创建在其默认位置,然后立即移动和调整大小 通过深入研究VCL源代码,我能找到的唯一解决方案是重写TCustomForm的CreateParams方法,并更改Params参数的X、Y、Width和Hei

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


通过深入研究VCL源代码,我能找到的唯一解决方案是重写TCustomForm的CreateParams方法,并更改Params参数的X、Y、Width和Height字段,但这感觉像是一次黑客攻击。有没有更干净的方法可以做到这一点?

我观察到根本没有闪烁,但这可能是因为我的电脑速度太快,或者可能是Windows 7中减少闪烁的改进

我将MDI子窗口的位置设置为FormShow:

procedure TForm2.FormShow(Sender: TObject);
begin
  Top := 200;
  Left := 400;
end;

您可以将
WM_SETREDRAW
消息发送到主窗体的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++:


谢谢我试图从构造函数中执行此操作,但没有意识到OldCreateOrder设置为true。一旦我修复了OldCreateOrder,就可以使用构造函数和FormShow来完成这两项工作。谢谢。我必须使用RedrawWindow而不是invalidate来让MDI子对象正确地重新绘制,如“备注”中所述。我使用invalidate-institute(),对我来说效果很好。备注指的是列表框,而不是MDI窗口。
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);
}