10

I have some code that positions windows to screen quadrants. It works fine on Windows XP, 7, and 8/8.1. However, on Windows 10, there is a weird gap between windows. The extra space surrounds the window on all 4 sides. I presume it has something to do with window borders, but can't figure out how to correct the problem. Any input would be highly appreciated. The code is as follows:

// Get monitor info
HMONITOR hm = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO mi;
mi.cbSize = sizeof(mi);
GetMonitorInfo(hm, &mi);

// Set screen coordinates and dimensions of monitor's work area
DWORD x = mi.rcWork.left;
DWORD y = mi.rcWork.top;
DWORD w = mi.rcWork.right - x;
DWORD h = mi.rcWork.bottom - y;

switch (corner) {
case 0: // Left top
    SetWindowPos(hWnd, HWND_TOP, x, y, w / 2, h / 2, SWP_NOZORDER);
    break;
case 1: // Right top
    SetWindowPos(hWnd, HWND_TOP, x + w / 2, y, w / 2, h / 2, SWP_NOZORDER);
    break;
case 2: // Right bottom
    SetWindowPos(hWnd, HWND_TOP, x + w / 2, y + h / 2, w / 2, h / 2, SWP_NOZORDER);
    break;
case 3: // Left bottom
    SetWindowPos(hWnd, HWND_TOP, x, y + h / 2, w / 2, h / 2, SWP_NOZORDER);
    break;
}
Paul
  • 265
  • 1
  • 2
  • 10
  • 2
    Yes, Windows 10 just does that. Note that the hotspot for resizing the window is actually outside the visible frame on the right and bottom edges. The visible size of the window is less than its actual size. – Jonathan Potter Sep 24 '15 at 03:32
  • 1
    @JonathanPotter Thanks. Wow, another ridiculous change by Microsoft. – Paul Sep 24 '15 at 03:50
  • 5
    In our own application we had the same behaviour on Windows 10. I fixed it by using a combination of the normal `GetWindowRect` function and the use of the [`DwmGetWindowAttribute` function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa969515%28v=vs.85%29.aspx), together with the `DWMWA_EXTENDED_FRAME_BOUNDS` parameter. – Uwe Keim Sep 24 '15 at 05:46
  • @UweKeim That is a good solution. However, I really like to avoid having to explicitly check the OS before calling an API function and we have to maintain XP compatibility. Is there anything similar that has a minimum supported client as XP or before? – Paul Sep 25 '15 at 19:46
  • I managed to compensate for this effect by inflating target rectangle by DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS) - GetWindowRect(). Surprisingly that worked for everything but Explorer windows. – LOST Mar 20 '18 at 00:23

2 Answers2

4

I managed to correct this effect by inflating target rectangle by a calculated margin like this:

static RECT GetSystemMargin(IntPtr handle) {
    HResult success = DwmGetWindowAttribute(handle, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS,
        out var withMargin, Marshal.SizeOf<RECT>());
    if (!success.Succeeded) {
        Debug.WriteLine($"DwmGetWindowAttribute: {success.GetException()}");
        return new RECT();
    }

    if (!GetWindowRect(handle, out var noMargin)) {
        Debug.WriteLine($"GetWindowRect: {new Win32Exception()}");
        return new RECT();
    }

    return new RECT {
        left = withMargin.left - noMargin.left,
        top = withMargin.top - noMargin.top,
        right = noMargin.right - withMargin.right,
        bottom = noMargin.bottom - withMargin.bottom,
    };
}

And then doing

RECT systemMargin = GetSystemMargin(this.Handle);
targetBounds.X -= systemMargin.left;
targetBounds.Y -= systemMargin.top;
targetBounds.Width += systemMargin.left + systemMargin.right;
targetBounds.Height += systemMargin.top + systemMargin.bottom;

That worked for all windows I could test it with, except Explorer windows, which I hardcoded to exclude. If I'd do that expansion on Explorer near the screen edge, window ends up spilling a large area past it to the adjacent monitor.

LOST
  • 2,956
  • 3
  • 25
  • 40
-3

The default font size of windows XP/7/8/8.1 is 100%, but in windows 10 the default is to display text and items in 125%. That affects directly all the window sizes.

Go to settings, display and you will find a scroller, move it to 100% and everything should display the same way as it did in Windows 8/7/XP

ArnaldoRivera
  • 372
  • 3
  • 5