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

The CreateWindow function creates a window with a size equal to the drawable area and the little header title. So the drawable size of the window is always smaller than what I want. How to create a window with a drawable size equal to the size that I pass in.

Edited by longtran2904 on Reason: Initial post
You need to use AdujstWindowRect. You give it the desired size and position (the client rect/area) and it will give you the window rect/area to use in CreateWindow.

Edited by Simon Anciaux on
Can the CreateWindow create a fullscreen window? If it can then what parameter should I pass in? I looked into the document but it didn't mention it.
It doesn't work. Here's my code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
RECT rect;
rect.left = 0;
rect.right = 1280;
rect.top = 0;
rect.bottom = 720;
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW|WS_VISIBLE, 0); // The function return true
HWND window = CreateWindowEx(
    0,
    windowClass.lpszClassName,
    "Title",
    WS_OVERLAPPEDWINDOW|WS_VISIBLE,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    rect.right,
    rect.bottom,
    0,
    0,
    NULL,
    0);

// Some place else
RECT clientRect;
GetClientRect(window, &clientRect); // (1272, 689)


It's output:
Begin: rect = (1280, 720)
Adjust: rect = (1288, 728)
GetClientRect: rect = (1272, 689)
You can use the WS_POPUPWINDOW style to remove all decoration and set the size to the screen size to get a fullscreen borderless window.

You need to pass the value you got back from AdjustWindowRect to CreateWindowEx.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
HWND window = CreateWindowEx(
    0,
    windowClass.lpszClassName,
    "Title",
    WS_OVERLAPPEDWINDOW|WS_VISIBLE,
    rect.left,
    rect.top,
    rect.right - rect.left,
    rect.bottom - rect.top,
    0,
    0,
    NULL,
    0);

You're right. Changing the width and height from
1
rect.right, rect.bottom
to
1
rect.right - rect.left, rect.bottom - rect.up
fix it. I can still keep the x and y to CW_USEDDEFAULT and it still works. After some test, I found out that left and top are usually negative (to hide the title bar out of sight), so if you want to see it, you should set x, y to 0 or CW_USEDDEFAULT.
A problem that I encounter is AdjustWindowRect wouldn't work with a rect that contains CW_USEDEFAULT (e.g Rect rect = { .left = 0, .right = CW_USEDEFAULT, .top = 0, .bottom = CW_USEDEFAULT). CW_USEDEFAULT only works when I pass in directly into CreateWindowEx. I can just check if both the width and height are valid or not, but sometimes I only want either width or height to be CW_USEDEFAULT. Is there any way to know up front what the width and height for CW_USEDEFAULT is before calling CreateWindowEx?
CW_USEDEFAULT is not any particular size. It can be anything depending on whatever Windows decides based on monitor size, dpi settings, etc...

If you want to use "default" size then there is no need to AdjustWindowRect at all. Because it will be arbitrary size anyway. So simply create window, and query its size afterwards with GetClientRect when window is already created. Without any calls to AdjustWindowRect.

Edited by Mārtiņš Možeiko on

Sometimes I want the window to have a specific width and a default height, or vise versa. But CreateWindowEx wouldn't work if only the height argument is CW_USEDEFAULT. It needs both the height and width to be CW_USEDEFAULT.

I don't think there is way to do that on creation. Best you can do is to create window with both width/height USEDEFAULT and then resize it to actual size you need.


Replying to longtran2904 (#24968)

How can I resize a window?

With SetWindowPos function.


Replying to longtran2904 (#24972)

For some reason, the AdjustWindowRect returns a bigger rect than I want. Here's an image of 2 windows. Both of them were created with the same size and position, then I set the inner rect of window 3 to the outer rect size.

GetWindowRect(window3, &rect); // The size of rect matches the initial size I pass into CreateWindow
if (AdjustWindowRect(&rect, style, 0))
    SetWindowPos(window2, HWND_TOP, r.left, r.top, r.right - r.left, r.bottom - r.top, 0));

image.png


Edited by longtran2904 on

From the GetWindowRect doc

In Windows Vista and later, the Window Rect now includes the area occupied by the drop shadow.

Calling GetWindowRect will have different behavior depending on whether the window has ever been shown or not. If the window has not been shown before, GetWindowRect will not include the area of the drop shadow.

To get the window bounds excluding the drop shadow, use DwmGetWindowAttribute, specifying DWMWA_EXTENDED_FRAME_BOUNDS. Note that unlike the Window Rect, the DWM Extended Frame Bounds are not adjusted for DPI. Getting the extended frame bounds can only be done after the window has been shown at least once.


Edited by Simon Anciaux on

But the size is way too big for the drop shadow, don't you think?


Replying to mrmixer (#30108)