Win32: Scrollbar problem

Started by
9 comments, last by GameDev.net 19 years ago
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: Eep 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.fMask = SIF_RANGE | SIF_PAGE;
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]
Advertisement
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
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.
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.
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;

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
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?
*bump* Anyone?
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.
Have you done something like this in your source code?:

TEXTMETRIC tm;
int cxChar;

cxChar = tm.AveCharWidth;

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

This topic is closed to new replies.

Advertisement