2

I developed an application that I can assign programs to specific monitors so that when I dock my laptop, which results in all my open windows being pushed to my main monitor, I can press a global hotkey, Alt+d, and all the applications that have been assigned to a monitor get pushed to their assigned monitor. I also have 3 other hotkeys, Alt+1, Alt+2 and Alt+3, which move the window in focus to the corresponding monitor. I have noticed that when returning to my desk and docking my laptop while it is sleeping and then logging back into Windows that the monitor working area returned in the code does not match what is shown in the display settings.

Here is the monitor layout that Windows shows. In red is what my code is showing.

Monitor Assignment

If I undock and then dock everything matches back up.

Here is my code for moving the currently focused window to a specific monitor.
Alt+1 sends a 0, Alt+2 sends a 1 and Alt+3 sends a 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;
    }
}

UPDATE
I did a little more debugging and Screen.AllScreens returns different arrays depending on the state my computer is in when docking:

Check this out.

Any ideas why this happens?

Uwe Keim
  • 36,867
  • 50
  • 163
  • 268
Jordanr
  • 21
  • 4
  • I would recommend adding the `c#` tag to your question. – absoluteAquarian Dec 14 '18 at 14:45
  • So the three screens in the `AllScreens` array have the same dimensions, but they are listed in a different order. Which may be okay, because [the order is not guaranteed](https://stackoverflow.com/a/13997975/11683). – GSerg Apr 02 '19 at 14:01

0 Answers0