マウスポインタの位置も元に戻したいと思ったんだけど、 モニターがオフの間にもなぜかスクリーンサイズが戻る瞬間があるみたいで、 そのときに MouseMove すると画面がオンになってしまう。(WinMove だけなら問題ない)
面倒なので、画面サイズじゃなくてやっぱり https://www.autohotkey.com/boards/viewtopic.php?p=539708 の通知を使うことにした。
だからループの頻度を減らしても良さそう。 ループを消してしまうことも考えたけど、 最小化ウィンドウが最小化する前の位置を記憶しておくために利用することにした。
#Requires AutoHotkey v2.0
#Warn
#SingleInstance Force
monpower := 1
registerpower()
awake := true
wins := Map()
while (true) {
if (awake and monpower) {
savewins(&wins, WinGetList(, , "Program Manager"))
}
Sleep(1000)
continue
}
savewins(&oldmap, ids) {
newmap := Map()
MouseGetPos(&mx, &my)
newmap["mouse"] := { x: mx, y: my }
for (this_id in ids) {
try {
minmax := WinGetminmax(this_id)
WinGetPos(&x, &y, , , this_id)
} catch (TargetError) {
continue
}
if (minmax = -1 && oldmap.Has(this_id)) {
newmap[this_id] := {
x: oldmap[this_id].x,
y: oldmap[this_id].y,
minmax: minmax
}
} else {
newmap[this_id] := { x: x, y: y, minmax: minmax }
}
}
oldmap := newmap
}
restorewins(winmap) {
for (this_id, d in winmap) {
if (this_id = "mouse") {
MouseMove(d.x, d.y, 0)
continue
}
try {
minmax := WinGetMinMax(this_id)
WinGetPos(&x, &y, , , this_id)
} catch (TargetError) {
continue
}
if (d.x = x && d.y = y && d.minmax = minmax) {
continue
}
if (d.minmax = 0) {
WinMove(d.x, d.y, , , this_id)
} else {
WinRestore(this_id)
WinMove(d.x, d.y, , , this_id)
if (d.minmax = 1) {
WinMaximize(this_id)
} else if (d.minmax = -1) {
WinMinimize(this_id)
}
}
}
}
; https://www.autohotkey.com/boards/viewtopic.php?p=539708
registerpower()
{
CLSID := Buffer(16)
if (res :=
DllCall("ole32\CLSIDFromString",
; GUID_CONSOLE_DISPLAY_STATE_
"WStr", "{6FE69556-704A-47A0-8F24-C28D936FDA47}",
"Ptr", CLSID,
"UInt")
) {
throw (Error("CLSIDFromString failed. Error: " . Format("{:#x}", res)))
}
if (! ;hPowerNotify :=
DllCall('RegisterPowerSettingNotification',
'Ptr', A_ScriptHwnd,
'Ptr', CLSID,
'UInt', 0,
'Ptr')
) {
throw (OSError(A_LastError, -1, 'RegisterPowerSettingNotification'))
}
Sleep(1) ; a notification is always emitted immediately after registering for it for some reason. this prevents seeing it
OnMessage(0x218, _WM_POWERBROADCAST)
}
_WM_POWERBROADCAST(wParam, lParam, msg, hwnd) {
global awake
global monpower
global wins
Critical(1000)
if (wParam = 0x8013) { ; PBT_POWERSETTINGCHANGE
monpower := NumGet(lParam, 20, 'UChar') ; 0 (off) or 1 (on).
if (awake and !monpower) {
awake := false
} else if (!awake and monpower) {
SetTimer(restorewins.Bind(wins), -1)
awake := true
}
}
return (true)
}