zoukankan      html  css  js  c++  java
  • 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 )

  • 相关阅读:
    Spring Boot从入门到精通(一)搭建第一个Spring Boot程序
    程序员未来的出路究竟在哪里?一位老码农的心声
    ​IntelliJ IDEA使用技巧—使用EasyCode插件一键生成代码04期
    浅谈Java后端开发工程师腾讯面试经历分享总结
    Java面试技巧—如何自我介绍
    互联网大厂Java面试题集—Spring boot常见面试题(二)
    互联网大厂Java面试题集—Spring boot面试题(一)
    ActiveMQ消息队列从入门到实践(4)—使用Spring JMS收发消息
    ActiveMQ消息队列从入门到实践(1)—JMS的概念和JMS消息模型
    有多少程序员干到35岁,那么其他人去干什么了?
  • 原文地址:https://www.cnblogs.com/cxiaoln/p/4395481.html
Copyright © 2011-2022 走看看