Reputation: 28
I've run into an issue when developing some software for windows, an issue related around moving windows on the screen.
Basically, I've found that specific windows will consitantly not follow the coordinate system. I have a function that takes a window and a ratio, then scales up the window to the max size it can be (in that ratio) and still be within the working area of the monitor (not going over the edges or the taskbar).
Example 1: The function works as intended, sizes the window (VSCode) to be the max size it can be in 4:3, and puts it in the corner of the screen (using SetWindowPos and passing in 0,0 for the coords).
Example 2: The exact same function is run on a different window (Firefox) and it is again resized to 4:3 and set to 0,0. However, this time you can see the window isn't quite in the corner, off by 8 pixels to be exact. If I fetch the window position with the api call for that, it returns 0,0, even though it clearly is not. If I manually snap it into the corner myself, then it returns -8,0.
I have no idea what's wrong or how to fix it. It always happens on the same windows, not exactly sure but I think it has something to do with the type of titlebar the window has.
The only other person I've ever seen with this problem is here: https://answers.microsoft.com/en-us/insider/forum/insider_wintp-insider_desktop/desktop-coordinate-system-is-broken/9e6fd9ab-6d27-45e0-bb55-4c868cd6ac45
Unfortunately, he never got a real answer, so I'm back to square one.
So, any ideas of some way to consistently set windows to actually be in the corner? I've come up with some janky solutions by like trying to dynamically find how much a window offsets from the corner but it's not really something I want to be relying on. Is this just a bug with windows and I'm stuck?
Thanks, let me know if you have any questions!
Upvotes: 0
Views: 955
Reputation: 6289
This is the design of windows system.
I saw similar questions long ago.
Windows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing. The borders might look like this: 7,0,7,7 (left, top, right, bottom).
The borders are invisible in Windows 10, so it appears that the window is in the wrong place. Visual Studio IDE has its own tool-windows, when tool-window is docked, it uses no borders or custom NC_PAINT
; and when its tool-window is floating, it uses default borders.
A workaroud:
RECT rect, frame;
GetWindowRect(hwnd, &rect);
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT));
//rect should be `0, 0, 1280, 1024`
//frame should be `7, 0, 1273, 1017`
RECT border;
border.left = frame.left - rect.left;
border.top = frame.top - rect.top;
border.right = rect.right - frame.right;
border.bottom = rect.bottom - frame.bottom;
//border should be `7, 0, 7, 7`
Then offset the rectangle like so:
rect.left -= border.left;
rect.top -= border.top;
rect.right += border.left + border.right;
rect.bottom += border.top + border.bottom;
//new rect should be `-7, 0, 1287, 1031`
For more information, please refer @Barmak Shemirani's answer.
Similar case:
Retrieve Window Size without Windows Shadows
GetWindowRect returns a size including “invisible” borders
Note: DwmGetWindowAttribute()
returns physical coordinates, but GetWindowRect()
returns logical coordinates. So the border width will be wrong for a non-DPI aware application on a screen scaled to anything other than 100%.
Upvotes: 2