2010-06-25 51 views
7

我正在Delphi写一个屏幕保护程序。我想要在每台显示器上全屏显示一个TpresentationFrm。为此,我写了下面的(不完全)程序:如何在辅助监视器上显示表单?

program ScrTemplate; 

uses 
    ... 

{$R *.res} 

type 
    TScreenSaverMode = (ssmConfig, ssmDisplay, ssmPreview, ssmPassword); 

function GetScreenSaverMode: TScreenSaverMode; 
begin 
    // Some non-interesting code 
end; 

var 
    i: integer; 
    presentationForms: array of TpresentationFrm; 

begin 
    Application.Initialize; 
    Application.MainFormOnTaskbar := True; 

    case GetScreenSaverMode of 
    ssmConfig: 
     Application.CreateForm(TconfigFrm, configFrm); 
    ssmDisplay: 
     begin 
     SetLength(presentationForms, Screen.MonitorCount); 
     for i := 0 to high(presentationForms) do 
     begin 
      Application.CreateForm(TpresentationFrm, presentationForms[i]); 
      presentationForms[i].BoundsRect := Screen.Monitors[i].BoundsRect; 
      presentationForms[i].Visible := true; 
     end; 
     end 
    else 
    ShowMessage(GetEnumName(TypeInfo(TScreenSaverMode), integer(GetScreenSaverMode))); 
    end; 

    Application.Run; 
end. 

当执行ssmDisplay码,两种形式确实是创造了(是的,我有整整两个显示器)。但它们都出现在第一台显示器上(索引0,但不是主要显示器)。

当单步调试代码,我看到Screen.Monitors[i].BoundsRect是正确的,但由于某些原因的形式得到不正确的边界:

Watch Name       Value (TRect: Left, Top, Right, Bottom, ...) 
Screen.Monitors[0].BoundsRect (-1680, 0, 0, 1050, (-1680, 0), (0, 1050)) 
Screen.Monitors[1].BoundsRect (0, 0, 1920, 1080, (0, 0), (1920, 1080)) 

presentationForms[0].BoundsRect (-1680, 0, 0, 1050, (-1680, 0), (0, 1050)) 
presentationForms[1].BoundsRect (-1920, -30, 0, 1050, (-1920, -30), (0, 1050)) 

第一种形式得到所需的位置,但第二次却没有。它不是从x = 0到1920,而是占用x = -1920到0,即它出现在第一个监视器上,高于第一个表格。哪里不对?什么是正确的程序来完成我想要的?

+0

您将有高DPI显示器的问题,如果您的应用程序不包含在其清单的highdpi意识到标志。在这种情况下,Windows将报告一个错误的(虚拟)绑定矩形。 – Ampere 2017-12-14 13:16:16

回答

7

的形式具有以设定使用BoundRect边界可见。

反转这样的台词:

presentationForms[i].Visible := true; 
presentationForms[i].BoundsRect := Screen.Monitors[i].BoundsRect; 
+0

是的,我只需交换'for'循环中的两行:首先设置可见性,然后更改边界! – 2010-06-25 14:36:51

2

显然我试图提前设置位置。

Application.CreateForm(TpresentationFrm, presentationForms[i]); 
presentationForms[i].Tag := i; 
presentationForms[i].Visible := true; 

更换for环块,然后写

procedure TpresentationFrm.FormShow(Sender: TObject); 
begin 
    BoundsRect := Screen.Monitors[Tag].BoundsRect; 
end; 
0

您将有高DPI显示器的问题,如果您的应用程序不包含在其清单的highdpi意识到标志。在这种情况下,Windows将报告一个错误的(虚拟)绑定矩形。

一个解决办法是到窗体手动移到要像这样的画面:

procedure MoveFormToScreen(Form: TForm; ScreenNo: Integer); 
begin 
Assert(Form.Position= poDesigned); 
Assert(Form.Visible= TRUE); 

Form.WindowState:= wsNormal; 
Form.Top := Screen.Monitors[ScreenNo].Top; 
Form.Left:= Screen.Monitors[ScreenNo].Left; 
Form.WindowState:= wsMaximized; 
end; 
相关问题