Dpi awareness functions not included?

Windows specific questions.
Tourist Trap
Posts: 2768
Joined: Jun 02, 2015 16:24

Dpi awareness functions not included?

Postby Tourist Trap » Feb 09, 2019 19:36

Hi,

apparently I can't use SetProcessDpiAware on win10. Then I'll need SetProcessDpiAwarenessContext and the constants taken as arguments.
https://msdn.microsoft.com/fr-fr/C94883 ... D9B869A5E2
Simply editing the manifest to set the awareness to false (this should be the default state, not the case in winfbe ide examples I found) is useless for some reason, so I need the functions.

There is a impracticable issue otherwise with 1920x1080 res and hi-dpi. Already seen with the testing of FBSHOOT game and so on.

Then thanks by advance!
Josep Roca
Posts: 448
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Dpi awareness functions not included?

Postby Josep Roca » Feb 10, 2019 0:47

> apparently I can't use SetProcessDpiAware on win10.

Why not? I use it.

> Simply editing the manifest to set the awareness to false (this should be the default state, not the case in winfbe ide examples I found) is useless for some reason, so I need the functions.

Why should it be the default state? I think the opposite.

If you include a manifest, it takes preference over the function. Therefore, set the DPI awareness using a manifest or calling a function, but not both. If you want to use a manifest and also call the function, then don't set <dpiAware>False</dpiAware> in the manifest, but remove it.
Josep Roca
Posts: 448
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Dpi awareness functions not included?

Postby Josep Roca » Feb 10, 2019 1:03

To get the DPI, you can use:

Code: Select all

DIM hDC AS HDC = GetDC(HWND_DESKTOP)
DIM dpi AS LONG = GetDeviceCaps(hDC, LOGPIXELSX)
ReleaseDC HWND_DESKTOP, hDC


To get the scaling ratio, just divide dpi by 96.
Tourist Trap
Posts: 2768
Joined: Jun 02, 2015 16:24

Re: Dpi awareness functions not included?

Postby Tourist Trap » Feb 10, 2019 20:40

Josep Roca wrote:To get the DPI, you can use:

Code: Select all

DIM hDC AS HDC = GetDC(HWND_DESKTOP)
DIM dpi AS LONG = GetDeviceCaps(hDC, LOGPIXELSX)
ReleaseDC HWND_DESKTOP, hDC


To get the scaling ratio, just divide dpi by 96.

Thanks Josep,

I was trying with gdi+ from here viewtopic.php?p=258160#p258160, but it worked only once giving me the 1.25 ratio I wished, then it returned only 1. I don't know what I do wrong.
I'll try now with GETDC and what you posted gracefully.

edit: so it's weird, I know obtain 96 dpi with this test also. I still will have an oversized window if I try screenres with desktop dimensions (1920, 1080), and I'm in 125% in the windows setting.
What is very strange is that the test with gdi+ first gave the right 1,25 value. That's only since then that the value has dropped to 1 despite the fact nothing is changed, just the value wrong.
Josep Roca
Posts: 448
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Dpi awareness functions not included?

Postby Josep Roca » Feb 12, 2019 1:53

If your application is not DPI aware, you will always get a DPI of 96, no matter if you are using 125% or another value. Make your application DPI aware by using an appropriate manifest of by calling the SetProcessDPIAware function. Non DPI aware applications are virtualized by Windows when using a DPI setting higher than 96.
Landeel
Posts: 695
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Postby Landeel » Feb 12, 2019 12:37

Code: Select all

dim as any ptr user32dll=dylibload("user32.dll")
if user32dll=0 then print "Error loading user32.dll" : end 1

dim shared SetProcessDPIAware as function cdecl() as boolean
SetProcessDPIAware=DyLibSymbol(user32dll,"SetProcessDPIAware")
if SetProcessDPIAware=0 then print "SetProcessDPIAware not found." : end 2

dim ret as boolean=SetProcessDPIAware()
if ret then
   print "SetProcessDPIAware() returned "+str(ret)+" : success!"
else
   print "SetProcessDPIAware() returned "+str(ret)+" : failure!"
end if

Does this work?
Seems to work with wine, but I don't have Win10 to test.
Landeel
Posts: 695
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Postby Landeel » Feb 12, 2019 13:49

Code: Select all

   dim shared shcoredll as any ptr
   #define S_OK 0
   #define PROCESS_PER_MONITOR_DPI_AWARE 2
   dim shared SetProcessDpiAwareness as function cdecl(byval PROCESS_DPI_AWARENESS as long=PROCESS_PER_MONITOR_DPI_AWARE) as long

   dim ret1 as long
   
   shcoredll=dylibload("shcore")
   if shcoredll=0 then
      print "DPI : Error loading shcore.dll"
      end 1
   else
      print "DPI : loaded shcore.dll"
   end if
   
   SetProcessDpiAwareness=DyLibSymbol(shcoredll,"SetProcessDpiAwareness")
   if SetProcessDpiAwareness=0 then
      print "DPI : SetProcessDpiAwareness not found."
      end 2
   else
      print "DPI : found SetProcessDpiAwareness"
   end if

   ret1=SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)
   if ret1=S_OK then
      print "DPI : SetProcessDpiAwareness() returned "+str(ret1)+" : success!" 'S_OK (0) = success
   else
      print "DPI : SetProcessDpiAwareness() returned "+str(ret1)+" : failure!" 'failure
   end if

This one uses the new API. Does it work?
Tourist Trap
Posts: 2768
Joined: Jun 02, 2015 16:24

Re: Dpi awareness functions not included?

Postby Tourist Trap » Feb 13, 2019 19:30

Landeel wrote:

Code: Select all

   dim shared shcoredll as any ptr
   #define S_OK 0
   #define PROCESS_PER_MONITOR_DPI_AWARE 2
   dim shared SetProcessDpiAwareness as function cdecl(byval PROCESS_DPI_AWARENESS as long=PROCESS_PER_MONITOR_DPI_AWARE) as long

   dim ret1 as long
   
   shcoredll=dylibload("shcore")
   if shcoredll=0 then
      print "DPI : Error loading shcore.dll"
      end 1
   else
      print "DPI : loaded shcore.dll"
   end if
   
   SetProcessDpiAwareness=DyLibSymbol(shcoredll,"SetProcessDpiAwareness")
   if SetProcessDpiAwareness=0 then
      print "DPI : SetProcessDpiAwareness not found."
      end 2
   else
      print "DPI : found SetProcessDpiAwareness"
   end if

   ret1=SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)
   if ret1=S_OK then
      print "DPI : SetProcessDpiAwareness() returned "+str(ret1)+" : success!" 'S_OK (0) = success
   else
      print "DPI : SetProcessDpiAwareness() returned "+str(ret1)+" : failure!" 'failure
   end if

This one uses the new API. Does it work?

I'll try this week-end. Lack of time by week.
Tourist Trap
Posts: 2768
Joined: Jun 02, 2015 16:24

Re: Dpi awareness functions not included?

Postby Tourist Trap » Feb 16, 2019 15:33

Landeel wrote:This one uses the new API. Does it work?

This seems to work, congrats! This is preventing the oversizing effect on my system :)
Landeel
Posts: 695
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Postby Landeel » Feb 16, 2019 16:25

Tourist Trap wrote:
Landeel wrote:This one uses the new API. Does it work?

This seems to work, congrats! This is preventing the oversizing effect on my system :)


Great!
This will work for windows 8.1 and 10. I think for 8.0, the old API must be used as fallback.
Tourist Trap
Posts: 2768
Joined: Jun 02, 2015 16:24

Re: Dpi awareness functions not included?

Postby Tourist Trap » Feb 16, 2019 16:29

Landeel wrote:
Tourist Trap wrote:
Landeel wrote:This one uses the new API. Does it work?

This seems to work, congrats! This is preventing the oversizing effect on my system :)


Great!
This will work for windows 8.1 and 10. I think for 8.0, the old API must be used as fallback.

Here on win10, I tested it on 2 programs, that solved the issue. Now I think it can be used from inside a #IF ... #ENDIF, to test the version of ms-windows. But I don't see what is the intrinsic that returns it like:

Code: Select all

#IF __WINVER__ = 10
....
Landeel
Posts: 695
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Postby Landeel » Feb 16, 2019 16:43

Hm, not really, because the defines are set at compile time, not at runtime.
You could retrieve the Windows version with something like that:

Code: Select all

      dim WindowsVersion as OSVERSIONINFO
      WindowsVersion.dwOSVersionInfoSize = len(OSVERSIONINFO)
      GetVersionEx(@WindowsVersion)

      dim as single winver=WindowsVersion.dwMajorVersion + .1*WindowsVersion.dwMinorVersion

The "winver", does not match the commercial name. You have to look here:https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version


But I think it's more compatible and future proof to try both and see which works.
I'll be using something like that:

Code: Select all

#ifdef __FB_WIN32__
sub _win32DPIaware()

   'SetProcessDpiAwareness ''' Shcore.dll
   
   dim ret1 as long
   
   shcoredll=dylibload("shcore")
   if shcoredll=0 then
      printconsole "DPI : Error loading shcore.dll"
      goto _win32dpiaware_altmethod
   else
      printconsole "DPI : loaded shcore.dll"
   end if
   
   SetProcessDpiAwareness=DyLibSymbol(shcoredll,"SetProcessDpiAwareness")
   if SetProcessDpiAwareness=0 then
      printconsole "DPI : SetProcessDpiAwareness not found."
      goto _win32dpiaware_altmethod
   else
      printconsole "DPI : found SetProcessDpiAwareness"
   end if

   ret1=SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)
   if ret1=S_OK then
      'S_OK (0) = success
      printconsole "DPI : SetProcessDpiAwareness() returned "+str(ret1)+" : success!"+char_CRLF
      exit sub
   else
      'failure
      printconsole "DPI : SetProcessDpiAwareness() returned "+str(ret1)+" : failure!"
   end if
   
   
   _win32dpiaware_altmethod:
      
   'SetProcessDPIAware() ''' winuser User32.dll

   dim ret2 as boolean

   user32dll=dylibload("user32")
   if user32dll=0 then
      printconsole "DPI : Error loading user32.dll"+char_CRLF
      exit sub
   else
      printconsole "DPI : loaded user32.dll"
   end if

   SetProcessDPIAware=DyLibSymbol(user32dll,"SetProcessDPIAware")
   if SetProcessDPIAware=0 then
      printconsole "DPI : SetProcessDPIAware not found."+char_CRLF
      exit sub
   else
      printconsole "DPI : found SetProcessDPIAware"
   end if

   ret2=SetProcessDPIAware()
   if ret2 then
      'true=success
      printconsole "DPI : SetProcessDPIAware() returned "+str(ret2)+" : success!"+char_CRLF
   else
      'false=failure
      printconsole "DPI : SetProcessDPIAware() returned "+str(ret2)+" : failure!"+char_CRLF
   end if
   
end sub
#endif
St_W
Posts: 1476
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Dpi awareness functions not included?

Postby St_W » Feb 17, 2019 18:29

@Tourist Trap:
The recommended way (according to Microsoft) to make your application dpi-aware (or explicitly dpi-unaware, which is the default when you specify nothing) is to add an entry to your application manifest. That's a better method than calling the API methods you mentioned. It should not be necessary to use them - if so you most likely have some other bad design choice in your application and should try to fix that.
Landeel
Posts: 695
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Postby Landeel » Feb 17, 2019 18:51

A desktop environment that by default stretches a fullscreen OpenGL game out of the screen, now that's what I call bad design.

Return to “Windows”

Who is online

Users browsing this forum: No registered users and 34 guests