Building a Better Scroll
The syntaxof the SetScrollInfoand GetScrollInfofunctions is
SetScrollInfo (hwnd, iBar, &si,bRedraw) ;
GetScrollInfo (hwnd, iBar, &si) ;
The thirdargument to both functions is a SCROLLINFO structure, which is defined like so:
typedef struct tagSCROLLINFO
{
UINT cbSize ; // set to sizeof(SCROLLINFO)
UINT fMask ; // values to set or get
int nMin ; // minimum range value
int nMax ; // maximum range value
UINT nPage ; // page size
int nPos ; // current position
int nTrackPos ; // current trackingposition
}
SCROLLINFO, * PSCROLLINFO ;
In yourprogram, you can define a structure of type SCROLLINFO like this:
SCROLLINFO si ;
Beforecalling SetScrollInfoor GetScrollInfo, you must set the cbSizefield to the sizeof the structure:
si.cbSize = sizeof (si) ;
or
si.cbSize = sizeof (SCROLLINFO) ;
When you usethe SIF_RANGE flag with theSetScrollInfofunction, you must set the nMinand nMaxfields to the desiredscroll bar range. When you use the SIF_RANGE flag with theGetScrollInfofunction, the nMinand nMax fields will be set to the current rangeon return from the function.
The SIF_POS flag is similar. When used with the SetScrollInfofunction,you must set the nPosfield of the structure to the desired position. You usethe SIF_POS flag with GetScrollInfoto obtain the current position.
The SIF_PAGE flag lets you set and obtain the pagesize. You set nPageto the desired page size with the SetScrollInfofunction.GetScrollInfowith the SIF_PAGE flag lets you obtain the current page size.Don't use this flag if you don't want a proportional scroll bar thumb.
You use the SIF_TRACKPOS flag only with GetScrollInfowhileprocessing a WM_VSCROLL or WM_HSCROLL message with a notification code ofSB_THUMBTRACK or SB_THUMBPOSITION. On return from the function, the nTrackPosfieldof the SCROLLINFO structure will indicate the current 32-bit thumb position.
You use the SIF_DISABLENOSCROLL flag only with theSetScrollInfofunction. If this flag is specified and the new scroll bararguments would normally render the scroll bar invisible, this scroll rendersthe scroll bar disabled instead. (I'll explain this more short
The SIF_ALL flag is a combination of SIF_RANGE,SIF_POS, SIF_PAGE, and SIF_TRACKPOS. This is handy when setting the scroll bararguments during a WM_SIZE message. (The SIF_TRACKPOS flag is ignored whenspecified in a SetScrollInfofunction.)
How Low Can You Scroll?
Rather thanset the scroll bar range when we process the WM_CREATE message, we could waituntil we receive the WM_SIZE message:
iVscrollMax = max (0, NUMLINES -cyClient / cyChar) ;
SetScrollRange (hwnd, SB_VERT, 0,iVscrollMax, TRUE) ;
Onenice feature of the new scroll bar functions is that when you use a scroll barpage size, much of this logic is done for you. Using the SCROLLINFO structure and SetScrollInfo,you'd have code that looked something like this:
si.cbSize = sizeof (SCROLLINFO) ;
si.cbMask = SIF_RANGE | SIF_PAGE ;
si.nMin = 0 ;
si.nMax = NUMLINES - 1 ;
si.nPage = cyClient / cyChar ;
SetScrollInfo (hwnd, SB_VERT,&si, TRUE) ;
What happenswhen the page size is as large as the scroll bar range? That is, in thisexample, what if nPageis 75 or above? Windows conveniently hides the scroll barbecause it's no longer needed. If you don't want the scroll bar to be hidden,use SIF_DISABLENOSCROLL when calling SetScrollInfoand Windows will merelydisable the scroll bar rather than hide it.
SYSMETS3uses the ScrollWindowfunction to scroll information in the window's client arearather than repaint it. Although the function is rather complex (and has beensuperseded in recent versions of Windows by the even more complexScrollWindowEx), SYSMETS3 uses it in a fairly simple way. The second argumentto the function gives an amount to scroll the client area horizontally inpixels, and the third argument is an amount to scroll the client areavertically.
The last twoarguments to ScrollWindoware set to NULL. This indicates that the entire clientarea is to be scrolled. Windows automatically invalidates the rectangle in theclient area "uncovered" by the scrolling operation. This generates aWM_PAINT message. InvalidateRectis no longer needed.