-1

我在双显示器系统上使用 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按钮返回到主监视器btnPrimaryMonitor

如何避免这个问题?

4

1 回答 1

1

几个问题:

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

  2. SettingBoundsRect会设置Left, Top, Width, and Height,所以不需要单独设置Leftand Top

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

这是一个例子:

创建一个新的 VCL 项目。将主窗体设置BorderStylebsNone.

然后添加以下代码:

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 系统可能存在问题。这应该完美无缺。

于 2021-07-29T09:31:18.733 回答