Skip to content

滚动条控件 (SScrollBar)

Warning

The current page still doesn't have a translation for this language.

You can read it through google translate.

滚动条控件提供垂直和水平两种方向的滚动功能,支持自定义外观,可用于列表、文本等需要滚动的场景。

基本信息

  • 类名SScrollBar
  • 控件标签scrollbar
  • 基类SWindow
  • 功能:提供垂直和水平滚动功能

属性说明

基本属性

属性名 类型 默认值 说明
min int 0 最小值
max int 100 最大值
value int 0 初始值
page int - 翻页高度
vertical bool 0 滚动方向(0-水平,1-垂直)
arrowSize int - 翻页高度

外观属性

属性名 类型 默认值 说明
skin string - 滚动条皮肤

使用示例

垂直滚动条

<!-- 基础垂直滚动条 -->
<scrollbar pos="right:-16,0,-0,-0" name="vscroll"
           vertical="1" min="0" max="100" value="0"/>

<!-- 自定义样式的垂直滚动条 -->
<scrollbar pos="right:-16,0,-0,-0" name="vscroll_custom"
           vertical="1" skin="skin_scrollbar_v"
           arrowSize="14" min="0" max="1000" page="100"/>

水平滚动条

<!-- 基础水平滚动条 -->
<scrollbar pos="0,bottom:-16,-0,-0" name="hscroll"
           vertical="0" min="0" max="100" value="0"/>

<!-- 自定义样式的水平滚动条 -->
<scrollbar pos="0,bottom:-16,-0,-0" name="hscroll_custom"
           vertical="0" skin="skin_scrollbar_h"
           arrowSize="14" min="0" max="500" page="50"/>

完整滚动条示例

<window>
    <!-- 垂直滚动条 -->
    <scrollbar name="vscrollMain" 
               pos="|-8,10,|8,-10" 
               vertical="1" 
               min="0" 
               max="1000" 
               value="0" 
               page="100"
               skin="skin_scrollbar_v"/>

    <!-- 水平滚动条 -->
    <scrollbar name="hscrollMain" 
               pos="10,|-8,-10,|8" 
               vertical="0" 
               min="0" 
               max="500" 
               value="0" 
               page="50"
               skin="skin_scrollbar_h"/>
</window>

### 代码示例
```cpp
// 创建滚动条控件
SScrollBar *pScroll = new SScrollBar();
pScroll->SetAttribute(L"pos", L"0,0,16,-0");
pScroll->SetAttribute(L"vertical", L"1");

// 添加到父窗口
pParent->AddChild(pScroll);

// 设置滚动范围和当前值
pScroll->SetScrollRange(0, 100);
pScroll->SetScrollPos(50);

// 设置页面大小
pScroll->SetScrollPage(10);

事件处理

滚动条控件支持以下事件:

事件名 EventID 说明
EVT_SCROLL EventScroll::EventID 滚动事件
// 事件处理示例
EVENT_MAP_BEGIN()
    EVENT_NAME_HANDLER(L"vscrollMain", EventScroll::EventID, OnScroll)
EVENT_MAP_END()

void OnScroll(IEvtArgs *pEvt)
{
    EventScroll *pRealEvt = sobj_cast<EventScroll>(pEvt);
    int nScrollCode = pRealEvt->nSbCode;  // 滚动代码
    int nPos = pRealEvt->nPos;            // 滚动位置

    switch(nScrollCode)
    {
    case SB_THUMBTRACK:
        // 拖动滑块时
        break;
    case SB_LINEUP:
        // 点击向上箭头
        break;
    case SB_LINEDOWN:
        // 点击向下箭头
        break;
    case SB_PAGEUP:
        // 点击滑块上方
        break;
    case SB_PAGEDOWN:
        // 点击滑块下方
        break;
    }
}

最佳实践

  1. 滚动条尺寸
  2. 设置合适的滚动条宽度
  3. 注意箭头按钮大小

  4. 滚动范围设置

  5. 根据内容设置合理的范围
  6. 合理设置页面大小

  7. 外观定制

  8. 使用自定义皮肤提升外观
  9. 保持与整体界面风格一致

  10. 性能优化

  11. 避免频繁更新滚动位置
  12. 合理处理滚动事件

常见问题

  1. 显示问题
  2. 检查pos属性设置
  3. 确认皮肤资源是否正确

  4. 滚动异常

  5. 验证滚动范围设置
  6. 检查页面大小是否合理

  7. 响应问题

  8. 确认事件处理函数绑定
  9. 检查父窗口布局

代码示例解析

让我们看一个更复杂的滚动条示例:

// 头文件包含
#include <core/SWindow.h>
#include <control/SScrollBar.h>

class CMainDlg : public SHostWnd
{
protected:
    // 滚动条相关变量
    SScrollBar *m_pVScroll;
    SScrollBar *m_pHScroll;

    void OnInit()
    {
        // 获取垂直滚动条
        m_pVScroll = FindChildByName2<SScrollBar>(L"vscroll");
        if(m_pVScroll)
        {
            // 设置滚动范围
            m_pVScroll->SetScrollRange(0, 1000);
            // 设置页面大小
            m_pVScroll->SetScrollPage(100);

            // 订阅滚动事件
            m_pVScroll->GetEventSet()->subscribeEvent(
                EventScroll::EventID,
                Subscriber(&CMainDlg::OnVerticalScroll, this));
        }

        // 获取水平滚动条
        m_pHScroll = FindChildByName2<SScrollBar>(L"hscroll");
        if(m_pHScroll)
        {
            m_pHScroll->SetScrollRange(0, 800);
            m_pHScroll->SetScrollPage(80);

            m_pHScroll->GetEventSet()->subscribeEvent(
                EventScroll::EventID,
                Subscriber(&CMainDlg::OnHorizontalScroll, this));
        }
    }

    // 垂直滚动事件处理
    bool OnVerticalScroll(EventScroll *pEvt)
    {
        if(!pEvt) return true;

        int nPos = pEvt->nPos;

        // 更新内容位置
        SWindow *pContent = FindChildByName(L"content");
        if(pContent)
        {
            CRect rcContent = pContent->GetWindowRect();
            rcContent.top = -nPos;
            pContent->Move(rcContent);
        }

        // 更新滚动信息显示
        SStatic *pText = FindChildByName2<SStatic>(L"text_vscroll");
        if(pText)
        {
            SStringT strInfo;
            strInfo.Format(L"垂直滚动位置:%d", nPos);
            pText->SetWindowText(strInfo);
        }

        return true;
    }

    // 水平滚动事件处理
    bool OnHorizontalScroll(EventScroll *pEvt)
    {
        if(!pEvt) return true;

        int nPos = pEvt->nPos;

        // 更新内容位置
        SWindow *pContent = FindChildByName(L"content");
        if(pContent)
        {
            CRect rcContent = pContent->GetWindowRect();
            rcContent.left = -nPos;
            pContent->Move(rcContent);
        }

        // 更新滚动信息显示
        SStatic *pText = FindChildByName2<SStatic>(L"text_hscroll");
        if(pText)
        {
            SStringT strInfo;
            strInfo.Format(L"水平滚动位置:%d", nPos);
            pText->SetWindowText(strInfo);
        }

        return true;
    }

    // 同步更新两个滚动条
    void UpdateScrollBars(int contentWidth, int contentHeight,
                         int viewWidth, int viewHeight)
    {
        if(m_pHScroll)
        {
            // 设置水平滚动范围
            int nRange = contentWidth - viewWidth;
            if(nRange > 0)
            {
                m_pHScroll->SetScrollRange(0, nRange);
                m_pHScroll->SetScrollPage(viewWidth / 10);
                m_pHScroll->Enable(TRUE);
            }
            else
            {
                m_pHScroll->Enable(FALSE);
            }
        }

        if(m_pVScroll)
        {
            // 设置垂直滚动范围
            int nRange = contentHeight - viewHeight;
            if(nRange > 0)
            {
                m_pVScroll->SetScrollRange(0, nRange);
                m_pVScroll->SetScrollPage(viewHeight / 10);
                m_pVScroll->Enable(TRUE);
            }
            else
            {
                m_pVScroll->Enable(FALSE);
            }
        }
    }
};

这个示例展示了: 1. 如何初始化垂直和水平滚动条 2. 如何处理滚动事件 3. 如何同步更新内容位置 4. 如何动态调整滚动范围