SetWindowPlacement 使模态窗体冻结

问题描述 投票:0回答:1

在模态表单的

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 winapi delphi-10.2-tokyo
1个回答
0
投票

我不知道根本情况,但我可以在 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);
© www.soinside.com 2019 - 2024. All rights reserved.