56

I find this beyond frustrating.

I have two extra screens on my laptop at work. I take my laptop and go home, with no extra screens connected. I come back, dock the laptop, and the windows need to be rearranged again.

Is there a way to get windows (or a utility) to keep track of the overall screen configuration (#, size, resolution), and remember where windows were placed, so when the screen configuration matches again, it puts applications BACK where they were?

  • 1
    I run into the same issue but my complaint is when I open the laptop later and the application window is still off-screen (end up using the arrow keys to move it back onscreen). I don't think there is a built-in solution to this. – Brad Patton May 10 '13 at 0:38
16

DISCLAIMER: I'm the creator of this tool.

I've created a little tool to rearrange windows on a traybar icon click. You may compile it from source or ask to have a (portable) binary through the issues link.

It is hosted at Github: https://github.com/manutalcual/winredock

I would be glad to hear from you if you have suggestions.

EDIT: 2018/11/22

It is fully automated now.

| improve this answer | |
  • This looks nice but I am looking for something more automatic. – Sellorio Oct 30 '18 at 1:24
  • 3
    I've added the automation feature due to user requests. – Manuel Nov 22 '18 at 15:35
  • Note that the version in Master has issues at least on Windows 10 with virtual desktops. Use the branch called I0010-restoring-positions-doesnt-work – HansHarhoff Nov 13 '19 at 11:23
  • 1
    This is fantastic! It works super well on first try! Thank you for making this! – B T Nov 22 '19 at 18:12
  • 1
    Tried this solution on 5/12/2020 and it worked great. Thank you for the application. – Kyle Ratliff May 12 at 12:21
7
+50

I'm currently using DisplayFusion Pro for window location (not only). I don't know how this works when you disconnect and connect your monitor - I have three always.

I think, that you must close and reopen your apps to be re-arranged.

Edit: This is feature is available only in Pro version. - Information from comments.

screenshot of settings

homepage of DisplayFusion

| improve this answer | |
  • 2
    FYI, the Window Location feature appears to solve my request. It should be noted to anyone else that this is a PRO version requiring a purchased license. – MADCookie Oct 7 '14 at 19:35
  • See the "Save or Restore all window locations" feature in the Feature Comparison for Free vs. Pro. Unfortunately the cheapest solution is $25. – Chiramisu Jan 19 '17 at 20:47
  • 2
    Does this work when you have multiple native virtual desktops in Windows 10? – K Robinson Jan 9 '18 at 19:19
2

The problem is that Windows applications don't really see multiple monitors. The window manager keeps track of window positions in reference to the Top-Left corner or your main display. I'm not aware of any commercial applications that do, but you could write an application in C# or even VB.NET that could write these values to a file and restore them later, but there would be no "trigger" for it. You'd have to tell the program when to store and retrieve the data manually.

| improve this answer | |
2

Try this script, written for Excel. It stores the window positions in a sheet and restores them from there. You may have buttons on one of the sheets to run the store and restore macros, or shortcuts to VBS scripts that run the Excel macros, maybe with shortcut keys assigned. That way the Excel workbook can remain minimized. Of course something similar may be written in a compiled program.

Public Declare PtrSafe Function GetWindowPlacement Lib "user32" (ByVal hwnd As LongPtr, lpwndpl As WINDOWPLACEMENT) As Long
Public Declare PtrSafe Function SetWindowPlacement Lib "user32" (ByVal hwnd As LongPtr, lpwndpl As WINDOWPLACEMENT) As Long

Public Declare PtrSafe Function GetWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal wCmd As Long) As Long

Public Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare PtrSafe Function IsWindowVisible Lib "user32.dll" (ByVal hwnd As Long) As Boolean
Public Declare PtrSafe Function GetParent Lib "user32.dll" (ByVal hwnd As Long) As Long
Public Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, ByVal lpString As String, ByVal cch As LongPtr) As Long

Public Type POINTAPI
X As Long
Y As Long
End Type

Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Public Type WINDOWPLACEMENT
Length As Long
    flags As Long
    showCmd As Long
    MinPosition As POINTAPI
    MaxPosition As POINTAPI
    rcNormalPosition As RECT
End Type

Global Const gw_hwndnext = 2
Global Const fwp_startswith = 0
Global Const fwp_contains = 1
Global title As String
Global Visible As Boolean
Global RowCount
Public prog As String


Public Sub StoreActiveWindows()
    Dim hwndapp As Long
    Dim hwndmax As Long
    Dim nret As Long
    Dim WinFrm As WINDOWPLACEMENT
    Dim RectFrm As RECT

    PleaseWait.Show vbModeless
    DoEvents

    RowCount = 1
    hwndmax = findwindow(0&, 0&)
    Do Until hwndmax = 0
    hwndapp = findthiswindow(hwndmax)
    If hwndapp Then
        If title <> "CURRENT WINDOWS OPEN" And Visible Then
            rtn = GetWindowPlacement(hwndapp, WinFrm)

            RectFrm = WinFrm.rcNormalPosition

            FrmTop = RectFrm.Top
            FrmRight = RectFrm.Right
            FrmLeft = RectFrm.Left
            FrmBottom = RectFrm.Bottom
            Workbooks(Filename).Activate
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 1) = title
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 2) = hwndapp
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 3) = FrmTop
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 4) = FrmRight
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 5) = FrmLeft
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 6) = FrmBottom
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 7) = WinFrm.MaxPosition.X
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 8) = WinFrm.MaxPosition.Y
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 9) = WinFrm.MinPosition.X
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 10) = WinFrm.MinPosition.Y
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 11) = WinFrm.showCmd
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 12) = WinFrm.flags
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 13) = WinFrm.Length
            RowCount = RowCount + 1
        End If
    End If
    hwndmax = GetWindow(hwndmax, gw_hwndnext)
    Loop
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 1) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 2) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 3) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 4) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 5) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 6) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 7) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 8) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 9) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 10) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 11) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 12) = ""
            Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 13) = ""

    Unload PleaseWait

End Sub

Public Function findthiswindow(ByVal hwndtopmost As Long) As Long
    Dim hwndtmp As Long
    Dim nret As Long
    Dim titletmp As String

    'Get the first window
    hwndtmp = hwndtopmost

    If GetParent(hwndtmp) = 0 Then
        'Set its visibility
        If IsWindowVisible(hwndtmp) Then
            Visible = True
        Else
            Visible = False
        End If
        'Get its title
        titletmp = Space(256)
        nret = GetWindowText(hwndtmp, titletmp, Len(titletmp))
        If nret Then
            findthiswindow = hwndtmp
        End If
    End If

    If Visible Then
        title = titletmp & " - Visible"
        Else
        title = titletmp & " - Invisible"
        End If
        title = titletmp
        If titletmp <> "" Then

        'If title = "SETTINGS" Then
            HasNoOWner = Not (GetWindow(hwndtmp, 4))
            n = 1
        'End If

        If (UCase(Left(title, 15)) = "PROGRAM MANAGER" Or UCase(title) = "SETTINGS") Then
            n = 1
            title = ""
            findthiswindow = 0
        End If
    End If
End Function

Sub RestoreWindowsLocations()
    Dim WinFrm As WINDOWPLACEMENT
    Dim RectFrm As RECT

    PleaseWait.Show vbModeless
    DoEvents

    Workbooks(Filename).Activate

    RowCount = 1
    Do Until Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 1) = ""
        hwndapp = Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 2)
'       rtn = GetWindowPlacement(hwndapp, WinFrm)
        WinFrm.rcNormalPosition.Top = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 3))
        WinFrm.rcNormalPosition.Right = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 4))
        WinFrm.rcNormalPosition.Left = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 5))
        WinFrm.rcNormalPosition.Bottom = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 6))
        WinFrm.MaxPosition.X = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 7))
        WinFrm.MaxPosition.Y = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 8))
        WinFrm.MinPosition.X = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 9))
        WinFrm.MinPosition.Y = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 10))
        WinFrm.showCmd = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 11))
        WinFrm.flags = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 12))
        WinFrm.Length = CLng(Workbooks(Filename).Sheets("Active Windows").Cells(RowCount, 13))

        rtn = SetWindowPlacement(hwndapp, WinFrm)
        rtn = SetWindowPlacement(hwndapp, WinFrm)

        RowCount = RowCount + 1

    Loop
    Unload PleaseWait
End Sub
| improve this answer | |
  • Please explain what this is supposed to do and clean up and format the entire code block properly as it's hard to read as-is. – Pimp Juice IT Aug 4 '17 at 4:42
  • And can you explain how to have VBS scripts that run the Excel macros? How can something similar be written into a compiled program? – G-Man Says 'Reinstate Monica' Aug 4 '17 at 5:43
  • This is an interesting approach. Have you yourself uses it? I am sure a lot of people would benefit if you can create an end-to-end working sample – Miserable Variable Feb 1 '18 at 16:43
2

Here is a console application to save and restore window locations and states on a Windows Desktop. To save windows locations run:

  winLayout save

to restore windows positions run:

  winLayout restore

Put these commands into a Desktop shortcut and pin to the Taskbar for convenience.

Disclaimer: I wrote this utility because the other tools on this page didn't work for me.

Caveat: It works for applications, but not explorer windows (at present)

| improve this answer | |
1

This one was looking promising: https://github.com/adamsmith/WindowsLayoutSnapshot

Unfortunately in my case, when saving the layout on 3x 24" 1920x1200 monitors, changing to one laptop 1920x1080, and then going back to three and trying to restore layout, windows didn't really move to other monitors. But maybe for someone else on other setup it will work.

| improve this answer | |
  • Looks promising, but that won't run on my PC (Windows 8.1) – Dunc Jan 5 '17 at 12:09
  • Discontinued unfortunately, and it loses all the config when the program is closed or the PC is restarted, which the author doesn't plan to fix. – laurent Jun 24 '17 at 21:04
  • The new version available here - github.com/nefarius/WindowsLayoutSnapshot . Works perfectly on win10! – Max Lazar Nov 20 '19 at 14:57
0

Alot of windows users had this issue, an application was developed and shared within the windows 7 forums as shown here:

http://www.sevenforums.com/free-developer-programs-projects/40916-shellfolderfix-manage-folder-window-positions-size.html#post396744 

There are instructions on the site which help and it should fix your issue.

| improve this answer | |
  • The forum says "This is an app to make Windows 7 explorer folder windows remember their size and position" and " It does NOT manage window size/positions of regular applications, if you want that, other apps like Window Manager do it". What is meant by Window Manager? Is that the Microsoft Windows Manager service or the product from DeskSoft link – MADCookie Oct 7 '14 at 19:26
  • yes it is the product from DeskSoft – DarkEvE Oct 7 '14 at 19:50
-1

I've used Stardock’s Fences before in a similar scenario:

Fences helps you organize your PC by automatically placing your shortcuts and icons into resizable shaded areas on your desktop called fences. Its many customization features are what make Fences the world's most popular Windows desktop enhancement.

| improve this answer | |
  • 8
    That arranges icons. Not windows. My issue is that I have 8 programs open across three screens. When I close the laptop, and re-open it with the three screens all my application windows are open on one screen, not arranged how I had them. – CaffGeek May 10 '13 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.