ScreenResolution_ : Get / List / Set | DualMID() : MonitorID for Dual monitor setup

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

ScreenResolution_ : Get / List / Set | DualMID() : MonitorID for Dual monitor setup

22 Jun 2020, 14:54

ScreenResolution_Get(Disp)
Returns current screen resolution as WxHaF (Width x Height @ Frequency), for example: 1280x720@60
Parameter:
  • Disp should be a MonitorName, eg: \\.\DISPLAY1. If Disp is omitted or is zero, primary monitor will be presumed.
Usage example: ScreenResolution_Get("\\.\DISPLAY1")
 
 
ScreenResolution_List(Disp)
Returns a valid MatchList of all supported screen resolution for a monitor.
Parameter:
  • Disp should be a MonitorName, eg: \\.\DISPLAY1. If Disp is omitted or is zero, primary monitor will be presumed.
Usage example: ScreenResolution_List("\\.\DISPLAY1")
 
Note 1: By default the function filters out entries whose frequency is less than 60Hz. Find and change this condition NumGet(DM,184,"UInt")>59 accordingly.
Note 2: If monitor is connected via a VGA port, this function will return MatchList even if the monitor is not connected to mains.
For HDMI, the monitor needs to be at least be in SOFT-OFF state.

 
 
ScreenResolution_Set(WxHaF, [Disp])
Changes screen resolution and returns 0 (DISP_CHANGE_SUCCESSFUL) when successful.
Return values
Parameters:
  • WxHaF : Pass screen resolution as WxHaF (Width x Height @ Frequency), for example: 1280x720@60
  • Disp should be a MonitorName, eg: \\.\DISPLAY1. If Disp is omitted or is zero, primary monitor will be presumed.
Usage example: ScreenResolution_Set("1280x024@60", "\\.\DISPLAY1")
 
Note: If your device is has dual-display, the function will return DISP_CHANGE_SUCCESSFUL even when Disp is not part of the desktop.
It is better to test, for eg. ScreenResolution_Get("\\.\DISPLAY2") before attempting to set a resolution.

 
 
The functions:

Code: Select all

ScreenResolution_Get(Disp:=0) {              ; v0.90 By SKAN on D36I/D36M @ tiny.cc/screenresolution
Local DM, N:=VarSetCapacity(DM,220,0) 
Return DllCall("EnumDisplaySettingsW", (Disp=0 ? "Ptr" : "WStr"),Disp, "Int",-1, "Ptr",&DM)=0 ? ""
     : Format("{:}x{:}@{:}", NumGet(DM,172,"UInt"),NumGet(DM,176,"UInt"),NumGet(DM,184,"UInt")) 
}

ScreenResolution_List(Disp:=0) {             ; v0.90 By SKAN on D36I/D36M @ tiny.cc/screenresolution
Local DM, N:=VarSetCapacity(DM,220,0), L:="", DL:=","
  While DllCall("EnumDisplaySettingsW", (Disp=0 ? "Ptr" : "WStr"),Disp, "Int",A_Index-1, "Ptr",&DM)
  If ( NumGet(DM,168,"UInt")=32 && NumGet(DM,184,"UInt")>59)
    L.=Format("{:}x{:}@{:}" . DL, NumGet(DM,172,"UInt"),NumGet(DM,176,"UInt"),NumGet(DM,184,"UInt")) 
Return RTrim(L,DL) 
}

ScreenResolution_Set(WxHaF, Disp:=0) {       ; v0.90 By SKAN on D36I/D36M @ tiny.cc/screenresolution
Local DM, N:=VarSetCapacity(DM,220,0), F:=StrSplit(WxHaF,["x","@"],A_Space)
Return DllCall("ChangeDisplaySettingsExW",(Disp=0 ? "Ptr" : "WStr"),Disp, "Ptr",NumPut(F[3]
     , NumPut(F[2], NumPut(F[1], NumPut(32, NumPut(0x5C0000, NumPut(220,DM,68,"UShort")+2,"UInt")+92
     , "UInt"),"UInt"),"UInt")+4,"UInt")-188, "Ptr",0, "Int",0, "Int",0)  
}
 
Credit: Thanks to @just me. Picked required unicode structure offsets from his ChangeDisplaySettings()
My Scripts and Functions: V1  V2
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

DualMID() : Returns array of MonitorID with matching MonitorName

22 Jun 2020, 16:19

The function:

Code: Select all

DualMID() {                                           ; v0.90 By SKAN on D36I/D36M @ tiny.cc/dualmid
Local
  ClassGuid:="{4d36e96e-e325-11ce-bfc1-08002be10318}", M1:="", M2:="", M3:=""
  WMI:=ComObjGet("winmgmts:{impersonationLevel=impersonate}!\\" . A_ComputerName . "\root\cimv2")
  For Monitor in  WMI.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE ClassGuid='" . ClassGuid . "'")
  {
    M:=StrSplit(U:=Monitor.DeviceID, ["\","UID"]),     M%A_Index%:=Format("{2:}\{4:}", M*) 
    RegRead, U, HKLM\SYSTEM\CurrentControlSet\Enum\%U%\Device Parameters, EDID
    U%A_Index% := Format("{1:}_{8:}{9:}{6:}{7:}{4:}{5:}{2:}{3:}", M[2], StrSplit(SubStr(U, 25, 8))*)
  } 

  Loop % ( 2, VarSetCapacity(DD,840,0),  NumPut(840,DD,0,"UInt"), D1:="", D2:="" )
    DllCall("EnumDisplayDevicesW", "wStr","\\.\DISPLAY" . A_Index, "Int",0, "Ptr",&DD, "Int",1)
  , D:=StrSplit(StrGet(&DD+328,"UTF-16"),["#","UID"]), D%A_Index%:=(D ? Format("{2:}\{4:}",D*) : "")

  R1:="\\.\DISPLAY1",  R2:="\\.\DISPLAY2", NUL:=""
  Return (M3) ? NUL  : (M2="")       ?          {(U1):(R1)}   
                     : (M2 && D2)    ? (M2=D2 ? {(U1):(R1),(U2):(R2)} : {(U2):(R1),(U1):(R2)})
                     : (M2 && D2="") ? (M1=D1 ? {(U1):(R1),(U2):(R2)} : {(U2):(R1),(U1):(R2)}) : NUL
}
 
 

This function is meant for and should work correctly with devices (Tablets/Laptops/PC) having on-board-graphics that support dual monitors.
The function will fail if 3rd display or additional graphics adapter is present.

DualMID() : MID is MonitorID (like PID is ProcessID) and Dual means this works only with dual monitor (single graphics adapter) devices.

Step 1: You need to find your monitor ID's.
 
  • Code: Select all

    L := ""
    For K,V in DualMID()
      L .= K . A_Tab . V . "`n"
    
    SysGet, Primary, MonitorName
    MsgBox % L . "`n`nPrimary`t" . Primary
    
    • Image
 
Step 2: You may now hard-code a MID into your script.
 

Code: Select all

ScreenResolution_Set("1280x1024@60", DualMID().DELA04B_4A314849)
My Scripts and Functions: V1  V2
User avatar
elModo7
Posts: 217
Joined: 01 Sep 2017, 02:38
Location: Spain
Contact:

Re: ScreenResolution_ : Get / List / Set | DualMID() : MonitorID for Dual monitor setup

22 Jun 2020, 17:36

Nice! Some scripts to play with tomorrow and add to the lib folder!
Seems like the simplest way to deal with 2 screens.
ozzii
Posts: 481
Joined: 30 Oct 2013, 06:04

Re: ScreenResolution_ : Get / List / Set | DualMID() : MonitorID for Dual monitor setup

23 Jun 2020, 09:01

If you don't have enough that I said to you 'Thank you'..... So.... Thank you again for your work ;)
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: ScreenResolution_ : Get / List / Set | DualMID() : MonitorID for Dual monitor setup

24 Jun 2020, 07:10

ozzii wrote:If you don't have enough that I said to you 'Thank you'..... So.... Thank you again for your work ;)
Thanks for all the encouragement, friend. :)
My Scripts and Functions: V1  V2
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: ScreenResolution_ : Get / List / Set | DualMID() : MonitorID for Dual monitor setup

02 Jan 2021, 19:53

Hey SKAN! Appreciate the code, but also, wow is it hard to read/edit lol. With some help from Discord, made a _Set that also changes orientation. (Name was too long imo, so I shortened it.)

Code: Select all

screenRes_Set(WxHaF, Disp:=0, orient:=0) {       ; v0.90 By SKAN on D36I/D36M @ tiny.cc/screenresolution ; edited orientation in by Masonjar13
	Local DM, N:=VarSetCapacity(DM,220,0), F:=StrSplit(WxHaF,["x","@"],A_Space)
	Return DllCall("ChangeDisplaySettingsExW",(Disp=0 ? "Ptr" : "WStr"),Disp,"Ptr",NumPut(F[3],NumPut(F[2],NumPut(F[1]
	,NumPut(32,NumPut(0x5C0080,NumPut(220,NumPut(orient,DM,84,"UInt")-20,"UShort")+2,"UInt")+92,"UInt"),"UInt")
	,"UInt")+4,"UInt")-188, "Ptr",0, "Int",0, "Int",0)  
}
orient arg should be 0-3, 0 being normal landscape, then rotating 90° from there.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
User avatar
pizzapizze
Posts: 44
Joined: 08 May 2019, 15:38

Re: ScreenResolution_ : Get / List / Set | DualMID() : MonitorID for Dual monitor setup

16 Jan 2021, 20:57

I changed my resolution and it actually works, nice

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 71 guests