• Scrollbar控件的认识


    关于scrollbar只研究上下滚动

    1. 首先Scrollbar的父窗口是ContainerUI,不管哪个控件想使用滚动条,该空间必须是Container或者继承Container.

    2. 该函数记录滚动条的百分比的数值是m_nScrollPos,然后记录滚动条总共被分成多少份的则是m_nRange。

    3、滚动条有四个关键的图标:button1、button2、thumb、rail.其中这两个按钮是两端的两个按钮,thumb则是整个滑动的按钮,而rail则是整个滑动按钮中间的小按钮,这两个按钮的位置都是通过动态计算获取到的。具体的thumb计算是在SetPos函数,而rail按钮则是通过thumb的位置来确定,直接在PaintRail的时候进行计算显示即可。

    4、thumb的大小则是通过在第479行:int cyThumb = cy * (rc.bottom - rc.top) / (m_nRange + rc.bottom - rc.top);计算出来的,也就是说如果m_nRange越大的话则thumb相对整个滚动条就越小。

    5、当整个滚动条的大小:button1高度+button2高度<m_cxyFixed.cy+m_cxyFixed.cy(这里是两个按钮均可见)的时候则thumb滚动条不显示第519行:::ZeroMemory(&m_rcThumb, sizeof(m_rcThumb));把滚动条的大小分给button1和button2。

    6、然后doevent中如果点击button1或者button2的时候则会触发containerui的linedown或者up然后可以看containerui中的linedown函数,linesize是固定大小的8,而滚动条则是默认大小的十六,但是这个没关系,因为当点击linedown或者up的时候,位置大小的修改时依赖containerui的移动位置来修改的。

    scrollbar的第551行
    if( m_pOwner != NULL ) m_pOwner->LineUp(); 
                        else SetScrollPos(m_nScrollPos - m_nLineSize);
    
    // 也就是说当有容器的时候本身不会去设置scrollpos而是通过containerui来设置大小。
    View Code

    然后这里看containerui的相关lineup函数

        void CContainerUI::LineUp()
        {
            int cyLine = 8;
            if( m_pManager ) cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8;
    
            SIZE sz = GetScrollPos();
            sz.cy -= cyLine;
            SetScrollPos(sz);
        }
    //这里明确表明了linesize大小为8
    
    
    
    // 而这里的setscrollpos函数则做了两件事:1、调用scrollbar的setscrollpos函数。    2、将自身的elements向上移动相应的像素。
    
        void CContainerUI::SetScrollPos(SIZE szPos)
        {
            int cx = 0;
            int cy = 0;
            if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
                int iLastScrollPos = m_pVerticalScrollBar->GetScrollPos();
                m_pVerticalScrollBar->SetScrollPos(szPos.cy);
                cy = m_pVerticalScrollBar->GetScrollPos() - iLastScrollPos;
            }
    
            if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
                int iLastScrollPos = m_pHorizontalScrollBar->GetScrollPos();
                m_pHorizontalScrollBar->SetScrollPos(szPos.cx);
                cx = m_pHorizontalScrollBar->GetScrollPos() - iLastScrollPos;
            }
    
            if( cx == 0 && cy == 0 ) return;
    
            RECT rcPos;
            for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) {
                CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
                if( !pControl->IsVisible() ) continue;
                if( pControl->IsFloat() ) continue;
    
                rcPos = pControl->GetPos();
                rcPos.left -= cx;
                rcPos.right -= cx;
                rcPos.top -= cy;
                rcPos.bottom -= cy;
                pControl->SetPos(rcPos);
            }
    
            Invalidate();
        }
    View Code

    同样的pageup跟pagedown也是通过contaierui函数来设定的。

    但是这里滚动的大小并不是固定大小而是一页的大小

    void CContainerUI::PageUp()
        {
            SIZE sz = GetScrollPos();
            int iOffset = m_rcItem.bottom - m_rcItem.top - m_rcInset.top - m_rcInset.bottom;
            if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) iOffset -= m_pHorizontalScrollBar->GetFixedHeight();
            sz.cy -= iOffset;
            SetScrollPos(sz);
        }
    View Code

    7、这里的uiscrollbar的第546行的settimer是为了在长按pageup或down(lineup跟down也是一样)时触发移动,或者拖动滚动条的时候触发的移动。具体可以看doevent函数。的第660行开始的if( event.Type == UIEVENT_TIMER && event.wParam == DEFAULT_TIMERID )

  • 相关阅读:
    Rolling Hash(Rabin-Karp算法)匹配字符串
    vim下单行长文本的时候卡顿解决办法
    设置vim的默认工作路径同时与自动设当前编辑的文件所在目录为当前工作路径不冲突
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
  • 原文地址:https://www.cnblogs.com/cxiaoln/p/4395481.html
Copyright © 2020-2023  润新知