Change screen resolution Rev. 1

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
Archimede
Posts: 509
Joined: 25 Nov 2021, 09:49
Location: Switzerland / Italy

Change screen resolution Rev. 1

15 Apr 2024, 12:01

Please, can you help me to convert this UDF Function Rev. 1.1 to Rev. 2?
This is a function that allow to change the screen resolution.
My problem is I no understand how to adapt the Rev.1 function
VarSetCapacity(...)
and the Rev. 1 function
NumPut
to Rev. 2 equivalent function.
Thank you very much

Code: Select all

DisplaySet( sDispRes := False, iColorRes := False, iFrequency := False, iDispNum := 0, sDispPos := False )
{
    ; MS constants
    Static CDS_TEST               := 0x00000002
    Static DISP_CHANGE_SUCCESSFUL := 0
    Static DM_ORIENTATION         := 0x00000001
    Static DM_POSITION            := 0x00000020
    Static DM_BITSPERPEL          := 0x00040000
    Static DM_PELSWIDTH           := 0x00080000
    Static DM_PELSHEIGHT          := 0x00100000
    Static DM_DISPLAYFREQUENCY    := 0x00400000

    ; ==============================================================================================================================
    ; AHK constants

    Static TCHARsize              := A_IsUnicode ? 64 : 32           ; size of TCHAR members dmDeviceName and dmFormName
    Static DEVMODEsize            := 92 + ( TCHARsize * 2 )          ; size of DEVMODE structure
    Static offSize                :=  4 +   TCHARsize                ; dmSize
    Static offFields              :=  8 +   TCHARsize                ; dmFields
    Static offPosition            := 12 +   TCHARsize                ; dmPosition
    Static offColorRes            := 40 + ( TCHARsize * 2 )          ; dmBitsPerPel
    Static offWidth               := 44 + ( TCHARsize * 2 )          ; dmPelsWidth
    Static offHeight              := 48 + ( TCHARsize * 2 )          ; dmPelsHeight
    Static offFrequency           := 56 + ( TCHARsize * 2 )          ; dmDisplayFrequency

    ; ==============================================================================================================================
    ; Create the DEVMODE structure

    VarSetCapacity( DEVMODE, DEVMODEsize, 0 )
    NumPut( DEVMODEsize, DEVMODE, offSize, "UShort" )

    ; =============================================================================================================================
    ; Initialize DEVMODEaddr and Fields with zero ( NULL ) in case the default registry settings shall be set.

    DEVMODEaddr := 0
    Fields := 0

    ; ==============================================================================================================================
    ; Check optional parameters.

    If( sDispRes )
    {

        aiCoord := StrSplit( sDispRes, "|" )
        If( aiCoord.MaxIndex() <> 2 )
        {

            ErrorLevel := "Bad parameter sDispRes!"
            Return False

        }                                                            ; If( Part0 <> 2 )

        NumPut( aiCoord[ 1 ], DEVMODE, offWidth, "UInt" )
        NumPut( aiCoord[ 2 ], DEVMODE, offHeight, "UInt" )
        Fields |= DM_PELSWIDTH | DM_PELSHEIGHT

    }                                                                ; If( sDispRes )

    If( iColorRes )
    {

        NumPut( iColorRes, DEVMODE, offColorRes, "UInt" )
        Fields |= DM_BITSPERPEL

    }                                                                ; If( iColorRes )

    If( iFrequency )
    {

        NumPut( iFrequency, DEVMODE, offFrequency, "UInt" )
        Fields |= DM_DISPLAYFREQUENCY

    }                                                                ; If( iFrequency )

    If( iDispNum < 1 )
        SysGet, iDispNum, MonitorPrimary

    If( sDispPos )
    {

        aiPos := StrSplit( sDispPos, "|" )
        SysGet, Displays, MonitorCount
        If(( aiPos.MaxIndex() <> 2 ) || ( Displays < 2 ))
        {

            ErrorLevel := "Bad parameter sDispPos!"
            Return False

        }                                                            ; If(( Part0 <> 2 ) || ( Displays < 2 ))
        If( iDispNum > Displays )
        {

            ErrorLevel := "Bad parameter iDispNum!"
            Return False

        }                                                            ; If( iDispNum > Displays )
        NumPut( aiPos[ 1 ], DEVMODE, offPosition + 0, "UInt" )
        NumPut( aiPos[ 2 ], DEVMODE, offPosition + 4, "UInt" )
        Fields |= DM_POSITION

    }                                                                ; If( sDispPos )

    ; ==============================================================================================================================
    ; Get the device name.

    SysGet, DevName, MonitorName, %iDispNum%
    If( DevName == "" )
    {

        ErrorLevel := "Bad parameter iDispNum!"
        Return False

    }                                                                ; If( DevName = "" )

    ; ==============================================================================================================================
    ; New settings will be checked, if any. If the DllCall returns an error the new settings won't be set.

    If( Fields )
    {

        NumPut( Fields, DEVMODE, offFields, "UInt" )
        DEVMODEaddr := &DEVMODE
        If( RetVal := DllCall( "ChangeDisplaySettingsEx", "Str", DevName, "Ptr", DEVMODEaddr, "Ptr", 0, "UInt", CDS_TEST, "Ptr", 0, "Int" ) )
        {

            ErrorLevel := RetVal
            Return False

        }                                                            ; If( RetVal := DllCall( "ChangeDisplaySettingsEx", "Str", DevName, "Ptr", DEVMODEaddr, "Ptr", 0, "UInt", CDS_TEST, "Ptr", 0, "Int" ) )
    }                                                                ; If( Fields )

    ; ==============================================================================================================================
    ; New settings will be set dynamically.

    If( RetVal := DllCall( "ChangeDisplaySettingsEx", "Str", DevName, "Ptr", DEVMODEaddr, "Ptr", 0, "UInt", 0, "Ptr", 0, "Int" ) )
    {

        ErrorLevel := RetVal
        Return False

    }                                                                ; If( RetVal := DllCall( "ChangeDisplaySettingsEx", "Str", DevName, "Ptr", DEVMODEaddr, "Ptr", 0, "UInt", 0, "Ptr", 0, "Int" ) )

    ; ==============================================================================================================================
    ; All done successfully.

    ErrorLevel := 0
    Return True
}
Rohwedder
Posts: 7659
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Change screen resolution Rev. 1

16 Apr 2024, 03:45

Hallo,
when I have to do this annoying (v1: VarSetCapacity -> v2: Buffer) translation, I always look at these examples:

Code: Select all

#Requires AutoHotkey v1.1.33
OnExit("ClipCursor")
Confine := False
q:: ; lock mouse in place On/Off
    CoordMode, Mouse, Screen
	MouseGetPos, x, y
    ClipCursor(Confine := !Confine, x++, y++, x, y)
Return
ClipCursor(Confine:=False, x1:=0 , y1:=0, x2:=1, y2:=1) {
	VarSetCapacity(Rect, 16)
	NumPut(x1, Rect, 0, "Int"), NumPut(y1, Rect, 4, "Int")
	NumPut(x2, Rect, 8, "Int"), NumPut(y2, Rect, 12, "Int")
	; or:
	; NumPut(x1, &Rect + 0), NumPut(y1, &Rect + 4)
	; NumPut(x2, &Rect + 8), NumPut(y2, &Rect + 12)
	DllCall("ClipCursor", "Ptr", Confine ? &Rect : 0)
	Return, False
}

Code: Select all

#Requires AutoHotkey v2.0
OnExit ClipCursor
q:: { ; lock mouse in place On/Off
    Static Confine := False
    CoordMode("Mouse", "Screen")
	MouseGetPos(&x, &y)
    ClipCursor(Confine := !Confine, x++, y++, x, y)
}
ClipCursor(Confine:=False, x1:=0, y1:=0, x2:=1, y2:=1) {
    Rect := Buffer(16)
	NumPut("Int", x1, Rect, 0), NumPut("Int", y1, Rect, 4)
	NumPut("Int", x2, Rect, 8), NumPut("Int", y2, Rect, 12)
	; or shorter:
    ; NumPut("Int", x1, "Int", y1, "Int", x2, "Int", y2, Rect)
    DllCall("ClipCursor", "Ptr", Confine ? Rect : 0)
	Return False
}
Archimede
Posts: 509
Joined: 25 Nov 2021, 09:49
Location: Switzerland / Italy

Re: Change screen resolution Rev. 1

16 Apr 2024, 03:57

Then, when I find

Code: Select all

VarSetCapacity(Rect, 16)
I can translate it with

Code: Select all

 Rect := Buffer(16)
and, obviously, adapt the syntax of all other?
Rohwedder
Posts: 7659
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Change screen resolution Rev. 1

16 Apr 2024, 04:06

I am not a DllCall expert (otherwise I wouldn't need such help scripts) but so far it has worked like this.
Archimede
Posts: 509
Joined: 25 Nov 2021, 09:49
Location: Switzerland / Italy

Re: Change screen resolution Rev. 1

16 Apr 2024, 04:15

Rohwedder: Thank you very much.
If there is any DllCall expert that can confirm it (or tell it is not exact) I think it is very useful.
Rohwedder
Posts: 7659
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Change screen resolution Rev. 1

16 Apr 2024, 07:08

Why do you want to convert this v1.1 function? Put it in a v1.1 script and call it with your v2 script via run with parameter passing.
Archimede
Posts: 509
Joined: 25 Nov 2021, 09:49
Location: Switzerland / Italy

Re: Change screen resolution Rev. 1

16 Apr 2024, 07:51

I am working in a V. 2 script.
Your idea is good, but I need a fast executing...
Archimede
Posts: 509
Joined: 25 Nov 2021, 09:49
Location: Switzerland / Italy

Re: Change screen resolution Rev. 1

16 Apr 2024, 08:10

Rohwedder: I found the problem: it is not simple.
If you are interested I can explain you that.
Archimede
Posts: 509
Joined: 25 Nov 2021, 09:49
Location: Switzerland / Italy

Re: Change screen resolution Rev. 1

16 Apr 2024, 09:02

Hallo.
It was very difficult, but I converted the UDF function to Rev. 2.0.
If you are interested tell me where I can upload it.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Google [Bot] and 73 guests