1

Problem
The resolution reported by Screen.Width/Screen.Height is sometimes (rarely) smaller that the resolution reported in Control Panel. The resolution reported by Delphi is always smaller (about 1/3) than the real resolution. And it 'makes sense'. I mean it seems to be one of those 'round' numbers used for resolution in normal computers, like 1280x720.

I cannot reproduce this in my system but I got few screenshots from 3rd party computers.

Recently I used

 var MonInfo: TMonitorInfo; begin MonInfo.cbSize := SizeOf(MonInfo); GetMonitorInfo(MonitorFromWindow(Application.MainForm.Handle, MONITOR_DEFAULTTONEAREST), @MonInfo); Result:= MonInfo.rcMonitor.Right; 

It returns the same (wrong) result as Screen.Width/Screen.Height. This was reported just on a couple of systems (3-4). Two of them were hooked to a external monitor/TV.

Details
Resolution shown by Delphi: 1280x720
Resolution shown by Control Panel: 1920x1080
DPI: 96
Make it easier to read what's on screen: 150%
Test project: I just started a new default project; no properties altered in the ObjInspector. A small test program made in C++ shows also the wrong resolution.
Delphi XE

Question
Which Delphi function will return the correct resolution OR how do I calculate the correct resolution from the resolution reported by Screen.Width (Screen.Height)?


Moved here:
How to obtain the real screen resolution in a High DPI system?

1
  • 1
    AFAIK, "150%" corresponds to 120 DPI. If you're getting 96, you're subject to DPI virtualization. Try calling SetProcessDPIAware. Commented Sep 29, 2014 at 10:32

2 Answers 2

3

Your program does not declare itself to be high dpi aware. And so it is subject to a compatibility mode known as DPI virtualization. The system will supply your program with fake screen dimensions and coordinates, and then scale your program's display to the true dimensions.

As well as giving you screen dimensions that you do not recognise, a much more significant issue is that DPI virtualization will result in your program appearing fuzzy due to aliasing. The system does its best to scale your program to fit the user's desired DPI, but it's just not possible to scale raster images without some aliasing.

Some useful links:

If you wish to avoid DPI virtualization, and have your program obtain true screen dimensions, then you should mark your program as being high DPI aware. This is best done with the high DPI aware application manifest.

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" > <asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true</dpiAware> </asmv3:windowsSettings> </asmv3:application> </assembly> 
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks David. I will try the manifest and come back with the result.
I have seen people advice against making your DPI aware (stackoverflow.com/questions/6983837/…). So, I would like a 'dirty' solution in which I just get the real screen resolution. There is any way to calculate this?
You can create a small program that is DPI aware, and start that new process to get it to obtain the information. Or you could do it with a WMI query. I cannot see any reason not to be high DPI aware. The only reason that I could imagine doing so would be if you wanted your program to suck. It will look appalling on modern screens without high DPI aware.
There is a warning here from WarenP about switching to DPI aware: stackoverflow.com/questions/6983837/…
My app runs high DPI aware, scales just fine to at least 200%. You aren't going to be able to ignore this forever. Modern high pixel density laptops are unreadable at 100% scaling because the text is too small. High DPI is coming whether you like it or not. And you app will really suck if you let Windows scale it for you with raster scaling.
|
3

TScreen gets its resolution values directly from Windows, so it is Windows that is "lying". Your GetMonitorInfo() test proves that. My guess would be that when your app is having this issue, it is likely being run in a compatibility mode, especially if your app is not High-DPI Aware on modern Windows versions. That requires your app to use special manifest values and API calls.

2 Comments

My app is created with Delphi XE. I started a new project and just put in it the Screen.Width/Screen.Height and GetMonitorInfo functions.
@remy-I got confirmation that the user has the DPI set to 96 but "Make it easier to read what's on screen" is set to "Larger 150%"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.