window border width and height in Win32 - how do I get it?
The GetWindowRect and GetClientRect functions can be used calculate the size of all the window borders.
Suite101 has a article on resizing a window and the keeping client area at a know size.
Here is their sample code:
void ClientResize(HWND hWnd, int nWidth, int nHeight)
{
RECT rcClient, rcWind;
POINT ptDiff;
GetClientRect(hWnd, &rcClient);
GetWindowRect(hWnd, &rcWind);
ptDiff.x = (rcWind.right - rcWind.left) - rcClient.right;
ptDiff.y = (rcWind.bottom - rcWind.top) - rcClient.bottom;
MoveWindow(hWnd,rcWind.left, rcWind.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
}
How do we get the border size of a window?
On windows you can use GetWindowRect
and GetClientRect
RECT windowRect;
GetWindowRect(hwnd, &windowRect);
RECT clientRect;
GetClientRect(hwnd, &clientRect);
int borderWidth = ((windowRect.right - windowRect.left) - (clientRect.right -clientRect.left))/2;
Though GetClientRect
should give you the inner width of the window and that should be enough for you.
int innerWidth = clientRect.right - clientRect.left;
How to adjust window border size
Maybe you can use MoveWindow to resize the window, and then draw the border yourself, like this,
Draw a borderless window first:
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
100, 100, 800, 600, nullptr, nullptr, hInstance, nullptr);
LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
SetWindowLong(hWnd, GWL_STYLE, lStyle);
Then handle the window border in the WM_LBUTTONDOWN
message:
int num = 0;
case WM_LBUTTONDOWN:
{
RECT rcWind;
HDC dc = GetDC(hWnd);
GetWindowRect(hWnd, &rcWind);
if (num >= 0)
{
num--;
RECT rcClient;
MoveWindow(hWnd, rcWind.left - 4, rcWind.top - 4, 8 + rcWind.right - rcWind.left, 8 + rcWind.bottom - rcWind.top, TRUE);
GetClientRect(hWnd, &rcClient);
HPEN hPen = CreatePen(PS_SOLID, 4, RGB(255, 128, 1));
HGDIOBJ hOldPen = SelectObject(dc, hPen);
Rectangle(dc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
DeleteObject(hPen);
}
else if (num < 0)
{
MoveWindow(hWnd, rcWind.left + 4, rcWind.top + 4, rcWind.right - rcWind.left - 8, rcWind.bottom - rcWind.top - 8, TRUE);
num++;
}
}
break;
How to change the border size of a single window?
Unless you do it by owner-drawn your only options are changing the border type between dialog, fixed single and none. They are of different thicknesses and looks and behaviors so not a great choice. Making your own is definitely the only way to go.
AN easy way to "create your own border" coould actually be to do Windows Skinning
GetWindowRect returns a size including invisible borders
Windows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing. The borders might look like this: 7,0,7,7
(left, top, right, bottom)
When you call SetWindowPos
to put the window at this coordinates:0, 0, 1280, 1024
The window will pick those exact coordinates, and GetWindowRect
will return the same coordinates. But visually, the window appears to be here: 7, 0, 1273, 1017
You can fool the window and tell it to go here instead:-7, 0, 1287, 1031
To do that, we get Windows 10 border thickness:
RECT rect, frame;
GetWindowRect(hwnd, &rect);
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT));
//rect should be `0, 0, 1280, 1024`
//frame should be `7, 0, 1273, 1017`
RECT border;
border.left = frame.left - rect.left;
border.top = frame.top - rect.top;
border.right = rect.right - frame.right;
border.bottom = rect.bottom - frame.bottom;
//border should be `7, 0, 7, 7`
Then offset the rectangle like so:
rect.left -= border.left;
rect.top -= border.top;
rect.right += border.left + border.right;
rect.bottom += border.top + border.bottom;
//new rect should be `-7, 0, 1287, 1031`
Unless there is a simpler solution!
Get the size of non-client area of a themed Edit Control
How do you get the width of the border (non-client) of a themed Edit
control in Windows XP and later versions?
The following works for all controls, whether they are themed or not. It doesn't even need the theme API.
- Call
GetClientRect()
to get the size of the client area. - Call
ClientToScreen()
to transform client rect to screen coordinates. - Call
GetWindowRect()
to get the rectangle of the control including NC area, in screen coordinates. - Calculate difference between client rect and window rect coordinates to get size of border (e. g.
leftBorderWidth = clientRect.left - windowRect.left
).
Edit:
Interestingly, the Wine source theme_edit.c doesn't use GetThemeMetric()
at all. Instead they call GetSystemMetrics()
with SM_CXEDGE
and SM_CYEDGE
.
On my systems (Windows 7 and Windows 10), this returns the correct value of 2
.
Windows: Getting a window title bar's height
Assuming that you don't have menu bar, you can map points from client coordinate system to screen one
RECT wrect;
GetWindowRect( hwnd, &wrect );
RECT crect;
GetClientRect( hwnd, &crect );
POINT lefttop = { crect.left, crect.top }; // Practicaly both are 0
ClientToScreen( hwnd, &lefttop );
POINT rightbottom = { crect.right, crect.bottom };
ClientToScreen( hwnd, &rightbottom );
int left_border = lefttop.x - wrect.left; // Windows 10: includes transparent part
int right_border = wrect.right - rightbottom.x; // As above
int bottom_border = wrect.bottom - rightbottom.y; // As above
int top_border_with_title_bar = lefttop.y - wrect.top; // There is no transparent part
Got 8, 8, 8 and 31 pixels (96DPI aka 100% scaling setting)
You should also take into account DPI awareness mode. Especially GetSystemMetrics
is tricky because it remembers state for System DPI when your application was launched.
Get exact window region size - CreateWindow window size isn't correct size of window
I use this method and now it works:
if ( IsWindow( hwnd ) )
{
DWORD dwStyle = GetWindowLongPtr( hwnd, GWL_STYLE ) ;
DWORD dwExStyle = GetWindowLongPtr( hwnd, GWL_EXSTYLE ) ;
HMENU menu = GetMenu( hwnd ) ;
RECT rc = { 0, 0, width, height } ;
AdjustWindowRectEx( &rc, dwStyle, menu ? TRUE : FALSE, dwExStyle );
SetWindowPos( hwnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOMOVE ) ;
}
Related Topics
What Is the Use of Volatile Keyword
How to Call a Template Member Function
Do Stl Maps Initialize Primitive Types on Insert
Which Sorting Algorithm Is Used by Stl's List::Sort()
What Optimization Does Move Semantics Provide If We Already Have Rvo
Implementing Future::Then() Equivalent for Asynchronous Execution in C++11
How to Declare Array with Auto
What Is the Modern, Correct Way to Do Type Punning in C++
Why Can't I Static_Cast Between Char * and Unsigned Char *
How to Build Openssl with Mingw in Windows
How Does a C/C++ Compiler Find the Definitions of Prototypes in Header Files
Dropping Privileges in C++ on Windows
Converting Cv::Mat for Tesseract
How to Use a Lambda Expression as a Template Parameter
C++: How to Check If the Cin Buffer Is Empty
Compile Time Template Instantiation Check
Why Don't I Need to Specify "Typename" Before a Dependent Type in C++20