c# - 将笔记本电脑连接到多台显示器时出现显示器编号问题
问题描述
我开发了一个应用程序,我可以将程序分配给特定的监视器,这样当我停靠我的笔记本电脑时,我的所有打开的窗口都会被推送到我的主监视器上,我可以按下全局热键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;
}
}
更新
我做了更多的调试,并Screen.AllScreens
根据我的计算机在对接时的状态返回不同的数组:
任何想法为什么会发生这种情况?
解决方案
推荐阅读
- spring-boot - 红帽中间件 Camel 解析 JDBC 输出
- javascript - Javascript 获取对 servicedesk plus 的 API 调用失败
- filtering - 调用 getGUI 后,ag-grid 自定义下拉过滤器不会刷新过滤器的 GUI
- ajax - 我在ajax中有什么遗漏吗
- asp.net - 请求头在Referer中添加脚本标签,如何在asp.net webfroms中验证
- css - 如何用圆形按钮替换浏览器滚动条箭头?
- c# - Syncfusion WPF DoubleTextBox 错误格式化与 Min 和 MaxValue 以及 MinValidation 和 MaxValidation
- c# - xUnit Test 中的 ClassData 是否接受参数?C#
- google-cloud-platform - 通过 Cloud Identity-Aware 代理连接失败
- android - 当我的服务发生崩溃时,华为崩溃服务无法正常工作