Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将笔记本电脑与多台显示器对接时出现显示器编号问题_C#_Multiple Monitors_Showwindow_Setwindowpos - Fatal编程技术网

C# 将笔记本电脑与多台显示器对接时出现显示器编号问题

C# 将笔记本电脑与多台显示器对接时出现显示器编号问题,c#,multiple-monitors,showwindow,setwindowpos,C#,Multiple Monitors,Showwindow,Setwindowpos,我开发了一个应用程序,可以将程序分配给特定的监视器,这样,当我对接笔记本电脑时,所有打开的窗口都会被推送到主监视器上,我可以按下全局热键Alt+d,所有分配给监视器的应用程序都会被推送到分配的监视器上。我还有另外3个热键,Alt+1、Alt+2和Alt+3,它们将焦点窗口移动到相应的监视器上。我注意到,当我回到我的办公桌,在笔记本电脑睡觉时对接,然后重新登录到Windows时,代码中返回的显示器工作区与显示设置中显示的不匹配 这是Windows显示的监视器布局。红色是我的代码显示的内容 如果我

我开发了一个应用程序,可以将程序分配给特定的监视器,这样,当我对接笔记本电脑时,所有打开的窗口都会被推送到主监视器上,我可以按下全局热键Alt+d,所有分配给监视器的应用程序都会被推送到分配的监视器上。我还有另外3个热键,Alt+1、Alt+2和Alt+3,它们将焦点窗口移动到相应的监视器上。我注意到,当我回到我的办公桌,在笔记本电脑睡觉时对接,然后重新登录到Windows时,代码中返回的显示器工作区与显示设置中显示的不匹配

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

如果我解开,然后把所有匹配的东西都装回去

以下是我将当前聚焦窗口移动到特定监视器的代码。
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;
    }
}
[DllImport(“user32.dll”)]
静态外部bool SetWindowPos(IntPtr hWnd、IntPtr hwninsertafter、intx、inty、intcx、intcy、SetWindowPosFlags uFlags);
[DllImport(“user32.dll”)]
静态外部布尔显示窗口(IntPtr hWnd、int nCmdShow);
[DllImport(“user32.dll”)]
私有静态外部IntPtr GetForegroundWindow();
[DllImport(“user32.dll”)]
静态外部布尔GetWindowPlacement(IntPtr hWnd,ref WINDOWPLACEMENT lpwndpl);
[旗帜]
公共枚举特殊indowHandles
{
/// 
///将窗口放置在Z顺序的底部。如果hWnd参数标识最顶部的窗口,则该窗口将失去其最顶部的状态,并放置在所有其他窗口的底部。
/// 
HWND_底部=1
}
[旗帜]
公共枚举SetWindowPosFlags:uint
{
/// 
///保留当前大小(忽略cx和cy参数)。
/// 
SWP_NOSIZE=0x0001,
/// 
///保留当前的Z顺序(忽略HwnInsertAfter参数)。
/// 
SWP_NOZORDER=0x0004
}
私有结构窗口放置
{
公共整数长度;
公共国旗;
公共int showCmd;
公共系统图点位置;
公共系统.Drawing.Point ptMaxPosition;
公共系统.Drawing.Rectangle位置;
}
/// 
///将用户进程保留启动移动到提供的监视器
/// 
/// 
公共空文档窗口(内部监视器)
{
var screens=Screen.AllScreens.Count();
如果(监视器==1&&screens<2 | |监视器==2&&screens<3)//防止将widnow移动到不存在的监视器
返回;
var hwnd=GetForegroundWindow();//获取聚焦窗口的句柄
var screenLocation=Screen.AllScreens[monitor].WorkingArea;//获取与windows关联的监视器的工作区域
var placement=新的WINDOWPLACEMENT();
GetWindowPlacement(hwnd,ref placement);//最大窗口位置信息
开关(placement.showCmd)
{
案例3://最大化
ShowWindow(hwnd,9);//切换到常规窗口
SetWindowPos(hwnd,(IntPtr)SpecialWindowWhandles.hwnd_底部,屏幕位置.X+100,屏幕位置.Y+100,0,0,SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOSIZE);//移动窗口
ShowWindow(hwnd,3);//最大化窗口
打破
默认值://常规窗口
SetWindowPos(hwnd,(IntPtr)SpecialWindowWhandles.hwnd_底部,屏幕位置.X+100,屏幕位置.Y+100,0,0,SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOSIZE);//移动窗口
打破
}
}
更新
我又进行了一些调试,并显示了
屏幕。根据计算机对接时的状态,AllScreens
返回不同的数组:


你知道为什么会发生这种情况吗?

我建议在你的问题中添加
c#
标记。因此
AllScreens
数组中的三个屏幕具有相同的维度,但它们的排列顺序不同。也许没关系,因为。