Thread: Automatic window scrollbars and other stories

  1. #1
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273

    Lightbulb Automatic window scrollbars and other stories

    Hi,

    I did raise the question of adding automatic scrollbars to an edit box some time ago and had a go at doing it, with some success. Anyway...

    I've made a window that is supposed to have the same client dimensions as the image it is showing. The image's dimensions are held in the variables sImgWidth and sImgHeight. If the window's client area is resized to below the image's width or height the appropriate scrollbar should be shown. I wrote this code for the window's WindowProc:
    Code:
    case WM_SIZE:
    {
    	if ((GetWindowLong(hwnd, GWL_STYLE) & WS_HSCROLL) != WS_HSCROLL && LOWORD(lParam) < sImgWidth)
    	{
    		SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_HSCROLL);
    		SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    	}
    	else if ((GetWindowLong(hwnd, GWL_STYLE) & WS_HSCROLL) == WS_HSCROLL && LOWORD(lParam) >= sImgWidth)
    	{
    		SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) ^ WS_HSCROLL);
    		SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    	}
    	if ((GetWindowLong(hwnd, GWL_STYLE) & WS_VSCROLL) != WS_VSCROLL && HIWORD(lParam) < sImgHeight)
    	{
    		SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_VSCROLL);
    		SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    	}
    	else if ((GetWindowLong(hwnd, GWL_STYLE) & WS_VSCROLL) == WS_VSCROLL && HIWORD(lParam) >= sImgHeight)
    	{
    		SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) ^ WS_VSCROLL);
    		SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    	}
    			
    	break;
    }
    I did have this working once, when the code was in the parent window's WindowProc (which is stupid, so I moved it), but it doesn't seem to work now. Anyone know why?

  2. #2
    Registered User sean345's Avatar
    Join Date
    Mar 2002
    Posts
    346
    If it is not inside the parent windows procedure then where did you put it? The child window might send the parent window the WM_SIZE message. Just a few thoughts.

    - Sean
    If cities were built like software is built, the first woodpecker to come along would level civilization.
    Black Frog Studios

  3. #3
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    The code is currently inside the child window's procedure (As it is the one showing the image).
    The only time WM_SIZE is called for this window is when its parent window calls MoveWindow with the child as the hwnd parameter in order to keep it visible in the resized parent. I didn't know non-WM_NOTIFY messages were passed up to parents?

  4. #4
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    Okay, after logging WM_SIZE messages with Spy++ I found out that although I was calling MoveWindow with the image width or height if the available client area equalled or exceeded the dimension in question, this wasn't what the window was receiving (I think that has something to do with the frame border and/or scrollbar dimensions). So I did this in the parent's WM_SIZE:
    Code:
    RECT rc, rc2, rcBwWindow, rcBwClient;
    
    GetWindowRect(hwndStatus, &rc);
    GetWindowRect(hwndToolbar, &rc2);
    GetWindowRect(hwndBrowser, &rcBwWindow);
    GetClientRect(hwndBrowser, &rcBwClient);
    MoveWindow(hwndBrowser, 0, (rc2.bottom - rc2.top), (LOWORD(lParam) < sImgWidth) ? LOWORD(lParam) : ((rcBwWindow.right - rcBwWindow.left) - rcBwClient.right) + sImgWidth, (HIWORD(lParam) - (rc.bottom - rc.top) - (rc2.bottom - rc2.top) < sImgHeight) ? HIWORD(lParam) - (rc.bottom - rc.top) - (rc2.bottom - rc2.top) : ((rcBwWindow.bottom - rcBwWindow.top) - rcBwClient.bottom) + sImgHeight, TRUE);
    Now it does seem to behave properly, although the window does seem to "snap to" the image dimensions when sized to a similar value...

Popular pages Recent additions subscribe to a feed