CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: WM_PAINT logic

Threaded View

  1. #1
    Join Date
    Sep 2010
    Posts
    66

    WM_PAINT logic

    hi all,

    I'm still a bit new to things here, but I am trying to understand the logic behind the processing of the WM_PAINT message in this case. I have put my comments in below, trying to make sense of it.

    Code:
       case WM_PAINT :
              hdc = BeginPaint (hwnd, &ps) ;
    
              si.cbSize = sizeof (si) ;
              si.fMask  = SIF_POS ;
    
              GetScrollInfo (hwnd, SB_VERT, &si) ;
              iVert = si.nPos ; //Okay, current position of vertical scroll bar
    
    
              GetScrollInfo (hwnd, SB_HORZ, &si) ;
              iHorz = si.nPos ; //Okay, current position of horizontal scroll bar
    
    
              //See below for questions about iPaintBeg and iPaintEnd
              iPnBeg = max (0, iVertPos + ps.rcPaint.top / cyChar) ;
    
              iPnEnd = min (NUMLINES - 1,
                               iVertPos + ps.rcPaint.bottom / cyChar) ;
              
              for (i = iPnBeg ; i <= iPnEnd ; i++)
              {
                   x = cxChar * (1 - iHorz) ;
                   y = cyChar * (i - iVert) ;
                   // Some TextOut calls here using x and y, for printing multiple values on the same line
    
              }
    
              EndPaint (hwnd, &ps) ;
              return 0 ;
    First of all, when will iPnBeg be less than 0 in this case. Here cyChar is initialized to tm.tmHeight + tm.tmExternalLeading. It will never be zero.

    The value of ps.rcPaint.top represents the start of the invalid rectangle (y coord). The lowest value it can have is 0. (Which would mean the invalid rectangle starts at the very top of the client area).

    ps.rcPaint.top could never be negative, and cyChar could never be negative. Therefore the expression ps.rcPaint.top / cyChar could never be negative.

    Then we add iVert. The range for most standard scroll bars I have come across begin at 0. So, the lowest value that iVert could possibly have is 0.

    So, the first question is why do we need max here, if the lowest possible value the expression can evaluate to is 0?

    Now, forgetting the max part of things, I am trying to understand the logic behind it. rcPaint.top / cyChar seems like another way of saying "How many rows of characters fit from the top of the client area to the top of the invalid rectangle?".

    For this example, let's say that cyChar = 5, there are 75 lines to print (NUMLINES), and the page size is 50. The scroll bar ranges from 0 (showing lines 0 through 49) to 25 (showing lines 25 through 74).

    Let's say the scroll bar is currently at position 20, meaning it is showing lines 20 though 69.

    Let's also say the top of the invalid rectangle is (y coord) 10 and the bottom of the invalid rectangle (y coord) is 20.

    So we have:

    iPnBeg = (20 + 10 / 5) = 22

    Now looking at iPnEnd, it is the smaller value between 74 and (20 + 20 / 5). That is, 74 and 24. So it will be 24.

    So, in this case the loop will be:
    for(i = 22; i <= 24; i++)

    This is the only place where iPnBeg and iPnEnd are used. Why does it go through the loop 3 times, when there is only room to print 2 rows?

    Why can't we do:

    int y = (bottom - top) / cyChar; //evaluates to 2 in this example
    for(int i = 0; i < y; i++)
    //print the 2 rows


    Sorry if I messed up anything fundamental in my explanation there. I've been staring at this for a while and I think my brain stopped working.
    Last edited by ttrz; October 19th, 2010 at 10:31 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured