# Win32: Scrollbar problem

## Recommended Posts

Evil Steve    2017
Hey all, I'm trying to make a custom control, since the ListView control was pissing me off no end. Now, I've got most of the code working fine, except there's a bug with the scrollbars. The scrollbar bars don't seem to move at all. I can click the arrows at the ends of the scrollbars, and click the pageup and pagedown bits, and my control recieves all the messages just fine, but the horizontal scrollbar stays stuck to the left hand side. Here's a screenshot, where I've scrolled over to the right by 37 pixels: As you can see, the contents are scrolled correctly, but the scrollbar doesn't move - it's still jammed into the left. And here's how my scrollbar is set up, and the code for handling WM_HSCROLL:
// Scrollbar setup
SCROLLINFO si;
memset(&si,0,sizeof(si));
si.cbSize = sizeof(si);
si.nPage = 32;
si.nMin = 0;
si.nMax = m_nMaxXScroll+BORDER_SIZE*3;   // Evaluates to 37
SetScrollInfo(m_hWnd,SB_HORZ,&si,TRUE);

// WM_HSCROLL handling:
case WM_HSCROLL:
{
switch(LOWORD(wParam))
{
case SB_BOTTOM: m_nX = m_nMaxXScroll; break;
case SB_LINEDOWN: if(m_nX < m_nMaxXScroll) ++m_nX; break;
case SB_LINEUP: if(m_nX > 0) --m_nX; break;
case SB_PAGEDOWN: if(m_nX < m_nMaxXScroll) ++m_nX; break;
case SB_PAGEUP: if(m_nX > 0) --m_nX; break;
case SB_THUMBTRACK: m_nX = HIWORD(wParam); break;
case SB_TOP: m_nX = 0; break;
}
InvalidateRect(m_hWnd,NULL,TRUE); // FIXME
}
break;


So, does anyone know what's causing this? EDIT: Changed title. I have a new question and didn't want to start a new thread... Thanks in advance, Steve [Edited by - Evil Steve on March 27, 2005 10:19:51 AM]

##### Share on other sites
Guest Anonymous Poster
Here's part of a wrapper I wrote awhile ago. Maybe it helps?

void WinScrollBar::setupScroll() {   SCROLLINFO si;   si.cbSize = sizeof(SCROLLINFO);   si.fMask = SIF_ALL;   si.nPos = propPosC;   si.nPage = propPageSizeC;   si.nMin = 0;   si.nMax = propScrollSizeC;   SetScrollInfo(hwndC, SB_CTL, &si, true);}void WinScrollBar::scroll(int scrollCode, int pos) {   switch (scrollCode) {      //In 'winuser.h' SB_LINEUP is equivalent to SB_LINELEFT, etc...      case SB_LINEUP:      scrollRight1();      break;      case SB_LINEDOWN:    scrollLeft1();       break;      case SB_PAGEDOWN:    scrollRightMany();   break;      case SB_PAGEUP:      scrollLeftMany();    break;      case SB_THUMBTRACK:  horScrollTrack(pos); return;      }   s_cast<WinBaseO*>(parentC)->setWindowPos(this, posC);   setupScroll();}

This is not using the default scrollbars for the windows, of course. It appears the I had to call the SetScrollInfo function after handling the message in order to set the correct state of the scrollbar.

David

##### Share on other sites
Guest Anonymous Poster
Never mind - it appears you have done that already. Sorry. But it doesn't appear that you set the .nPos member of the SCROLLINFO variable.

##### Share on other sites
Colin Jeanne    1114
When you handle WM_HSCROLL/WM_VSCROLL you have to update the scroll bar's info using SetScrollInfo(). It's counterintuitive, unfortunately. Here's an example from the MSDN.

##### Share on other sites
Evil Steve    2017
The nPos variable should default to 0, shouldn't it?
I also tried manually setting the position of the scrollbar like this, and it didn't make any difference:
case SB_THUMBPOSITION:{   SCROLLINFO si;   memset(&si,0,sizeof(si));   si.cbSize = sizeof(si);   si.fMask = SIF_POS;   si.nPos = HIWORD(wParam);   SetScrollInfo(m_hWnd,SB_VERT,&si,TRUE);   m_nX = HIWORD(wParam);}break;

##### Share on other sites
Evil Steve    2017
D'oh, I'm an idiot. I was setting the wrong scrollbar info >_< SetScrollInfo(m_hWnd,SB_VERT,&si,TRUE); should be SetScrollInfo(m_hWnd,SB_HORZ,&si,TRUE);

Oh well, I feel like an idiot now [smile]
Thanks for the replies

##### Share on other sites
Evil Steve    2017
Ok, I've got another scrollbar related question.
I was looking at the source for Scrolling A Bitmap again, and I tried to do what's done in that source for setting up the page size, which is:
nMin = 0;
nMax = max(ContentWidth-ClientWidth, 0);
nPage = ClientWidth;

My content width is 192px, my client width is 167px, so the max scrollbar range is 25px.
However, now the scrollbar doesn't show up at all. I suspect the page size is supposed to be less than the scroll range, but that doesn't match the MSDN example.

Am I being an idiot again, and missing the blindingly obvious?

##### Share on other sites
Evil Steve    2017
*bump* Anyone?

##### Share on other sites
Implementing Scroll bars with the Win32 API is a B**ch!.

Do you have Petzold's Windows Programming book? cause he has some pretty good examples in it about scroll bars (a whole chapter).

relient.

##### Share on other sites
Have you done something like this in your source code?:

TEXTMETRIC tm;
int cxChar;

cxChar = tm.AveCharWidth;

nMax = max((ContentWidth-ClientWidth) * cxChar, 0);

##### Share on other sites
Guest Anonymous Poster
I've placed an example of a working scrollbar on my site for you, using my wrapper library. It should show you enough by stepping through it that you can figure out how to recreate it in pure Win32 if you so desire. It was put together in Borland, so you will have to recreate it if using VC. (Shouldn't be that hard. Just keep adding units until no more errors.)

http://www.randommonkeyworks.com/realdraw/scrollbars.zip

David