AdjustWindowRect/Setting client size
I know I've seen posted at least a couple times this link which gives an example of using AdjustWindowRect to set the client size to a specified width and height. But this doesn't appear to work correctly if the window has scrollbars. For example:
Code:
#include <windows.h>
#include <cassert>
void SetClientSize( HWND hwnd, int clientWidth, int clientHeight )
{
if ( IsWindow( hwnd ) )
{
DWORD dwStyle = GetWindowLongPtr( hwnd, GWL_STYLE ) ;
DWORD dwExStyle = GetWindowLongPtr( hwnd, GWL_EXSTYLE ) ;
HMENU menu = GetMenu( hwnd ) ;
RECT rc = { 0, 0, clientWidth, clientHeight } ;
if(!AdjustWindowRectEx( &rc, dwStyle, menu ? TRUE : FALSE, dwExStyle ))
MessageBox(NULL,"AdjustWindowRectEx Failed!","Error",MB_OK);
SetWindowPos( hwnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
SWP_NOZORDER | SWP_NOMOVE ) ;
#ifdef _DEBUG
RECT newClientRC;
GetClientRect(hwnd,&newClientRC);
assert((newClientRC.right-newClientRC.left)==clientWidth);
assert((newClientRC.bottom-newClientRC.top)==clientHeight);
#endif
}
}
LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreviousInstance,LPSTR lpcmdline,int nCmdShow)
{
WNDCLASS wc;
MSG msg;
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = MainWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_SCROLLBAR + 1);
wc.lpszMenuName = 0;
wc.lpszClassName = "WinClassName";
if (!RegisterClass (&wc))
return 0;
HWND hwnd;
hwnd = CreateWindow ( "WinClassName",
"AdjustWindowRect test",
WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL,
20,
20,
400,
400,
NULL,
NULL,
hInstance,
NULL);
if (!hwnd)
return 0;
SetClientSize(hwnd,500,500);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return 0;
}
LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
This gives an assertion error for me. It seems as though the scrollbars are counted as part of the client area for AdjustWindowRect, but not for GetClientRect. My solution was this:
Code:
void SetClientSize( HWND hwnd, int clientWidth, int clientHeight )
{
if ( IsWindow( hwnd ) )
{
RECT winRC,clientRC;
GetWindowRect(hwnd,&winRC); //get the current window rect
GetClientRect(hwnd,&clientRC); //get the current client rect
int dx = (clientRC.right-clientRC.left)-clientWidth; //calculate difference between current client width and desired client width
int dy = (clientRC.bottom-clientRC.top)-clientHeight; //same for height
//adjust the size
SetWindowPos(hwnd,0,0,0,winRC.right-winRC.left-dx,winRC.bottom-winRC.top-dy,SWP_NOZORDER|SWP_NOMOVE);
#ifdef _DEBUG
RECT newClientRC;
GetClientRect(hwnd,&newClientRC);
assert((newClientRC.right-newClientRC.left)==clientWidth);
assert((newClientRC.bottom-newClientRC.top)==clientHeight);
#endif
}
}
Which does not give an assertion error. Does anyone see any potential drawbacks to my solution, or have a reason for AdjustWindowRect to behave this way?
Edit: And this was built with VS 2003 if that makes a difference