Thread: AdjustWindowRect/Setting client size

  1. #1
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972

    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
    Last edited by JaWiB; 06-23-2006 at 02:35 PM. Reason: Fixed typo
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  2. #2
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    Code:
        assert((newClientRC.bottom-newClientRC.left)==clientHeight)
    bottom - left != height. Simple typo, change to bottom - top and see if that fixes it.
    EDIT: Nevermind, that wasn't throwing errors for you anyways. (It would if height != width...)
    EDIT: And I get the same results, oddly, for your first example. It's off by 16 pixels in either direction, the size of a scrollbar. Unless it counting that as client space...? You might get a scrollbars size with GetSystemMetrics() with SM_CHTHUMB (or SM_CVTHUMB)
    Last edited by Cactus_Hugger; 06-23-2006 at 01:55 PM.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  3. #3
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Whoops, fixed the typo. I already knew that the client size wasn't correct, however, because it was causing problems in my program and I checked it in the debugger (for me it was off by 21)
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    It seems as though the scrollbars are counted as part of the client area for AdjustWindowRect, but not for GetClientRect.
    I think it may be the other way around. AdjustWindowRectEx has a note:
    Quote Originally Posted by MSDN
    The AdjustWindowRectEx function does not add extra space when a menu bar wraps to two or more rows.

    The AdjustWindowRectEx function does not take the WS_VSCROLL or WS_HSCROLL styles into account. To account for the scroll bars, call the GetSystemMetrics function with SM_CXVSCROLL or SM_CYHSCROLL.
    I think your approach is probably fine, although it may be slightly less future-proof than using AdjustWindowRectEx. Consider the (very unlikely) scenario where the size of a window's title bar depended on the size of the client area. AdjustWindowRectEx would correctly handle this situation while your code would break.

    Then again, AdjustWindowRectEx has already not been updated to handle scroll bars and some styles, so maybe your code is more future-proof.

    Yep, that's having a bet each way. I'm not sure which approach I'd go with. I think both are fine.

  5. #5
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Tricksey documentation...I need to learn to read more carefully (or maybe I was looking at the windows CE reference, which doesn't have that note)
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Adventures in labyrinth generation.
    By guesst in forum Game Programming
    Replies: 8
    Last Post: 10-12-2008, 01:30 PM
  2. Socket Programming Problem!!!!
    By bobthebullet990 in forum Networking/Device Communication
    Replies: 2
    Last Post: 02-21-2008, 07:36 PM
  3. WSAAsyncSelect Socket Model. She's Not Hot.
    By Tonto in forum Networking/Device Communication
    Replies: 2
    Last Post: 03-24-2007, 08:34 AM
  4. Client works on a LAN but don't send all the data
    By Niara in forum Networking/Device Communication
    Replies: 9
    Last Post: 01-04-2007, 04:44 PM
  5. An exercise in optimization
    By Prelude in forum Contests Board
    Replies: 10
    Last Post: 04-29-2005, 03:06 PM