Get scroll bar information from autoscroll controls in Managed C++

            One of the early problems that I needed to solve when I started working at Microsoft was how to get the caller / callee view (shown below) to work properly. The difficult thing was getting three separate treegrid controls to scroll together (controlled by one bottom scrollbar) horizontally, but to also allow the top and bottom treegrids to scroll vertically independently of each other. I was also a little disappointed in the lack of control over the automatically generated scrollbars from managed winforms. I was hoping to directly be able to manipulate the auto-scrollbars as properties of the parent controls.

 

 

 

            While I won’t go into all the details of the various panels and events I used to solve this issue, I thought that I would quickly mention the way to get and set information in controls with auto-scrollbars from managed code. The two function that we are going to use for this are GetScrollInfo and SetScrollInfo. These functions are defined in winuser.h and you will have to include windows.h to use them. Also, you will need the ScrollInfo structure to pass in to these functions.

 

            To get information from a control (myControl) with an auto-scrollbar you need to do the following:

 

SCROLLINFO scrollInfo;

scrollInfo.cbSize = sizeof( SCROLLINFO );

scrollInfo.fMask = (SIF_ALL);

HWND ctrHandle = static_cast<HWND> ( myControl->Handle.ToPointer() );

GetScrollInfo( ctrHandle, SB_VERT, (LPSCROLLINFO)&scrollInfo );

     The scollInfo structure now contains info on the position, page, min, max and tracking position of the auto-scrollbar. To get information from a scrollbar we need to pass a scrollinfo structure in to SetScrollInfo, with the mask specifying the values that we want to set. Below is an example of setting just the scroll position on a vertical auto-scrollbar:

 

SCROLLINFO scrollInfo;

scrollInfo.cbSize = sizeof( SCROLLINFO );

scrollInfo.fMask = SIF_POS;

scrollInfo.nPos = newValue;

HWND ctrHandle = static_cast<HWND> ( myControl->Handle.ToPointer() );

SetScrollInfo( ctrHandle, SB_VERT, (LPSCROLLINFO)&scrollInfo, true );

      To get the control to update correctly, you will need to post a message to it, such as the one below (this message is for adjusting vertical position):

 

PostMessageA( ctrHandle, WM_VSCROLL, SB_THUMBPOSITION + (0x10000 * scrollInfo.nPos), 0 );

      By using these functions you can get better control over autoscroll controls then the .NET framework can give you. Sure this isn’t the most earth-shatteringly cool stuff, but if you need to mess around with autoscrolling controls from managed code, maybe it will help you out.