I'm coding in c++ on windows 10 - straight win32 API.
I wanted to make a window show up in the top right of the screen. As I was doing this, I noticed that screen coordinates for a maximized window are left=-8, top=-8, right=1936, bottom=1088.
Also, when I position a window so right=1920 and top=0, there's about an 8 pixel gap on the right. I tried moving the window around to see what screen coordinates I got.
rect.left for a nonmaximized window can go from -7 to 1912.
so things are slid by 7 pixels ? WTF microsoft ??
How am I supposed to come up with the rec.right=1913 value to position my window aligned to right side of screen without that dang gap ?
But rect.right of 1920 leaves a gap. So rect.right of 1912 would leave MORE of a gap...
And I need a solution that'll work back to Vista. Pre win10, that rect.right should be 1920 like ya expect.
Whaaaaat is going on here? I'm about to start throwing knives around !!
Code wise, this is just what GetWindowRect is reporting... (excuse my weird debugging function)
::GetWindowRect (_wndo, r);
DBG("ExtRc l=`d r=`d t=`d b=`d w=`d h=`d",
r->left, r->right, r->top, r->bottom, r->right-r->left, r->bottom-r->top);
Well thanks to @ChristopherOicles This is really his answer. Duplicate this as your own (or tweak it, whatever) and I'll accept your's.
What's going on is microsoft wrecking border widths in windows 10.
GetWindowRect returns the outside window coordinates as screen coordinates. GetClientRect returns the inside the window coordinates. Up until Windows 10 (F U Win10 !!),
The difference in width and height between them was the width and height of the borders.
Upon win10, the border width reports 16 pixels, so 8 pixels a side. However, only 1 of those pixels are visible. 7 of them are transparent. So your window has a transparent 7 pixels to the left, right, and bottom.
So you need to take those transparent 7 pixels into account if you're going to line up the window on the screen programmatically. The user doesn't want that 7 pixel gap next to the screen border !
DwmGetWindowAttribute with the attribute DWMWA_EXTENDED_FRAME_BOUNDS will get you the width and height of the ACTUALLY SHOWING part of the border in screen coordinates. So similar to GetWindowRect, but the rect does not include the invisible-ness.
You're still going to need GetWindowRect most of the time to set the width and height of your window and those 7 pixels per side of invisible-ness are needed to size the window properly programmatically.
So use the difference between the .left of the rect GetWindowRect returns and .left of what DwmTerribleName returns to get that 7 pixels of offset.
In my opinion, whoever did this at Microsoft should be immediately shot. This is a hoop I didn't need to jump through. This breaks compatibility with the past.
This is because of the width of the window border and other factors, which vary depending on OS version, user preference, and DPI settings. See the GetSystemMetrics function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With