I'm just trying to understand why your code worked. Let me list out some of my questions:
Does the drop shadow matter at all here, or all that matter is the size handles?
Do SetWindowPos
, AdjustWindowRect
, GetWindowRect
, and DwmGetWindowAttribute
account for the sie handles (or the drop shadow)? Like, for example, does the size you pass into SetWindowPos
include the size handles?
My first assumption is the rect you pass into SetWindowPos
must include the size handles, which means it must be bigger than your desired rect. So in your original code, when you constructed small_window_rect
by using GetClientRect
and ClientToScreen
, small_window_rect
now has the inner rect (client rect, I will use these 2 terms interchangeably now) of the big window. Then you just call AdjustWindowRect
on that big window's inner rect:
RECT window_rect = small_window_rect; AdjustWindowRect( &window_rect, WS_OVERLAPPEDWINDOW, 0 ); window_rect.top = small_window_rect.top - 1;
So now window_rect
should be equal to the big window's outer rect, right? This works on the assumption that if you pass the window's inner rect to AdjustWindowRect
, it will give you the outer rect (equals to GetWindowRect
):
RECT inner_rect; GetClientRect(...) and ClientToScreen(...) on the inner_rect; RECT outer_rect; GetWindowRect(...) on outer_rect; AdjustWindowRect(&inner_rect, ...) inner_rect == outer_rect? SetWindowPos(...) with inner_rect GetWindowRect(...) == outer_rect? (The window's rectangle shouldn't change, right?)
That's why I can understand why my DwmGetWindowAttribute
code worked but why your AdjustWindowRect
works is beyond me. Please point out what is wrong with my thought process.
1 The drop shadow doesn't matter at all. Only the resize handles.
2
SetWindowPos
you need to give it a rectangle that takes the size of the window including the resize handles;AdjustWindowRect
you pass it the client rect (the area where you can draw in the window). It returns the size of the window, including the resize handles (and title bar). You typically pass the result to CreateWindow
or SetWindowPos
.GetWindowRect
I didn't tested it until now, and I was surprised (not really) to see that contrary to what the doc says, it returns the size of the window, including the resize handles and title bar, but not containing the drop shadows.DwmGetWindowAttribute
gives the rect that contains the visible part of the window. On windows 10 it means the client rect + the title bar, but not the resize handles.3
So now window_rect should be equal to the big window's outer rect, right?
After AdjustWindowRect
yes both are the same.
But you seem to skip the line
window_rect.top = small_window_rect.top - 1;
that aligns the top edge of window_rect
to the top edge of the client rect of the big window. The -1 adds the space required by the top resize handle (which is only 1 pixel thick).
Since know I know that GetWindowRect returns the size containing the resize handle, a third way to do what you want is:
RECT window_rect; GetWindowRect( big_window, &window_rect ); window_rect.top += 30;
But once again, all those codes rely on the way the windows are displayed, and it might not be reliable.
So is it safe to say that the 2 windows' width will be the same the only difference is the height (accounting for the title bar)? Because that isn't what I want. I want to change the visible non-client rect (outer rect). This means the border should be included in the calculation, which means one window's width will be smaller than the other width (accounts for the border). Because the border is visible while the resize handles aren't. That's why I'm confused about your code. Sorry for not making that clear before. So in Windows 7 when the resize handles are visible, I want the small window resize handles to be inside the big window resize handles. But on Windows 10, because the resize handles are invisible, I want the visible border of the small window to be inside the big window. In both cases, the width of the small window must be smaller than the big window. So I guess my original DwmGetWindowAttribute
is the only way that works and will give different results compared to AdjustWindowRect
/GetWindowRect
.