Is there really no way to set screen orientation in modern Windows 10? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
MedBooster
Posts: 54
Joined: 24 Nov 2022, 12:33

Re: Is there really no way to set screen orientation in modern Windows 10?

Post by MedBooster » 24 Apr 2023, 13:49

sraasch wrote: Sorry to dredge up an old post...

I'm wondering if anyone has translated this to the new syntax?

What do you mean by new syntax? And what would that accomplish? The script is working great for me in Windows 10 as well as Windows 11.

Isn't it working for you? Or do you just want to make it shorter?

Edit:
New YouTube video link:
MedBooster wrote: I changed the script to use the display in which the selected window is

The issue with using the cursor "Point" position is that the mouse position gets repositioned to the main display once you rotate a display,
so I recommend using the script that rotates the display the active/selected window is in. It is also more stable
(the "Point" one does not always work on other displays than the primary display)


Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

;help received by [+] https://www.autohotkey.com/boards/viewtopic.php?f=76&t=87453&p=492976&sid=643f7444d745cc540978272aece7091f#p492976


#singleInstance force
#noEnv


;put together by MedBooster thank you to everyone that helped!

;the rotation code by masonjar13 ChangeDisplaySettingsExW down below edited in get active monitor down below 




lookup:={"^!down":[0,0],"^!right":[1,1],"^!up":[2,0],"^!left":[3,1]}
return

^!down::
^!right::
^!up::
^!left::

display := GetMonitorName("Window")


if (lookup[a_thisHotkey][2]){ ; rotating to portrait
	sRes:=strSplit((cRes:=screenRes_Get(display)),["x","@"])
	if (sRes[2] < sRes[1]) {
		cRes:=sRes[2] "x" sRes[1] "@" sRes[3]
	}
} else { ; rotating to landscape
	sRes:=strSplit((cRes:=screenRes_Get(display)),["x","@"])
	if (sRes[2] > sRes[1]) {
		cRes:=sRes[2] "x" sRes[1] "@" sRes[3]
	}
 }
screenRes_Set(cRes,display,lookup[a_thisHotkey][1])
return

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)  
}
screenRes_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")) 
}



;Usage instructions below start of Vieira GetMonitorName

;GetMonitorName("Point") -> Uses the mouse location

;GetMonitorName("Window") -> Uses the active window
;GetMonitorName("Rect", [1921, 1, 1951, 10]) -> Uses the provided rectangle coordinates


;Get monitor cursor by Vieira

GetMonitorName(method := "Window", coords := "", default_to := "Nearest") {
    static default := {"Null": MONITOR_DEFAULTTONULL := 0x0, "Primary": MONITOR_DEFAULTTOPRIMARY := 0x1, "Nearest": MONITOR_DEFAULTTONEAREST := 0x2}
    If (method = "Window")
        hMonitor := DllCall("MonitorFromWindow", "UInt", WinExist("A"), "UInt", default[default_to], "Ptr")
    Else if (method = "Point") {
        if coords
            x := coords[1], y := coords[2]
        Else
            MouseGetPos, x, y
        hMonitor := DllCall("MonitorFromPoint", "Int64", (x&0xFFFFFFFF) | (y<<32), "Int", default[default_to], "Ptr")
    }
    Else if (method = "Rect") {
        if !coords
            Throw % "Rect method requires coordinates"
        VarSetCapacity(RECT, 16, 0)
        NumPut(coords[4], NumPut(coords[3], NumPut(coords[2], NumPut(coords[1], &RECT, "UInt"), "UInt"), "UInt"), "UInt")
        hMonitor := DllCall("MonitorFromRect", "Ptr", &RECT, "UInt", default[default_to], "Ptr")
    }
    Else
        Throw % "Invalid method"
    NumPut(VarSetCapacity(MONITORINFOEX, 40 + (32 << !!A_IsUnicode)), MONITORINFOEX, 0, "UInt")
    DllCall("GetMonitorInfoW", "Ptr", hMonitor, "Ptr", &MONITORINFOEX)
    return StrGet(&MONITORINFOEX + 40, 32)
}


[Mod edit: Replaced quote tags with [code][/code] tags.]
Last edited by MedBooster on 07 Oct 2023, 13:10, edited 2 times in total.

User avatar
Huh-Say What
Posts: 25
Joined: 24 Apr 2023, 20:44

Re: Is there really no way to set screen orientation in modern Windows 10?

Post by Huh-Say What » 25 Apr 2023, 08:17

New syntax = AHK Version 2 maybe?

usrlocalben
Posts: 1
Joined: 19 Jun 2023, 22:12

Re: Is there really no way to set screen orientation in modern Windows 10?

Post by usrlocalben » 20 Jun 2023, 01:02

sraasch wrote:
17 Apr 2023, 14:59
Sorry to dredge up an old post...

I'm wondering if anyone has translated this to the new syntax?
>> be me, surface book 2 user.
>> tablet orientation sensor stopped working two years ago
>> intel driver no longer includes rotation hotkeys
>> upgrading to win11 fixed nothing
>> turned to ahk for a solution
>> installed ahk2
>> all examples in this thread are ahk1

Here is a version for Ahk2.

Code: Select all

#SingleInstance

^!Up::SetDisplayOrientation(0)
^!Left::SetDisplayOrientation(1)
^!Down::SetDisplayOrientation(2)
^!Right::SetDisplayOrientation(3)

SetDisplayOrientation(theta) {
    DisplayMode.Retrieve()
               .Reorient(Orientation(theta))
               .Submit()
    }

class DisplayMode {
; provides a representation of a display mode incl.
; orientation, size, and methods for getting/setting
; the mode from/to Windows.
    __New(orientation, size, data) {
        this.orientation := orientation
        this.size := size
        this.data := data  ; extra windows opaque data
        }
    Reorient(a) =>
    ; create a new mode with a different orientation,
    ; adjusting the size as necessary. see dydy below
        this.ReplaceOrientation(a)
            .ReplaceSize(
               Abs(this.orientation.dydy()) != Abs(a.dydy())
               ? this.size.Transpose()  ; next mode is orthogonal
               : this.size)             ; next mode is 180 degrees
    ReplaceOrientation(a) =>
        DisplayMode(a, this.size, this.data)
    ReplaceSize(a) =>
        DisplayMode(this.orientation, a, this.data)
    static Retrieve() {
        msg := Buffer(220)
        NumPut("Short", 220, msg, 68)  ; dmSize
        DllCall("EnumDisplaySettingsW", "ptr", 0, "int", -1, "ptr", msg)
        o := NumGet(msg, 84, "int")
        w := NumGet(msg, 172, "uint")
        h := NumGet(msg, 176, "uint")
        return DisplayMode(Orientation(o), Vec2(w, h), msg)
        }
    Submit() {
        ; start with the opaque data, then apply instance
        msg := this.data
        NumPut("int", this.size.x, msg, 172)
        NumPut("int", this.size.y, msg, 176)
        NumPut("int", this.orientation.th, msg, 84)
        DllCall("ChangeDisplaySettingsW", "ptr", msg, "uint", 0)
        }
    }

class Orientation {
; provides a representation of a 2D rotation.
; value is given in integer units of 1/2pi, i.e.
; (counter-clockwise)
; 0 = 0, 1 = 1/2pi, 2 = pi, 3 = 3/2pi, 4 = 2pi
; this matches the windows orientation parameter
    __New(th) {
        this.th := th
        }

    ; Compute the Y-component of the Y-contribution of the
    ; screen-to-video translation matrix for a given mode
    ; or, change-in-y-with-respect-to-change-in-y, dydy
    ;
    ; mode: m0      m1      m2       m3
    ; rad:   0    1/2pi     pi     3/2pi
    ; deg:  0d     90d     180d    270d
    ;     |1 0|  | 0 1|  |-1  0|  |0 -1|
    ;     |0 1|  |-1 0|  | 0 -1|  |1  0|
    ;        ^       ^        ^       ^
    ;
    ; Use-Case:
    ; When submitting a settings change request to Windows,
    ; the size must be given in addition to the rotation.
    ; If the requested orientation is orthogonal to the
    ; current mode, then the width and height must be
    ; transposed. dydy is sufficient to compare modes.
    dydy() => [1, 0, -1, 0][this.th + 1]
    }

class Vec2 {
    __New(x, y) {
        this.x := x
        this.y := y
        }
    Transpose() => Vec2(this.y, this.x)
    }


MedBooster
Posts: 54
Joined: 24 Nov 2022, 12:33

Re: Is there really no way to set screen orientation in modern Windows 10?

Post by MedBooster » 13 Sep 2023, 09:00

sraasch wrote:
17 Apr 2023, 14:59
Sorry to dredge up an old post...

I'm wondering if anyone has translated this to the new syntax?
Edit: It is good that we have a V2 version now. So thank you for that. I'll give it a try, maybe it will free up some memory.

@usrlocalben
Your script seems to currently only affect the primary display, is that right?
I will keep you posted if I will be able to make it rotate the active window display just like the AHK V1 script I posted. :)
Last edited by MedBooster on 07 Oct 2023, 13:05, edited 6 times in total.

RussF
Posts: 1301
Joined: 05 Aug 2021, 06:36

Re: Is there really no way to set screen orientation in modern Windows 10?

Post by RussF » 13 Sep 2023, 10:09

MedBooster wrote: What do you mean by new syntax? And what would that accomplish? The script is working great for me in Windows 10 as well as Windows 11.
No need to be defensive. I, too, have many scripts that work just fine in V1 and will continue to run them that way until I have time to convert.

The previous post was the first one from the person, indicating they are probably a new AHK coder (their message somewhat confirms this). It would make sense that a new user would be starting out with V2 as that is what has been recommended on this forum ever since V2 was removed from beta and V1 was removed from support.

Russ

Post Reply

Return to “Ask for Help (v1)”