Page 1 of 2

How do I get the SCALE directly from Windows?

Posted: Tue Aug 24, 2021 11:28 am
by StarWarsFan
Example:

Image

In the example picture it is 100

How do I read that value in PureBasic code?

Re: How do I get the SCALE

Posted: Tue Aug 24, 2021 12:48 pm
by Marc56us
See help on DesktopScaledX(), DesktopScaledY()
PB >= 5.70
:wink:

Re: How do I get the SCALE

Posted: Tue Aug 24, 2021 1:35 pm
by infratec
Extended version:

Code: Select all

DesktopScaledX(100)

Re: How do I get the SCALE

Posted: Tue Aug 24, 2021 2:45 pm
by StarWarsFan
THANK YOU! WORKS!

Re: How do I get the SCALE

Posted: Thu Aug 26, 2021 3:23 pm
by StarWarsFan
Ok, this PB-command does only work when DPI-aware is ON when compiling
So it if you have DPI-aware = OFF Windows is still scaling at xxx % and the value that PB reads is always 100,
so it does not tell you at what scale Windows is actually working then (see picture!)

How can I read the value directly from Windows?
Is there maybe an API command for that or some already existing code
to get that integer value? (see picture!)
** without enabling DPI-awareness in my code** ?

Re: How do I get the SCALE directly from Windows?

Posted: Thu Aug 26, 2021 4:25 pm
by Mijikai
https://docs.microsoft.com/en-us/window ... formonitor

Code: Select all

HRESULT GetDpiForMonitor(
  HMONITOR         hmonitor,
  MONITOR_DPI_TYPE dpiType,
  UINT             *dpiX,
  UINT             *dpiY
);

Re: How do I get the SCALE directly from Windows?

Posted: Thu Aug 26, 2021 4:38 pm
by StarWarsFan
Nice, but that also only works if the calling programm is compiled DPI-aware= ON
"When you call GetDpiForMonitor, you will receive different DPI values depending on the DPI awareness of the calling application."

But still I would like to get that value without being DPI-aware,
because regardless of that settings, I can also read the screen and see the value (see picture)

So there must be another way. Where is that value stored?

Re: How do I get the SCALE directly from Windows?

Posted: Thu Aug 26, 2021 4:42 pm
by Mijikai
This works for unaware:

Code: Select all

int GetDeviceCaps(
  HDC hdc,
  int index
);

;with LOGPIXELSX and LOGPIXELSY
https://docs.microsoft.com/en-us/window ... devicecaps

Re: How do I get the SCALE directly from Windows?

Posted: Thu Aug 26, 2021 5:08 pm
by StarWarsFan
That goes into the right direction. Thanks, Mijikai!

I am now reading up the docs in the link you provided, but I honestly have no clue how to put this into PB-code and what "A handle to the DC." means. Is there somewhere a functioning PB-code example?

Re: How do I get the SCALE directly from Windows?

Posted: Thu Aug 26, 2021 5:40 pm
by Mijikai
Example

Code: Select all

EnableExplicit

Procedure.i GetDPI(*X.Double,*Y.Double)
  Protected hdc.i
  hdc = GetDC_(#Null)
  If hdc
    *X\d = GetDeviceCaps_(hdc,#LOGPIXELSX) / 96.0
    *Y\d = GetDeviceCaps_(hdc,#LOGPIXELSY) / 96.0
    ReleaseDC_(#Null,hdc)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.i Main()
  Protected factor_x.d
  Protected factor_y.d
  Debug GetDPI(@factor_x,@factor_y)
  Debug factor_x
  Debug factor_y
  ProcedureReturn #Null
EndProcedure

Main()

End

Re: How do I get the SCALE directly from Windows?

Posted: Thu Aug 26, 2021 5:44 pm
by chi

Code: Select all

hdc = GetDC_(0)
Debug GetDeviceCaps_(hdc, #LOGPIXELSY) / 96.0
ReleaseDC_(0, hdc)

Re: How do I get the SCALE directly from Windows?

Posted: Fri Aug 27, 2021 5:09 am
by breeze4me
Here is a way to get the DPI scale factor per monitor.

https://github.com/lihas/windows-DPI-scaling-sample

Code: Select all

;DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY: uint
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER                   = $FFFFFFFF
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15                    = 0
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO                  = 1
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO         = 2
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO         = 3
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI                     = 4
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI                    = 5
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS                    = 6
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN                   = 8
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI                     = 9
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL    = 10
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED    = 11
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL            = 12
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED            = 13
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE              = 14
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST                = 15
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL                = $80000000
#DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32            = $FFFFFFFF


;DISPLAYCONFIG_SCANLINE_ORDERING: uint
#DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED                 = 0
#DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE                 = 1
#DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED                  = 2
#DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST  = #DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED
#DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST  = 3
#DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32                = $FFFFFFFF


;DISPLAYCONFIG_ROTATION: uint
#DISPLAYCONFIG_ROTATION_IDENTITY     = 1
#DISPLAYCONFIG_ROTATION_ROTATE90     = 2
#DISPLAYCONFIG_ROTATION_ROTATE180    = 3
#DISPLAYCONFIG_ROTATION_ROTATE270    = 4
#DISPLAYCONFIG_ROTATION_FORCE_UINT32 = $FFFFFFFF


;DISPLAYCONFIG_SCALING: uint
#DISPLAYCONFIG_SCALING_IDENTITY                  = 1
#DISPLAYCONFIG_SCALING_CENTERED                  = 2
#DISPLAYCONFIG_SCALING_STRETCHED                 = 3
#DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX    = 4
#DISPLAYCONFIG_SCALING_CUSTOM                    = 5
#DISPLAYCONFIG_SCALING_PREFERRED                 = 128
#DISPLAYCONFIG_SCALING_FORCE_UINT32              = $FFFFFFFF


;DISPLAYCONFIG_PIXELFORMAT : uint
#DISPLAYCONFIG_PIXELFORMAT_8BPP          = 1
#DISPLAYCONFIG_PIXELFORMAT_16BPP         = 2
#DISPLAYCONFIG_PIXELFORMAT_24BPP         = 3
#DISPLAYCONFIG_PIXELFORMAT_32BPP         = 4
#DISPLAYCONFIG_PIXELFORMAT_NONGDI        = 5
#DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32  = $ffffffff


;DISPLAYCONFIG_MODE_INFO_TYPE : uint
#DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1
#DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2
#DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = $FFFFFFFF


;DISPLAYCONFIG_DEVICE_INFO_TYPE : uint
#DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME             = 1
#DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME             = 2
#DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE   = 3
#DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME            = 4
#DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE      = 5
#DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE        = 6
#DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32                = $FFFFFFFF

#DISPLAYCONFIG_DEVICE_INFO_GET_DPI_SCALE = -3


#QDC_ALL_PATHS = $1
#QDC_ONLY_ACTIVE_PATHS = $2
#QDC_DATABASE_CURRENT = $4

#SDC_TOPOLOGY_INTERNAL = $1
#SDC_TOPOLOGY_CLONE = $2
#SDC_TOPOLOGY_EXTEND = $4
#SDC_TOPOLOGY_EXTERNAL = $8
#SDC_TOPOLOGY_SUPPLIED = $10
#SDC_USE_DATABASE_CURRENT = #SDC_TOPOLOGY_INTERNAL | #SDC_TOPOLOGY_CLONE | #SDC_TOPOLOGY_EXTEND | #SDC_TOPOLOGY_EXTERNAL

#SDC_USE_SUPPLIED_DISPLAY_CONFIG = $20
#SDC_VALIDATE = $40
#SDC_APPLY = $80
#SDC_NO_OPTIMIZATION = $100
#SDC_SAVE_TO_DATABASE = $200
#SDC_ALLOW_CHANGES = $400
#SDC_PATH_PERSIST_IF_REQUIRED = $800
#SDC_FORCE_MODE_ENUMERATION = $1000
#SDC_ALLOW_PATH_ORDER_CHANGES = $2000

#DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1
#DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2
#DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = $FFFFFFFF

#DISPLAYCONFIG_PATH_ACTIVE = 1

;DISPLAYCONFIG_TOPOLOGY_ID
#DISPLAYCONFIG_TOPOLOGY_INTERNAL = $1
#DISPLAYCONFIG_TOPOLOGY_CLONE = $2
#DISPLAYCONFIG_TOPOLOGY_EXTEND = $4
#DISPLAYCONFIG_TOPOLOGY_EXTERNAL = $8
#DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32 = $FFFFFFFF

#DISPLAYCONFIG_PATH_MODE_IDX_INVALID = $FFFFFFFF

#DISPLAYCONFIG_SOURCE_IN_USE = $1

;DISPLAYCONFIG_DEVICE_INFO_TYPE;
#DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1
#DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2
#DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3
#DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4
#DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5
#DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE = 6
#DISPLAYCONFIG_DEVICE_INFO_GET_SUPPORT_VIRTUAL_RESOLUTION = 7
#DISPLAYCONFIG_DEVICE_INFO_SET_SUPPORT_VIRTUAL_RESOLUTION = 8
#DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = $FFFFFFFF

#CCHDEVICENAME = 32

#CCHFORMNAME = 32

Structure DISPLAYCONFIG_PATH_SOURCE_INFO
  adapterId.LUID
  id.l
  StructureUnion
    modeInfoIdx.l
    
    cloneGroupId.l
    sourceModeInfoIdx.l
  EndStructureUnion
  statusFlags.l
EndStructure

Structure DISPLAYCONFIG_RATIONAL
  Numerator.l
  Denominator.l
EndStructure

Structure DISPLAYCONFIG_PATH_TARGET_INFO
  adapterId.LUID
  id.l
  StructureUnion
    modeInfoIdx.l
    
    desktopModeInfoIdx.l
    targetModeInfoIdx.l
  EndStructureUnion
  outputTechnology.l
  rotation.l
  scaling.l
  refreshRate.DISPLAYCONFIG_RATIONAL
  scanLineOrdering.l
  targetAvailable.l
  statusFlags.l
EndStructure

Structure DISPLAYCONFIG_PATH_INFO
  sourceInfo.DISPLAYCONFIG_PATH_SOURCE_INFO
  targetInfo.DISPLAYCONFIG_PATH_TARGET_INFO
  flags.l
EndStructure

Structure DISPLAYCONFIG_2DREGION
  cx.l
  cy.l
EndStructure

Structure DISPLAYCONFIG_VIDEO_SIGNAL_INFO
  pixelRate.q
  hSyncFreq.DISPLAYCONFIG_RATIONAL
  vSyncFreq.DISPLAYCONFIG_RATIONAL
  activeSize.DISPLAYCONFIG_2DREGION
  totalSize.DISPLAYCONFIG_2DREGION
  StructureUnion
    videoStandard.l
    vSyncFreqDivider.l
    reserved.l
    ;videoStandard.l
  EndStructureUnion
  scanLineOrdering.l
EndStructure

Structure DISPLAYCONFIG_TARGET_MODE
  targetVideoSignalInfo.DISPLAYCONFIG_VIDEO_SIGNAL_INFO
EndStructure

Structure DISPLAYCONFIG_SOURCE_MODE
  width.l
  height.l
  pixelFormat.l
  position.POINT
EndStructure

Structure DISPLAYCONFIG_DESKTOP_IMAGE_INFO
  PathSourceSize.POINT
  DesktopImageRegion.RECT
  DesktopImageClip.RECT
EndStructure

Structure DISPLAYCONFIG_MODE_INFO
  infoType.l
  id.l
  adapterId.LUID
  StructureUnion
    targetMode.DISPLAYCONFIG_TARGET_MODE
    sourceMode.DISPLAYCONFIG_SOURCE_MODE
    desktopImageInfo.DISPLAYCONFIG_DESKTOP_IMAGE_INFO
  EndStructureUnion
EndStructure


Structure DISPLAYCONFIG_DEVICE_INFO_HEADER
  type.l
  size.l
  adapterId.LUID
  id.l
EndStructure

Structure DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS
  StructureUnion
    friendlyNameFromEdid.l
    friendlyNameForced.l
    edidIdsValid.l
    reserved.l
    
    value.l
  EndStructureUnion
EndStructure

Structure DISPLAYCONFIG_TARGET_DEVICE_NAME
  header.DISPLAYCONFIG_DEVICE_INFO_HEADER
  flags.DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS
  outputTechnology.l
  edidManufactureId.w
  edidProductCodeId.w
  connectorInstance.l
  monitorFriendlyDeviceName.c[64]
  monitorDevicePath.c[128]
EndStructure

Structure DISPLAYCONFIG_SOURCE_DEVICE_NAME
  header.DISPLAYCONFIG_DEVICE_INFO_HEADER
  viewGdiDeviceName.c[#CCHDEVICENAME]
EndStructure

Structure PathArray
  dp.DISPLAYCONFIG_PATH_INFO[0]
EndStructure

Structure ModeArray
  dm.DISPLAYCONFIG_MODE_INFO[0]
EndStructure


Structure DISPLAYCONFIG_SOURCE_DPI_SCALE_GET
  header.DISPLAYCONFIG_DEVICE_INFO_HEADER
  minScaleRel.l
  curScaleRel.l
  maxScaleRel.l
EndStructure

Prototype.l ptGetDisplayConfigBufferSizes(flags.i, *numPathArrayElements, *numModeInfoArrayElements)
Prototype.l ptQueryDisplayConfig(flags.i, *numPathArrayElements, *pathArray, *numModeInfoArrayElements, *modeInfoArray, *currentTopologyId)
Prototype.l ptDisplayConfigGetDeviceInfo(*requestPacket)

Define GetDisplayConfigBufferSizes.ptGetDisplayConfigBufferSizes
Define QueryDisplayConfig.ptQueryDisplayConfig
Define DisplayConfigGetDeviceInfo.ptDisplayConfigGetDeviceInfo

Define PathArraySize, ModeArraySize, i, minAbs

Dim DPI_List.i(11)

DPI_List(0) = 100
DPI_List(1) = 125
DPI_List(2) = 150
DPI_List(3) = 175
DPI_List(4) = 200
DPI_List(5) = 225
DPI_List(6) = 250
DPI_List(7) = 300
DPI_List(8) = 350
DPI_List(9) = 400
DPI_List(10) = 450
DPI_List(11) = 500

Define DevTargetName.DISPLAYCONFIG_TARGET_DEVICE_NAME
Define ScaleFactor.DISPLAYCONFIG_SOURCE_DPI_SCALE_GET

Define *PathArray.PathArray
Define *ModeArray.ModeArray

If OpenLibrary(0, "user32.dll")
  
  GetDisplayConfigBufferSizes = GetFunction(0, "GetDisplayConfigBufferSizes")
  QueryDisplayConfig = GetFunction(0, "QueryDisplayConfig")
  DisplayConfigGetDeviceInfo = GetFunction(0, "DisplayConfigGetDeviceInfo")
  
  If GetDisplayConfigBufferSizes And QueryDisplayConfig And DisplayConfigGetDeviceInfo
    
    If GetDisplayConfigBufferSizes(#QDC_ONLY_ACTIVE_PATHS, @PathArraySize, @ModeArraySize) = #ERROR_SUCCESS
      
      ;Debug PathArraySize
      ;Debug ModeArraySize
      ;Debug "-----"
      
      *PathArray = AllocateMemory(PathArraySize * SizeOf(DISPLAYCONFIG_PATH_INFO))
      *ModeArray = AllocateMemory(ModeArraySize * SizeOf(DISPLAYCONFIG_MODE_INFO))
      
      If QueryDisplayConfig(#QDC_ONLY_ACTIVE_PATHS, @PathArraySize, *PathArray, @ModeArraySize, *ModeArray, 0) = #ERROR_SUCCESS
        
        For i = 1 To PathArraySize
          
          DevTargetName\header\type = #DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME
          DevTargetName\header\size = SizeOf(DISPLAYCONFIG_TARGET_DEVICE_NAME)
          DevTargetName\header\id = *PathArray\dp[i - 1]\targetInfo\id
          DevTargetName\header\adapterId = *PathArray\dp[i - 1]\targetInfo\adapterId
          
          If DisplayConfigGetDeviceInfo(DevTargetName) = #ERROR_SUCCESS
            ;Debug PeekS(@DevTargetName\monitorDevicePath, 128)
            Debug "Monitor Name: " + PeekS(@DevTargetName\monitorFriendlyDeviceName, 64)
            Debug ""
          EndIf
          
          ScaleFactor\header\type = #DISPLAYCONFIG_DEVICE_INFO_GET_DPI_SCALE
          ScaleFactor\header\size = SizeOf(DISPLAYCONFIG_SOURCE_DPI_SCALE_GET)
          ScaleFactor\header\id = *PathArray\dp[i - 1]\sourceInfo\id
          ScaleFactor\header\adapterId = *PathArray\dp[i - 1]\sourceInfo\adapterId
          
          If DisplayConfigGetDeviceInfo(ScaleFactor) = #ERROR_SUCCESS
            
            If ScaleFactor\curScaleRel < ScaleFactor\minScaleRel
              ScaleFactor\curScaleRel = ScaleFactor\minScaleRel
            ElseIf ScaleFactor\curScaleRel > ScaleFactor\maxScaleRel
              ScaleFactor\curScaleRel = ScaleFactor\maxScaleRel
            EndIf
            
            minAbs = Abs(ScaleFactor\minScaleRel)
            If ArraySize(DPI_List()) + 1 >= (minAbs + ScaleFactor\maxScaleRel + 1)
              Debug "Recommended scale: " + DPI_List(minAbs)
              Debug "Current scale: " + DPI_List(minAbs + ScaleFactor\curScaleRel)
              Debug "Max scale: " + DPI_List(minAbs + ScaleFactor\maxScaleRel)
              Debug "------------------------------------------------"
            EndIf
            
          EndIf
        Next
        
      EndIf
      
    EndIf
  EndIf
  
  CloseLibrary(0)
  
EndIf

The following is an example of the results of executing the code.
Monitor Name: 2777M

Recommended scale: 100
Current scale: 100
Max scale: 175
------------------------------------------------
Monitor Name: PHL 275M8RZ

Recommended scale: 100
Current scale: 125
Max scale: 225
------------------------------------------------

Re: How do I get the SCALE directly from Windows?

Posted: Fri Aug 27, 2021 8:10 am
by Marc56us
Another solution: create your own (command line) tool... with PB :D

Code: Select all

; Get_DPI_Scale.exe
; Compile it as Console and with DPI aware
OpenConsole()
DPI$ = Str(DesktopResolutionX() * 100)
Print(DPI$)
Sample of usage (no need DPI aware)

Code: Select all

; Get_DPI_Scale.exe
; Compile it with as Console and with DPI aware
Compiler = RunProgram("Get_DPI_Scale.exe", "", "", #PB_Program_Open | #PB_Program_Read)
If Compiler
  While ProgramRunning(Compiler)
    If AvailableProgramOutput(Compiler)
      Debug ReadProgramString(Compiler)
    EndIf
  Wend
  CloseProgram(Compiler) 
EndIf
End

Code: Select all

100
Maybe we can even create a DLL? (I never did it)
:wink:

Re: How do I get the SCALE directly from Windows?

Posted: Fri Aug 27, 2021 9:43 am
by RASHAD

Code: Select all

  Global ScaleX1.d,ScaleY1.d,ScaleX2.d,ScaleY2.d,ScaleX.d,ScaleY.d

  ScaleX1 = GetDeviceCaps_(GetDC_(0),#LOGPIXELSX) / 96
  ScaleY1 = GetDeviceCaps_(GetDC_(0),#LOGPIXELSY) / 96
  ExamineDesktops()
  h.WINDOWPLACEMENT
  GetWindowPlacement_(GetDesktopWindow_(),@h)
  ScaleX2 =  DesktopWidth(0) / h\rcNormalPosition\right
  ScaleY2 =  DesktopHeight(0) / h\rcNormalPosition\bottom
  If ScaleX1 > ScaleX2
     ScaleX = ScaleX1
  Else
     ScaleX = ScaleX2
  EndIf
  If ScaleY1 > ScaleY2
     ScaleY = ScaleY1
  Else
     ScaleY = ScaleY2
  EndIf
  If OSVersion() < #PB_OS_Windows_Vista
    ScaleX = ScaleX1
    ScaleY = ScaleY1
  EndIf
  MessageRequester("Info","ScaleX : "+StrD(ScaleX) +#CRLF$ +"ScaleY : "+StrD(scaleY),#PB_MessageRequester_Ok|#MB_ICONINFORMATION)
  Debug ScaleX
  Debug ScaleY
Scale * 100

Re: How do I get the SCALE directly from Windows?

Posted: Fri Aug 27, 2021 10:34 am
by Rinzwind
You need GetDpiForMonitor on Windows because each monitor can have it's own settings. Even more common now. Having a main 4K monitor with your old one next to it. Sadly, PB does not support that yet (incl. it's gadgets) which makes it a real PAIN if you want to support it properly in which case you better turn off PB hi-dpi support and handle it all yourself.