-1

My delphi(7 or XE5) application is getting wrong monitor resolution when resolution is over 1920x1080.

I have a samsung ultra book with resolution of 2560x1440 running windows 8.1

When I run the simple resolution test, the app returns right at 1920x1080 and less, but when run the app with max resolution of 2560x1440 the resolution returned is 1600x900.

This is the code, I try with dpiaware manifest and get same wrong result, any idea about this ?

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetDesktopArea: TRect;
var
  m: integer;
  USCR: TScreen;
begin
  USCR := TScreen.Create(Application);
  try
    with USCR do
    if MonitorCount = 1 then
      Result := WorkAreaRect
    else
    begin
      for m:=0 to MonitorCount-1 do
      begin
        with Monitors[m] do
          if Primary then
            Result := Rect(Left, Top, Left+Width, Top+Height);
         // UpdScreen.Monitors[m].BoundsRect;
      end;
    end;
  finally
    USCR.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  msg : String;
  scr : TRect;
begin
  scr := GetDesktopArea;

  msg := Format('Left:%d Top:%d -- W:%d H:%d', [scr.Left, scr.Top, scr.Width, scr.Height] );

  Memo1.Lines.Add( msg );
end;

end.

Thanks

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Leonardo
  • 159
  • 1
  • 15
  • 2
    Does your app have a manifest that explicitly states Windows 8.1 is supported? Is your app high-DPI aware? If no to either, then Windows is going to report virtualized screen values related to the scaling it has to perform behind the scenes. `TScreen` is merely reporting what Windows is reporting. BTW, DO NOT call `TScreen.Create` manually. Use the existing global `Screen` object in the `Vcl.Forms` unit instead. – Remy Lebeau Apr 06 '15 at 19:30
  • Take a look at http://stackoverflow.com/questions/26852150/how-can-i-make-windows-8-1-aware-that-my-delphi-application-wants-to-support-per – Dalija Prasnikar Apr 06 '15 at 19:57
  • FWIW, I run XE7 (currently) day in and day out on a 2560x1440 monitor under Windows 8.1, and both Delphi itself and my apps all work fine (in this regard, at least). And your function with Remy's modification (not to create a custom TScreen instance) returns the screen resolution correctly. – 500 - Internal Server Error Apr 06 '15 at 19:58
  • You'll be experiencing dpi virtualization – David Heffernan Apr 06 '15 at 20:25
  • The question states that the app is dpi aware by a manifest. – Sertac Akyuz Apr 06 '15 at 20:40
  • @Sertac Presumably the manifest is applied incorrectly and the app is not dpi aware – David Heffernan Apr 07 '15 at 06:56

1 Answers1

1

The likely explanation is that your application is not dpi aware and so experiences dpi virtualization. I know of nothing else that could influence these system API calls.

You state that you have manifested the application to be dpi aware. Since the evidence is that your app is not dpi aware then I conclude that you have applied the manifest incorrectly.

Don't ever instantiate TScreen. Use the Screen global variable instead.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • thanks, solution was found in manifest sintax with true/PM parameter value. – Leonardo Apr 07 '15 at 13:21
  • Ok, does this answer your question then? – David Heffernan Apr 07 '15 at 13:45
  • Well, the answer is that the cause of problem stay on manifest syntax, the TScreen.Create or global Screen dont make diference. The solution is the manifest that I post in edit 1. Real cause is that application needs to be DPI AWARE, that depends of manifest. Now with the listed manifest all works fine. Thanks – Leonardo Apr 07 '15 at 13:50
  • 1
    I answered the question, by deducing that your manifest (which you had not presented) was defective. My advice not to instantiate `TScreen` is accurate and you should heed it. – David Heffernan Apr 07 '15 at 14:09
  • @Leonardo - Not creating a 'screen' is not proposed as a solution in the answer. Answer here accurately diagnoses the problem which is your application is not dpi aware, although you state in the question otherwise. – Sertac Akyuz Apr 07 '15 at 15:03
  • @Leonardo you should note that Delphi applications do not have built in support for per-monitor DPI on Windows 8.1. So your application may exhibit issues on Windows 8.1 and high DPI multi-monitor setups, even if you have true/PM entry in your manifest. – Dalija Prasnikar Apr 07 '15 at 15:26