Jump to content

More elegant way than this to get monitor scaling?


Recommended Posts

What is the most elegant way of obtaining the scaling for a monitor?

For example, my Surface Pro suggests a scaling of 200, so with a resolution of 2736 x 1824, @DesktopWidth = 1368  (i.e. 2736 / 2).

When I want to perform a PixelGetColor I need to multiply the x & y coordinates by the scaling factor.  (in this case, 2.0)

While I've put together code works for me (no  testing on other machines), is there a more elegant way?  Something simpler than messing with the manifest? (unless that's way simpler than I think).    

Thanks,

Ed

#include <WinAPISys.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WinAPIHObj.au3>

_ConsoleWrite_WithTimeAndCR("Starting")
_ConsoleWrite_WithTimeAndCR("_GetDesktopScaling_RoundaboutDraft()=" & _GetDesktopScaling_RoundaboutDraft() & @CRLF)

_ConsoleWrite_WithTimeAndCR("_WinAPI_GetSystemMetrics(0)=" & _WinAPI_GetSystemMetrics(0))   ;showing that these do not reflect scaling
_ConsoleWrite_WithTimeAndCR("_WinAPI_GetSystemMetrics(1)=" & _WinAPI_GetSystemMetrics(1))   ;showing that these do not reflect scaling
_ConsoleWrite_WithTimeAndCR("_WinAPI_GetSystemMetrics(78)=" & _WinAPI_GetSystemMetrics(78)) ;showing that these do not reflect scaling
_ConsoleWrite_WithTimeAndCR("_WinAPI_GetSystemMetrics(79)=" & _WinAPI_GetSystemMetrics(79)) ;showing that these do not reflect scaling

Func _GetDesktopScaling_RoundaboutDraft()
;~  Purpose is to get the scaling for the primary monitor.  Necessary when getting pixel color at certain coordinates.
;~      MS suggests not using an API call to make a thread DPIAware (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiaware)
;~      I have not found a function to return this (may be missing it).
;~      Have not found it reliably in registry (? is in display adapter info, but that changes from machine to machine). (Have backed up entire reg, changed the setting and immediately backed it up again, then did WinMerge to compare.)
;~      Strategy is to create a window, maximize it while transparent, capture it as an image, get the dimensions, and compare against @DesktopWidth or @DesktopHeight.  This takes between .25 and .4 sec to run on one particular Surface.
    Local $h_GUI_Handle = GUICreate("Window Just For Capture To Determine Scaling")
    GUISetState(@SW_DISABLE) ;
    WinSetTrans("Window Just For Capture To Determine Scaling", "", 0) ;prevents an ugly window from appearing.  Could mess with controls that are being used when this runs.
    GUISetState(@SW_MAXIMIZE) ;@SW_MAXIMIZE seems to make the window visible even if it was hidden, or disabled prior.  Thus an ugly flash on the screen.
    Local $h_HBITMAP = _ScreenCapture_CaptureWnd("", $h_GUI_Handle)
    GUIDelete($h_GUI_Handle)
    _GDIPlus_Startup()
    Local $h_GDIObject = _GDIPlus_BitmapCreateFromHBITMAP($h_HBITMAP)
    Local $i_ImageWidth = _GDIPlus_ImageGetWidth($h_GDIObject)
    Local $i_ImageHeight = _GDIPlus_ImageGetHeight($h_GDIObject)
    _GDIPlus_ImageDispose($h_GDIObject)
    _WinAPI_DeleteObject($h_HBITMAP)
    _GDIPlus_Shutdown()
    Local $n_Scaling_W = $i_ImageWidth / @DesktopWidth
    Local $n_Scaling_H = $i_ImageHeight / @DesktopHeight
    _ConsoleWrite_WithTimeAndCR("$i_ImageWidth=" & $i_ImageWidth & "  $i_ImageHeight=" & $i_ImageHeight)
    _ConsoleWrite_WithTimeAndCR("@DesktopWidth=" & @DesktopWidth & "  @DesktopHeight=" & @DesktopHeight)
    _ConsoleWrite_WithTimeAndCR("$n_Scaling_W=" & $n_Scaling_W & "  $n_Scaling_H=" & $n_Scaling_H)
    Return Round($n_Scaling_W, 2)
EndFunc   ;==>_GetDesktopScaling_RoundaboutDraft

; Logging and Console writes
Func _ConsoleWrite_WithTimeAndCR($s_ConsoleMessage)
    ConsoleWrite(@YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & "." & @MSEC & " " & $s_ConsoleMessage & @CRLF)
    ;If $s_Log_WriteConsoleWrites_To_LogFile = "Y" Then _LogWrite_WithRollCapability($s_ConsoleMessage)
EndFunc   ;==>_ConsoleWrite_WithTimeAndCR

 

 

Edited by EdWilson
Link to comment
Share on other sites

  • EdWilson changed the title to More elegant way than this to get monitor scaling?
  • 2 weeks later...

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...