停靠和取消停靠时记住窗口位置


45

我发现这令人沮丧。

我的笔记本电脑上有两个额外的屏幕。我带上笔记本电脑回家,没有连接任何其他屏幕。我回来,将笔记本电脑对接,然后需要重新布置窗户。

有没有一种方法来获取窗口(或实用程序)以跟踪整个屏幕配置(#,大小,分辨率),并记住窗口的放置位置,因此当屏幕配置再次匹配时,它将应用程序返回到它们原来所在的位置?


1
我遇到了同样的问题,但我的抱怨是稍后打开笔记本电脑时,应用程序窗口仍在屏幕外(最终使用箭头键将其移回屏幕上)。我认为没有内置的解决方案。
布拉德·帕顿

Answers:


8

免责声明:我是这个工具的创建者。

我创建了一个小工具来重新排列托盘栏图标单击上的窗口。您可以从源代码编译它,也可以通过问题链接要求提供(便携式)二进制文件。

它托管在Github上:https : //github.com/manutalcual/winredock

如果您有任何建议,我将很高兴收到您的来信。

编辑:2018/11/22

现在它是完全自动化的。


这看起来不错,但我正在寻找更自动的东西。
Sellorio '18年

3
我已根据用户要求添加了自动化功能。
曼努埃尔

请注意,Master版中的版本至少在带有虚拟桌面的Windows 10上存在问题。使用名为I0010-restoring-positions-doesnt-work
HansHarhoff

我已经将分支I0010-restoreing-positions-doesnt-work合并到master中,所以现在我们可能会更好地工作
Manuel

1
这是太棒了!第一次尝试时效果很好!谢谢你做这个!
英国电信

6

我目前正在使用DisplayFusion Pro进行窗口定位(不仅如此)。当您断开连接并连接显示器时,我不知道这是如何工作的-我总是有三个。

我认为,您必须关闭并重新打开应用程序才能进行重新排列。

编辑:此功能仅在Pro版本中可用。-评论信息。

设置屏幕截图

DisplayFusion的主页


2
仅供参考,“窗口位置”功能似乎可以解决我的要求。应当向其他任何人指出,这是需要购买许可证的PRO版本。
MADCookie 2014年

请参阅免费版与专业版功能比较中的“保存或还原所有窗口位置”功能。不幸的是,最便宜的解决方案是25美元。
Chiramisu

1
当您在Windows 10中具有多个本机虚拟桌面时,此方法是否起作用?
K罗宾逊

2

问题是Windows应用程序实际上看不到多个监视器。窗口管理器会根据左上角或主显示跟踪窗口位置。我不知道有任何商业应用程序可以这样做,但是您可以用C#甚至VB.NET编写一个可以将这些值写入文件并在以后还原它们的应用程序,但是不会有任何“触发”。您必须告诉程序何时手动存储和检索数据。


2

尝试为Excel编写的此脚本。它将窗口位置存储在工作表中,然后从那里恢复它们。您可能在工作表之一上具有运行存储和还原宏的按钮,或者运行Excel宏的VBS脚本的快捷方式,可能已分配了快捷键。这样,Excel工作簿可以保持最小化。当然,类似的东西也可以写在已编译的程序中。

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

请解释该怎么做,并清理和格式化整个代码块,因为很难按原样阅读。
Pimp Juice IT

并且您能解释一下如何使VBS脚本运行Excel宏吗?如何将类似的东西写入已编译的程序?
G-Man说'Resstate Monica''8

这是一个有趣的方法。您自己使用过吗?我敢肯定,如果您可以创建一个端到端的工作样本,那么很多人都会从中受益
悲惨的变量

1

这个看起来很有希望:https : //github.com/adamsmith/WindowsLayoutSnapshot

不幸的是,在我的情况下,当在3x 24英寸1920x1200显示器上保存布局,更改为一台笔记本电脑1920x1080,然后又回到三台笔记本电脑并尝试恢复布局时,窗口并没有真正移到其他显示器上。但是也许对于其他显示器其他设置将起作用。


看起来很有希望,但是不能在我的PC上运行(Windows 8.1)
Dunc

不幸的是停产了,并且在程序关闭或重新启动PC时,它会丢失所有配置,而作者不打算予以修复。
劳伦特

此处提供了新版本-github.com/nefarius/WindowsLayoutSnapshot。在win10上完美工作!
Max Lazar

1

这是一个控制台应用程序,用于保存和还原Windows桌面上的窗口位置和状态。要保存Windows位置,请运行:

  winLayout save

恢复Windows位置运行:

  winLayout restore

将这些命令放在桌面快捷方式中,并固定到任务栏以方便使用。

免责声明:之所以写此实用程序,是因为此页面上的其他工具对我不起作用。

警告:它适用于应用程序,但不适用于浏览器窗口(当前)


0

在类似的情况下,我之前使用过Stardock的栅栏

Fences通过将快捷方式和图标自动放置在桌面上可调整大小的阴影区域(称为围栏)中来帮助您整理PC。它的许多自定义功能使Fences成为世界上最受欢迎的Windows桌面增强功能。


8
排列图标。不是窗户。我的问题是我在三个屏幕上打开了8个程序。当我关闭笔记本电脑并用三个屏幕重新打开它时,我所有的应用程序窗口都在一个屏幕上打开,而不是按我的方式安排它们。
CaffGeek

0

许多Windows用户都遇到了这个问题,在Windows 7论坛中开发并共享了一个应用程序,如下所示:

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

该站点上有说明,可以帮助您解决问题。


该论坛说:“这是一个使Windows 7资源管理器文件夹窗口记住其大小和位置的应用程序”和“它不管理常规应用程序的窗口大小/位置,如果需要的话,其他应用程序(如Window Manager)也可以。” 窗口管理器是什么意思?是Microsoft Windows Manager服务还是DeskSoft 链接
MADCookie 2014年

是的,它是DeskSoft的产品
DarkEvE 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.