总结并顺带问几个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????
使用这个函数有不解的地方: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????
是要全部 信息
sfi_pos
是 只要 pos 信息
对 Get 都 是 all 没什么问题。
发个例子,来自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 ;然后进行更新界面。
我的理解有什么偏差?
// 保存 位置 便于 以后比较
iVertPos = si.nPos ;
// If the position has changed, scroll the window and update it
// 如果 位置改变,滚动 查看 更新
I see ,很多时候滚动条也不会改变的。但是用户点击滚动条,就会产生消息, 有 消息码:
sb_thumbtrack, 产生这个消息码的时候, 滚动条位置不会改变。所以没有必要每次都 scollwindow(hwnd,0, cyChar* (iVerpso-npos),,);
必定 是 什么 变了 才会 来的
真如此,那么我觉得,if语句是否多余了,可能这里有点咬文嚼字嫌疑。进入case wm_vscorll,说明变化,既然变化,自然不需要判断。6楼我提供的代码,我自己版本的, 会有什么漏洞? 漏了什么没有考虑?
{
ScrollWindow (hwnd, 0, cyChar * (iVertPos - .nPos), NULL, NULL) ;
UpdateWindow (hwnd) ;
}
你试试快速 来回地 滚动