I hate how Windows can't remember the position of all of your program windows. This is especially apparent when I undock my laptop and it goes from _dual_ 1920x1080 displays to its small, single display. When I redock I need to manually move the windows back to my preferred positions.
I really thought there would be a AHK script to record the current window locations and then be able to recall them when you want. I found some scripts (including one in French) but none really worked for me.
So I wrote the following script. Use Win-Shift-0 (zero above the P key, not on the numpad) to record the current window positions. The positions are stored in a file called WinPos.txt which is saved in the same folder as the script. You can then edit the window titles to be more generic (i.e., just "Mozille Firefox" instead of including the URL) and remove any you do not want saved.
To restore the window positions, use Win-0 (zero above the P key, not on the numpad).
The nice thing is the script creates a separate section that depends on the number of monitors, the primary monitor, and the total resolution. That means the script recognizes when the laptop is docked (and how you like your windows positioned) and also when it's undocked (and how you like your windows positioned).
This is my first real script and so I'm sure it's ripe for improvements. Please have at it and we will all benefit!
;DockWin v0.3 - Save and Restore window positions when docking/undocking (using hotkeys) ; Paul Troiano, 6/2014 ; ; Hotkeys: ^ = Control; ! = Alt; + = Shift; # = Windows key; * = Wildcard; ; & = Combo keys; Others include ~, $, UP (see "Hotkeys" in Help) ;#InstallKeybdHook #SingleInstance, Force SetTitleMatchMode, 2 ; 2: A window's title can contain WinTitle anywhere inside it to be a match. SetTitleMatchMode, Fast ;Fast is default DetectHiddenWindows, off ;Off is default SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. CrLf=`r`n FileName:="WinPos.txt" ;Win-0 (Restore window positions from file) #0:: WinGetActiveTitle, SavedActiveWindow ParmVals:="Title x y height width" SectionToFind:= SectionHeader() SectionFound:= 0 Loop, Read, %FileName% { if !SectionFound { ;Read through file until correction section found If (A_LoopReadLine<>SectionToFind) Continue } ;Exit if another section reached If ( SectionFound and SubStr(A_LoopReadLine,1,8)="SECTION:") Break SectionFound:=1 Win_Title:="", Win_x:=0, Win_y:=0, Win_width:=0, Win_height:=0 Loop, Parse, A_LoopReadLine, CSV { EqualPos:=InStr(A_LoopField,"=") Var:=SubStr(A_LoopField,1,EqualPos-1) Val:=SubStr(A_LoopField,EqualPos+1) IfInString, ParmVals, %Var% { ;Remove any surrounding double quotes (") If (SubStr(Val,1,1)=Chr(34)) { StringMid, Val, Val, 2, StrLen(Val)-2 } Win_%Var%:=Val } } If ( (StrLen(Win_Title) > 0) and WinExist(Win_Title) ) { WinRestore WinActivate WinMove, A,,%Win_x%,%Win_y%,%Win_width%,%Win_height% } } if !SectionFound { msgbox,,Dock Windows, Section does not exist in %FileName% `nLooking for: %SectionToFind%`n`nTo save a new section, use Win-Shift-0 (zero key above letter P on keyboard) } ;Restore window that was active at beginning of script WinActivate, %SavedActiveWindow% RETURN ;Win-Shift-0 (Save current windows to file) #+0:: MsgBox, 4,Dock Windows,Save window positions? IfMsgBox, NO, Return WinGetActiveTitle, SavedActiveWindow file := FileOpen(FileName, "a") if !IsObject(file) { MsgBox, Can't open "%FileName%" for writing. Return } line:= SectionHeader() . CrLf file.Write(line) ; Loop through all windows on the entire system WinGet, id, list,,, Program Manager Loop, %id% { this_id := id%A_Index% WinActivate, ahk_id %this_id% WinGetPos, x, y, Width, Height, A ;Wintitle WinGetClass, this_class, ahk_id %this_id% WinGetTitle, this_title, ahk_id %this_id% if ( (StrLen(this_title)>0) and (this_title<>"Start") ) { line=Title="%this_title%"`,x=%x%`,y=%y%`,width=%width%`,height=%height%`r`n file.Write(line) } } file.write(CrLf) ;Add blank line after section file.Close() ;Restore active window WinActivate, %SavedActiveWindow% RETURN ; ------- ;Create standardized section header for later retrieval SectionHeader() { SysGet, MonitorCount, MonitorCount SysGet, MonitorPrimary, MonitorPrimary line=SECTION: Monitors=%MonitorCount%,MonitorPrimary=%MonitorPrimary% WinGetPos, x, y, Width, Height, Program Manager line:= line . "; Desktop size:" . x . "," . y . "," . width . "," . height Return %line% } ;<EOF>
Paul