The 2024 Wheel Reinvention Jam is in 16 days. September 23-29, 2024. More info

CreateWindow with the drawable size equal to the width and height pass in.

I'm just trying to understand why your code worked. Let me list out some of my questions:

  1. Does the drop shadow matter at all here, or all that matter is the size handles?

  2. 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?

  3. 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.


Edited by longtran2904 on
Replying to mrmixer (#30126)

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.


Edited by longtran2904 on
Replying to mrmixer (#30129)