Что нового

Как узнать и изменить масштаб экрана (Win 10)

pvnn

Осваивающий
Сообщения
305
Репутация
32
Всем привет!
В Windows 10 Параметры экрана -> Масштаб и разметка
1. Как узнать текущий масштаб экрана. Ну и хотелось бы его еще и уметь изменять.
2. То же что и выше, только для нескольких мониторов (хотя бы для двух). Если подключены, например сразу 2 монитора, то масштаб может быть разный
Кто-нибудь вообще такое делал?
 

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
Как узнать текущий масштаб экрана.
Взять соотношение между шириной и высотой из информации:
Код:
#include <Array.au3>
#include <WinAPIGdi.au3>

Local $aPos, $aData = _WinAPI_EnumDisplayMonitors()

If IsArray($aData) Then
        ReDim $aData[$aData[0][0] + 1][5]
        For $i = 1 To $aData[0][0]
                $aPos = _WinAPI_GetPosFromRect($aData[$i][1])
                For $j = 0 To 3
                        $aData[$i][$j + 1] = $aPos[$j]
                Next
        Next
EndIf

_ArrayDisplay($aData, '_WinAPI_EnumDisplayMonitors')


или так, выдернул из кода, там можно сократить до 1 строки

Код:
#include <WinAPIGdiDC.au3>
#include <Array.au3>
_GetDeviceCaps()
Func _GetDeviceCaps()
  Local $aRet=StringSplit('118|117|4|6|88|90|12','|'),$h=_WinAPI_GetDC(0)
  For $i=1 To $aRet[0]
    $aRet[$i]=_WinAPI_GetDeviceCaps($h,$aRet[$i])
  Next
  $MASHTAB=$aRet[1]/@DesktopWidth
  MsgBox(4096,'$MASHTAB',$MASHTAB)
  $aRet[0]=$MASHTAB*100
  _WinAPI_ReleaseDC(0,$h)
_ArrayDisplay($aRet,'Инфо')
EndFunc


Код:
#include <WinAPIGdiDC.au3>
Local $h=_WinAPI_GetDC(0),$MASHTAB=_WinAPI_GetDeviceCaps($h,118)/@DesktopWidth,$0=_WinAPI_ReleaseDC(0,$h)
MsgBox(4096,'$MASHTAB','$MASHTAB= '&$MASHTAB)


А как изменять - ребята подтянутся ))
 
Последнее редактирование:
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32

Andrey_A

а как определить масштаб в контексте двух мониторов, например хочу узнать масштаб Монитор 2
Код:
$aData = _WinAPI_EnumDisplayMonitors()
$hMon1=$aData[1][0] ; Монитор 1
$hMon2=$aData[2][0] ; Монитор 2
 

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
К сожалению нет под рукой 2-го монитора, чтобы потестировать и дать точный ответ.
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
Я не совсем понимаю, как вообще использовать хендл монитора, возвращаемый _WinAPI_EnumDisplayMonitors()
чтобы определить масштаб. Как Монитор 1 ($hMon1) связать с WinAPI_GetDC()
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
А точно масштаб разный?
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
Масштаб может быть разный, попробовал, на разных мониторах можно установить разное разрешение и масштаб
 

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
Я не совсем понимаю, как вообще использовать хендл монитора,
Добрался до 2-х мониторов - один из вариантов получения масштаба нескольких мониторов:
Код:
#include <WinAPIGdi.au3>
#include <Array.au3>

Local $aMonitors=_WinAPI_EnumDisplayMonitors()
If Not IsArray($aMonitors)Then Exit MsgBox(0,'','EnumDisplayMonitors error')
DllCall('Shcore.dll','long','SetProcessDpiAwareness','int',2)

Local $n=UBound($aMonitors),$aMashtab[$n]=[$n-1],$aDPI
For $i=1 To $aMonitors[0][0]
  $aDPI=_WinAPI_GetDpiForMonitor($aMonitors[$i][0],0)
  $aMashtab[$i]=IsArray($aDPI)? $aDPI[0]*100/96:'error'
Next
_ArrayDisplay($aMashtab,'Массив $aMashtab')

Func _WinAPI_SetProcessDpiAwareness($DPIAware)
  DllCall('Shcore.dll','long','SetProcessDpiAwareness','int',$DPIAware)
EndFunc

Func _WinAPI_GetDpiForMonitor($hMonitor,$dpiType)
  Local $X,$Y,$aRet=DllCall('Shcore.dll','long','GetDpiForMonitor','long',$hMonitor,'int',$dpiType,'uint*',$X,'uint*',$Y)
  If @error Or Not IsArray($aRet)Then Return SetError(1,0,0)
  Local $aDPI[2]=[$aRet[3],$aRet[4]]
  Return $aDPI
EndFunc

Доп. ссылки:
; https://www.autoitscript.com/forum/topic/189341-get-per-monitor-dpi-scaling-factor/
; https://stackru.com/questions/53648...vraschaet-nevernyij-koeffitsient-masshtabirov
 
Верх