问题描述
- duilib界面库给container添加滚动条后子控件不能正常显示的问题
-
container子控件需要任意在容器中任意拖拽,就使用了绝对布局,现在要给这个container添加垂直滚动条随子控件位置的改变而改变,现在虽然拖拽和滚动条都实现了,但是当双击向下拖动子控件到一定程度(拖动时顶部有一部分未显示)滚动条以后也不会显示这部分内容了。
解决方案
主要修改的代码如下:
- void CContainerUI::SetPos(RECT rc)
{
if( m_pVerticalScrollBar|| m_pHorizontalScrollBar)//modify 2014-11-14
{
CControlUI::SetPos(rc);
rc = m_rcItem;// Adjust for inset rc.left += m_rcInset.left; rc.top += m_rcInset.top; rc.right -= m_rcInset.right; rc.bottom -= m_rcInset.bottom; if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) { rc.right -= m_pVerticalScrollBar->GetFixedWidth(); } if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) { rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight(); } if( m_items.GetSize() == 0) { ProcessScrollBar(rc, 0, 0); return; } // Determine the minimum size SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top }; if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) szAvailable.cx += m_pHorizontalScrollBar->GetScrollRange(); // Place elements int cyNeeded = 0; int cyFixedtop = 0; int cyFixedbottm = 0; for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]); if( !pControl->IsVisible() ) continue; if( pControl->IsFloat() ) { //modify 2014-11-14 SetFloatPos(it2); } //RECT rcPadding = pControl->GetPadding();//外边距在相对布局中才有效 RECT rt = pControl->GetPos(); cyFixedbottm = MAX(cyFixedbottm,rt.bottom); cyFixedtop = MIN(cyFixedtop,rt.top); } cyNeeded = MAX(cyFixedbottm-cyFixedtop,szAvailable.cy); // Process the scrollbar ProcessScrollBar(rc, 0, cyNeeded); } else{ CControlUI::SetPos(rc); if( m_items.IsEmpty() ) return; rc.left += m_rcInset.left; rc.top += m_rcInset.top; rc.right -= m_rcInset.right; rc.bottom -= m_rcInset.bottom; for( int it = 0; it < m_items.GetSize(); it++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it]); if( !pControl->IsVisible() ) continue; if( pControl->IsFloat() ) { SetFloatPos(it); } else { pControl->SetPos(rc); // 所有非float子控件放大到整个客户区 } } }
}
- void CContainerUI::SetScrollPos(SIZE szPos)
{.............. RECT rcPos; for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]); if( !pControl->IsVisible() ) continue; if( (!m_pVerticalScrollBar) && (!m_pHorizontalScrollBar))//modify 2014-11-14 { if( pControl->IsFloat() ) //SetFloatPos(it2); continue; } rcPos = pControl->GetPos(); rcPos.left -= cx; rcPos.right -= cx; rcPos.top -= cy; rcPos.bottom -= cy; pControl->SetPos(rcPos); } Invalidate();
}
- 滚动条事件响应
- void CContainerUI::DoEvent(TEventUI& event)
{
if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
if( m_pParent != NULL ) m_pParent->DoEvent(event);
else CControlUI::DoEvent(event);
return;
}if( event.Type == UIEVENT_TIMER && event.wParam == SCROLL_TIMERID )//modify 2014-11-14 { if( (m_uButtonState1 & UISTATE_CAPTURED) != 0 ) { POINT pt = m_pManager->GetMousePos(); LONG cy = (pt.y - m_ptLastMouse.y); m_ptLastMouse = pt; SIZE sz = GetScrollPos(); sz.cy -= cy; SetScrollPos(sz); return; } else if( m_dwDelayLeft > 0 ) { --m_dwDelayLeft; SIZE sz = GetScrollPos(); LONG lDeltaY = (LONG)(CalculateDelay((double)m_dwDelayLeft / m_dwDelayNum) * m_dwDelayDeltaY); if( (lDeltaY > 0 && sz.cy != 0) || (lDeltaY < 0 && sz.cy != GetScrollRange().cy ) ) { sz.cy -= lDeltaY; SetScrollPos(sz); return; } } m_dwDelayDeltaY = 0; m_dwDelayNum = 0; m_dwDelayLeft = 0; m_pManager->KillTimer(this, SCROLL_TIMERID); return; } if( event.Type == UIEVENT_BUTTONDOWN && IsEnabled() ) { m_uButtonState1 |= UISTATE_CAPTURED; m_ptLastMouse = event.ptMouse; m_dwDelayDeltaY = 0; m_dwDelayNum = 0; m_dwDelayLeft = 0; ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND))); m_pManager->SetTimer(this, SCROLL_TIMERID, 50U); //return; } if( event.Type == UIEVENT_BUTTONUP ) { if( (m_uButtonState1 & UISTATE_CAPTURED) != 0 ) { m_uButtonState1 &= ~UISTATE_CAPTURED; ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); if( m_ptLastMouse.y != event.ptMouse.y ) { m_dwDelayDeltaY = (event.ptMouse.y - m_ptLastMouse.y); if( m_dwDelayDeltaY > 120 ) m_dwDelayDeltaY = 120; else if( m_dwDelayDeltaY < -120 ) m_dwDelayDeltaY = -120; m_dwDelayNum = (DWORD)sqrt((double)abs(m_dwDelayDeltaY)) * 5; m_dwDelayLeft = m_dwDelayNum; } else m_pManager->KillTimer(this, SCROLL_TIMERID); } //return; } if( event.Type == UIEVENT_SCROLLWHEEL ) { LONG lDeltaY = 0; if( m_dwDelayNum > 0 ) lDeltaY = (LONG)(CalculateDelay((double)m_dwDelayLeft / m_dwDelayNum) * m_dwDelayDeltaY); switch( LOWORD(event.wParam) ) { case SB_LINEUP: if( m_dwDelayDeltaY >= 0 ) m_dwDelayDeltaY = lDeltaY + 8; else m_dwDelayDeltaY = lDeltaY + 12; break; case SB_LINEDOWN: if( m_dwDelayDeltaY <= 0 ) m_dwDelayDeltaY = lDeltaY - 8; else m_dwDelayDeltaY = lDeltaY - 12; break; } if( m_dwDelayDeltaY > 100 ) m_dwDelayDeltaY = 100; else if( m_dwDelayDeltaY < -100 ) m_dwDelayDeltaY = -100; m_dwDelayNum = (DWORD)sqrt((double)abs(m_dwDelayDeltaY)) * 5; m_dwDelayLeft = m_dwDelayNum; m_pManager->SetTimer(this, SCROLL_TIMERID, 50U); return; }
解决方案二:
直接使用HorLayout或者VerLayout就行了
时间: 2025-01-21 15:45:18