windows的滚动条使用

背景

在毕业快一年的工作时间中,对windows编程的某些特性并不够熟悉,例如滚动条的使用。在一次需求中需要用到滚动条,在开发过程中走了不少弯路,因此需要做一些笔记总结一下学习到的内容。

先推荐几个写的特别好的博客:

Windows编程之滚动条—滚动条消息
C语言Windows程序设计-> 第八天-> 滚动条
三、Windows编程之滚动条—滚动条信息函数

基本滚动条的使用是非常简单的,无法就那么几个步骤

  • 判断是否需要滚动条,并初始化滚动条,比如页面大小等变量。

如: EnableScrollBarCtrlSetScrollInfo等API, SetScrollInfo用于设置滚动条的相关参数, 包括滚动范围的最大值和最小值, 页面大小, 滑块的位置。

  typedef struct tagSCROLLINFO 
  { 
    UINT cbSize ;            //设置为sizeof (SCROLLINFO), 表示该结构的大小
    UINT fMask ;           //要设置或获取的值
    int nMin ;               //滚动条范围的最小值
    int nMax ;                //滚动条范围的最大值
    UINT nPage ;          //页面大小
    int nPos ;               //当前位置 
    int nTrackPos ;           //当前追踪位置 
  }SCROLLINFO;

fMask中我们常用的是 SIF_ALL(是SIF_RANGE、SIF_POS、SIF_PAGE和SIF_TRACKPOS的组合),

在win32中,滚动条的长度和窗口的长度是成一定比例的。如下公式所控制:

  • 对滚动条的消息处理,例如几个典型的消息:SB_LINEDOWNSB_LINEUPSB_THUMBPOSITIONSB_THUMBTRACK; 以及SB_PAGEDOWN等之类的消息。主要逻辑就是在滚动条移动时,要更新子窗口相对于父窗口的位置(如,调用MoveWindow函数等)。
    鼠标滑轮的消息,在MFC的CWnd窗口中,捕获滑轮消息,转发滚动条消息:
BOOL CxxxxWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	if (m_bEnableVScroll)
	{
		if (zDelta > 0)
		{
			PostMessage(WM_VSCROLL, SB_LINEUP, 0);
		}
		else
		{
			PostMessage(WM_VSCROLL, SB_LINEDOWN, 0);
		}
	}

	return __super::OnMouseWheel(nFlags, zDelta, pt);
}

常用的滚动条消息如下:

开发过程中遇到的问题

  • 带滚动条的窗口的窗口结构
    之前不太晓得带滚动条的窗口的窗口结构,带滚动条的窗口一定是有子窗口的。滑动的时候,改变子窗口的相对位置。参考一张图:

  • 如何使滚动条可以拖拽?
    主要是对 SB_THUMBPOSITIONSB_THUMBTRACK消息的处理。当把鼠标的光标放在卷动方块上并按住鼠标键时,您就可以移动卷动方块。这样就产生了带有SB_THUMBTRACKSB_THUMBPOSITION通知码的滚动条消息。在wParam的低字组是SB_THUMBTRACK时,wParam的高字组是使用者在拖动卷动方块时的目前位置。该位置位于卷动列范围的最小值和最大值之间。在wParam的低字组是SB_THUMBPOSITION时,wParam的高字组是使用者释放鼠标键后卷动方块的最终位置。

    case SB_THUMBPOSITION:
    case SB_THUMBTRACK:
    {
        bSuccess = GetScrollInfo(SB_VERT, &si);
        si.fMask = SIF_POS;
        si.nPos = si.nTrackPos;
        bSuccess = SetScrollInfo(SB_VERT, &si);
        //按照成员变量nPos的消息移动子窗口位置即可....
        Invalidate();
    }
        break;
posted @ 2019-03-24 16:00  HelloWooo  阅读(1813)  评论(0编辑  收藏  举报