マウスポインタの位置も元に戻したいと思ったんだけど、 モニターがオフの間にもなぜかスクリーンサイズが戻る瞬間があるみたいで、 そのときに 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) }