在模态表单的
OnCreate
事件中,我使用 SetWindowPlacement()
恢复之前保存的表单大小和位置。它在非模态形式下工作正常,但在模态形式出现几秒钟后就完全冻结了。
Form1
正在调用 Form2
作为模态。
我无法在
SetWindowPlacement()
事件中使用 OnShow
,因为我们遇到了异常:
EInvalidOperation 类,带有消息“无法更改 OnShow 或 OnHide 中的可见项”。
期望的结果是在关闭之前的最后一个位置显示一个模态表单。
SetWindowPlacement()
是正确使用的功能,因为它可以在多个显示器上正常工作,即使在保存位置后拔掉其中一台显示器的插头也是如此。如果我们不考虑这种可能性,表单就会出现在屏幕外(隐藏)。
这是一小段代码:
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(nil);
Form2.ShowModal;
FreeAndNil(form2);
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
//Hard coded paremeters to make it simple
RestoreFormPosition(self, 100, 200, 301, 463);
end;
procedure TForm2.RestoreFormPosition(WhichForm: TForm; const pTop, pLeft, pHeight, pWidth: Integer);
var
recWndPlmt : TWindowPlacement;
begin
WhichForm.Position := poDesigned;
recWndPlmt.Length:= SizeOf(TWindowPlacement);
//GetWindowPlacement(WhichForm.Handle, @recWndPlmt);
recWndPlmt.rcNormalPosition.Top := pTop;
recWndPlmt.rcNormalPosition.Left := pLeft;
recWndPlmt.rcNormalPosition.Height := pHeight;
recWndPlmt.rcNormalPosition.Width := pWidth;
recWndPlmt.showCMD:= SW_SHOWNORMAL; //1;
SetWindowPlacement(WhichForm.Handle, @recWndPlmt);
end;
我不知道根本情况,但我可以在 Delphi 12.2 中重现该问题。 无论出于何种原因,以这种方式使用
SetWindowPlacement()
都会导致窗体窗口在窗口显示在屏幕上之前在 VCL 深处被禁用。 在 OnShow
事件中,IsWindowEnabled()
返回 False,而如果不使用 SetWindowPlacement()
,则返回 True。
在
EnableWindow()
事件中调用 OnShow
可以解决问题:
procedure TForm2.FormShow(Sender: TObject);
begin
EnableWindow(Handle, True);
end;
使用Form的
SetBounds()
方法代替SetWindowPlacement()
也可以避免这个问题:
//SetWindowPlacement(WhichForm.Handle, @recWndPlmt);
WhichForm.SetBounds(pLeft, pTop, pWidth, pHeight);