Delphi 11 应用程序中的多监视器操作

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

我正在 Delphi 11 中构建以下简单应用程序,以便与双显示器计算机一起使用。该应用程序只有一个带有按钮的表单。

单击按钮后,表单应显示在另一个屏幕上,反之亦然。我使用 VCL 方法 TForm.MakeFullyVisible 使表单在指定的监视器上完全可见。

如果表单具有属性 windowstate =

wsNormal
,则可以正常工作

如果有窗口状态 =

wsMaximized
:

  • 它在默认显示器上显示良好
  • 但在第二个显示器上仅显示表单标题栏的下部,没有其他内容

我该怎么做才能使表单在两个屏幕上最大化并完全可见?

表格(.dfm)文件:

object Form17: TForm17
  Left = 551
  Top = 291
  Caption = 'Form17'
  ClientHeight = 442
  ClientWidth = 628
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -12
  Font.Name = 'Segoe UI'
  Font.Style = []
  Position = poDesigned
  WindowState = wsMaximized
  TextHeight = 15
  object Label1: TLabel
    Left = 112
    Top = 80
    Width = 34
    Height = 15
    Caption = 'Label1'
  end
  object Button1: TButton
    Left = 384
    Top = 24
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
end

代码(.pas)文件:

unit Unit17;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,  Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm17 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form17: TForm17;

implementation

{$R *.dfm}

var monitorNo :integer = 0; // EDITED FROM const to var as Ken White suggested

procedure TForm17.Button1Click(Sender: TObject);
begin
     monitorNo := (monitorNo + 1) mod screen.MonitorCount;
     label1.Caption := intToStr(monitorNo);
     MakeFullyVisible(screen.Monitors[monitorNo]);
end;

end.
delphi
1个回答
0
投票

我无法在我的家用计算机(带双显示器)上访问 Delphi 11。

而且我无法访问工作计算机上的双显示器(远程操作)。

但是看看 TCustomForm.MakeFullyVisible 的实现,看起来它可能容易受到 dpi 变化的影响:

procedure TCustomForm.MakeFullyVisible(AMonitor: TMonitor);
var
  ALeft: Integer;
  ATop: Integer;
begin
  if AMonitor = nil then
    AMonitor := Monitor;
  ALeft := Left;
  ATop := Top;
  if Left + Width > AMonitor.Left + AMonitor.Width then
    ALeft := AMonitor.Left + AMonitor.Width - Width;
  if Left < AMonitor.Left then
    ALeft := AMonitor.Left;
  if Top + Height > AMonitor.Top + AMonitor.Height then
    ATop := AMonitor.Top + AMonitor.Height - Height;
  if Top < AMonitor.Top then
    ATop := AMonitor.Top;
  SetBounds(ALeft, ATop, Width, Height);
end;

正在阅读:

  • 显示器宽度
  • 显示器.高度

当您有以下情况时,这可能不准确:

  • 非标准DPI
  • “主”显示器和备用显示器之间的 DPI 不同

除非您的应用程序表明它可以理解非 96 dpi,或者表明它可以理解不同的 per-monitor、dpi,否则 TMonitor.WidthTMonitor.Height 的值不可信。

我建议您将应用程序清单为“每个显示器”dpi 感知,然后忘记 VCL,并直接使用 GetMonitorInfo Windows 函数来获取

rcWork
工作区域,然后设置左上角-您表格的右下角。

© www.soinside.com 2019 - 2024. All rights reserved.