使用 Parallels VM 将 Form 重新定位到第二台显示器时屏幕变黑
Screen becomes black when repositioning Form to second monitor using Parallels VM
我在双显示器系统上使用 Delphi 10.4.2 in Windows 10(在 Parallels 中虚拟化)。要在多显示器系统上重现该问题,请创建一个新的 Windows VCL 应用程序并在窗体上放置两个按钮:btnPrimaryMonitor
和 btnSecondaryMonitor
。然后通过为两个按钮创建点击处理程序来插入此代码:
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 = 1
或 offset = 0
屏幕就变黑了!
代码的目的是通过单击 btnSecondMonitor
按钮将最大化的停留在顶部的表单从主监视器重新定位到辅助监视器,然后通过单击btnPrimaryMonitor
按钮。
如何避免这个问题?
几个问题:
您不应将 WindowState
设置为 wsMaximized
。事实上,你根本不应该碰这个 属性。
设置BoundsRect
会设置Left
、Top
、Width
、Height
,所以不需要设置Left
和 Top
分开。
要返回主监视器,只需设置表单的 BoundsRect
。
这是一个例子:
创建一个新的 VCL 项目。将主窗体的 BorderStyle
设置为 bsNone
.
然后添加以下代码:
procedure TForm1.FormCreate(Sender: TObject);
begin
for var i := 0 to Screen.MonitorCount - 1 do
begin
var btn := TButton.Create(Self);
btn.Parent := Self;
btn.Caption := i.ToString;
btn.Tag := i;
btn.OnClick := MonitorButtonClick;
btn.Top := 8;
btn.Left := 8 + (btn.Width + 8) * i;
end;
end;
procedure TForm1.MonitorButtonClick(Sender: TObject);
begin
BoundsRect := Screen.Monitors[(Sender as TButton).Tag].BoundsRect;
end;
如果此代码无法在您的系统上正常运行,则您的 Windows 系统可能存在问题。这应该可以完美地工作。
我在双显示器系统上使用 Delphi 10.4.2 in Windows 10(在 Parallels 中虚拟化)。要在多显示器系统上重现该问题,请创建一个新的 Windows VCL 应用程序并在窗体上放置两个按钮:btnPrimaryMonitor
和 btnSecondaryMonitor
。然后通过为两个按钮创建点击处理程序来插入此代码:
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 = 1
或 offset = 0
屏幕就变黑了!
代码的目的是通过单击 btnSecondMonitor
按钮将最大化的停留在顶部的表单从主监视器重新定位到辅助监视器,然后通过单击btnPrimaryMonitor
按钮。
如何避免这个问题?
几个问题:
您不应将
WindowState
设置为wsMaximized
。事实上,你根本不应该碰这个 属性。设置
BoundsRect
会设置Left
、Top
、Width
、Height
,所以不需要设置Left
和Top
分开。要返回主监视器,只需设置表单的
BoundsRect
。
这是一个例子:
创建一个新的 VCL 项目。将主窗体的 BorderStyle
设置为 bsNone
.
然后添加以下代码:
procedure TForm1.FormCreate(Sender: TObject);
begin
for var i := 0 to Screen.MonitorCount - 1 do
begin
var btn := TButton.Create(Self);
btn.Parent := Self;
btn.Caption := i.ToString;
btn.Tag := i;
btn.OnClick := MonitorButtonClick;
btn.Top := 8;
btn.Left := 8 + (btn.Width + 8) * i;
end;
end;
procedure TForm1.MonitorButtonClick(Sender: TObject);
begin
BoundsRect := Screen.Monitors[(Sender as TButton).Tag].BoundsRect;
end;
如果此代码无法在您的系统上正常运行,则您的 Windows 系统可能存在问题。这应该可以完美地工作。