;WinPosSaver.ahk ; Save and restore window positions ;Skrommel @ 2017 #NoEnv #SingleInstance,Force SetBatchLines,-1 SetWindelay,0 DetectHiddenWindows,Off applicationname=WinPosSaver OnExit,EXIT Gosub,MENU VarSetCapacity(newGUID,16,0) If A_OsVersion in WIN_8,WIN_8.1,WIN_10 DllCall("Rpcrt4\UuidFromString","Str","6fe69556-704a-47a0-8f24-c28d936fda47","UInt",&newGUID) ;GUID_CONSOLE_DISPLAY_STATE:="6fe69556-704a-47a0-8f24-c28d936fda47" Else DllCall("Rpcrt4\UuidFromString","Str","02731015-4510-4526-99e6-e5a17ebd1aea","UInt",&newGUID) ;GUID_MONITOR_POWER_ON:="02731015-4510-4526-99e6-e5a17ebd1aea" rhandle:=DllCall("RegisterPowerSettingNotification","UInt",a_scriptHwnd,"Str",strGet(&newGUID),"Int",0) OnMessage(0x218,"WM_POWERBROADCAST") SetTimer,SAVE,-60000 Gosub,SAVE Return ;Stolen from lexikos at https://autohotkey.com/boards/viewtopic.php?t=14543 ;Stolen from Masjonjar13 at https://autohotkey.com/boards/viewtopic.php?t=17457 WM_POWERBROADCAST(wparam,lparam) { Global newGUID Static changeText := {10: "PBT_APMPOWERSTATUSCHANGE", 18: "PBT_APMRESUMEAUTOMATIC", 7: "PBT_APMRESUMESUSPEND", 4: "PBT_APMSUSPEND", 32787: "PBT_POWERSETTINGCHANGE"} change := changeText[wparam] If !change change := wparam If change In PBT_POWERSETTINGCHANGE { If (SubStr(StrGet(lParam),1,StrLen(StrGet(lParam))-1)=StrGet(&newGUID)) { monitorStatus:=NumGet(lParam+0,20,"UInt")?"On":"Off" If monitorStatus=Off SetTimer,SAVE,Off Else { SetTimer,SAVE,-60000 Gosub,LOAD } } } If change In PBT_APMSUSPEND { SetTimer,SAVE,Off } If change In PBT_APMRESUMESUSPEND,PBT_APMRESUMEAUTOMATIC { SetTimer,SAVE,-60000 Gosub,LOAD } FileAppend,%A_Now% - %change% - Monitor: %monitorStatus%`n,log.txt } SAVE: start:=A_TickCount filename:=applicationname ".ini" SysGet,count,MonitorCount WinGet,list,List ini:="" Loop,% list { id:=list%A_Index% Loop { parent:=DllCall("GetParent","UInt",id) If parent=0 Break id:=parent } WinGetPos,x,y,w,h,Ahk_id %id% WinGet,path,ProcessPath,Ahk_id %id% WinGet,pid,PID,Ahk_id %id% line:=GetCommandLine(pid) WinGet,minmax,MinMax,Ahk_id %id% If minmax<>0 WinGetNormalPos(id,x,y,w,h) WinGetClass,class,Ahk_id %id% WinGetTitle,title,Ahk_id %id% key:=id ;path "|" class "|" title "|" count ini.="[" key "]`n" ini.="x=" x "`n" ini.="y=" y "`n" ini.="w=" w "`n" ini.="h=" h "`n" ini.="minmax=" minmax "`n" ini.="id=" id "`n" ini.="class=" class "`n" ini.="title=" title "`n" ini.="path=" path "`n" ini.="line=" line "`n" ini.="count=" count "`n`n" } FileDelete,%filename% FileAppend,%ini%,%filename% SetTimer,SAVE,-60000 Return LOAD: filename:=applicationname ".ini" SysGet,count,MonitorCount WinGet,list,List Loop,% list { id:=list%A_Index% Loop { parent:=DllCall("GetParent","UInt",id) If parent=0 Break id:=parent } WinGet,path,ProcessPath,Ahk_id %id% WinGetClass,class,Ahk_id %id% WinGetTitle,title,Ahk_id %id% key:=id ;path "|" class "|" title "|" count IniRead,x ,% filename,% key,x IniRead,y ,% filename,% key,y IniRead,w ,% filename,% key,w IniRead,h ,% filename,% key,h IniRead,minmax,% filename,% key,minmax ; IniRead,id ,% filename,% key,id ; IniRead,class ,% filename,% key,class ; IniRead,title ,% filename,% key,title ; IniRead,path ,% filename,% key,path ; IniRead,line ,% filename,% key,line ; IniRead,count ,% filename,% key,count If minmax=Error Continue WinGet,newminmax,MinMax,Ahk_id %id% If (minmax<>newminmax) { WinRestore,Ahk_id %id% Loop,10 { WinGet,newminmax,MinMax,Ahk_id %id% If newminmax=0 Break Sleep,0 } } If minmax=-1 { WinMinimize,Ahk_id %id% Loop,10 { WinGet,newminmax,MinMax,Ahk_id %id% If newminmax=-1 Break Sleep,0 } WinSetNormalPos(id,x,y,w,h) } Else If minmax=1 { WinMaximize,Ahk_id %id% Loop,10 { WinGet,newminmax,MinMax,Ahk_id %id% If newminmax=1 Break Sleep,0 } WinSetNormalPos(id,x,y,w,h) } Else WinMove,Ahk_id %id%,,% x,% y,% w,% h } Return EXIT: ExitApp MENU: Menu,Tray,Click,1 Menu,Tray,NoStandard Menu,Tray,Add,%applicationname%,LOAD Menu,Tray,Add Menu,Tray,Add,&Load layout,LOAD Menu,Tray,Add,&Save layout,SAVE Menu,Tray,Add,&About...,ABOUT Menu,Tray,Add,E&xit,EXIT Menu,Tray,Default,%applicationname% Menu,Tray,Tip,%applicationname% Return ABOUT: Gui,99:Destroy Gui,99:Margin,20,20 Gui,99:Add,Picture,xm Icon1,%applicationname%.exe Gui,99:Font,Bold Gui,99:Add,Text,x+10 yp+10,%applicationname% v0.9 Gui,99:Font Gui,99:Add,Text,y+10,Save and restore window positions Gui,99:Add,Text,y+10,- Saves layout every minute Gui,99:Add,Text,y+10,- Restores layout after sleep and hibernation Gui,99:Add,Picture,xm y+20 Icon2,%applicationname%.exe Gui,99:Font,Bold Gui,99:Add,Text,x+10 yp+10,1 Hour Software by Skrommel Gui,99:Font Gui,99:Add,Text,y+10,For more tools, information and donations, please visit Gui,99:Font,CBlue Underline Gui,99:Add,Text,y+5 G1HOURSOFTWARE,www.1HourSoftware.no Gui,99:Font Gui,99:Add,Picture,xm y+20 Icon3,%applicationname%.exe Gui,99:Font,Bold Gui,99:Add,Text,x+10 yp+10,DonationCoder Gui,99:Font Gui,99:Add,Text,y+10,Please support the contributors at Gui,99:Font,CBlue Underline Gui,99:Add,Text,y+5 GDONATIONCODER,www.DonationCoder.com Gui,99:Font Gui,99:Add,Picture,xm y+20 Icon4,%applicationname%.exe Gui,99:Font,Bold Gui,99:Add,Text,x+10 yp+10,AutoHotkey Gui,99:Font Gui,99:Add,Text,y+10,This tool was made using the powerful Gui,99:Font,CBlue Underline Gui,99:Add,Text,y+5 GAUTOHOTKEY,www.AutoHotkey.com Gui,99:Font Gui,99:Show,,%applicationname% About hCur:=DllCall("LoadCursor","UInt",NULL,"Int",32649,"UInt") ;IDC_HAND OnMessage(0x200,"WM_MOUSEMOVE") Return 1HOURSOFTWARE: Run,http://www.1hoursoftware.no,,UseErrorLevel Return DONATIONCODER: Run,http://www.donationcoder.com,,UseErrorLevel Return AUTOHOTKEY: Run,http://www.autohotkey.com,,UseErrorLevel Return 99GuiClose: Gui,99:Destroy OnMessage(0x200,"") DllCall("DestroyCursor","Uint",hCur) Return WM_MOUSEMOVE(wParam,lParam) { Global hCur MouseGetPos,,,,ctrl If ctrl in Static9,Static13,Static17 DllCall("SetCursor","UInt",hCur) Return } Return GetCommandLine(pid) { wmi:=ComObjGet("winmgmts:") ; Get WMI service object queryEnum:=wmi.ExecQuery("" ; Run query to retrieve matching process(es) . "Select * from Win32_Process where ProcessId=" . pid) ._NewEnum() queryEnum[process] ; Get first matching process Return process.CommandLine } ;Stolen from Lexikos at https://autohotkey.com/board/topic/25204-original-window-positionsize/ WinGetNormalPos(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 } WinSetNormalPos(hwnd,ByRef x,ByRef y,ByRef w="",ByRef h="") { VarSetCapacity(wp,44) NumPut(44,wp) DllCall("GetWindowPlacement","UInt",hwnd,"UInt",&wp) NumPut(x,wp,28) NumPut(y,wp,32) NumPut(x+w,wp,36) NumPut(y+h,wp,40) DllCall("SetWindowPlacement","uint",hwnd,"UInt",&wp) }