Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does GetSystemMetrics() return these values?

I am having some issues creating a client area of a set size. AdjustWindowRect() won't work properly so I decided to try manually calculating the width and height of the window.

That didn't work either and I wondered why so I checked up the values I used to take in account the borders etc.

#include <iostream>
#include <Windows.h>

int main(void)
{
    std::cout << "GetSystemMetrics(SM_CYEDGE) = " << GetSystemMetrics(SM_CYEDGE) << std::endl;
    std::cout << "GetSystemMetrics(SM_CXEDGE) = " << GetSystemMetrics(SM_CXEDGE) << std::endl;
    std::cout << "GetSystemMetrics(SM_CYBORDER) = " << GetSystemMetrics(SM_CYBORDER) << std::endl;
    std::cout << "GetSystemMetrics(SM_CXBORDER) = " << GetSystemMetrics(SM_CXBORDER) << std::endl;
    std::cout << "GetSystemMetrics(SM_CYCAPTION) = " << GetSystemMetrics(SM_CYCAPTION);

    std::cin.get();
}

This gives me:

GetSystemMetrics(SM_CYEDGE) = 2
GetSystemMetrics(SM_CXEDGE) = 2
GetSystemMetrics(SM_CYBORDER) = 1
GetSystemMetrics(SM_CXBORDER) = 1
GetSystemMetrics(SM_CYCAPTION) = 22

I am PRETTY sure that the borders of my window aren't that thin. What am I doing wrong?

EDIT 1:

Initially my window used the WS_OVERLAPPED style. Since the AdjustWindowRect does not allow that style to be used alongside it I constructed the same type of window I wanted with: (WS_BORDER | WS_CAPTION | WS_SYSMENU). This is the same style I use during the call to AdjustWindowRect and AdjustWindowRectEx(this one with NULL as extended style since I do not use any). This gives me the correct width but the height is missing a few pixels.

RECT rect = { 0, 0, 800, 600};

AdjustWindowRectEx( &rect, (WS_BORDER | WS_CAPTION | WS_SYSMENU), FALSE, NULL);

CreateWindowEx( ..., rect.right - rect.left, rect.bottom - rect.top, ...);

This gives me 800 pixels wide client-area but only 582 pixels in height.

EDIT 2:

CURIOUS, I used GetClientRect(); and it gave me that the width is 800 and the height IS 600. How come it doesn't display properly?


It seems that when I painted the whole window it all measured up. The reason? I don't know.

Maybe someone else can shed some light over this.

like image 509
Root Avatar asked Jul 29 '12 02:07

Root


1 Answers

The first issue is that you use the wrong metric. You'll need to use SM_CXSIZEFRAME to get the width of a resizable border.

The second issue is that Windows won't give you the correct value. The fat borders of a window on Aero are a serious appcompat problem. Windows intentionally lies about the window rectangle and border size. Required to allow old programs to still work correctly, they specify the size of the window in the CreateWindow() call. But that's the size of the frame, including the borders. Without the lie, the window would end up with a client area that's too small.

To turn off the lie, you have to tell Windows that you know about the Aero behavior and don't need to be lied to. Project + Properties, Linker, Command Line, Additional options box and add:

/SUBSYSTEM:CONSOLE,6.0

Version 6.0 is the Vista version number, the first version of Windows that had Aero. Beware that your program won't run on XP anymore when you do this.

like image 77
Hans Passant Avatar answered Sep 28 '22 05:09

Hans Passant