将笔记本电脑对接多个显示器时显示器编号出现问题

时间:2018-12-12 15:48:13

标签: c# multiple-monitors showwindow setwindowpos

我开发了一个应用程序,可以将程序分配给特定的显示器,以便在我固定笔记本电脑时,所有打开的窗口都被推到主显示器上,可以按全局热键 Alt + d ,并且所有已分配给监视器的应用程序都将推送到其分配的监视器。我还有3个其他热键,分别是 Alt + 1 Alt + 2 Alt + 3 ,它将焦点对准的窗口移动到相应的监视器。我注意到,当回到办公桌并在笔记本电脑处于睡眠状态时对接时,然后重新登录Windows时,代码中返回的监视器工作区与显示设置中显示的内容不匹配。

这是Windows显示的监视器布局。我的代码显示为红色。

Monitor Assignment

如果我先取消停放然后停靠,则所有匹配项都将备份。

这是我的代码,用于将当前聚焦的窗口移动到特定的监视器。
Alt + 1 发送0, Alt + 2 发送1, Alt + 3 发送2:

[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);      

[Flags]
public enum SpecialWindowHandles
{
    /// <summary>
    ///     Places the window at the bottom of the Z order. If the hWnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.
    /// </summary>
    HWND_BOTTOM = 1            
}
[Flags]
public enum SetWindowPosFlags : uint
{
    /// <summary>
    ///     Retains the current size (ignores the cx and cy parameters).
    /// </summary>
    SWP_NOSIZE = 0x0001,

    /// <summary>
    ///     Retains the current Z order (ignores the hWndInsertAfter parameter).
    /// </summary>
    SWP_NOZORDER = 0x0004
}

private struct WINDOWPLACEMENT
{
    public int length;
    public int flags;
    public int showCmd;
    public System.Drawing.Point ptMinPosition;
    public System.Drawing.Point ptMaxPosition;
    public System.Drawing.Rectangle rcNormalPosition;
}

/// <summary>
/// Moves the user process retaining start to the provided monitor
/// </summary>
/// <param name="monitor"></param>
public void DockWindow(int monitor)
{
    var screens = Screen.AllScreens.Count();
    if (monitor == 1 && screens < 2 || monitor == 2 && screens < 3) // Prevent moving widnow to monitor that doesn't exist
        return;
    var hwnd = GetForegroundWindow(); // Gets the handle for the focused window
    var screenLocation = Screen.AllScreens[monitor].WorkingArea; // Gets the working area of the windows associated monitor
    var placement = new WINDOWPLACEMENT();
    GetWindowPlacement(hwnd, ref placement); // Gest window placement info
    switch (placement.showCmd)
    {
        case 3: // Maximized
            ShowWindow(hwnd, 9); // Switch to regular window
            SetWindowPos(hwnd, (IntPtr)SpecialWindowHandles.HWND_BOTTOM, screenLocation.X + 100, screenLocation.Y + 100, 0, 0, SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOSIZE); // Move window
            ShowWindow(hwnd, 3); // Maximize window
            break;
        default: // Regular window
            SetWindowPos(hwnd, (IntPtr)SpecialWindowHandles.HWND_BOTTOM, screenLocation.X + 100, screenLocation.Y + 100, 0 ,0, SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOSIZE); // Move window
            break;
    }
}

更新
我进行了一些调试,Screen.AllScreens根据对接时计算机所处的状态返回不同的数组:

Check this out.

为什么会发生这种情况?

0 个答案:

没有答案