Я разработал приложение, которое позволяет назначать программы определенным мониторам, чтобы при подключении ноутбука к ноутбуку, в результате чего все мои открытые окна были перенесены на основной монитор, я мог нажать глобальную горячую клавишу Alt * 1002.* + 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
возвращает различные массивы в зависимости от состояния, в котором находится мой компьютер при стыковке:
Есть идеи, почему это происходит?