Thread: Scroll bar help

  1. #1
    rEtaRD r HUMANS TOO !!! rEtard's Avatar
    Join Date
    Feb 2005
    Posts
    80

    Scroll bar help

    Guys i need help with my scroll bar, when it scrolls down or up, my bitmap within the client area will be smudged. What codes m i missing ? Err how should i attach my picture files?
    http://cboard.cprogramming.com/attac...achmentid=5599

    Below is the code to displaying the scrollbar and my icons, the program im doing is to mimic a windows folder and display the icons depending on how many there are.
    Code:
    		case WM_PAINT:
    			HDC hdc;
    			PAINTSTRUCT ps;
    			hdc = BeginPaint(hwnd,&ps);
    			HBITMAP test;
    
    			int x,y,i,IconsNo, Columns;
    			x = 10; y = 10;
    			i = 0;
    			IconsNo = 20; // artificial icon number to test my program firsthand.
    
    			test = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_NOTE));
    
    			while(i<IconsNo)
    			{
    				if ( x > 265 ) 
    				{
    					x = 10;
    					y = y + 90;
    					bMp->Draw(test,hdc,1,x,y,0,0); // this is just a bitblt function 
    				}
    				bMp->Draw(test,hdc,1,x,y,0,0);
    				x = x + 85;
    				i++;
    			}
    
    			Columns = IconsNo / 4 + 1; // Each row only takes 4 icons + 1 to round up
                si.cbSize = sizeof (si) ;
                si.fMask  = SIF_RANGE | SIF_PAGE ;
                si.nMin   = 1 ;
                si.nMax   = Columns * TextperIcon - (cyClient / cyChar) - 10;
    			// 10 is the starting y value, icon starts at (10,10)
                si.nPage  = cyClient / cyChar ; // No. of text displayed
                SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
    
    			DeleteObject(test);
    			break;
    	    case WM_VSCROLL:
    			si.cbSize = sizeof(si);
    			si.fMask = SIF_ALL;
    			GetScrollInfo(hwnd,SB_VERT,&si);
    			PosVert = si.nPos;
    			switch(LOWORD(wParam))
    			{
    		    	case SB_LINEDOWN:
    					si.nPos += 1 ;
    					break;
    				case SB_PAGEDOWN:
    					 si.nPos += si.nPage ;
    					break;
    				case SB_THUMBTRACK:
    					si.nPos = si.nTrackPos ;
    					break;
    				case SB_PAGEUP:
    					si.nPos -= si.nPage ;
    					break;
    				case SB_LINEUP:
    					si.nPos -= 1 ;
    					break;
    			}
                si.fMask = SIF_POS ;
                SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
                GetScrollInfo (hwnd, SB_VERT, &si) ;
    
                   // If the position has changed, scroll the window and update it
    
                if (si.nPos != PosVert)
    			{                    
                     ScrollWindowEx(hwnd,0,cyChar * (PosVert - si.nPos), 
                                    NULL,NULL,NULL,NULL,SW_ERASE) ;
                     UpdateWindow (hwnd) ;
    			}
    			break;
    I apologise for the huge codings but is there something i missed ? i have no idea how to salvage the situation.
    /* Have a nice day */

  2. #2
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    It becomes smudged because you are not clearing the screen and then drawing. You are just drawing over what is already there. I recommend that at the end of the WM_SCROLL message, instead of using UpdateWindow, use InvalidateRect(). You can have it clear out the window and then have it call WM_PAINT. Just use this code:
    InvalidateRect(hwnd, NULL, TRUE);
    Don't quote me on that... ...seriously

  3. #3
    rEtaRD r HUMANS TOO !!! rEtard's Avatar
    Join Date
    Feb 2005
    Posts
    80
    I tried using InvalidateRect(), it does help but somehow it looks worse.
    Code:
                if (si.nPos != PosVert)
    			{                    
                     ScrollWindowEx(hwnd,0,cyChar * (PosVert - si.nPos), 
                                    NULL,NULL,NULL,NULL,SW_ERASE) ;
                     InvalidateRect(hwnd,NULL,FALSE);
    				 UpdateWindow(hwnd);
    			}
    			break;
    What SHOULD I DO ~!?!!?!! MY hair is dropping !!!
    /* Have a nice day */

  4. #4
    rEtaRD r HUMANS TOO !!! rEtard's Avatar
    Join Date
    Feb 2005
    Posts
    80
    Really No One Can Help ???!?!!? Argh.... !!!!
    /* Have a nice day */

  5. #5
    -AppearingOnThis..........
    Join Date
    May 2005
    Location
    Netherlands
    Posts
    44
    The last paramenter for InvalidateRect() is for erasing the background, and you set that to false. Try putting it as TRUE and see what happens. By the way, I don't think you don't need to call UpdateWindow() after InvalidateRect(), for a WM_PAINT message is sent when any part of the client area is invalid.

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You need to look at the scrolling example again. Your current paint routine draws the icons in the same position, regardless of the position of the scroll bar. This defeats the point of having a scroll bar.

    The easiest way for you to achieve scrolling is to get the position of the scrollbar and subtract it from your beginning y value in WM_PAINT. For example, if the scrollbar is at position 10 you start with a y value of 0, if the scrollbar is at 25, you start with a beginning y value of -15. This will scroll your icons upwards as you scroll down.

    The purpose of ScrollWindowEx is to provide smoother scrolling by limiting the amount of redrawing that needs to be performed. It works by moving the content of the window up or down as specified by its arguments. This leaves only a box at the bottom or top of the window that needs repainting. For example, if you scroll down 10 units it will move the content up and leave a 10 unit box at the bottom of the window that needs repainting. The rest of the window does not need repainting as the content has been moved up. You can find the area that needs repainting by looking in ps.rcPaint inside your WM_PAINT routine.

    For now I would suggest you do not use ScrollWindowEx. Just comment it out and use InvalidateRect instead (use TRUE as the last argument so the window is erased before you draw again). This will cause the entire screen to be repainted but is simpler to start with. Once you have that working well you can make use of ScrollWindowEx (and delete the InvalidateRect call) to reduce flicker.

    Finally, you need to call EndPaint at the end of your WM_PAINT routine.
    Last edited by anonytmouse; 05-15-2005 at 10:06 AM. Reason: Mixed up x and y.

  7. #7
    rEtaRD r HUMANS TOO !!! rEtard's Avatar
    Join Date
    Feb 2005
    Posts
    80
    wow, i didn't know msdn offers examples, alrite THANZ everione ! i shall do a bit of reading, and cum back to you all if i met with more problems.
    /* Have a nice day */

  8. #8
    Registered User
    Join Date
    Mar 2005
    Posts
    135
    Quote Originally Posted by SirNot
    By the way, I don't think you don't need to call UpdateWindow() after InvalidateRect(), for a WM_PAINT message is sent when any part of the client area is invalid.
    The problem is; When InvalidateRect causes the program to send a WM_PAINT, this message is placed in the message queue and therefore, it will not be processed UNTIL ALL other messages in the message queue have been processed first. Why?, because WM_PAINT is a low priority message. Thus, not calling UpdateWindow after a call to InvalidateRect will cause your app to NOT erase the background/paint the client area 'immediately'.

  9. #9
    rEtaRD r HUMANS TOO !!! rEtard's Avatar
    Join Date
    Feb 2005
    Posts
    80
    anonytmouse, anyone, im at a total lost to this scrollbar thing. I reviewed MSDN scrolling examples, i did wat i could, modified the codes, improved on the scroll position and max n min values but i still can't get the output of my bitmap icons correct. Someone pls advise.
    Code:
    static int xClient, yClient, Column, IconsNo, CurrentPos;
    		case WM_SIZE:
    			IconsNo = 13;
    			Column = IconsNo / 4 + 1; // if possible correct this formula
                xClient = LOWORD (lParam) ;
                yClient = HIWORD (lParam) ; // this is what we wan
    			si.cbSize = sizeof(si);
    			si.fMask = SIF_RANGE | SIF_PAGE;
    			si.nPage = yClient; // page/viewing size is Y coord, Reasonable rite
    			si.nMin = 0;
    			si.nMax = Column * 150 + 10 - yClient;
    			SetScrollInfo(hwnd,SB_VERT,&si,TRUE);
    		case WM_PAINT:
    			HDC hdc;
    			hdc = BeginPaint(hwnd,&ps);
    			HBITMAP test;
    			test = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_NOTE));
    			int x,y,i;
    			x = 10; y = 10; // starting coordinates
    			i = 0;
    
    			// Displaying the Icons onto the client area
    			while(i<IconsNo)
    			{
    				if ( x > 265 ) 
    				{
    					x = 10;
    					y = y + 90;
    					bMp->Draw(test,hdc,1,x,y,0,0);
    				}
    				bMp->Draw(test,hdc,1,x,y,0,0);
    				x = x + 85;
    				i++;
    			}
    
    			if (Scroll )
    			{
    				HDC TempHDC;
    				TempHDC = CreateCompatibleDC(hdc);
    				SelectObject(TempHDC,test);
     // i did this SelectObject to show if scrolling worked
    // but this bitmap will only appear if i did an extreme
    // thumb position from down to up, other than it wun even appear
    				BitBlt(ps.hdc,ps.rcPaint.left,ps.rcPaint.top,
    					   ps.rcPaint.right - ps.rcPaint.left,
    					   ps.rcPaint.bottom - ps.rcPaint.top,
    					   TempHDC,
    					   ps.rcPaint.left + 0,
    					   ps.rcPaint.top + CurrentPos,SRCCOPY);
    				Scroll = FALSE;
    			}
    			
    			EndPaint(hwnd,&ps);
    			DeleteObject(test);
    			break;
    	    case WM_VSCROLL:
    			// coding this scroll bar is making my hair drop !
    			int YnewPos,MovedAmt;
                si.cbSize = sizeof (si); // impt
                si.fMask  = SIF_ALL; // impt
    			GetScrollInfo(hwnd,SB_VERT,&si);
    			YnewPos = si.nPos;
    			switch(LOWORD(wParam))
    			{
    		    	case SB_LINEDOWN:
    					si.nPos +=5;
    					break;
    				case SB_PAGEDOWN:
    					si.nPos += 20;
    					break;
    				case SB_THUMBPOSITION:
    					si.nPos = si.nTrackPos;
    					break;
    				case SB_PAGEUP:
    					si.nPos -= 20;
    					break;
    				case SB_LINEUP:
    					si.nPos -=5;
    					break;
    			}
    			if ( si.nPos != YnewPos )
    			{
    			    SetScrollInfo(hwnd,SB_VERT,&si,TRUE); // impt
    			    GetScrollInfo(hwnd,SB_VERT,&si); // impt
    
    			    Scroll = TRUE; // flag to inform WM_PAINT abt new job
    			    MovedAmt = YnewPos - si.nPos; // determine scroll moved amt
    
                    ScrollWindowEx(hwnd,0,MovedAmt,NULL,NULL,NULL,NULL,SW_INVALIDATE);
    			    UpdateWindow(hwnd); // push WM_PAINT now
    			}
    		  break;
    everithing abt the scrollbar is fine now, all i need is that it display the correct amount of icons being hidden below or above. This is what im stucked with.
    Please take a look at my attached Image1. My variable IconsNo was set to 13, so there should be another Bitmap icon at the end of my scroll.
    Ok, for now, let me get one thing straight first, do me(the programmer) have to take charge of all drawings to make up for the scrolling actions the user did ? or win32 will take care of it for me.
    Last edited by rEtard; 05-17-2005 at 02:52 PM.
    /* Have a nice day */

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. beach bar (sims type game)
    By DrKillPatient in forum Game Programming
    Replies: 1
    Last Post: 03-06-2006, 01:32 PM
  2. Bitmap with a scroll bar
    By SuperNewbie in forum Windows Programming
    Replies: 1
    Last Post: 10-29-2003, 11:36 PM
  3. no horizontal scroll bar?
    By scott27349 in forum C++ Programming
    Replies: 0
    Last Post: 03-16-2002, 10:41 PM
  4. Problem with Scroll Bar
    By Garfield in forum Windows Programming
    Replies: 8
    Last Post: 11-05-2001, 05:34 AM
  5. Problem with Scroll Bar
    By Garfield in forum Windows Programming
    Replies: 3
    Last Post: 11-01-2001, 02:23 PM