总结并顺带问几个srollinfo的问题 getscrollinfo是一个获取滚动条的函数注意,其饭回来的信息是上一次滚动条的信息。si.npos这个成员是lastly的位置,不是现在的位置。而nTrackpos则是currently的位置
使用这个函数有不解的地方:case wm_vscroll:si.fmask=sif_all;getsrcollinfo(hwnd,sb_vert,&si);switch(loword(wParam)
{
case case SB_TOP:case SB_BOTTOMcase sb_lineupcase sb_linedown};
.........
si.fmask=SIF_POS;setscrollbar(,sb_vert,&si,TRUE);getscrollbar(,sb_vert,&is);
为什么需要设置2次scrollinfo结构体的成员fmask????

解决方案 »

  1.   

    滚动条的Set和Get函数,需要申明你到底修改什么东西,到底需要获得什么东西。函数根据指定的mask,来进行相应信息的设置和获取。你的程序中,两个mask是不同的,所以需要重新调整。如果是相同的,就不需要了。
      

  2.   

    菜鸟不解sfi_all不就包含了 sfi_pos了吗?是作者有意 ,还是他随意写的。望大师点石成金
      

  3.   

    si.fmask=sif_all;
    是要全部 信息
    sfi_pos
    是 要 pos 信息
      

  4.   

    这种 标记对 Set是 很 重要的,否则会乱套。
    对 Get 都 是 all 没什么问题。
      

  5.   


    发个例子,来自windwos程序设计, 这个例子是讲解垂直滚动的。用到了scrollinfo.
    windwos程序设计的原版代码为: case WM_VSCROLL:
                   // Get all the vertial scroll bar information          si.cbSize = sizeof (si) ;
              si.fMask  = SIF_ALL ;
              GetScrollInfo (hwnd, SB_VERT, &si) ;               // Save the position for comparison later on          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:
                   si.nPos -= 1 ;
                   break ;
                   
              case SB_LINEDOWN:
                   si.nPos += 1 ;
                   break ;
                   
              case SB_PAGEUP:
                   si.nPos -= si.nPage ;
                   break ;
                   
              case SB_PAGEDOWN:
                   si.nPos += si.nPage ;
                   break ;
                   
              case SB_THUMBTRACK:
                   si.nPos = si.nTrackPos ;
                   break ;
                   
              default:
                   break ;         
              }
                   // Set the position and then retrieve it.  Due to adjustments
                   //   by Windows it may not be the same as the value set.          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 != iVertPos)
              {                    
                   ScrollWindow (hwnd, 0, cyChar * (iVertPos - si.nPos), 
                                       NULL, NULL) ;
                   UpdateWindow (hwnd) ;
              }
              return 0 ;si.nTrackPos是当前的位置。si.nPos是记录上次的位置。iVertPos是当前的位置,
    一旦滚动后,我们需要修改2个值,一个是si.npos,一个是iVertPos.难道这样不行吗?          // 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:
                   si.nPos -= 1 ;
                   break ;
                   
              case SB_LINEDOWN:
                   si.nPos += 1 ;
                   break ;
                   
              case SB_PAGEUP:
                   si.nPos -= si.nPage ;
                   break ;
                   
              case SB_PAGEDOWN:
                   si.nPos += si.nPage ;
                   break ;
                   
              case SB_THUMBTRACK:
                   si.nPos = si.nTrackPos ;
                   break ;
                   
              default:
                   break ;         
              }
                   成功修改上次后,执行完switch后,  添加一句:iVertPos = si.nPos ;然后进行更新界面。
    我的理解有什么偏差?
      

  6.   

    // Save the position for comparison later on 
    // 保存 位置 便于 以后比较
       iVertPos = si.nPos ; 
    // If the position has changed, scroll the window and update it 
    // 如果 位置改变,滚动 查看 更新
      

  7.   


    I see ,很多时候滚动条也不会改变的。但是用户点击滚动条,就会产生消息, 有 消息码:
    sb_thumbtrack, 产生这个消息码的时候, 滚动条位置不会改变。所以没有必要每次都 scollwindow(hwnd,0, cyChar* (iVerpso-npos),,);
      

  8.   

    "case WM_VSCROLL:"
    必定 是 什么 变了 才会 来的
      

  9.   


    真如此,那么我觉得,if语句是否多余了,可能这里有点咬文嚼字嫌疑。进入case wm_vscorll,说明变化,既然变化,自然不需要判断。6楼我提供的代码,我自己版本的, 会有什么漏洞? 漏了什么没有考虑?
      

  10.   

    if (si.nPos != iVertPos)//没有这个 不是 多了 这个 ?
    {
    ScrollWindow (hwnd, 0, cyChar * (iVertPos - .nPos), NULL, NULL) ; 
    UpdateWindow (hwnd) ;

    你试试快速 来回地 滚动