基于duilib实现的可滑动tab标签控件
最近一直在忙棋牌游戏大厅的开发,使用了duilib界面库,在大厅界面游戏菜单的展现上需要用到滑动的效果,类似悠扬棋牌,jj棋牌的菜单左右(上下)滑动的效果。通过自己的设计思路完善了一个可滑动的tab标签控件。效果如下:
控件实现部分
code:
UISliderTabLayout.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef __SLIDERTABLAYOUT_H__ 2 #define __SLIDERTABLAYOUT_H__ 3 4 #pragma once 5 6 7 namespace DuiLib { 8 9 class UILIB_API CSliderTabLayoutUI : public CTabLayoutUI 10 { 11 public: 12 CSliderTabLayoutUI(); 13 14 LPCTSTR GetClass() const; 15 LPVOID GetInterface(LPCTSTR pstrName); 16 void DoEvent(TEventUI& event); 17 void OnTimer( int nTimerID ); 18 19 bool SelectItem( int iIndex ); 20 21 void OnSliderStep(); 22 23 void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); 24 25 protected: 26 int m_iCurFrame; 27 bool m_bIsVertical; 28 int m_nPositiveDirection; 29 30 RECT m_rcCurPos; 31 RECT m_rcNextPos; 32 33 CControlUI* m_pCurPage; // 保存当前显示的页面 34 CControlUI* m_pNextPage; // 保存下一页面 35 36 37 enum 38 { 39 TIMER_ANIMATION_ID = 1, 40 ANIMATION_ELLAPSE = 2, 41 ANIMATION_FRAME_COUNT = 30 42 }; 43 }; 44 45 class UILIB_API CSliderTabLayoutUI2 : public CTabLayoutUI 46 { 47 public: 48 CSliderTabLayoutUI2(); 49 50 LPCTSTR GetClass() const; 51 LPVOID GetInterface(LPCTSTR pstrName); 52 void DoEvent(TEventUI& event); 53 void OnTimer( int nTimerID ); 54 55 bool SelectItem( int iIndex ); 56 57 void OnSliderStep(); 58 59 void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); 60 61 protected: 62 int m_iCurFrame; 63 bool m_bIsVertical; 64 int m_nPositiveDirection; 65 66 RECT m_rcCurPos; 67 RECT m_rcNextPos; 68 RECT m_SldItem; 69 70 CControlUI* m_pCurPage; // 保存当前显示的页面 71 CControlUI* m_pNextPage; // 保存下一页面 72 CHorizontalLayoutUI* m_pTabSlider; 73 CVerticalLayoutUI* m_pVTabSlider; 74 75 enum 76 { 77 TIMER_ANIMATION_ID = 1, 78 ANIMATION_ELLAPSE = 10, 79 ANIMATION_FRAME_COUNT = 30 80 }; 81 }; 82 83 84 class UILIB_API CSliderTabLayoutUI3 : public CTabLayoutUI 85 { 86 public: 87 CSliderTabLayoutUI3(); 88 89 LPCTSTR GetClass() const; 90 LPVOID GetInterface(LPCTSTR pstrName); 91 void DoEvent(TEventUI& event); 92 void OnTimer( int nTimerID ); 93 94 void SetPos(RECT rc); 95 bool SelectItem( int iIndex ); 96 97 void OnSliderStep(); 98 99 void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); 100 101 protected: 102 int m_iCurFrame; 103 bool m_bIsVertical; 104 int m_nPositiveDirection; 105 106 bool m_bAnimating; 107 108 RECT m_rcCurPos; 109 RECT m_rcNextPos; 110 111 CControlUI* m_pCurPage; // 保存当前显示的页面 112 CControlUI* m_pNextPage; // 保存下一页面 113 114 enum 115 { 116 TIMER_ANIMATION_ID = 1, 117 ANIMATION_ELLAPSE = 10, 118 ANIMATION_FRAME_COUNT = 15 119 }; 120 }; 121 122 } // namespace DuiLib 123 124 #endif // __UISlider_H__
UISliderTabLayout.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "StdAfx.h" 2 #include "UISliderTabLayout.h" 3 4 namespace DuiLib { 5 6 7 8 ////////////////////////////////////////////////////////////////////////// 9 // CSliderTabLayoutUI 10 CSliderTabLayoutUI::CSliderTabLayoutUI() : 11 m_bIsVertical( false ), 12 m_iCurFrame( 0 ) 13 { 14 } 15 16 LPCTSTR CSliderTabLayoutUI::GetClass() const 17 { 18 return _T("SliderTabLayoutUI"); 19 } 20 21 LPVOID CSliderTabLayoutUI::GetInterface(LPCTSTR pstrName) 22 { 23 if( _tcscmp(pstrName, _T("SliderTabLayoutUI")) == 0 ) 24 return static_cast<CSliderTabLayoutUI*>(this); 25 return CTabLayoutUI::GetInterface(pstrName); 26 } 27 28 bool CSliderTabLayoutUI::SelectItem( int iIndex ) 29 { 30 if( iIndex < 0 || iIndex >= m_items.GetSize() ) return false; 31 if( iIndex == m_iCurSel ) return true; 32 if( iIndex > m_iCurSel ) m_nPositiveDirection = -1; 33 if( iIndex < m_iCurSel ) m_nPositiveDirection = 1; 34 35 m_iCurFrame = 0; 36 m_rcNextPos = m_rcCurPos = m_rcItem; 37 if( !m_bIsVertical ) //横向 38 { 39 m_rcNextPos.left = m_rcCurPos.left - (m_rcCurPos.right - m_rcCurPos.left) * m_nPositiveDirection; 40 m_rcNextPos.right = m_rcCurPos.right - (m_rcCurPos.right - m_rcCurPos.left) * m_nPositiveDirection; 41 } 42 else 43 { 44 m_rcNextPos.top = m_rcCurPos.top - (m_rcCurPos.bottom - m_rcCurPos.top) * m_nPositiveDirection; 45 m_rcNextPos.bottom = m_rcCurPos.bottom - (m_rcCurPos.bottom - m_rcCurPos.top) * m_nPositiveDirection; 46 } 47 48 int iOldSel = m_iCurSel; 49 m_iCurSel = iIndex; 50 for( int it = 0; it < m_items.GetSize(); it++ ) 51 { 52 if( it == iIndex ) { 53 m_pNextPage = GetItemAt(it); 54 m_pNextPage->SetPos(m_rcNextPos); 55 m_pNextPage->SetVisible(true); 56 } 57 else if( it == iOldSel ) 58 { 59 m_pCurPage = GetItemAt(it); 60 m_pCurPage->SetVisible(true); 61 } 62 else 63 GetItemAt(it)->SetVisible(false); 64 } 65 66 m_pManager->SetTimer( this, TIMER_ANIMATION_ID, ANIMATION_ELLAPSE ); 67 if( m_pManager != NULL ) { 68 //m_pManager->SetNextTabControl(); 69 m_pManager->SendNotify(this, _T("tabselect"), m_iCurSel, iOldSel); 70 } 71 return true; 72 } 73 74 void CSliderTabLayoutUI::DoEvent(TEventUI& event) 75 { 76 if( event.Type == UIEVENT_TIMER ) 77 { 78 OnTimer( event.wParam ); 79 } 80 else 81 CContainerUI::DoEvent(event); 82 //__super::DoEvent( event ); 83 } 84 85 void CSliderTabLayoutUI::OnTimer( int nTimerID ) 86 { 87 OnSliderStep(); 88 } 89 90 void CSliderTabLayoutUI::OnSliderStep() 91 { 92 int iStepLen = 0; 93 if( !m_bIsVertical ) //横向 94 { 95 iStepLen = ( m_rcItem.right - m_rcItem.left ) * m_nPositiveDirection / ANIMATION_FRAME_COUNT; 96 if( m_iCurFrame != ANIMATION_FRAME_COUNT ) 97 { 98 //当前窗体位置 99 m_rcCurPos.left = m_rcCurPos.left + iStepLen; 100 m_rcCurPos.right = m_rcCurPos.right +iStepLen; 101 //下一个窗体位置 102 m_rcNextPos.left = m_rcNextPos.left + iStepLen; 103 m_rcNextPos.right = m_rcNextPos.right +iStepLen; 104 m_pCurPage->SetPos(m_rcCurPos); 105 m_pNextPage->SetPos(m_rcNextPos); 106 } 107 else 108 { 109 m_pCurPage->SetVisible(false); 110 m_pNextPage->SetPos(m_rcItem); 111 } 112 } 113 else //竖向 114 { 115 iStepLen = ( m_rcItem.bottom - m_rcItem.top ) * m_nPositiveDirection / ANIMATION_FRAME_COUNT; 116 if( m_iCurFrame != ANIMATION_FRAME_COUNT ) 117 { 118 //当前窗体位置 119 m_rcCurPos.top = m_rcCurPos.top + iStepLen; 120 m_rcCurPos.bottom = m_rcCurPos.bottom +iStepLen; 121 //下一个窗体位置 122 m_rcNextPos.top = m_rcNextPos.top + iStepLen; 123 m_rcNextPos.bottom = m_rcNextPos.bottom +iStepLen; 124 m_pCurPage->SetPos(m_rcCurPos); 125 m_pNextPage->SetPos(m_rcNextPos); 126 } 127 else 128 { 129 m_pCurPage->SetVisible(false); 130 m_pNextPage->SetPos(m_rcItem); 131 } 132 } 133 134 //NeedParentUpdate(); 135 136 if( m_iCurFrame == ANIMATION_FRAME_COUNT ) 137 { 138 NeedParentUpdate(); 139 m_pManager->KillTimer( this, TIMER_ANIMATION_ID ); 140 } 141 m_iCurFrame ++; 142 } 143 144 void CSliderTabLayoutUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) 145 { 146 if( _tcscmp(pstrName, _T("direction")) == 0 && _tcscmp( pstrValue, _T("vertical")) == 0 ) m_bIsVertical = true; // pstrValue = "vertical" or "horizontal" 147 return CTabLayoutUI::SetAttribute(pstrName, pstrValue); 148 } 149 150 ////////////////////////////////////////////////////////////////////////// 151 // CSliderTabLayoutUI2 152 CSliderTabLayoutUI2::CSliderTabLayoutUI2() : 153 m_bIsVertical( false ), 154 m_iCurFrame( 0 ) 155 { 156 } 157 158 LPCTSTR CSliderTabLayoutUI2::GetClass() const 159 { 160 return _T("SliderTabLayoutUI2"); 161 } 162 163 LPVOID CSliderTabLayoutUI2::GetInterface(LPCTSTR pstrName) 164 { 165 if( _tcscmp(pstrName, _T("SliderTabLayoutUI2")) == 0 ) 166 return static_cast<CSliderTabLayoutUI2*>(this); 167 return CTabLayoutUI::GetInterface(pstrName); 168 } 169 170 bool CSliderTabLayoutUI2::SelectItem( int iIndex ) 171 { 172 if( iIndex < 0 || iIndex >= m_items.GetSize() ) return false; 173 if( iIndex == m_iCurSel ) return true; 174 175 m_iCurFrame = 0; 176 177 int iOldSel = m_iCurSel; 178 m_iCurSel = iIndex; 179 for( int it = 0; it < m_items.GetSize(); it++ ) 180 { 181 if( it == iIndex ) { 182 m_pNextPage = GetItemAt(it); 183 } 184 else if( it == iOldSel ) 185 { 186 m_pCurPage = GetItemAt(it); 187 m_pCurPage->SetVisible(true); 188 } 189 else 190 GetItemAt(it)->SetVisible(false); 191 } 192 193 if( !m_bIsVertical ) //横向 194 { 195 m_pTabSlider = new CHorizontalLayoutUI; 196 m_pTabSlider->ApplyAttributeList("bkcolor=\"#FFFFFFFF\""); 197 m_pTabSlider->SetFloat(true); 198 m_SldItem = m_rcItem; 199 if( m_iCurSel > iOldSel ) 200 { 201 m_nPositiveDirection = -1; 202 m_SldItem.left = m_rcItem.left; 203 m_SldItem.right = m_rcItem.left + (m_rcItem.right - m_rcItem.left) * 2; 204 m_pTabSlider->SetPos(m_SldItem); 205 m_pTabSlider->SetVisible(true); 206 m_pTabSlider->Add(m_pCurPage); 207 m_pTabSlider->Add(m_pNextPage); 208 } 209 else 210 { 211 m_nPositiveDirection = 1; 212 m_SldItem.left = m_rcItem.left - (m_rcItem.right - m_rcItem.left); 213 m_SldItem.right = m_rcItem.left + (m_rcItem.right - m_rcItem.left);; 214 m_pTabSlider->SetPos(m_SldItem); 215 m_pTabSlider->SetVisible(true); 216 m_pTabSlider->Add(m_pNextPage); 217 m_pTabSlider->Add(m_pCurPage); 218 } 219 } 220 else 221 { 222 m_pVTabSlider = new CVerticalLayoutUI; 223 m_pVTabSlider->SetFloat(true); 224 m_SldItem = m_rcItem; 225 if( m_iCurSel > iOldSel ) 226 { 227 m_nPositiveDirection = -1; 228 m_SldItem.top = m_rcItem.top; 229 m_SldItem.bottom = m_rcItem.bottom + (m_rcItem.bottom - m_rcItem.top); 230 m_pVTabSlider->SetPos(m_SldItem); 231 m_pVTabSlider->SetVisible(true); 232 m_pVTabSlider->Add(m_pCurPage); 233 m_pVTabSlider->Add(m_pNextPage); 234 } 235 else 236 { 237 m_nPositiveDirection = 1; 238 m_SldItem.top = m_rcItem.top - (m_rcItem.bottom - m_rcItem.top); 239 m_SldItem.bottom = m_rcItem.bottom; 240 m_pVTabSlider->SetPos(m_SldItem); 241 m_pVTabSlider->SetVisible(true); 242 m_pVTabSlider->Add(m_pNextPage); 243 m_pVTabSlider->Add(m_pCurPage); 244 } 245 } 246 247 RECT rcTmp = {0}; 248 m_pNextPage->SetPos(rcTmp); 249 m_pNextPage->SetFixedWidth(1); 250 m_pNextPage->SetFixedHeight(1); 251 m_pNextPage->SetVisible(true); 252 //m_pNextPage->NeedUpdate(); 253 254 m_pManager->SetTimer( this, TIMER_ANIMATION_ID, ANIMATION_ELLAPSE ); 255 if( m_pManager != NULL ) { 256 //m_pManager->SetNextTabControl(); 257 m_pManager->SendNotify(this, _T("tabselect"), m_iCurSel, iOldSel); 258 } 259 return true; 260 } 261 262 void CSliderTabLayoutUI2::DoEvent(TEventUI& event) 263 { 264 if( event.Type == UIEVENT_TIMER ) 265 { 266 OnTimer( event.wParam ); 267 } 268 else 269 CContainerUI::DoEvent(event); 270 //__super::DoEvent( event ); 271 } 272 273 void CSliderTabLayoutUI2::OnTimer( int nTimerID ) 274 { 275 OnSliderStep(); 276 } 277 278 void CSliderTabLayoutUI2::OnSliderStep() 279 { 280 281 282 int iStepLen = 0; 283 if( !m_bIsVertical ) //横向 284 { 285 iStepLen = ( m_rcItem.right - m_rcItem.left ) * m_nPositiveDirection / ANIMATION_FRAME_COUNT; 286 if( m_iCurFrame != ANIMATION_FRAME_COUNT ) 287 { 288 m_SldItem.left = m_SldItem.left + iStepLen; 289 m_SldItem.right = m_SldItem.right +iStepLen; 290 m_pTabSlider->SetPos(m_SldItem); 291 } 292 else 293 { 294 m_pCurPage->SetVisible(false); 295 m_pNextPage->SetPos(m_rcItem); 296 m_pNextPage->SetFixedWidth(m_rcItem.right - m_rcItem.left); 297 m_pNextPage->SetFixedHeight(m_rcItem.bottom - m_rcItem.top); 298 } 299 } 300 else //竖向 301 { 302 iStepLen = ( m_rcItem.bottom - m_rcItem.top ) * m_nPositiveDirection / ANIMATION_FRAME_COUNT; 303 if( m_iCurFrame != ANIMATION_FRAME_COUNT ) 304 { 305 m_SldItem.top = m_SldItem.top + iStepLen; 306 m_SldItem.bottom = m_SldItem.bottom +iStepLen; 307 m_pVTabSlider->SetPos(m_SldItem); 308 } 309 else 310 { 311 m_pCurPage->SetVisible(false); 312 m_pNextPage->SetPos(m_rcItem); 313 } 314 } 315 316 if( m_iCurFrame == ANIMATION_FRAME_COUNT ) 317 { 318 NeedParentUpdate(); 319 m_pManager->KillTimer( this, TIMER_ANIMATION_ID ); 320 } 321 m_iCurFrame ++; 322 } 323 324 void CSliderTabLayoutUI2::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) 325 { 326 if( _tcscmp(pstrName, _T("direction")) == 0 && _tcscmp( pstrValue, _T("vertical")) == 0 ) m_bIsVertical = true; // pstrValue = "vertical" or "horizontal" 327 return CTabLayoutUI::SetAttribute(pstrName, pstrValue); 328 } 329 330 331 332 ////////////////////////////////////////////////////////////////////////// 333 // CSliderTabLayoutUI3 334 CSliderTabLayoutUI3::CSliderTabLayoutUI3() : 335 m_bIsVertical( false ), 336 m_bAnimating(false), 337 m_iCurFrame( 0 ) 338 { 339 } 340 341 LPCTSTR CSliderTabLayoutUI3::GetClass() const 342 { 343 return _T("SliderTabLayoutUI3"); 344 } 345 346 LPVOID CSliderTabLayoutUI3::GetInterface(LPCTSTR pstrName) 347 { 348 if( _tcscmp(pstrName, _T("SliderTabLayoutUI3")) == 0 ) 349 return static_cast<CSliderTabLayoutUI3*>(this); 350 return CTabLayoutUI::GetInterface(pstrName); 351 } 352 353 bool CSliderTabLayoutUI3::SelectItem( int iIndex ) 354 { 355 if( iIndex < 0 || iIndex >= m_items.GetSize() ) return false; 356 if( iIndex == m_iCurSel ) return true; 357 if( iIndex > m_iCurSel ) m_nPositiveDirection = -1; 358 if( iIndex < m_iCurSel ) m_nPositiveDirection = 1; 359 360 m_bAnimating = true; 361 m_iCurFrame = 0; 362 363 RECT rcInset = GetInset(); 364 m_rcCurPos = GetPos(); 365 366 m_rcCurPos.left += rcInset.left; 367 m_rcCurPos.top += rcInset.top; 368 m_rcCurPos.right -= rcInset.right; 369 m_rcCurPos.bottom -= rcInset.bottom; 370 371 m_rcNextPos = m_rcCurPos; 372 373 if( !m_bIsVertical ) //横向 374 { 375 m_rcNextPos.left = m_rcCurPos.left - (m_rcCurPos.right - m_rcCurPos.left) * m_nPositiveDirection; 376 m_rcNextPos.right = m_rcCurPos.right - (m_rcCurPos.right - m_rcCurPos.left) * m_nPositiveDirection; 377 } 378 else 379 { 380 m_rcNextPos.top = m_rcCurPos.top - (m_rcCurPos.bottom - m_rcCurPos.top) * m_nPositiveDirection; 381 m_rcNextPos.bottom = m_rcCurPos.bottom - (m_rcCurPos.bottom - m_rcCurPos.top) * m_nPositiveDirection; 382 } 383 384 int iOldSel = m_iCurSel; 385 m_iCurSel = iIndex; 386 for( int it = 0; it < m_items.GetSize(); it++ ) 387 { 388 if( it == iIndex ) { 389 m_pNextPage = GetItemAt(it); 390 m_pNextPage->SetPos(m_rcNextPos); 391 m_pNextPage->SetVisible(true); 392 } 393 else if( it == iOldSel ) 394 { 395 m_pCurPage = GetItemAt(it); 396 m_pCurPage->SetVisible(true); 397 } 398 else 399 GetItemAt(it)->SetVisible(false); 400 } 401 402 m_pManager->SetTimer( this, TIMER_ANIMATION_ID, ANIMATION_ELLAPSE ); 403 if( m_pManager != NULL ) { 404 //m_pManager->SetNextTabControl(); 405 m_pManager->SendNotify(this, _T("tabselect"), m_iCurSel, iOldSel); 406 } 407 return true; 408 } 409 410 void CSliderTabLayoutUI3::DoEvent(TEventUI& event) 411 { 412 if( event.Type == UIEVENT_TIMER ) 413 { 414 OnTimer( event.wParam ); 415 } 416 else 417 CContainerUI::DoEvent(event); 418 } 419 420 void CSliderTabLayoutUI3::OnTimer( int nTimerID ) 421 { 422 NeedParentUpdate(); 423 } 424 425 void CSliderTabLayoutUI3::SetPos(RECT rc) 426 { 427 CControlUI::SetPos(rc); 428 429 RECT rcInset = GetInset(); 430 rc.left += rcInset.left; 431 rc.top += rcInset.top; 432 rc.right -= rcInset.right; 433 rc.bottom -= rcInset.bottom; 434 435 if(m_bAnimating) 436 { 437 int iStepLen = 0; 438 if( !m_bIsVertical ) //横向 439 { 440 iStepLen = ( rc.right - rc.left ) * m_nPositiveDirection / ANIMATION_FRAME_COUNT; 441 if( m_iCurFrame != ANIMATION_FRAME_COUNT ) 442 { 443 //当前窗体位置 444 ::OffsetRect(&m_rcCurPos,iStepLen,0); 445 m_pCurPage->SetPos(m_rcCurPos); 446 //下一个窗体位置 447 ::OffsetRect(&m_rcNextPos,iStepLen,0); 448 m_pNextPage->SetPos(m_rcNextPos); 449 } 450 else 451 { 452 m_pCurPage->SetVisible(false); 453 ::OffsetRect(&m_rcCurPos,iStepLen,0); 454 m_pCurPage->SetPos(m_rcCurPos); 455 m_pNextPage->SetPos(rc); 456 } 457 } 458 else //竖向 459 { 460 iStepLen = ( rc.bottom - rc.top ) * m_nPositiveDirection / ANIMATION_FRAME_COUNT; 461 if( m_iCurFrame != ANIMATION_FRAME_COUNT ) 462 { 463 //当前窗体位置 464 ::OffsetRect(&m_rcCurPos,0,iStepLen); 465 m_pCurPage->SetPos(m_rcCurPos); 466 //下一个窗体位置 467 ::OffsetRect(&m_rcNextPos,0,iStepLen); 468 m_pNextPage->SetPos(m_rcNextPos); 469 } 470 else 471 { 472 m_pCurPage->SetVisible(false); 473 ::OffsetRect(&m_rcCurPos,0,iStepLen); 474 m_pCurPage->SetPos(m_rcCurPos); 475 m_pNextPage->SetPos(rc); 476 } 477 } 478 if( m_iCurFrame == ANIMATION_FRAME_COUNT ) 479 { 480 m_iCurFrame = 0; 481 m_bAnimating = false; 482 m_pManager->KillTimer( this, TIMER_ANIMATION_ID ); 483 } 484 m_iCurFrame ++; 485 } 486 else 487 { 488 for (int it = 0; it < GetCount(); it++) { 489 CControlUI* pControl = GetItemAt(it); 490 if (!pControl->IsVisible()) continue; 491 if (pControl->IsFloat()) { 492 SetFloatPos(it); 493 continue; 494 } 495 496 if (it != GetCurSel()) continue; 497 498 RECT rcPadding = pControl->GetPadding(); 499 rc.left += rcPadding.left; 500 rc.top += rcPadding.top; 501 rc.right -= rcPadding.right; 502 rc.bottom -= rcPadding.bottom; 503 504 SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top }; 505 506 SIZE sz = pControl->EstimateSize(szAvailable); 507 if (sz.cx == 0) { 508 sz.cx = MAX(0, szAvailable.cx); 509 } 510 if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth(); 511 if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth(); 512 513 if (sz.cy == 0) { 514 sz.cy = MAX(0, szAvailable.cy); 515 } 516 if (sz.cy < pControl->GetMinHeight()) sz.cy = pControl->GetMinHeight(); 517 if (sz.cy > pControl->GetMaxHeight()) sz.cy = pControl->GetMaxHeight(); 518 519 RECT rcCtrl = {rc.left, rc.top, rc.left + sz.cx, rc.top + sz.cy}; 520 pControl->SetPos(rcCtrl); 521 } 522 } 523 } 524 525 void CSliderTabLayoutUI3::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) 526 { 527 if( _tcscmp(pstrName, _T("direction")) == 0 && _tcscmp( pstrValue, _T("vertical")) == 0 ) m_bIsVertical = true; // pstrValue = "vertical" or "horizontal" 528 return CTabLayoutUI::SetAttribute(pstrName, pstrValue); 529 } 530 } // namespace DuiLib
xml部分
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <SliderTabLayout3 name="TAY_1" direction="vertical"> 2 <!--基本资料--> 3 <VerticalLayout> 4 <HorizontalLayout width="458" height="29"> 5 <Label text="基本资料" float="true" pos="13,0,0,0" width="105" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="0"/> 6 </HorizontalLayout> 7 <VerticalLayout width="458" height="339" bkimage="file='bk_bxg_right.png' corner='5,5,5,5'"> 8 <Label text="昵称:" float="true" pos="38,14,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 9 <Label name="LBL_VIP" text="" float="true" pos="96,64,0,0" width="25" height="12" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA"/> 10 <Edit name="TXT_NC" float="true" pos="94,17,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="18" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 11 <Button name="BTN_JBZL_SAVE" float="true" pos="172,291,0,0" width="115" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file='bt_45.png' source='0,0,115,36'" hotimage="file='bt_45.png' source='115,0,230,36'" pushedimage="file='bt_45.png' source='230,0,345,36'"/> 12 <Label text="VIP:" float="true" pos="38,54,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 13 <Label text="等级:" float="true" pos="233,93,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right" /> 14 <Label name="LBL_DJ" float="true" pos="291,93,0,0" width="131" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" /> 15 <Label text="金币:" float="true" pos="38,92,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 16 <Label name="LBL_JB" text="" float="true" pos="96,92,0,0" width="131" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA"/> 17 <Label text="幸运豆:" float="true" pos="234,131,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right" /> 18 <Label name="LBL_XYD" float="true" pos="292,131,0,0" width="131" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" /> 19 <Label text="奖券:" float="true" pos="38,131,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 20 <Label name="LBL_JQ" text="" float="true" pos="96,131,0,0" width="131" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA"/> 21 <Label text="性别:" float="true" pos="39,169,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 22 <Label text="生日:" float="true" pos="39,207,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 23 <Label text="Email:" float="true" pos="39,246,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 24 <Label text="年龄:" float="true" pos="239,207,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 25 <Label text="QQ:" float="true" pos="239,246,0,0" width="50" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 26 <Edit name="TXT_EMAIL" text="" float="true" pos="98,248,0,0" width="136" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" maxchar="50" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 27 <Combo name="CMB_SR_1" float="true" pos="97,210,0,0" droptype="droplist" width="50" height="22" textpadding="4,1,1,1" normalimage="file='cmb.png' source='0,0,100,22' corner='2,2,20,2'" hotimage="file='cmb.png' source='0,22,100,44' corner='2,2,22,2'" pushedimage="file='cmb.png' source='0,44,100,66' corner='2,2,22,2'" vscrollbar="true" vscrollbarstyle="width="6" showbutton1="false" showbutton2="false""/> 28 <Label text="月" float="true" pos="145,213,0,0" width="15" height="15" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 29 <Combo name="CMB_SR_2" float="true" pos="160,210,0,0" droptype="droplist" width="45" height="22" textpadding="4,1,1,1" normalimage="file='cmb.png' source='0,0,100,22' corner='2,2,20,2'" hotimage="file='cmb.png' source='0,22,100,44' corner='2,2,22,2'" pushedimage="file='cmb.png' source='0,44,100,66' corner='2,2,22,2'"/> 30 <Label text="日" float="true" pos="204,213,0,0" width="15" height="15" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 31 <Edit name="TXT_QQ" text="" float="true" pos="291,248,0,0" width="127" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" maxchar="32" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 32 <Combo name="CMB_NL" float="true" pos="295,210,0,0" droptype="droplist" width="50" height="22" textpadding="4,1,1,1" normalimage="file='cmb.png' source='0,0,100,22' corner='2,2,20,2'" hotimage="file='cmb.png' source='0,22,100,44' corner='2,2,22,2'" pushedimage="file='cmb.png' source='0,44,100,66' corner='2,2,22,2'"/> 33 <Option name="OPN_BOY" text="男" float="true" pos="99,170,0,0" width="60" height="30" textpadding="5,0,0,0" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file='chk_1.png' dest='5,5,20,20'" hotimage="file='chk_2.png' dest='5,5,20,20'" group="sex" selected="true" selectedimage="file='chk_3.png' dest='5,5,20,20'"/> 34 <Option name="OPN_GIRL" text="女" float="true" pos="161,170,0,0" width="60" height="30" textpadding="5,0,0,0" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file='chk_1.png' dest='5,5,20,20'" hotimage="file='chk_2.png' dest='5,5,20,20'" group="sex" selectedimage="file='chk_3.png' dest='5,5,20,20'"/> 35 <Label name="LBL_JBZL_ERROR" text="" float="true" pos="100,278,0,0" width="260" height="18" textcolor="#00FF0000" disabledtextcolor="#FFA7A6AA"/> 36 <Button name="BTN_FACE" float="true" pos="337,16,0,0" width="62" height="60" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" bkimage="file='face\default.png' dest='2,2,60,58'" /> 37 <Button name="BTN_CHANGEFACE" text="{a}更新头像{/a}" float="true" pos="338,76,0,0" width="60" height="24" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" showhtml="true" align="center" /> 38 </VerticalLayout> 39 </VerticalLayout> 40 <!--详细资料--> 41 <VerticalLayout> 42 <HorizontalLayout width="458" height="29"> 43 <Label text="详细资料" float="true" pos="13,0,0,0" width="105" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="0"/> 44 </HorizontalLayout> 45 <VerticalLayout width="458" height="339" bkimage="file='bk_bxg_right.png' corner='5,5,5,5'"> 46 <Label text="真实姓名:" float="true" pos="62,40,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 47 <Edit name="TXT_ZSXM" float="true" pos="146,42,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="16" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 48 <Button name="BTN_XXZL_SAVE" float="true" pos="174,235,0,0" width="115" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file='bt_45.png' source='0,0,115,36'" hotimage="file='bt_45.png' source='115,0,230,36'" pushedimage="file='bt_45.png' source='230,0,345,36'"/> 49 <Label text="身份证号:" float="true" pos="62,73,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 50 <Edit name="TXT_SFZH" float="true" pos="146,75,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="18" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 51 <Label text="手机号码:" float="true" pos="62,106,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 52 <Edit name="TXT_SJHM" float="true" pos="146,108,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="12" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 53 <Label text="固定电话:" float="true" pos="62,140,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 54 <Edit name="TXT_GDDH" float="true" pos="146,142,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="16" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 55 <Label text="地 址:" float="true" pos="62,173,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 56 <Edit name="TXT_DZ" float="true" pos="146,175,0,0" width="272" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="50" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 57 <Text text="注:请您填写真实信息,因资料填写错误造成奖品无法投递的情况,6513游戏中心将不承担责任。" float="true" pos="64,279,0,0" width="333" height="36" textpadding="2,0,2,0" textcolor="#00FF0000" disabledtextcolor="#FFA7A6AA" align="wrap"/> 58 <Label name="LBL_XXZL_ERROR" float="true" pos="147,202,0,0" width="198" height="30" textcolor="#00FF0000" disabledtextcolor="#FFA7A6AA"/> 59 </VerticalLayout> 60 </VerticalLayout> 61 <!--密码修改--> 62 <VerticalLayout> 63 <HorizontalLayout width="458" height="29"> 64 <Label text="登录密码修改" float="true" pos="13,0,0,0" width="159" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="0"/> 65 </HorizontalLayout> 66 <VerticalLayout width="458" height="154" bkimage="file='bk_bxg_right.png' corner='5,5,5,5'"> 67 <Label text="旧密码:" float="true" pos="63,4,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 68 <Edit name="TXT_MM_JMM" password="true" float="true" pos="147,4,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="16" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 69 <Label text="新密码:" float="true" pos="63,33,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 70 <Edit name="TXT_MM_XMM" password="true" float="true" pos="147,33,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="16" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 71 <Label text="确认密码:" float="true" pos="63,65,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 72 <Edit name="TXT_MM_QRMM" password="true" float="true" pos="147,65,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="16" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 73 <Button name="BTN_MMXG_MM_SAVE" float="true" pos="172,107,0,0" width="115" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file='bt_45.png' source='0,0,115,36'" hotimage="file='bt_45.png' source='115,0,230,36'" pushedimage="file='bt_45.png' source='230,0,345,36'"/> 74 <Label name="LBL_MM_ERROR" float="true" pos="148,94,0,0" width="203" height="17" textcolor="#00FF0000" disabledtextcolor="#FFA7A6AA"/> 75 </VerticalLayout> 76 <HorizontalLayout width="458" height="29"> 77 <Label text="保险箱密码修改" float="true" pos="13,0,0,0" width="159" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="0"/> 78 </HorizontalLayout> 79 <VerticalLayout width="458" height="154" bkimage="file='bk_bxg_right.png' corner='5,5,5,5'"> 80 <Label text="旧密码:" float="true" pos="63,5,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 81 <Edit name="TXT_BXG_JMM" password="true" float="true" pos="147,5,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="16" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 82 <Label text="新密码:" float="true" pos="63,33,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 83 <Edit name="TXT_BXG_XMM" password="true" float="true" pos="147,33,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="16" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 84 <Label text="确认密码:" float="true" pos="63,64,0,0" width="82" height="30" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="right"/> 85 <Edit name="TXT_BXG_QRMM" password="true" float="true" pos="147,64,0,0" width="181" height="25" bkcolor="#00000000" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" font="1" maxchar="16" normalimage="file='txt_1.png' source='0,0,33,34' corner='5,5,5,5'" hotimage="file='txt_1.png' source='33,0,66,34' corner='5,5,5,5'" focusedimage="file='txt_1.png' source='66,0,99,34' corner='5,5,5,5'"/> 86 <Button name="BTN_MMXG_BXX_SAVE" float="true" pos="172,107,0,0" width="115" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file='bt_45.png' source='0,0,115,36'" hotimage="file='bt_45.png' source='115,0,230,36'" pushedimage="file='bt_45.png' source='230,0,345,36'"/> 87 <Label name="LBL_BXG_ERROR" float="true" pos="148,94,0,0" width="203" height="17" textcolor="#00FF0000" disabledtextcolor="#FFA7A6AA"/> 88 </VerticalLayout> 89 </VerticalLayout> 90 </SliderTabLayout3>
代码实现部分当初用了三种方式实现滑动效果,但最理想的还是CSliderTabLayoutUI3实现。不知大家有没有更好的实现思路,可一起交流交流。