使用 Parallels VM 将 Form 重新定位到第二台显示器时屏幕变黑

问题描述

我正在双显示器系统上的 Windows 10(在 Parallels 中虚拟化)中使用 Delphi 10.4.2。要在多监视器系统上重现该问题,请创建一个新的 Windows VCL 应用程序并在表单上放置两个按钮:btnPrimaryMonitorbtnSecondaryMonitor。然后通过为两个按钮创建单击处理程序来插入此代码

procedure TForm1.btnPrimaryMonitorClick(Sender: TObject);
begin
  RepositionFormToMonitor(0);
  EnabledisableButtons;
end;

procedure TForm1.RepositionFormToMonitor(const aMonitor: Integer);
const
  offset = 2;
begin
  Self.Width := Screen.Monitors[aMonitor].Width - offset;
  Self.Height := Screen.Monitors[aMonitor].Height - offset;

  Self.Top := Screen.Monitors[aMonitor].Top;
  Self.Left := Screen.Monitors[aMonitor].Left;
end;

procedure TForm1.btnSecondaryMonitorClick(Sender: TObject);
begin
  RepositionFormToMonitor(1);
  EnabledisableButtons;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  EnabledisableButtons;
  Self.BorderStyle := bsNone;
  Self.FormStyle := fsstayOnTop;
  RepositionFormToMonitor(0);
end;

procedure TForm1.EnabledisableButtons;
begin
  btnPrimaryMonitor.Enabled := (Self.Monitor.MonitorNum = 1);
  btnSecondMonitor.Enabled := (Self.Monitor.MonitorNum = 0);
end;

这很好用,但是一旦我设置了 offset = 1offset = 0,屏幕就会变黑!

代码的目的是通过单击 btnSecondMonitor 按钮将最大化的停留在顶部窗体从主监视器重新定位到辅助监视器,然后通过单击 {{ 1}} 按钮。

如何避免这个问题?

解决方法

一些问题:

  1. 您不应将 WindowState 设置为 wsMaximized。事实上,你根本不应该碰这个属性。

  2. 设置BoundsRect会设置LeftTopWidthHeight,所以不需要设置{{1} } 和 Left 分开。

  3. 要返回主监视器,只需设置表单的 Top

这是一个例子:

创建一个新的 VCL 项目。将主窗体的 BoundsRect 设置为 BorderStyle

然后添加以下代码:

bsNone

如果此代码在您的系统上无法正常工作,则您的 Windows 系统可能存在问题。这应该可以完美运行。