Dpi awareness functions not included?

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

Dpi awareness functions not included?

Post by Tourist Trap »

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!
Landeel
Posts: 777
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Post by Landeel »

Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Dpi awareness functions not included?

Post by Josep Roca »

> 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: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Dpi awareness functions not included?

Post by Josep Roca »

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: 2958
Joined: Jun 02, 2015 16:24

Re: Dpi awareness functions not included?

Post by Tourist Trap »

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: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Dpi awareness functions not included?

Post by Josep Roca »

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: 777
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Post by Landeel »

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: 777
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Post by Landeel »

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: 2958
Joined: Jun 02, 2015 16:24

Re: Dpi awareness functions not included?

Post by Tourist Trap »

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: 2958
Joined: Jun 02, 2015 16:24

Re: Dpi awareness functions not included?

Post by Tourist Trap »

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: 777
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Post by Landeel »

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: 2958
Joined: Jun 02, 2015 16:24

Re: Dpi awareness functions not included?

Post by Tourist Trap »

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: 777
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Post by Landeel »

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/window ... em-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: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Dpi awareness functions not included?

Post by St_W »

@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: 777
Joined: Jan 25, 2007 10:32
Location: Brazil
Contact:

Re: Dpi awareness functions not included?

Post by Landeel »

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