Thread: Scrolling

  1. #1
    Cheesy Poofs! PJYelton's Avatar
    Join Date
    Sep 2002
    Location
    Boulder
    Posts
    1,728

    Scrolling

    Ok, keep in mind that I have only been doing windows programming for a week! I am reading petzolds book and am on scrolling, but I simply cannot get this to work at all. Petzolds example required a LOT of extra writing creating this struct that printed out system information which I didn't want to do, so instead I am trying to do my own example. All I want to do is have it print something like this:
    0. This works!
    1. This works!
    2. This works!
    etc...
    but it only prints the first line and nothing more. I got it to work with his obsolete scrolling example at the beginning of chapter 4, but not with his better scrolling example at the end of chapter 4. Here is my wndProc:
    Code:
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {	HDC hdc;
    	PAINTSTRUCT ps;
    	SCROLLINFO si;  // scroll info
    	static int cxChar, cxCaps, cyChar;
    	static int cxClient, cyClient, iMaxWidth;  // current size of the window
    	int iVertPos,iHorzPos, iPaintBeg, iPaintEnd, y,x,i;
    	static int NUMLINES=1000;
    	TCHAR szBuffer[10];
    	TEXTMETRIC tm;
    
    	switch (message)
    	{
    	case WM_CREATE:  // when window is created
    		hdc=GetDC(hwnd);  // gets handle for paint functions
    
    		GetTextMetrics (hdc,&tm);  // gets info for text, like font size
    		cxChar=tm.tmAveCharWidth;
    		cxCaps=(tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar/2;
    		cyChar = tm.tmHeight+tm.tmExternalLeading;
    		ReleaseDC(hwnd, hdc);
    		iMaxWidth=1000;
    		return 0;
    
    	case WM_SIZE:   // for when the window is resized
    		cxClient=LOWORD(lParam);
    		cyClient=HIWORD(lParam);
    
    		// Set vertical scroll bar range and page size
    		si.cbSize=sizeof(si);  // always done.  this way in future updates the size updates auto
    		si.fMask=SIF_RANGE | SIF_PAGE;
    		si.nMin=0;
    		si.nMax=NUMLINES-1;
    		si.nPage=cyClient/cyChar;
    		SetScrollInfo(hwnd,SB_VERT,&si,TRUE);
    
    		// Set horizontal scroll bar range and page size
    		si.cbSize=sizeof(si);  // always done.  this way in future updates the size updates auto
    		si.fMask=SIF_RANGE | SIF_PAGE;
    		si.nMin=0;
    		si.nMax=2+iMaxWidth/cxChar;
    		si.nPage=cxClient/cxChar;
    		SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);
    		return 0;
    
    	case WM_PAINT:  // when it needs to be painted/repainted
    		hdc=BeginPaint(hwnd, &ps);
    
    		si.cbSize=sizeof(si);
    		si.fMask=SIF_POS;
    		GetScrollInfo(hwnd,SB_VERT,&si);
    		iVertPos=si.nPos;
    		GetScrollInfo(hwnd,SB_HORZ,&si);
    		iHorzPos=si.nPos;
    
    		iPaintBeg=max(0,iVertPos+ps.rcPaint.top/cyChar);
    		iPaintEnd=min(NUMLINES-1,iVertPos+ps.rcPaint.bottom/cyChar);
    
    		for (i=iPaintBeg; i<=iPaintEnd; i++)
    		{
    			x=0;
    			y=cyChar*(i-iVertPos);
    			
    			TextOut(hdc,x,y,szBuffer,wsprintf(szBuffer,TEXT("%i. This Works!"),y));
    
    		}
    		EndPaint(hwnd, &ps);
    		return 0;
    
    	case WM_VSCROLL:  // vertical scroll
    
    		si.cbSize=sizeof(si);
    		si.fMask=SIF_ALL;
    		GetScrollInfo(hwnd,SB_VERT,&si);
    
    		iVertPos=si.nPos;
    
    			switch (LOWORD(wParam))
    			{
    			case SB_TOP:
    				si.nPos=si.nMin;
    				break;
    			case SB_BOTTOM:
    				si.nPos=si.nMax;
    				break;
    			case SB_LINEUP:  // click arrow pointing up
    				si.nPos--;
    				break;
    			case SB_LINEDOWN: // click arrow pointing down
    				si.nPos++;
    				break;
    			case SB_PAGEUP:  // click empty spot above thumbtab
    				si.nPos-=si.nPage;
    				break;
    			case SB_PAGEDOWN:  // click empty spot below thumbtab
    				si.nPos+=si.nPage;
    				break;
    			case SB_THUMBPOSITION:  // click thumbtab
    				si.nPos=si.nTrackPos;
    				break;
    			default:
    				break;
    			}
    
    			// set position and then retrieve it.
    
    			si.fMask=SIF_POS;
    			SetScrollInfo(hwnd,SB_VERT,&si,TRUE);
    			GetScrollInfo(hwnd,SB_VERT,&si);
    
    			// if position has changed, scroll window and update it
    
    			if (si.nPos!=iVertPos)
    			{
    				ScrollWindow(hwnd,0,cyChar*(iVertPos-si.nPos),NULL,NULL);
    				UpdateWindow(hwnd);
    			}
    			return 0;
    
    	case WM_HSCROLL:  // side-to-side scroll
    		si.cbSize=sizeof(si);
    		si.fMask=SIF_ALL;
    		GetScrollInfo(hwnd,SB_HORZ,&si);
    
    		iHorzPos=si.nPos;
    
    			switch (LOWORD(wParam))
    			{
    			case SB_LINELEFT:  // click arrow pointing left
    				si.nPos--;
    				break;
    			case SB_LINERIGHT: // click arrow pointing right
    				si.nPos++;
    				break;
    			case SB_PAGELEFT:  // click empty spot next to thumbtab
    				si.nPos-=si.nPage;
    				break;
    			case SB_PAGERIGHT:  // click empty spot next to thumbtab
    				si.nPos+=si.nPage;
    				break;
    			case SB_THUMBPOSITION:  // click thumbtab
    				si.nPos=si.nTrackPos;
    				break;
    			default:
    				break;
    			}
    
    			// set position and then retrieve it.
    
    			si.fMask=SIF_POS;
    			SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);
    			GetScrollInfo(hwnd,SB_HORZ,&si);
    
    			// if position has changed, scroll window and update it
    
    			if (si.nPos!=iHorzPos)
    			{
    				ScrollWindow(hwnd,cxChar*(iHorzPos-si.nPos),0,NULL,NULL);
    				UpdateWindow(hwnd);
    			}
    			return 0;
    			
    	case WM_DESTROY:  // when it is destroyed
    		PostQuitMessage(0);
    		return 0;
    
    	}
    
    	return DefWindowProc(hwnd, message, wParam, lParam);
    }

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    We can debug it alot faster if you post the entire source (zipped) and describe what it isn't doing right. If I can run it in the debugger I can find out what's not right alot faster.

    gg

  3. #3
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    The attached compiles. iPaintBeg and iPaintEnd are always zero. Conceptually, what are you trying to do?
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  4. #4
    Cheesy Poofs! PJYelton's Avatar
    Join Date
    Sep 2002
    Location
    Boulder
    Posts
    1,728
    I don't want it to do anything fancy, I'm just trying to learn scrolling. What I want it to do is write something like this, one sentence on each line:
    0. This works!
    1. This works!
    2. This works!
    3. This works!
    4. This works!
    etc...
    1000. This works!
    so on and so forth down to some arbitrary number like say 1000. I want to be able to scroll down and see all of the numbers. I got this to work with an obsolete version of scrolling presented at the beginning of chapter 4 in petzolds book, but in my attempt to mimic his better scrolling example at the end, it isn't working. All that is printing is:
    0. This works!
    and if you scroll down then you get only half written text. And when I run it though, iPaintBeg and iPaintEnd are not always zero, but are the top and bottom of the coordinates of the page. I'm attaching all the code that I have which is very similar to what you have adrianxw.

  5. #5
    Cheesy Poofs! PJYelton's Avatar
    Join Date
    Sep 2002
    Location
    Boulder
    Posts
    1,728
    Oops, change this line:
    Code:
    TextOut(hdc,x,y,szBuffer,wsprintf(szBuffer,TEXT("%i This Works!"),y));
    to this:
    Code:
    TextOut(hdc,x,y,szBuffer,wsprintf(szBuffer,TEXT("%i This Works!"),i));

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    LOL!

    gg

  7. #7
    Cheesy Poofs! PJYelton's Avatar
    Join Date
    Sep 2002
    Location
    Boulder
    Posts
    1,728
    Errr... I didn't mean that fixes the problem. I just didn't want somebody to look at my code and think that it doesn't print the numbers 1-1000 because I was printing the wrong variable. It still doesn't do what I want. It only prints the first line and no more.

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    DOH!

    (Hopefully I'll have some time to look at it soon)

    gg

  9. #9
    Registered User Dohojar's Avatar
    Join Date
    Feb 2002
    Posts
    115
    I got your program to work with a few minor changes. For some reason this for loop wasnt working properly.

    Code:
    for( i = PaintBeg;  i <= PaintEnd;  i++ )
    {
       x=0;
       y=cyChar*(i-iVertPos);			
       TextOut(hdc,x,y,szBuffer,wsprintf(szBuffer,TEXT("%i. ThisWorks!"),y));
    }
    I ran this code though my debugger and put i and PaintBeg and PaintEnd it the watch window. Seems when the program runs though the first paint msg, i and PaintBeg both = 0. Which is what they should be, but after the first iteration of the loop, all of a sudden i was = 8564. Now this was bugging me cause there is nothing in your code that is changing the value of i so I rewrote the code like this
    Code:
    for( i = PaintBeg;  i <= PaintEnd;  i++ )
    {
       x=0;
       y=cyChar*(i-iVertPos);	
       wsprintf(szBuffer,TEXT("%i. ThisWorks!"),i)		
       TextOut(hdc,x,y,szBuffer,lstrlen(szBuffer);
    }
    That is when I noticed wsprintf() was changing the value of i for some reason. so I did this...
    Code:
    for (i=iPaintBeg; i<= iPaintEnd; i++)
    {
        x=0;
        y=cyChar*(i-iVertPos);
        int q = i;
        TextOut(hdc,x,y,szBuffer,
                 wsprintf(szBuffer,TEXT("i.ThisWorks!"),i));
        i = q;
    }
    and now it works fine. If anyone else can figure out why wsprintf() is changing the value of i, I sure would like to know. But the code works the way it should now.
    Hope this helps ya.
    Dohojar Moajbuj
    Time is the greatest teacher, too bad it kills all its students

  10. #10
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    >>int iVertPos,iHorzPos, iPaintBeg, iPaintEnd, y,x,i;

    as Dohojar pointed out these vars are the problem.

    declare them as static and your original code should work.

    The Wndproc is called many, many times a second. A msg is processed, ignored or passed on to the default processing.

    So any variables you need to have scope (hold a certain value) for more than one msg, they must be declared as static.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  11. #11
    Cheesy Poofs! PJYelton's Avatar
    Join Date
    Sep 2002
    Location
    Boulder
    Posts
    1,728


    Thank you all for your help!! You won't believe how much time I spent trying to figure this out to no avail. I made those variables non static simply because Petzold's example had them as non-static in his example. Didn't want to question the king of windows programming! I did try making x, y, and i static but then for some reason the window crashed. After making them ALL static after your suggestion novacain, the thing worked! Well almost, the left right scrolling isn't perfect, its printing garbage if you scroll right then back left, but I'll see if I can figure that out.

    I guess I really need to work through Petzolds code to see why his didn't need to declare those variables static.

    Thanks again guys!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Scrolling background?
    By Deo in forum Game Programming
    Replies: 6
    Last Post: 06-09-2005, 05:40 PM
  2. Bitmap scrolling with scroll bars
    By solar3147 in forum Windows Programming
    Replies: 0
    Last Post: 03-17-2003, 02:39 AM
  3. SkyLock graphics demo (scrolling, etc.)
    By jdinger in forum Game Programming
    Replies: 9
    Last Post: 06-30-2002, 08:18 PM
  4. Vesa. Parallax scrolling.
    By r0x in forum Game Programming
    Replies: 5
    Last Post: 06-10-2002, 05:39 PM
  5. My Console RPG with scrolling terrain ver 4!
    By Jeremy G in forum Game Programming
    Replies: 4
    Last Post: 11-25-2001, 04:39 PM