web-dev-qa-db-ja.com

ドッキング時とドッキング解除時にウィンドウの位置を記憶する

私はこれをイライラさせる以上に見つけます。

職場のラップトップに2つの追加画面があります。ノートパソコンを持って帰宅しました。追加の画面は接続していません。私は戻ってきて、ラップトップをドッキングします、そしてウィンドウは再び再配置される必要があります。

ウィンドウ(またはユーティリティ)を取得して画面構成全体(#、サイズ、解像度)を追跡し、ウィンドウが配置された場所を覚えておくことで、画面構成が再び一致すると、アプリケーションを元の場所に戻す?

52
CaffGeek

免責事項:私はこのツールの作成者です。

トレイバーアイコンのクリックでウィンドウを再配置する小さなツールを作成しました。ソースからコンパイルするか、課題リンクから(ポータブル)バイナリを入手するように依頼できます。

Githubでホストされています: https://github.com/manutalcual/winredock

ご提案がございましたら、お気軽にご連絡ください。

編集:2018/11/22

今では完全に自動化されています。

13
Manuel

現在、ウィンドウの場所(だけでなく)にDisplayFusion Proを使用しています。モニターを外して接続したときの動作はわかりません。常に3つあります。

私は、あなたがあなたのアプリを閉じて再度開き、再配置する必要があると思います。

編集:これは、Proバージョンでのみ使用できる機能です。 -コメントからの情報。

screenshot of settings

DisplayFusion のホームページ

7
Wild_A

Excel用に書かれたこのスクリプトを試してください。ウィンドウの位置をシートに保存し、そこから復元します。シートの1つに、ストアを実行してマクロを復元するためのボタン、または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
2
Max

問題は、Windowsアプリケーションが実際にはマルチモニターを認識しないことです。ウィンドウマネージャーは、左上隅またはメインディスプレイを基準にウィンドウの位置を追跡します。動作する商用アプリケーションについては知りませんが、C#またはVB.NETでこれらの値をファイルに書き込んで後で復元できるアプリケーションを作成できますが、「トリガー」はありません。データを手動で保存および取得するタイミングをプログラムに指示する必要があります。

2
Mr. Mascaro

これはコンソールアプリケーションです Windowsデスクトップでウィンドウの場所と状態を保存および復元します。ウィンドウの場所を保存するには、次のコマンドを実行します。

  winLayout save

実行するウィンドウの位置を復元するには:

  winLayout restore

これらのコマンドをデスクトップのショートカットに入れ、タスクバーにピン留めしておくと便利です。

免責事項:このページの他のツールが機能しなかったため、このユーティリティを作成しました。

警告:アプリケーションでは機能しますが、エクスプローラーウィンドウでは機能しません(現在のところ)。

2
Phillip Ngan

これは有望に見えました: https://github.com/adamsmith/WindowsLayoutSnapshot

残念ながら、私の場合、レイアウトを3x 24インチ1920x1200モニターに保存し、1つのラップトップ1920x1080に変更してから、3つに戻ってレイアウトを復元しようとすると、ウィンドウが他のモニターに移動しませんでした。それが動作する他のセットアップ。

1
Koshmaar

以前、同様のシナリオで Stardock’s Fences を使用しました。

フェンスは、ショートカットとアイコンを、フェンスと呼ばれるデスクトップ上のサイズ変更可能な網掛け領域に自動的に配置することで、PCを整理するのに役立ちます。その多くのカスタマイズ機能は、フェンスを世界で最も人気のあるWindowsデスクトップの機能強化にするものです。

0
Pete Q

多くのWindowsユーザーがこの問題を抱えていました。次に示すように、Windows 7フォーラム内でアプリケーションが開発および共有されました。

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

サイトに役立つ説明があり、問題を解決するはずです。

0
DarkEvE