SDK程序中,添加了垂直滚动条,出现这个问题,程序很简单:
我定义了一个int count=0,让它在WM_PAINT 中打印到窗口中。
相关程序如下:
注意:WM_SIZE,WM_VSCROLL都是不大相关代码段,可以不看。
现在问题是:
窗口出来后,我往下拉滚动条,让显示内容"(1)"消失,然后再向上拉滚动条,让内容出现,但现在出现的内容却不对,而通过WM_LBUTTONDOWN测试,count是一个整数。
我怀疑 wsprintf(buffer,"(%d)",count);有问题,如果改为
 wsprintf(buffer,"(%d)",5);就能一直显示正确。以上过程,可以从我贴的3个地址的图片里看出。
想了很久,真不知道为何??
第一张图:
http://photo.gznet.com/photos/1511580/1511580-5a575q!gRM.JPG
第2张图:
http://photo.gznet.com/photos/1511580/1511580-I1Rih$jPG9.JPG
第3张图:
http://photo.gznet.com/photos/1511580/1511580-kFs6fHgGqr.JPG
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
        SetWindowOrgEx(hdc,0,m_nVScrollPos,NULL);
GetClientRect(hWnd, &rt);
count++;
        wsprintf(buffer,"(%d)",count);
TextOut(hdc,250,2,buffer,strlen(buffer) );
EndPaint(hWnd, &ps);
break; case WM_SIZE:
     m_nVPageSize = HIWORD(lParam);//得客户区高度
si.cbSize = sizeof(SCROLLINFO);
    si.fMask = SIF_RANGE | SIF_PAGE |SIF_POS ;
si.nMin = 0;
si.nMax = 400;
si.nPage = m_nVPageSize;
if(m_nVPageSize < 400)//400是我设定的滚动范围。
m_nVScrollPos = min(m_nVScrollPos,400 - m_nVPageSize);//
si.nPos = m_nVScrollPos;

SetScrollInfo(hWnd,SB_VERT,&si,TRUE);  
break;
case WM_VSCROLL:
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(hWnd,SB_VERT,&si);
nVScrollPos = si.nPos;

switch(LOWORD(wParam))
{
case SB_LINEUP:
si.nPos -= LINESIZE;
break; case SB_PAGEUP:
si.nPos -= m_nVPageSize;
break; case SB_THUMBTRACK:
si.nPos = si.nTrackPos;                break;
case SB_PAGEDOWN:
si.nPos += m_nVPageSize;
break; case SB_LINEDOWN:
   si.nPos += LINESIZE;
break; default: // Ignore other scroll bar messages
return 0;
}
//当si.nPos=-1时,
SetScrollInfo(hWnd,SB_VERT,&si,TRUE); 
//此句不可少,否则滚动块位于0位置时候,向上点击,图形可能往下移,因为si.nPos=0,再点击变成si.nPos=-1,不合法
//而通过调用GetScrollInfo(),取得当前滚动块的位置0,则图形不会往下移动了。
            GetScrollInfo(hWnd,SB_VERT,&si);
if(si.nPos != nVScrollPos)
{
m_nVScrollPos = si.nPos;
ScrollWindow(hWnd,0,nVScrollPos - si.nPos,NULL,NULL);

}   

return 0;

解决方案 »

  1.   

    buffer 是怎么定义的?  有点怪,应该就是wsprintf(buffer,"(%d)",count);
    TextOut(hdc,250,2,buffer,strlen(buffer) );
      问题,你用F9设断点或是TRACE() 看一下 ---  上面的F9是针对VC6说的
      

  2.   

    count的值如果是全局或静态 肯定是变了的 可以是strlen() 有问题~
      

  3.   

    实际上5也不是很OK,可以
    ScrollWindow(hWnd,0,nVScrollPos - si.nPos,NULL,NULL);后面加
    InvalidateRect (hWnd, NULL, TRUE) ;
      

  4.   

    WM_VSCROLL之后应该:InvalidateRect 更新窗口!!!
      

  5.   

    char buffer[100];
    -------------------
    2。
    InvalidateRect (hWnd, NULL, TRUE) ; 虽然这个可以,但要更新整个客户区,效率不高。
    &ps.rcPaint存有当前无效矩形,
    InvalidateRect (hWnd, &ps.rcPaint, TRUE) ;
    但为何这样没用?3。没有InvalidateRect (hWnd, NULL, TRUE) 时候,为何点击滚动条的向上按钮,却能正确显示?
      

  6.   

    另外, InvalidateRect 换成UpdateWindow(hWnd);为何没用?不都是发送WM_PAINT更新整个客户区么?
      

  7.   

    int nLength;
             nLength = wsprintf(buffer,"(%d)",count);
             buffer[nLength] = 0;
    TextOut(hdc, 250, 2, buffer, nLength);另外,不要在WM_PAINT中再调用Invalidate...,会造成死循环。
      

  8.   

    Mackz(在相互) .d你方法不行
      

  9.   

    为何这样不行,
    RECT rt;
    GetUpdateRect(hWnd,&rt,TRUE);
    InvalidateRect(hWnd,&rt,TRUE);我觉得得到更新区域后,就能重画正确了阿。为何非要用InvalidateRect(hWnd,NULL,TRUE);使整个客户区无效呢?