Alaska Software Inc. - Re: Bug in AppDesktop():CurrentSize()
Username: Password:
AuthorTopic: Re: Bug in AppDesktop():CurrentSize()
Andreas Gehrs-Pahl

View the complete thread for this message in:

Re: Bug in AppDesktop():CurrentSize()
on Thu, 22 Oct 2015 01:22:34 -0400
Itai,

>Iʼve setup screen resolution to 1920 x 1200.
>AppDesktop():CurrentSize() = {1920,1200}
>Iʼve changed desktop font size to 150% (screen resolution kept at 1920 X 
>1200).
>AppDesktop:CurrentSize() = {1280,800}
>Can this bug be fixed?

This is called "DPI Virtualization" and is correct behavior, so it doesn't 
need to be fixed. On Windows Vista and higher, Windows APIs report a virtual 
resolution, based on the actual Screen Resolution and the applied scaling 
factor, leaving the (reported) DPI at the default of 96 DPI. That way, the 
entire application dialog is transparently scaled by the OS, not only the 
fonts. This feature allows applications that are "not DPI aware" appear the 
same as if the resolution was changed, even though they might look "blurry", 
as they are scaled by the Desktop Window Manager (DWM). In Windows Vista, 
the text isn't scaled correctly, but in Windows 7 and later the text is also 
scaled.

>Is there a way to retrieve screen resolution independent of desktop 
>font-size?

Yes, to change this behavior (for all applications), select "Control Panel" 
==> "Appearance and Personalization" ==> "Display" and from that dialog the: 
"Set custom text size (DPI)" option on the left (this is for Windows 7, 
other OS versions might be slightly different).

On the popup dialog, select the "Use Windows XP style DPI scaling" check 
box and [Apply] the settings. After Log-off or Restart, the OS will report 
the original resolution (of 1920 x 1200) with an adjusted DPI setting (for 
fonts), which will be 120 DPI (for the "Medium - 125%" setting) or 144 DPI 
(for the "Larger - 150%") setting, instead of the default of 96 DPI (for 
the "Smaller - 100%" setting).

DPI virtualization is by default enabled when a scale factor of greater than 
120 (125 percent) is selected. But it can be disabled (or enabled) with this 
check box for any scale (or DPI) setting.

You can also change this for just a particular application, by selecting the 
Compatibility tab on the Properties dialog, and then select the box labeled 
"Disable display scaling on high DPI settings". Another option to disable 
DPI virtualization for a particular application, is to supply a manifest 
file for the application with the <dpiAware>true</dpiAware> setting. 
Additionally, you can use the SetProcessDPIAware() Windows API function to 
change the setting at runtime, but MS discourages doing this.

To check if the above-mentioned check box has been selected, you can also 
read the "UseDpiScaling" value of the following Registry key: 
HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM. If it is set to 0 (Zero)
(a DWord), then the check box is selected (XP-style scaling is used). If 
it is set to 1, then the check box is not selected (and DPI virtualization 
is used).

You can verify (and experiment with) this using the Windows API functions 
GetClientRect() and GetDeviceCaps(). Here is what I use:

Function GetDeskTopSize()
*************************************************************************
* Used to get the actual, current Desktop Size, as this value is not    
 updated correctly, if the Deskop resolution is changed during program 
 execution, and "AppDektop():CurrentSize() always reports the original 
 settings. See also PDR 109-4244 for details.                          *
*************************************************************************
LOCAL nHWnd   := AppDesktop():GetHWnd()
LOCAL nWidth  := 0
LOCAL nHeight := 0
LOCAL cBuffer := U2Bin(0) + U2Bin(0) + U2Bin(nWidth) + U2Bin(nHeight)
   DllCall("User32.DLL", DLL_STDCALL, "GetClientRect", nHWnd, @cBuffer)
   nWidth     := Bin2U(substr(cBuffer,  9, 4))
   nHeight    := Bin2U(substr(cBuffer, 13, 4))
return ({nWidth, nHeight})

Function GetWindowsFontsDPI(lWidth)
LOCAL lHeight := iif(lWidth == NIL, .t., .not. lWidth)
LOCAL nHeight := iif(lHeight, LOGPIXELSY, LOGPIXELSX)
LOCAL nHWnd   := AppDesktop():GetHWnd()
LOCAL nHDC    := DllCall("User32.DLL", DLL_STDCALL, "GetDC", nHWnd)
LOCAL nLogPix := 96		 default for Small Fonts (100%)
   if nHDC # 0
      nLogPix := DllCall("GDI32.DLL", DLL_STDCALL, "GetDeviceCaps", nHDC, nHeight)
      DllCall("User32.DLL", DLL_STDCALL, "ReleaseDC", nHWnd, nHDC)
   endif
return (nLogPix)

For more information, see also this MS article on "Writing DPI-Aware Desktop 
and Win32 Applications":

https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266(v=vs.85).aspx

Hope this helps,

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas.GP@Charter.net
web:   http://www.Aerospace-History.net