AutoHotkey Community

It is currently May 26th, 2012, 9:06 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: August 30th, 2007, 11:21 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
ChangeDisplayOrientation(Orientation [, Display, Flags])

Description: Changes the orientation of the display. :roll: (orientation=rotation)

Note: This feature is most likely chipset-specific. It is known to work on (some?) nVidia cards.
Code:
; Orientation
;    0  - DMDO_DEFAULT
;    1  - DMDO_90
;    2  - DMDO_180
;    3  - DMDO_270

; Display:
;   The name of the display device. Usually something like: \\.\DISPLAY1
;   If omitted, uses the default display device.

; dwflags:
;   0   - change dynamically (use ResetDisplay() to reset to settings in registry)
;   1   - change dynamically and update registry (CDS_UPDATEREGISTRY)
;   2   - test if the requested mode could be set (CDS_TEST)

ChangeDisplayOrientation(Orientation, Display="", dwflags=0)
{
    ; DEVMODE is 156 bytes on Windows XP and later.
    ; It is smaller on earlier versions of Windows, but that's okay.
    VarSetCapacity(devmode, 156, 0)
    NumPut(156, devmode, 36)    ; devmode.dmSize := sizeof(devmode)
   
    ; Get the current resolution and orientation.
    if ! DllCall("EnumDisplaySettings"
        , "uint", Display ? &Display : 0  ; device name or NULL
        , "int", -1  ; ENUM_CURRENT_SETTINGS
        , "uint", &devmode
        , "uint", 0)
        return ; FAILED
   
    ; Get current resolution.
    dmPelsWidth  := NumGet(devmode, 108)
    dmPelsHeight := NumGet(devmode, 112)

    if (mod(NumGet(devmode, 52),2) != mod(Orientation,2))
    {  ; Swap height and width.
        NumPut(dmPelsHeight, devmode, 108) ; width
        NumPut(dmPelsWidth,  devmode, 112) ; height
    }
   
    ; Set orientation.
    NumPut(Orientation, devmode, 52)
   
    ; Update display settings.
    return DllCall("ChangeDisplaySettingsEx"
        , "uint", Display ? &Display : 0
        , "uint", &devmode
        , "uint", 0
        , "uint", dwflags
        , "uint", 0)
   
    /* Return values for ChangeDisplaySettings
    #define DISP_CHANGE_SUCCESSFUL       0
    #define DISP_CHANGE_RESTART          1
    #define DISP_CHANGE_FAILED          -1
    #define DISP_CHANGE_BADMODE         -2
    #define DISP_CHANGE_NOTUPDATED      -3
    #define DISP_CHANGE_BADFLAGS        -4
    #define DISP_CHANGE_BADPARAM        -5
    #define DISP_CHANGE_BADDUALVIEW     -6
    */
}

ResetDisplay(Display="")
{
    return DllCall("ChangeDisplaySettingsEx"
        , "uint", Display ? &Display : 0  ; device name or NULL
        , "uint", 0, "uint", 0, "uint", 0, "uint", 0)
}
Example usage - rotates the default display device 180 degrees, waits 10 seconds, then resets it.
Code:
ChangeDisplayOrientation(2)  ; temporary by default (not saved to registry)
Sleep, 10000
ResetDisplay()  ; reset to the values currently in the registry
It also supports multiple monitors, with the help of GetDisplayDeviceList():
Code:
; Creates a global array using ArrayName as the base.
;   %ArrayName%             Number of display devices.
;   %ArrayName%Primary      The index of the primary display device.
;   %ArrayName%%N%          Name of display device (used by ChangeDisplaySettingsEx.)
;   %ArrayName%%N%ID        {GUID} value required for some registry operations.
; Only set if DesktopOnly=false:
;   %ArrayName%%N%Attached  =1 if "Extend the desktop onto this monitor" is enabled.
GetDisplayDeviceList(ArrayName, DesktopOnly=true)
{
    local DisplayDevice, Count, DeviceName, StateFlags, DeviceKey
   
    ; DISPLAY_DEVICE DisplayDevice
    VarSetCapacity(DisplayDevice, 424)
    ; lpDisplayDevice.cb := sizeof(DISPLAY_DEVICE)
    NumPut(424, DisplayDevice, 0)
   
    if %ArrayName%Primary
        %ArrayName%Primary =
   
    VarSetCapacity(DeviceName,  32, 0)
    VarSetCapacity(DeviceKey , 128, 0)
   
    Loop
    {
        if ! DllCall("EnumDisplayDevices"
            , "UInt", 0         ; lpDevice (NULL: use iDevNum to identify devices)
            , "UInt", A_Index-1 ; iDevNum
            , "UInt", &DisplayDevice ; lpDisplayDevice
            , "UInt", 0)        ; dwFlags
            break
       
        StateFlags := NumGet(DisplayDevice, 164)
       
        ; Useful DISPLAY_DEVICE.StateFlags:
        ;   #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
        ;   #define DISPLAY_DEVICE_PRIMARY_DEVICE      0x00000004
        ;   #define DISPLAY_DEVICE_MIRRORING_DRIVER    0x00000008

        if (StateFlags & 8) ; always exclude pseudo-devices
            continue
        if (DesktopOnly && !(StateFlags & 1))
            continue
       
        Count += 1

        DllCall("lstrcpynA", "Str", DeviceName  , "UInt", &DisplayDevice+4  , "int", 32)
        DllCall("lstrcpynA", "Str", DeviceKey   , "UInt", &DisplayDevice+296, "int", 128)
       
        %ArrayName%%Count% := DeviceName
       
        ; DeviceKey is something like:
        ;   \Registry\Machine\System\CurrentControlSet\Control\Video\{device-specific-value}\0000
        ; We want the:
        ;   {device-specific-value}
        SplitPath, DeviceKey,, DeviceKey ; "up one level"
        SplitPath, DeviceKey, %ArrayName%%Count%ID
       
        if (StateFlags & 4)
            %ArrayName%Primary := Count
       
        if (!DesktopOnly)
            %ArrayName%%Count%Attached := (StateFlags&1)
        ; else: function only returns attached monitors, no need for %..%Attached.
    }
   
    %ArrayName% := Count
}
Example (same as example above, but for the second monitor):
Code:
GetDisplayDeviceList("Display", false)

if Display2 ; second monitor
{
    ChangeDisplayOrientation(2, Display2)
    Sleep, 10000
    ResetDisplay(Display2)
}


Last edited by Lexikos on August 31st, 2007, 2:31 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 30th, 2007, 10:23 pm 
Refuses to work on my computer.. returns -2 which according to the script means "DISP_CHANGE_BADMODE"


:shock:

I tried using the 90°,180, and 270. With no results from any of them.
My computer is constantly running an ATI program in the tray that controls the resolution. But closing it then trying the script has no results, either.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 30th, 2007, 10:34 pm 
Offline

Joined: June 26th, 2006, 6:14 pm
Posts: 1379
Location: USA
NotLoggedIn-Conquer wrote:
... returns -2 ...


Same here.

IBM Thinkpad, ATI graphics


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 30th, 2007, 11:26 pm 
Found any work around's at all?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 30th, 2007, 11:44 pm 
Offline
User avatar

Joined: August 30th, 2005, 8:43 pm
Posts: 8666
Location: Salem, MA
I think it depends on your video chipset. I think this is an NVidia feature.

_________________
Image
(Common Answers) - New Tutorials Forum - Humongous FAQ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 30th, 2007, 11:45 pm 
Ah. Ic. Thx.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 31st, 2007, 2:30 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
Chipset feature, probably. Not just nVidia, though. I've used Dells with integrated (Intel?) graphics that have this feature. ^!Up (or ^!Down?) turns the screen upside down (the other key resets it.) The other orientations don't work on those Dell's, though. At least, there's no hotkey for them. My PC doesn't have the ^!Arrow hotkeys, though... yet, :lol:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 13th, 2008, 8:46 pm 
Is there a tweak that will enable this on ATI cards? :)


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Klark92, Stigg, Yahoo [Bot] and 19 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group