Jump to content

Recommended Posts

Posted (edited)
In the display settings, in the advanced settings on the General tab is more or less the setting: 
 
The translation from GOOGLE: "If the resolution makes items are too small to achieve visual comfort, you can to offset this effect increase the resolution dpi. To change only the font size, click Cancel and go to the Appearance tab." 
 
EDIT: Here there is a possibility to choose:
Default size 96 dpi 
Big size 120 dpi 
 
When I Change this option to 120 dpi, this causes display problems with elements such as Button.
The problem is manifested by the fact that the text does not fit within the limits set by the size of the button. 
Of course, if you set 96 dpi, the text looks normal. 
 
Does anyone know a solution to this problem. 
 
I note that the solution like this: 
GUICtrlSetResizing(-1, $GUI_DOCKALL)

unfortunately does not help.

 

 
mLipok
Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted

try to enable "DPI virtualization" - Windows will automatically resize your GUI elements to fit:

post-47848-0-31151100-1394218235_thumb.p

this is enabled system-wide. you may need to disable DPI Virtualization for specific applications. for example i found Safari to be better looking when disabled:

post-47848-0-04984200-1394218309_thumb.p

(P.S. this is valid for Windows Vista or later)

Signature - my forum contributions:

  Reveal hidden contents

 

  • Solution
Posted

You can set the control size depending on the DPI.

I use this GDI+ function to get the DPI size:

Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
    Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
    If @error Then Return SetError(1, @extended, 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
    If @error Then Return SetError(2, @extended, 0)
    Local $iDPI = $aResult[2]
    _GDIPlus_GraphicsDispose($hGfx)
    Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
    Return $aResults
EndFunc   ;==>_GDIPlus_GraphicsGetDPIRatio

According the information you can set the size of your control or the font size.

 

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

  • 7 months later...
Posted

@UEZ , I forgot to thank you.

Thanks a lot.

mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

  • 6 years later...
Posted (edited)
  On 3/7/2014 at 8:35 PM, UEZ said:

I use this GDI+ function to get the DPI size:

Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
    Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
    If @error Then Return SetError(1, @extended, 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
    If @error Then Return SetError(2, @extended, 0)
    Local $iDPI = $aResult[2]
    _GDIPlus_GraphicsDispose($hGfx)
    Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
    Return $aResults
EndFunc   ;==>_GDIPlus_GraphicsGetDPIRatio

 

Expand  

Is this snippet works for you ?
 

Here is testing script which I use:
 

#include <Array.au3>
#include <GDIPlus.au3>
#include <MsgBoxConstants.au3>
Global $aDPI =_GDIPlus_GraphicsGetDPIRatio()
ConsoleWrite(_ArrayToString($aDPI) & @CRLF)

Exit

Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
    _GDIPlus_Startup()
    Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
    If @error Then Return SetError(1, @extended, 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
    If @error Then Return SetError(2, @extended, 0)
    Local $iDPI = $aResult[2]
    ConsoleWrite("! " & $iDPI & @CRLF )
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_Shutdown()
    Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
    Return $aResults
EndFunc   ;==>_GDIPlus_GraphicsGetDPIRatio


I always get:
 

  Quote

1|1

Expand  

 

Can anyone check if he has other results ?

Thank you in advance and best regards,
mLipok

 

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted

Exactly. 

Waiting for few more answer. 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted (edited)

Hhmmm, that's odd why it doesn't work anymore.

 

#include <Array.au3>
#include <GDIPlus.au3>
#include <MsgBoxConstants.au3>

_GDIPlus_Startup()
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE

;https://docs.microsoft.com/en-us/windows/desktop/hidpi/dpi-awareness-context
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware

; enum _MONITOR_DPI_TYPE
Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI
Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI

_WinAPI_SetDPIAwareness()
;_WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
;_WinAPI_SetProcessDpiAwarenessContext()

Global $aDPI =_GDIPlus_GraphicsGetDPIRatio()
ConsoleWrite("_GDIPlus_GraphicsGetDPIRatio: " & _ArrayToString($aDPI) & @CRLF)
Global $hGUI_dummy = GUICreate("", 1, 1)
ConsoleWrite("_WinAPI_GetDpiForWindow: " & _WinAPI_GetDpiForWindow($hGUI_dummy) & @CRLF)
ConsoleWrite("_WinAPI_GetDpiForMonitor: " & _ArrayToString(_WinAPI_GetDpiForMonitor())& @CRLF)

$hDC = _WinAPI_GetDC(0)
ConsoleWrite("_WinAPI_GetDeviceCaps: " & (_WinAPI_GetDeviceCaps($hDC, 88) + _WinAPI_GetDeviceCaps($hDC, 90)) / 2 & @CRLF) ;$LOGPIXELSY = 88, $LOGPIXELSY = 90
_WinAPI_ReleaseDC(0, $hDC)
_GDIPlus_Shutdown()
Exit

Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
    Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
    If @error Then Return SetError(1, @extended, 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
    If @error Then Return SetError(2, @extended, 0)
    Local $iDPI = $aResult[2]
    _GDIPlus_GraphicsDispose($hGfx)
    Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
    Return $aResults
EndFunc   ;==>_GDIPlus_GraphicsGetDPIRatio

Func _WinAPI_GetDpiForWindow($hWnd)
    Local $aResult = DllCall("user32.dll", "uint", "GetDpiForWindow", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_GetDpiForWindow

Func _WinAPI_GetDpiForMonitor($dpiType = $MDT_DEFAULT, $iDPIDef = 96)
    Local $aMonitors = _WinAPI_EnumDisplayMonitors()
    Local $x, $y
    Local $aRet = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "long", $aMonitors[1][0], "int", $dpiType, "uint*", $x, "uint*", $y)
    If @error Or Not IsArray($aRet) Then Return SetError(1, 0, 0)
    Local $aDPI[2] = [$iDPIDef / $aRet[3], $aRet[3] / $iDPIDef]
    Return $aDPI
EndFunc   ;==>_WinAPI_GetDpiForMonitor

Func _WinAPI_SetDPIAwareness($hGUI = 0)
    Switch @OSBuild
        Case 6000 To 9199
            DllCall("user32.dll", "bool", "SetProcessDPIAware")
        Case 9200 To 13999
            _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
        Case 14000 To 30000
            #cs
                Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
                Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
                Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
                Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
                Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
            #ce
            _WinAPI_SetProcessDpiAwarenessContext(-4, $hGUI)
    EndSwitch
EndFunc   ;==>_WinAPI_SetDPIAwareness

Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
    DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware)
    If @error Then Return SetError(1, 0, 0)
    Return 1
EndFunc   ;==>_WinAPI_SetProcessDpiAwareness

;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 3) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
    $DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
    $iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
    Switch $iMode
        Case 1
            Local $hDC = _WinAPI_GetDC($hGUI)
            Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC)
            If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
            _WinAPI_ReleaseDC(0, $hDC)
            Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
        Case 2
;~          If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
            Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI)
            If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
            Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
        Case 3
            Local $aResult31 = DllCall("user32.dll", "int", "GetThreadDpiAwarenessContext")
            If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
            Local $aResult32 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "int", $aResult31[0])
            If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
            Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
    EndSwitch

    Return 1
EndFunc   ;==>_WinAPI_SetProcessDpiAwarenessContext

Obviously DPI awareness must be set but it doesn't work for the GDI+ function.

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

Thanks @UEZ 

I will look on yours code toomorow.

Going to sleep. 

 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted (edited)

As I have 2 monitors, and because in my DevEnv  I use Au3Check  as a standard option, I had to change your code a little.

;~ https://www.autoitscript.com/forum/topic/159612-dpi-resolution-problem/?do=findComment&comment=1490110
#AutoIt3Wrapper_AutoIt3Dir="z:\AutoItPortable\AutoIt_3_3_14_5"

#include <Array.au3>
#include <GDIPlus.au3>
#include <MsgBoxConstants.au3>

_GDIPlus_Startup()
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE

;https://docs.microsoft.com/en-us/windows/desktop/hidpi/dpi-awareness-context
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware

; enum _MONITOR_DPI_TYPE
Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI
Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI

_Example()
Exit

Func _Example()
    _WinAPI_SetDPIAwareness()
    Local $aMonitors = _WinAPI_EnumDisplayMonitors()
    If UBound($aMonitors) > 2 Then
        _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
    EndIf
;~  _WinAPI_SetProcessDpiAwarenessContext()

    Local $aDPI = _GDIPlus_GraphicsGetDPIRatio()
    ConsoleWrite(@ScriptLineNumber & " _GDIPlus_GraphicsGetDPIRatio: " & _ArrayToString($aDPI) & @CRLF)
    Local $hGUI_dummy = GUICreate("", 1, 1)
    GUISetState()

    Local $hDC = _WinAPI_GetDC($hGUI_dummy)

    For $IDX_Monitor = 1 To UBound($aMonitors) - 1
        If $IDX_Monitor > 1 Then MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONINFORMATION, "Information #" & @ScriptLineNumber, "Move GUI to monitor #" & $IDX_Monitor)
        ConsoleWrite(@ScriptLineNumber & " $IDX_Monitor = " & $IDX_Monitor & @CRLF)
        ConsoleWrite(@ScriptLineNumber & " _WinAPI_GetDpiForWindow: " & _WinAPI_GetDpiForWindow($hGUI_dummy) & @CRLF)
        ConsoleWrite(@ScriptLineNumber & " _WinAPI_GetDpiForMonitor: " & _ArrayToString(_WinAPI_GetDpiForMonitor($MDT_DEFAULT, 96, $IDX_Monitor)) & @CRLF)
        ConsoleWrite(@ScriptLineNumber & " _WinAPI_GetDeviceCaps: " & (_WinAPI_GetDeviceCaps($hDC, 88) + _WinAPI_GetDeviceCaps($hDC, 90)) / 2 & @CRLF) ;$LOGPIXELSY = 88, $LOGPIXELSY = 90
    Next


    _WinAPI_ReleaseDC(0, $hDC)
    _GDIPlus_Shutdown()

EndFunc   ;==>_Example


Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
    Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
    If @error Then Return SetError(1, @extended, 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
    If @error Then Return SetError(2, @extended, 0)
    Local $iDPI = $aResult[2]
    _GDIPlus_GraphicsDispose($hGfx)
    Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
    Return $aResults
EndFunc   ;==>_GDIPlus_GraphicsGetDPIRatio

Func _WinAPI_GetDpiForWindow($hWnd)
    Local $aResult = DllCall("user32.dll", "uint", "GetDpiForWindow", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_GetDpiForWindow

Func _WinAPI_GetDpiForMonitor($dpiType = $MDT_DEFAULT, $iDPIDef = 96, $IDX_Monitor = 1)
    Local $aMonitors = _WinAPI_EnumDisplayMonitors()
    Local $x, $y

    Local $aRet = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "long", $aMonitors[$IDX_Monitor][0], "int", $dpiType, "uint*", $x, "uint*", $y)
    If @error Or Not IsArray($aRet) Then Return SetError(1, 0, 0)
    Local $aDPI[2] = [$iDPIDef / $aRet[3], $aRet[3] / $iDPIDef]
    Return $aDPI
EndFunc   ;==>_WinAPI_GetDpiForMonitor

Func _WinAPI_SetDPIAwareness($hGUI = 0)
    Switch @OSBuild
        Case 6000 To 9199
            DllCall("user32.dll", "bool", "SetProcessDPIAware")
        Case 9200 To 13999
            _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
        Case 14000 To 30000
            #cs
                Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
                Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
                Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
                Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
                Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
            #ce
            _WinAPI_SetProcessDpiAwarenessContext(-4, $hGUI)
    EndSwitch
EndFunc   ;==>_WinAPI_SetDPIAwareness

Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
    DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware)
    If @error Then Return SetError(1, 0, 0)
    Return 1
EndFunc   ;==>_WinAPI_SetProcessDpiAwareness

;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 3) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
    $DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
    $iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
    Local $aResult
    Switch $iMode
        Case 1
            Local $hDC = _WinAPI_GetDC($hGUI)
            Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC)
            If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
            _WinAPI_ReleaseDC(0, $hDC)
            $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
        Case 2
;~          If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
            Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI)
            If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
            $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
        Case 3
            Local $aResult31 = DllCall("user32.dll", "int", "GetThreadDpiAwarenessContext")
            If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
            Local $aResult32 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "int", $aResult31[0])
            If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
            $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
    EndSwitch

    Return 1
EndFunc   ;==>_WinAPI_SetProcessDpiAwarenessContext

Your new code works, almost perfectly because I notice few problems.

When I run them with F5 in SciTE4Au3 then I get wrong results.
When I run them with Shift+F5 in SciTE4Au3 then I get proper results.

I checked and I figure out that I had to call _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE), hence my modifications.
 

Also I use:

Local $hDC = _WinAPI_GetDC($hGUI_dummy)

but you used:

Local $hDC = _WinAPI_GetDC(0)

Does it matter in my test case (I mean with two monitors with different DPI settings) ?
 

When to use:
 

_WinAPI_SetProcessDpiAwarenessContext()

?

 

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted
  On 10/1/2021 at 7:31 AM, mLipok said:

When I run them with F5 in SciTE4Au3 then I get wrong results.
When I run them with Shift+F5 in SciTE4Au3 then I get proper results.

Expand  

That's odd whereas I'm currently in home office and have only one monitor which works properly for latest version and beta version. Next week I can test in my office with 3 monitors.

 

  On 10/1/2021 at 7:31 AM, mLipok said:

Does it matter in my test case (I mean with two monitors with different DPI settings) ?

Expand  

I don't think so that it makes any real difference.

 

  On 10/1/2021 at 7:31 AM, mLipok said:

When to use:
 

_WinAPI_SetProcessDpiAwarenessContext()

?

Expand  

As the name states it set the awareness for the process only but MS recommend to use the manifest instead.

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted (edited)

New version + more tests:

;~ https://www.autoitscript.com/forum/topic/159612-dpi-resolution-problem/?do=findComment&comment=1490110
#AutoIt3Wrapper_AutoIt3Dir="z:\AutoItPortable\AutoIt_3_3_14_5"

#include <Array.au3>
#include <GDIPlus.au3>
#include <MsgBoxConstants.au3>

_GDIPlus_Startup()
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE

;https://docs.microsoft.com/en-us/windows/desktop/hidpi/dpi-awareness-context
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware

; enum _MONITOR_DPI_TYPE
Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI
Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI

_Example()
Exit

Func _Example()
    _WinAPI_SetDPIAwareness()

    Local $aDPI = _GDIPlus_GraphicsGetDPIRatio()
    ConsoleWrite(@ScriptLineNumber & " _GDIPlus_GraphicsGetDPIRatio: " & _ArrayToString($aDPI) & @CRLF)
    Local $hGUI_dummy = GUICreate("", 1, 1)
    GUISetState()

    Local $aMonitors = _WinAPI_EnumDisplayMonitors()
    If UBound($aMonitors) > 2 Then
        _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
;~      _WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAware, $hGUI_dummy, 3)
    EndIf

    Local $hDC = _WinAPI_GetDC($hGUI_dummy)

    For $IDX_Monitor = 1 To UBound($aMonitors) - 1
        If $IDX_Monitor > 1 Then MsgBox($MB_OK + $MB_TOPMOST + $MB_ICONINFORMATION, "Information #" & @ScriptLineNumber, "Move GUI to monitor #" & $IDX_Monitor)
        ConsoleWrite(@ScriptLineNumber & " $IDX_Monitor = " & $IDX_Monitor & @CRLF)
        ConsoleWrite(@ScriptLineNumber & " _WinAPI_GetDpiForWindow: " & _WinAPI_GetDpiForWindow($hGUI_dummy) & @CRLF)
        ConsoleWrite(@ScriptLineNumber & " _WinAPI_GetDpiForMonitor: " & _ArrayToString(_WinAPI_GetDpiForMonitor($MDT_DEFAULT, 96, $IDX_Monitor)) & @CRLF)
        ConsoleWrite(@ScriptLineNumber & " _WinAPI_GetDeviceCaps: " & (_WinAPI_GetDeviceCaps($hDC, 88) + _WinAPI_GetDeviceCaps($hDC, 90)) / 2 & @CRLF) ;$LOGPIXELSY = 88, $LOGPIXELSY = 90
    Next


    _WinAPI_ReleaseDC(0, $hDC)
    _GDIPlus_Shutdown()

EndFunc   ;==>_Example


Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
    Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
    If @error Then Return SetError(1, @extended, 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
    If @error Then Return SetError(2, @extended, 0)
    Local $iDPI = $aResult[2]
    _GDIPlus_GraphicsDispose($hGfx)
    Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
    Return $aResults
EndFunc   ;==>_GDIPlus_GraphicsGetDPIRatio

Func _WinAPI_GetDpiForWindow($hWnd)
    Local $aResult = DllCall("user32.dll", "uint", "GetDpiForWindow", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_GetDpiForWindow

Func _WinAPI_GetDpiForMonitor($dpiType = $MDT_DEFAULT, $iDPIDef = 96, $IDX_Monitor = 1)
    Local $aMonitors = _WinAPI_EnumDisplayMonitors()
    Local $x, $y

    Local $aRet = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "long", $aMonitors[$IDX_Monitor][0], "int", $dpiType, "uint*", $x, "uint*", $y)
    If @error Or Not IsArray($aRet) Then Return SetError(1, 0, 0)
    Local $aDPI[2] = [$iDPIDef / $aRet[3], $aRet[3] / $iDPIDef]
    Return $aDPI
EndFunc   ;==>_WinAPI_GetDpiForMonitor

Func _WinAPI_SetDPIAwareness($hGUI = 0)
    Switch @OSBuild
        Case 6000 To 9199
            DllCall("user32.dll", "bool", "SetProcessDPIAware")
        Case 9200 To 13999
            _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
        Case 14000 To 30000
            #cs
                Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
                Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
                Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
                Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
                Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
            #ce
            _WinAPI_SetProcessDpiAwarenessContext(-4, $hGUI)
    EndSwitch
EndFunc   ;==>_WinAPI_SetDPIAwareness

Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
    DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware)
    If @error Then Return SetError(1, 0, 0)
    Return 1
EndFunc   ;==>_WinAPI_SetProcessDpiAwareness

;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 3) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
    $DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
    $iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
    Local $aResult
    Switch $iMode
        Case 1
            Local $hDC = _WinAPI_GetDC($hGUI)
            Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC)
            If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
            _WinAPI_ReleaseDC(0, $hDC)
            $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
        Case 2
;~          If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
            Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI)
            If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
            $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
        Case 3
            Local $aResult31 = DllCall("user32.dll", "int", "GetThreadDpiAwarenessContext")
            If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
            Local $aResult32 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "int", $aResult31[0])
            If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
            $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext)
            If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
    EndSwitch

    Return 1
EndFunc   ;==>_WinAPI_SetProcessDpiAwarenessContext

REMARK: I have 2 monitors: first DPI 125% second DPI 100%


TEST _WinAPI_SetProcessDpiAwareness() + F5:

Local $aMonitors = _WinAPI_EnumDisplayMonitors()
    If UBound($aMonitors) > 2 Then
        _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
;~      _WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAware, $hGUI_dummy, 3)
    EndIf
  Quote

26 _GDIPlus_GraphicsGetDPIRatio: 1|1
40 $IDX_Monitor = 1
41 _WinAPI_GetDpiForWindow: 120
42 _WinAPI_GetDpiForMonitor: 0.8|1.25
43 _WinAPI_GetDeviceCaps: 120
40 $IDX_Monitor = 2
41 _WinAPI_GetDpiForWindow: 120
42 _WinAPI_GetDpiForMonitor: 1|1
43 _WinAPI_GetDeviceCaps: 120
 

Expand  

 

TEST _WinAPI_SetProcessDpiAwareness() + SHIFT+F5:

  Quote

26 _GDIPlus_GraphicsGetDPIRatio: 1|1
40 $IDX_Monitor = 1
41 _WinAPI_GetDpiForWindow: 120
42 _WinAPI_GetDpiForMonitor: 0.8|1.25
43 _WinAPI_GetDeviceCaps: 120
40 $IDX_Monitor = 2
41 _WinAPI_GetDpiForWindow: 120
42 _WinAPI_GetDpiForMonitor: 1|1
43 _WinAPI_GetDeviceCaps: 120

Expand  

 

 

TEST _WinAPI_SetProcessDpiAwarenessContext() + F5:

Local $aMonitors = _WinAPI_EnumDisplayMonitors()
    If UBound($aMonitors) > 2 Then
;~      _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
        _WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAware, $hGUI_dummy, 3)
    EndIf
  Quote

26 _GDIPlus_GraphicsGetDPIRatio: 1|1
40 $IDX_Monitor = 1
41 _WinAPI_GetDpiForWindow: 96
42 _WinAPI_GetDpiForMonitor: 1|1
43 _WinAPI_GetDeviceCaps: 96
40 $IDX_Monitor = 2
41 _WinAPI_GetDpiForWindow: 96
42 _WinAPI_GetDpiForMonitor: 1|1
43 _WinAPI_GetDeviceCaps: 96
 

Expand  

 

TEST _WinAPI_SetProcessDpiAwarenessContext() + SHIFT+F5:

  Quote

26 _GDIPlus_GraphicsGetDPIRatio: 1|1
40 $IDX_Monitor = 1
41 _WinAPI_GetDpiForWindow: 120
42 _WinAPI_GetDpiForMonitor: 1|1
43 _WinAPI_GetDeviceCaps: 96
40 $IDX_Monitor = 2
41 _WinAPI_GetDpiForWindow: 120
42 _WinAPI_GetDpiForMonitor: 1|1
43 _WinAPI_GetDeviceCaps: 96
 

Expand  

 

 

 

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted (edited)

as so far I used:

.....
    _WinAPI_SetDPIAwareness()

    Local $aDPI = _GDIPlus_GraphicsGetDPIRatio()
    ConsoleWrite(@ScriptLineNumber & " _GDIPlus_GraphicsGetDPIRatio: " & _ArrayToString($aDPI) & @CRLF)
    Local $hGUI_dummy = GUICreate("", 1, 1)
    GUISetState()
.....

Should I change the order and use $hGUI_dummy in parameters for _WinAPI_SetDPIAwareness($hGUI_dummy)

....
    Local $hGUI_dummy = GUICreate("", 1, 1)
    GUISetState()
    _WinAPI_SetDPIAwareness($hGUI_dummy)
    Local $aDPI = _GDIPlus_GraphicsGetDPIRatio()
    ConsoleWrite(@ScriptLineNumber & " _GDIPlus_GraphicsGetDPIRatio: " & _ArrayToString($aDPI) & @CRLF)
....


?

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

  • 1 month later...
Posted
  On 9/30/2021 at 7:38 PM, UEZ said:

Hhmmm, that's odd why it doesn't work anymore.

Obviously DPI awareness must be set but it doesn't work for the GDI+ function.

Expand  

WELL HECK

image.png.ed0b8e0e2b24a11315e27e1e0b935422.png

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11
Cisco FinesseGithubIRC UDFWindowEx UDF

 

Posted

_GDIPlus_GraphicsGetDPIRatio() works correctly only if you compile it with #AutoIt3Wrapper_Res_HiDpi=Y. Obviously, the manifest must be present in the executable.

 

#include <Array.au3>
#include <GDIPlus.au3>
#AutoIt3Wrapper_Res_HiDpi=Y
_ArrayDisplay(_GDIPlus_GraphicsGetDPIRatio())


Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
  Local $aResults[2] = [0, 0]
  _GDIPlus_Startup()
  Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
  If @error Then Return SetError(1, @extended, $aResults)
  #forcedef $__g_hGDIPDll, $ghGDIPDll
  $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
  If @error Then Return SetError(2, @extended, $aResults)
  Local $iDPI = $aResult[2]
  Local $aresults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
  _GDIPlus_GraphicsDispose($hGfx)
  _GDIPlus_Shutdown()
  Return $aresults
EndFunc   ;==>_GDIPlus_GraphicsGetDPIRatio

This way I get the correct array values which are not 1, 1!

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...