aboutsummaryrefslogtreecommitdiff
path: root/drm.ahk
blob: ed864abb89fce28e9550f02eb733c4a581c94c40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#NoEnv
#SingleInstance Force
#Persistent

; Try to retrieve user-set resolutions

RegRead, ResolutionsString, HKEY_CURRENT_USER\Software\JohnAJ\DRM, Resolutions

if (ErrorLevel != 1)
  goto Start

; Fall back on default resolutions

ResolutionsString = 1600x1200|1024x768|800x600|640x480 ; 4:3
if (A_ScreenWidth/A_ScreenHeight = 1.6)
  ResolutionsString = 1920x1200|1680x1050|1440x900|1280x800 ; 16:10
if (Round(A_ScreenWidth/A_ScreenHeight, 2) = 1.77)
  ResolutionsString = 1920x1080|1366x768|1280x720|854x480 ; 16:9

RegWrite, REG_SZ, HKEY_CURRENT_USER\Software\JohnAJ\DRM, Resolutions, %ResolutionsString%

; Set up tray menu

Start:
Resolutions := StrSplit(ResolutionsString, "|")
Menu, Tray, NoStandard
Menu, Tray, Tip, Dynamic Resolution Manager
for k, res in Resolutions
  Menu, Tray, Add, %res%, SelectMenuResolution
Menu, Tray, Add
Menu, Tray, Add, E&xit, ButtonExit
return

ButtonExit:
ExitApp

; Select resolution from tray menu

SelectMenuResolution(ItemName, ItemPos, MenuName)
{
  ResArray := StrSplit(ItemName, "x")
  SwitchToResolutionFrom(ResArray[1], ResArray[2], A_ScreenWidth, A_ScreenHeight) 
}

; Save window positions, switch to given resolution, restore window positions

SwitchToResolutionFrom(WidthNew, HeightNew, WidthOrig, HeightOrig)
{
  Positions := {}
  
  Save(Positions)
  SetResolution(WidthNew, HeightNew)
  Sleep, 500
  Restore(Positions)
  
  TrayTip, Resolution changed, % "Press Escape within 3 seconds to revert."
  KeyWait, Esc, D T3
  TrayTip
  if (ErrorLevel = 1) ; user didn't press escape
    return
  
  SetResolution(%WidthOrig%, %HeightOrig%)
  Sleep, 500
  Restore(Positions)
}

; Set screen resolution

SetResolution(Width, Height, ColorDepth := 32)
{
  VarSetCapacity(DeviceMode, 156, 0)
  NumPut(156, DeviceMode, 36) 
  DllCall("EnumDisplaySettingsA", UInt, 0, UInt, -1, UInt, &DeviceMode)
  NumPut(0x5c0000, DeviceMode, 40) 
  NumPut(ColorDepth, DeviceMode, 104)
  NumPut(Width, DeviceMode, 108)
  NumPut(Height, DeviceMode, 112)
  DllCall("ChangeDisplaySettingsA", UInt, &DeviceMode, UInt, 0)
}

Save(ByRef Positions)
{
  Positions := {}
  WinGet, id, list
  SysGet, WorkArea, MonitorWorkArea
  Width := WorkAreaRight - WorkAreaLeft
  Height := WorkAreaBottom - WorkAreaTop
  Loop, %id%
  {
    i := id%A_Index%
    WinReallyGetPos(i, x, y, w, h)
    Positions[i] := [x / Width, y / Height, w / Width, h / Height]
  }
}

Restore(Positions)
{
  SysGet, WorkArea, MonitorWorkArea
  Width := WorkAreaRight - WorkAreaLeft
  Height := WorkAreaBottom - WorkAreaTop
  for i, props in Positions
  {
    x := props[1]
    y := props[2]
    w := props[3]
    h := props[4]
    WinReallyMove(i, x * Width, y * Height, w * Width, h * Height)
  }
}

; Get position of any window, even a minimized one

WinReallyGetPos(hwnd, ByRef x, ByRef y, ByRef w="", ByRef h="")
{
    VarSetCapacity(wp, 44), NumPut(44, wp)
    DllCall("GetWindowPlacement", "uint", hwnd, "uint", &wp)
    x := NumGet(wp, 28, "int")
    y := NumGet(wp, 32, "int")
    w := NumGet(wp, 36, "int") - x
    h := NumGet(wp, 40, "int") - y
}

; Set position of any window, even a minimized one

WinReallyMove(hwnd, x, y, w, h)
{
    VarSetCapacity(wp, 44, 0), NumPut(44, wp, "uint")
    NumPut(5, wp, 8, "uint")
    NumPut(x, wp, 28, "int")
    NumPut(y, wp, 32, "int")
    NumPut(w + x, wp, 36, "int")
    NumPut(h + y, wp, 40, "int")
    DllCall("SetWindowPlacement", "ptr", hwnd, "ptr", &wp)
}