VS2010-MFC(经常使用控件:滚动条控件Scroll Bar)

 

转自:http://www.jizhuomi.com/software/191.htmlhtml

 

 

       滚动条控件简介app

       滚动条你们也很熟悉了,Windows窗口中不少都有滚动条。前面讲的列表框和组合框设置了相应属性后,若是列表项显示不下也会出现滚动条。滚动条分为水平滚动条(Horizontal Scroll Bar)和垂直滚动条(Vertical Scroll Bar)两种。滚动条中有一个滚动块,用于标识滚动条当前滚动的位置。咱们能够拖动滚动块,也能够用鼠标点击滚动条某一位置使滚动块移动。less

       从滚动条的建立形式来分,有标准滚动条和滚动条控件两种。像列表框和组合框设置了WS_HSCROLL 或WS_VSCROLL风格之后出现的滚动条,不是一个独立的窗口,而是这些窗口的一部分,这就是标准滚动条。而滚动条控件是一个独立的窗口,它能够得到焦点,响应某些操做。函数

 

       滚动条控件的建立工具

       MFC也为滚动条控件的操做提供了类,即为CScrollBar类this

       滚动条控件的建立依然有两种方式,一种是直接在Toolbox中将滚动条控件拖入对话框模板,而后添加控件变量使用,另外一种就是用CScrollBar类的Create成员函数动态建立。这两种方式适用于不一样的场合。spa

       CScrollBar类的成员函数Create的函数原型以下:指针

virtual BOOL Create(
   DWORD dwStyle,
   const RECT& rect,
   CWnd* pParentWnd,
   UINT nID 
);code

       此函数与其余控件类的Create函数原型基本相同。参数dwStyle指定滚动条控件的风格,rect指定滚动条控件的位置和尺寸,pParentWnd为指向滚动条控件父窗口的指针,nID指定滚动条控件的ID。下面简单介绍几个主要的滚动条控件风格,更加具体的能够查阅MSDN。htm

       SBS_HORZ:指定滚动条为水平滚动条。若是没有指定SBS_BOTTOMALIGN或SBS_TOPALIGN风格,则滚动条的高度、宽度和位置由Create函数的rect参数给出。
       SBS_VERT:指定滚动条为垂直滚动条。若是没有指定SBS_RIGHTALIGN或SBS_LEFTALIGN风格,则滚动条的高度、宽度和位置由Create函数的rect参数给出。
       SBS_TOPALIGN:与SBS_HORZ配合使用。滚动条的上边缘与Create函数的rect参数指定矩形的上边缘对齐。滚动条高度为系统滚动条的默认高度。
       SBS_BOTTOMALIGN:与SBS_HORZ配合使用。滚动条的下边缘与Create函数的rect参数指定矩形的下边缘对齐。滚动条高度为系统滚动条的默认高度。
       SBS_LEFTALIGN:与SBS_VERT配合使用。滚动条的左边缘与Create函数的rect参数指定矩形的左边缘对齐。滚动条宽度为系统滚动条的默认宽度。
       SBS_RIGHTALIGN:与SBS_VERT配合使用。滚动条的右边缘与Create函数的rect参数指定矩形的右边缘对齐。滚动条宽度为系统滚动条的默认宽度。

       dwStyle参数能够是以上风格中某几个的组合,另一般也会用到WS_CHILD、WS_VISIBLE风格。例如,建立一个水平滚动条控件,dwStyle参数应该为WS_CHILD|WS_VISIBLE|SBS_HORZ,建立垂直滚动条控件时dwStyle参数应该为WS_CHILD|WS_VISIBLE|SBS_VERT。

 

 

       CScrollBar类的主要成员函数:

       BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo, UINT nMask = SIF_ALL);

       获取的滚动条的参数信息,该信息为SCROLLINFO结构体的形式。参数lpScrollInfo为指向SCROLLINFO结构体变量的指针。SCROLLINFO结构体的定义以下:

C++代码
typedef struct tagSCROLLINFO { UINT cbSize; // 结构的尺寸(字节为单位) 
    UINT fMask;          // 说明结构中的哪些参数是有效的,能够是屏蔽值的组合,如SIF_POS|SIF_PAGE,若为SIF_ALL则整个结构都有效 
    int  nMin;           // 滚动范围最小值,当fMask 中包含SIF_RANGE 时有效 
    int  nMax;           // 滚动范围最大值,当fMask 中包含SIF_RANGE 时有效 
    UINT nPage;          // 页尺寸,用来肯定比例滚动框的大小,当fMask中包含SIF_PAGE时有效 
    int  nPos;           // 滚动框的位置,当fMask 中包含SIF_POS 有效 
    int  nTrackPos;      // 滚动时滚动框的位置,当fMask 中包含SIF_TRACKPOS 时有效,该参数只能查询,不能设置,最好不要用该参数来查询拖动时滚动框的位置 
}   SCROLLINFO, *LPSCROLLINFO; typedef SCROLLINFO CONST *LPCSCROLLINFO;  

       参数nMask 的含义与SCROLLINFO 结构体中的fMask同样。该函数在获取信息成功则返回TRUE,不然返回FALSE。

 

 

       BOOL SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE);

       用于设置滚动条的各类参数信息。参数lpScrollInfo为指向SCROLLINFO结构体变量的指针,参数bRedraw表示是否须要重绘滚动条,若是为TRUE,则重绘。该函数操做成功则返回TRUE,不然返回FALSE。

 

 

       int GetScrollPos( ) const;

       获取滚动块的当前位置。若是失败则返回0。

 

       int SetScrollPos(int nPos, BOOL bRedraw = TRUE);

       将滚动块移动到指定位置。参数nPos指定了滚动块的新位置,参数bRedraw 表示是否须要重绘滚动条,若是为TRUE,则重绘。函数返回滚动框原来的位置,若操做失败则返回0。

 

       void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const;

       获取滚动条的滚动范围。参数lpMinPos指向滚动条滚动范围的最小值,参数lpMaxPos指向滚动条滚动范围的最大值。

 

       void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE);

       用于指定滚动条的滚动范围。参数nMinPos 和nMaxPos 分别指定了滚动范围的最小值和最大值,二者的差不得超过32767。当二者都为0 时,滚动条将被隐藏。参数bRedraw 表示是否须要重绘滚动条,若是为TRUE,则重绘。

 

       OnHScroll()与OnVScroll()函数

       不管是标准滚动条,仍是滚动条控件,滚动条的通知消息都是用WM_HSCROLL 和WM_VSCROLL消息发送出去的。对这两个消息的默认处理函数是CWnd::OnHScroll和CWnd::OnVScroll,通常须要在派生类中对这两个函数进行重载,以实现滚动功能。也就是说,假设在一个对话框中放入了一个水平滚动条,咱们能够在对话框类中重载OnHScroll函数,并在OnHScroll函数中实现滚动功能。

       这两个函数的声明以下:

       afx_msg void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar);
       afx_msg void OnVScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar);

       参数nSBCode是通知消息码,主要通知码及含义的介绍下面已列出。nPos 是滚动框的位置,只有在nSBCode为SB_THUMBPOSITION或SB_THUMBTRACK时,该参数才有意义。若是通知消息是滚动条控件发来的,那么pScrollBar 是指向该控件的指针,若是是标准滚动条发来的,则pScrollBar 为NULL。

 

       SB_BOTTOM/SB_RIGHT:滚动到底端(右端)
       SB_TOP/SB_LEFT:滚动到顶端(左端)
       SB_LINEDOWN/SB_LINERIGHT:向下(向右)滚动一行(列)
       SB_LINEUP/SB_LINELEFT:向上(向左)滚动一行(列)
       SB_PAGEDOWN/SB_PAGERIGHT:向下(向右)滚动一页
       SB_PAGEUP/SB_PAGELEFT:向上(向左)滚动一页
       SB_THUMBPOSITION:滚动到指定位置
       SB_THUMBTRACK:滚动框被拖动。可利用该消息来跟踪对滚动框的拖动
       SB_ENDSCROLL:滚动结束

 

 

 

       CScrollBar类应用实例

       讲完了基础知识再给你们一个简单的实例。例子很是简单,就是在一个对话框中加入一个水平滚动条控件和一个编辑框控件,不管滚动条控件是在滚动仍是静止,编辑框中都显示滚动块的当前位置。如下是具体开发步骤:

       1. 建立一个基于对话框的MFC工程,名称设置为“Example26”。

       2. 在自动生成的对话框模板IDD_EXAMPLE26_DIALOG中,删除“TODO: Place dialog controls here.”静态文本控件、“OK”按钮和“Cancel”按钮。添加一个Horizontal Scroll Bar控件,ID设置为IDC_HORI_SCROLLBAR。再添加一个静态文本控件和一个编辑框,静态文本控件的Caption属性设为“滚动块当前位置:”,编辑框的ID设为IDC_HSCROLL_EDIT,Read Only属性设为True。此时的对话框模板以下图:

      
       3. 为滚动条IDC_HORI_SCROLLBAR添加CScrollBar类型的控件变量m_horiScrollbar。

       4. 在对话框初始化时,咱们须要设置滚动条的滚动范围和初始位置,并在编辑框中显示初始位置,那么须要修改CExample26Dlg::OnInitDialog()函数为:

C++代码
BOOL CExample26Dlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. 
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog 
    SetIcon(m_hIcon, TRUE);         // Set big icon 
    SetIcon(m_hIcon, FALSE);        // Set small icon // TODO: Add extra initialization here // 设置水平滚动条的滚动范围为1到100 
    m_horiScrollbar.SetScrollRange(1, 100); // 设置水平滚动条的初始位置为20 
    m_horiScrollbar.SetScrollPos(20); // 在编辑框中显示20 
    SetDlgItemInt(IDC_HSCROLL_EDIT, 20); return TRUE;  // return TRUE unless you set the focus to a control 
}  

 

 

       5. 如今滚动条还不能正常滚动,而且编辑框中数字也不随滚动改变。根据上面所讲,咱们能够重载CExample26Dlg类的OnHScroll函数。具体操做为,在CExample26Dlg类的属性页面的工具栏上点“Messages”按钮,找到WM_HSCROLL消息,添加响应函数就能够了。

 

OnHScroll函数重写后以下:

void CExample26Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default 
    int pos = m_horiScrollbar.GetScrollPos();    // 获取水平滚动条当前位置 
  
    switch (nSBCode) { // 若是向左滚动一列,则pos减1 
        case SB_LINELEFT: pos -= 1; break; // 若是向右滚动一列,则pos加1 
        case SB_LINERIGHT: pos += 1; break; // 若是向左滚动一页,则pos减10 
        case SB_PAGELEFT: pos -= 10; break; // 若是向右滚动一页,则pos加10 
        case SB_PAGERIGHT: pos += 10; break; // 若是滚动到最左端,则pos为1 
        case SB_LEFT: pos = 1; break; // 若是滚动到最右端,则pos为100 
        case SB_RIGHT: pos = 100; break; // 若是拖动滚动块滚动到指定位置,则pos赋值为nPos的值 
        case SB_THUMBPOSITION: pos = nPos; break; // 下面的m_horiScrollbar.SetScrollPos(pos);执行时会第二次进入此函数,最终肯定滚动块位置,而且会直接到default分支,因此在此处设置编辑框中显示数值 
        default: SetDlgItemInt(IDC_HSCROLL_EDIT, pos); return; } // 设置滚动块位置 
 m_horiScrollbar.SetScrollPos(pos); CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar); }

 

 

       6. 编译运行程序,弹出结果对话框,能够本身拖动滚动块看是否能正常滚动,而且编辑框中也显示了正确的数值。效果以下:

 

 

 

        至于垂直滚动条,其实与水平滚动条相似,你们能够本身写写垂直滚动条的例子。滚动条控件的内容就讲到这里了,比较基础,但这些是之后应用滚动条控件的必知内容。

 

 

PS:关于OnHScroll函数重写的几个疑问。

一、注释掉while循环中部分代码,程序运行没有影响。

 

void CExample26Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default 
    int pos = m_horiScrollbar.GetScrollPos();    // 获取水平滚动条当前位置 
  
    switch (nSBCode) { // 若是向左滚动一列,则pos减1 
        case SB_LINELEFT: pos -= 1; break; // 若是向右滚动一列,则pos加1 
        case SB_LINERIGHT: pos += 1; break; // 若是向左滚动一页,则pos减10 
       /* case SB_PAGELEFT: pos -= 10; break; // 若是向右滚动一页,则pos加10 case SB_PAGERIGHT: pos += 10; break; // 若是滚动到最左端,则pos为1 case SB_LEFT: pos = 1; break; // 若是滚动到最右端,则pos为100 case SB_RIGHT: pos = 100; break; */
        // 若是拖动滚动块滚动到指定位置,则pos赋值为nPos的值 
        case SB_THUMBPOSITION: pos = nPos; break; // 下面的m_horiScrollbar.SetScrollPos(pos);执行时会第二次进入此函数,最终肯定滚动块位置,而且会直接到default分支,因此在此处设置编辑框中显示数值 
        default: SetDlgItemInt(IDC_HSCROLL_EDIT, pos); return; } // 设置滚动块位置 
 m_horiScrollbar.SetScrollPos(pos); CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar); }

 

 

二、关于default的注释应该写错了,改为:

//最下面的CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);执行时会第二次进入此函数,最终肯定滚动块位置,而且会直接到default分支,因此在此处设置编辑框中显示数值

 

 

若是把 SetDlgItemInt(IDC_HSCROLL_EDIT, pos); 语句拿出来(剪切)放到 m_horiScrollbar.SetScrollPos(pos);  下面,其他代码不变,则程序运行无影响。

相关文章
相关标签/搜索