UIContainer.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. #include "StdAfx.h"
  2. namespace DuiLib
  3. {
  4. /////////////////////////////////////////////////////////////////////////////////////
  5. //
  6. //
  7. IMPLEMENT_DUICONTROL(CContainerUI)
  8. CContainerUI::CContainerUI()
  9. : m_iChildPadding(0),
  10. m_iChildAlign(DT_LEFT),
  11. m_iChildVAlign(DT_TOP),
  12. m_bAutoDestroy(true),
  13. m_bDelayedDestroy(true),
  14. m_bMouseChildEnabled(true),
  15. m_pVerticalScrollBar(NULL),
  16. m_pHorizontalScrollBar(NULL),
  17. m_nScrollStepSize(0),
  18. m_bFixedScrollbar(false),
  19. m_bShowScrollbar(true)
  20. {
  21. ::ZeroMemory(&m_rcInset, sizeof(m_rcInset));
  22. }
  23. CContainerUI::~CContainerUI()
  24. {
  25. m_bDelayedDestroy = false;
  26. RemoveAll();
  27. if( m_pVerticalScrollBar ) {
  28. delete m_pVerticalScrollBar;
  29. m_pVerticalScrollBar = NULL;
  30. }
  31. if( m_pHorizontalScrollBar ) {
  32. delete m_pHorizontalScrollBar;
  33. m_pHorizontalScrollBar = NULL;
  34. }
  35. }
  36. LPCTSTR CContainerUI::GetClass() const
  37. {
  38. return _T("ContainerUI");
  39. }
  40. LPVOID CContainerUI::GetInterface(LPCTSTR pstrName)
  41. {
  42. if( _tcsicmp(pstrName, _T("IContainer")) == 0 ) return static_cast<IContainerUI*>(this);
  43. else if( _tcsicmp(pstrName, DUI_CTR_CONTAINER) == 0 ) return static_cast<CContainerUI*>(this);
  44. return CControlUI::GetInterface(pstrName);
  45. }
  46. CControlUI* CContainerUI::GetItemAt(int iIndex) const
  47. {
  48. if( iIndex < 0 || iIndex >= m_items.GetSize() ) return NULL;
  49. return static_cast<CControlUI*>(m_items[iIndex]);
  50. }
  51. int CContainerUI::GetItemIndex(CControlUI* pControl) const
  52. {
  53. for( int it = 0; it < m_items.GetSize(); it++ ) {
  54. if( static_cast<CControlUI*>(m_items[it]) == pControl ) {
  55. return it;
  56. }
  57. }
  58. return -1;
  59. }
  60. bool CContainerUI::SetItemIndex(CControlUI* pControl, int iIndex)
  61. {
  62. for( int it = 0; it < m_items.GetSize(); it++ ) {
  63. if( static_cast<CControlUI*>(m_items[it]) == pControl ) {
  64. NeedUpdate();
  65. m_items.Remove(it);
  66. return m_items.InsertAt(iIndex, pControl);
  67. }
  68. }
  69. return false;
  70. }
  71. int CContainerUI::GetCount() const
  72. {
  73. return m_items.GetSize();
  74. }
  75. bool CContainerUI::Add(CControlUI* pControl)
  76. {
  77. if( pControl == NULL) return false;
  78. if( m_pManager != NULL ) m_pManager->InitControls(pControl, this);
  79. if( IsVisible() ) NeedUpdate();
  80. else pControl->SetInternVisible(false);
  81. return m_items.Add(pControl);
  82. }
  83. bool CContainerUI::AddAt(CControlUI* pControl, int iIndex)
  84. {
  85. if( pControl == NULL) return false;
  86. if( m_pManager != NULL ) m_pManager->InitControls(pControl, this);
  87. if( IsVisible() ) NeedUpdate();
  88. else pControl->SetInternVisible(false);
  89. return m_items.InsertAt(iIndex, pControl);
  90. }
  91. bool CContainerUI::Remove(CControlUI* pControl)
  92. {
  93. if( pControl == NULL) return false;
  94. for( int it = 0; it < m_items.GetSize(); it++ ) {
  95. if( static_cast<CControlUI*>(m_items[it]) == pControl ) {
  96. NeedUpdate();
  97. if( m_bAutoDestroy ) {
  98. if( m_bDelayedDestroy && m_pManager ) m_pManager->AddDelayedCleanup(pControl);
  99. else delete pControl;
  100. }
  101. return m_items.Remove(it);
  102. }
  103. }
  104. return false;
  105. }
  106. bool CContainerUI::RemoveAt(int iIndex)
  107. {
  108. CControlUI* pControl = GetItemAt(iIndex);
  109. if (pControl != NULL) {
  110. return CContainerUI::Remove(pControl);
  111. }
  112. return false;
  113. }
  114. void CContainerUI::RemoveAll()
  115. {
  116. for( int it = 0; m_bAutoDestroy && it < m_items.GetSize(); it++ ) {
  117. CControlUI* pItem = static_cast<CControlUI*>(m_items[it]);
  118. if( m_bDelayedDestroy && m_pManager ) {
  119. m_pManager->AddDelayedCleanup(pItem);
  120. }
  121. else {
  122. delete pItem;
  123. pItem = NULL;
  124. }
  125. }
  126. m_items.Empty();
  127. NeedUpdate();
  128. }
  129. bool CContainerUI::IsAutoDestroy() const
  130. {
  131. return m_bAutoDestroy;
  132. }
  133. void CContainerUI::SetAutoDestroy(bool bAuto)
  134. {
  135. m_bAutoDestroy = bAuto;
  136. }
  137. bool CContainerUI::IsDelayedDestroy() const
  138. {
  139. return m_bDelayedDestroy;
  140. }
  141. void CContainerUI::SetDelayedDestroy(bool bDelayed)
  142. {
  143. m_bDelayedDestroy = bDelayed;
  144. }
  145. RECT CContainerUI::GetInset() const
  146. {
  147. if(m_pManager) return m_pManager->GetDPIObj()->Scale(m_rcInset);
  148. return m_rcInset;
  149. }
  150. void CContainerUI::SetInset(RECT rcInset)
  151. {
  152. m_rcInset = rcInset;
  153. NeedUpdate();
  154. }
  155. int CContainerUI::GetChildPadding() const
  156. {
  157. if (m_pManager) return m_pManager->GetDPIObj()->Scale(m_iChildPadding);
  158. return m_iChildPadding;
  159. }
  160. void CContainerUI::SetChildPadding(int iPadding)
  161. {
  162. m_iChildPadding = iPadding;
  163. NeedUpdate();
  164. }
  165. UINT CContainerUI::GetChildAlign() const
  166. {
  167. return m_iChildAlign;
  168. }
  169. void CContainerUI::SetChildAlign(UINT iAlign)
  170. {
  171. m_iChildAlign = iAlign;
  172. NeedUpdate();
  173. }
  174. UINT CContainerUI::GetChildVAlign() const
  175. {
  176. return m_iChildVAlign;
  177. }
  178. void CContainerUI::SetChildVAlign(UINT iVAlign)
  179. {
  180. m_iChildVAlign = iVAlign;
  181. NeedUpdate();
  182. }
  183. bool CContainerUI::IsMouseChildEnabled() const
  184. {
  185. return m_bMouseChildEnabled;
  186. }
  187. void CContainerUI::SetMouseChildEnabled(bool bEnable)
  188. {
  189. m_bMouseChildEnabled = bEnable;
  190. }
  191. bool CContainerUI::IsFixedScrollbar()
  192. {
  193. return m_bFixedScrollbar;
  194. }
  195. void CContainerUI::SetFixedScrollbar(bool bFixed)
  196. {
  197. m_bFixedScrollbar = bFixed;
  198. Invalidate();
  199. }
  200. bool CContainerUI::IsShowScrollbar()
  201. {
  202. return m_bShowScrollbar;
  203. }
  204. void CContainerUI::SetShowScrollbar(bool bShow)
  205. {
  206. m_bShowScrollbar = bShow;
  207. if( m_pVerticalScrollBar != NULL ) m_pVerticalScrollBar->SetShow(bShow);
  208. if( m_pHorizontalScrollBar != NULL ) m_pHorizontalScrollBar->SetShow(bShow);
  209. }
  210. void CContainerUI::SetVisible(bool bVisible)
  211. {
  212. if( m_bVisible == bVisible ) return;
  213. CControlUI::SetVisible(bVisible);
  214. for( int it = 0; it < m_items.GetSize(); it++ ) {
  215. static_cast<CControlUI*>(m_items[it])->SetInternVisible(IsVisible());
  216. }
  217. }
  218. // 逻辑上,对于Container控件不公开此方法
  219. // 调用此方法的结果是,内部子控件隐藏,控件本身依然显示,背景等效果存在
  220. void CContainerUI::SetInternVisible(bool bVisible)
  221. {
  222. CControlUI::SetInternVisible(bVisible);
  223. if( m_items.IsEmpty() ) return;
  224. for( int it = 0; it < m_items.GetSize(); it++ ) {
  225. // 控制子控件显示状态
  226. // InternVisible状态应由子控件自己控制
  227. static_cast<CControlUI*>(m_items[it])->SetInternVisible(IsVisible());
  228. }
  229. }
  230. void CContainerUI::SetEnabled(bool bEnabled)
  231. {
  232. if( m_bEnabled == bEnabled ) return;
  233. m_bEnabled = bEnabled;
  234. for( int it = 0; it < m_items.GetSize(); it++ ) {
  235. static_cast<CControlUI*>(m_items[it])->SetEnabled(m_bEnabled);
  236. }
  237. Invalidate();
  238. }
  239. void CContainerUI::SetMouseEnabled(bool bEnabled)
  240. {
  241. if( m_pVerticalScrollBar != NULL ) m_pVerticalScrollBar->SetMouseEnabled(bEnabled);
  242. if( m_pHorizontalScrollBar != NULL ) m_pHorizontalScrollBar->SetMouseEnabled(bEnabled);
  243. CControlUI::SetMouseEnabled(bEnabled);
  244. }
  245. void CContainerUI::DoEvent(TEventUI& event)
  246. {
  247. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  248. if( m_pParent != NULL ) m_pParent->DoEvent(event);
  249. else CControlUI::DoEvent(event);
  250. return;
  251. }
  252. // [NIM 触屏模型] 手指拖拽 → 容器内容 1:1 跟手平移(对标 NIM Duilib 的 ScrollableBox)。
  253. // 对照 NIM Duilib Box.cpp:903-933 的 ScrollableBox::DoEvent:
  254. // detaValue = ptMouse.y - m_ptLastTouchPos.y;
  255. // detaValue > 0 ? TouchUp(detaValue) : TouchDown(-detaValue);
  256. // 其中 TouchUp = scrollPos.cy -= detaValue,即【手指下移 → 内容上滚】;到顶/到底由 SetScrollPos 夹紧。
  257. //
  258. // 能吃到这里的原因:CPaintManagerUI 把 UIEVENT_TOUCHMOVE 派发给触点下的最底层控件后,
  259. // 该控件不认此事件,会沿 CControlUI::DoEvent 末尾的 m_pParent->DoEvent 冒泡到这里。
  260. if( event.Type == UIEVENT_TOUCHMOVE )
  261. {
  262. // 位移增量由 CPaintManagerUI 随事件下发:wParam = dx,lParam = dy
  263. int dx = (int)event.wParam;
  264. int dy = (int)event.lParam;
  265. bool bScrolled = false;
  266. SIZE szPos = GetScrollPos();
  267. if( dy != 0 && m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() && m_pVerticalScrollBar->IsEnabled() )
  268. {
  269. szPos.cy -= dy;
  270. bScrolled = true;
  271. }
  272. if( dx != 0 && m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() && m_pHorizontalScrollBar->IsEnabled() )
  273. {
  274. szPos.cx -= dx;
  275. bScrolled = true;
  276. }
  277. if( bScrolled )
  278. {
  279. SetScrollPos(szPos);
  280. return; // 已消费:不再向父冒泡,只让最近的一层可滚动容器跟随手指
  281. }
  282. }
  283. if( event.Type == UIEVENT_SETFOCUS )
  284. {
  285. m_bFocused = true;
  286. return;
  287. }
  288. if( event.Type == UIEVENT_KILLFOCUS )
  289. {
  290. m_bFocused = false;
  291. return;
  292. }
  293. if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() && m_pVerticalScrollBar->IsEnabled() )
  294. {
  295. if( event.Type == UIEVENT_KEYDOWN )
  296. {
  297. switch( event.chKey ) {
  298. case VK_DOWN:
  299. LineDown();
  300. return;
  301. case VK_UP:
  302. LineUp();
  303. return;
  304. case VK_NEXT:
  305. PageDown();
  306. return;
  307. case VK_PRIOR:
  308. PageUp();
  309. return;
  310. case VK_HOME:
  311. HomeUp();
  312. return;
  313. case VK_END:
  314. EndDown();
  315. return;
  316. }
  317. }
  318. else if( event.Type == UIEVENT_SCROLLWHEEL )
  319. {
  320. switch( LOWORD(event.wParam) ) {
  321. case SB_LINEUP:
  322. LineUp();
  323. return;
  324. case SB_LINEDOWN:
  325. LineDown();
  326. return;
  327. }
  328. }
  329. }
  330. if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() && m_pHorizontalScrollBar->IsEnabled() ) {
  331. if( event.Type == UIEVENT_KEYDOWN )
  332. {
  333. switch( event.chKey ) {
  334. case VK_DOWN:
  335. LineRight();
  336. return;
  337. case VK_UP:
  338. LineLeft();
  339. return;
  340. case VK_NEXT:
  341. PageRight();
  342. return;
  343. case VK_PRIOR:
  344. PageLeft();
  345. return;
  346. case VK_HOME:
  347. HomeLeft();
  348. return;
  349. case VK_END:
  350. EndRight();
  351. return;
  352. }
  353. }
  354. else if( event.Type == UIEVENT_SCROLLWHEEL )
  355. {
  356. switch( LOWORD(event.wParam) ) {
  357. case SB_LINEUP:
  358. LineLeft();
  359. return;
  360. case SB_LINEDOWN:
  361. LineRight();
  362. return;
  363. }
  364. }
  365. }
  366. CControlUI::DoEvent(event);
  367. }
  368. SIZE CContainerUI::GetScrollPos() const
  369. {
  370. SIZE sz = {0, 0};
  371. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) sz.cy = m_pVerticalScrollBar->GetScrollPos();
  372. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) sz.cx = m_pHorizontalScrollBar->GetScrollPos();
  373. return sz;
  374. }
  375. SIZE CContainerUI::GetScrollRange() const
  376. {
  377. SIZE sz = {0, 0};
  378. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) sz.cy = m_pVerticalScrollBar->GetScrollRange();
  379. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) sz.cx = m_pHorizontalScrollBar->GetScrollRange();
  380. return sz;
  381. }
  382. void CContainerUI::SetScrollPos(SIZE szPos, bool bMsg)
  383. {
  384. int cx = 0;
  385. int cy = 0;
  386. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  387. int iLastScrollPos = m_pVerticalScrollBar->GetScrollPos();
  388. m_pVerticalScrollBar->SetScrollPos(szPos.cy);
  389. cy = m_pVerticalScrollBar->GetScrollPos() - iLastScrollPos;
  390. }
  391. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  392. int iLastScrollPos = m_pHorizontalScrollBar->GetScrollPos();
  393. m_pHorizontalScrollBar->SetScrollPos(szPos.cx);
  394. cx = m_pHorizontalScrollBar->GetScrollPos() - iLastScrollPos;
  395. }
  396. if( cx == 0 && cy == 0 ) return;
  397. RECT rcPos;
  398. for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) {
  399. CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
  400. if( !pControl->IsVisible() ) continue;
  401. if( pControl->IsFloat() ) continue;
  402. rcPos = pControl->GetPos();
  403. rcPos.left -= cx;
  404. rcPos.right -= cx;
  405. rcPos.top -= cy;
  406. rcPos.bottom -= cy;
  407. pControl->SetPos(rcPos);
  408. }
  409. Invalidate();
  410. if(m_pVerticalScrollBar)
  411. {
  412. // 发送滚动消息
  413. if( m_pManager != NULL && bMsg ) {
  414. int nPage = (m_pVerticalScrollBar->GetScrollPos() + m_pVerticalScrollBar->GetLineSize()) / m_pVerticalScrollBar->GetLineSize();
  415. m_pManager->SendNotify(this, DUI_MSGTYPE_SCROLL, (WPARAM)nPage);
  416. }
  417. }
  418. }
  419. void CContainerUI::SetScrollStepSize(int nSize)
  420. {
  421. if (nSize >0)
  422. m_nScrollStepSize = nSize;
  423. }
  424. int CContainerUI::GetScrollStepSize() const
  425. {
  426. if(m_pManager )return m_pManager->GetDPIObj()->Scale(m_nScrollStepSize);
  427. return m_nScrollStepSize;
  428. }
  429. void CContainerUI::LineUp()
  430. {
  431. int cyLine = GetScrollStepSize();
  432. if (cyLine == 0) {
  433. cyLine = 8;
  434. if( m_pManager ) cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8;
  435. }
  436. SIZE sz = GetScrollPos();
  437. sz.cy -= cyLine;
  438. SetScrollPos(sz);
  439. }
  440. void CContainerUI::LineDown()
  441. {
  442. int cyLine = GetScrollStepSize();
  443. if (cyLine == 0) {
  444. cyLine = 8;
  445. if( m_pManager ) cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8;
  446. }
  447. SIZE sz = GetScrollPos();
  448. sz.cy += cyLine;
  449. SetScrollPos(sz);
  450. }
  451. void CContainerUI::PageUp()
  452. {
  453. SIZE sz = GetScrollPos();
  454. int iOffset = m_rcItem.bottom - m_rcItem.top - m_rcInset.top - m_rcInset.bottom;
  455. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) iOffset -= m_pHorizontalScrollBar->GetFixedHeight();
  456. sz.cy -= iOffset;
  457. SetScrollPos(sz);
  458. }
  459. void CContainerUI::PageDown()
  460. {
  461. SIZE sz = GetScrollPos();
  462. int iOffset = m_rcItem.bottom - m_rcItem.top - m_rcInset.top - m_rcInset.bottom;
  463. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) iOffset -= m_pHorizontalScrollBar->GetFixedHeight();
  464. sz.cy += iOffset;
  465. SetScrollPos(sz);
  466. }
  467. void CContainerUI::HomeUp()
  468. {
  469. SIZE sz = GetScrollPos();
  470. sz.cy = 0;
  471. SetScrollPos(sz);
  472. }
  473. void CContainerUI::EndDown()
  474. {
  475. if(m_pManager) {
  476. ::UpdateWindow(m_pManager->GetPaintWindow());
  477. }
  478. SIZE sz = GetScrollPos();
  479. sz.cy = GetScrollRange().cy;
  480. SetScrollPos(sz);
  481. }
  482. void CContainerUI::LineLeft()
  483. {
  484. int nScrollStepSize = GetScrollStepSize();
  485. int cxLine = nScrollStepSize == 0 ? 8 : nScrollStepSize;
  486. SIZE sz = GetScrollPos();
  487. sz.cx -= cxLine;
  488. SetScrollPos(sz);
  489. }
  490. void CContainerUI::LineRight()
  491. {
  492. int nScrollStepSize = GetScrollStepSize();
  493. int cxLine = nScrollStepSize == 0 ? 8 : nScrollStepSize;
  494. SIZE sz = GetScrollPos();
  495. sz.cx += cxLine;
  496. SetScrollPos(sz);
  497. }
  498. void CContainerUI::PageLeft()
  499. {
  500. SIZE sz = GetScrollPos();
  501. RECT rcInset = GetInset();
  502. int iOffset = m_rcItem.right - m_rcItem.left - rcInset.left - rcInset.right;
  503. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) iOffset -= m_pVerticalScrollBar->GetFixedWidth();
  504. sz.cx -= iOffset;
  505. SetScrollPos(sz);
  506. }
  507. void CContainerUI::PageRight()
  508. {
  509. SIZE sz = GetScrollPos();
  510. RECT rcInset = GetInset();
  511. int iOffset = m_rcItem.right - m_rcItem.left - rcInset.left - rcInset.right;
  512. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) iOffset -= m_pVerticalScrollBar->GetFixedWidth();
  513. sz.cx += iOffset;
  514. SetScrollPos(sz);
  515. }
  516. void CContainerUI::HomeLeft()
  517. {
  518. SIZE sz = GetScrollPos();
  519. sz.cx = 0;
  520. SetScrollPos(sz);
  521. }
  522. void CContainerUI::EndRight()
  523. {
  524. if(m_pManager) {
  525. ::UpdateWindow(m_pManager->GetPaintWindow());
  526. }
  527. SIZE sz = GetScrollPos();
  528. sz.cx = GetScrollRange().cx;
  529. SetScrollPos(sz);
  530. }
  531. void CContainerUI::EnableScrollBar(bool bEnableVertical, bool bEnableHorizontal)
  532. {
  533. if( bEnableVertical && !m_pVerticalScrollBar ) {
  534. m_pVerticalScrollBar = new CScrollBarUI;
  535. m_pVerticalScrollBar->SetOwner(this);
  536. m_pVerticalScrollBar->SetManager(m_pManager, NULL, false);
  537. if ( m_pManager ) {
  538. LPCTSTR pDefaultAttributes = m_pManager->GetDefaultAttributeList(_T("VScrollBar"));
  539. if( pDefaultAttributes ) {
  540. m_pVerticalScrollBar->ApplyAttributeList(pDefaultAttributes);
  541. }
  542. m_pVerticalScrollBar->SetShow(m_bShowScrollbar);
  543. }
  544. }
  545. else if( !bEnableVertical && m_pVerticalScrollBar ) {
  546. delete m_pVerticalScrollBar;
  547. m_pVerticalScrollBar = NULL;
  548. }
  549. if( bEnableHorizontal && !m_pHorizontalScrollBar ) {
  550. m_pHorizontalScrollBar = new CScrollBarUI;
  551. m_pHorizontalScrollBar->SetHorizontal(true);
  552. m_pHorizontalScrollBar->SetOwner(this);
  553. m_pHorizontalScrollBar->SetManager(m_pManager, NULL, false);
  554. if ( m_pManager ) {
  555. LPCTSTR pDefaultAttributes = m_pManager->GetDefaultAttributeList(_T("HScrollBar"));
  556. if( pDefaultAttributes ) {
  557. m_pHorizontalScrollBar->ApplyAttributeList(pDefaultAttributes);
  558. }
  559. m_pHorizontalScrollBar->SetShow(m_bShowScrollbar);
  560. }
  561. }
  562. else if( !bEnableHorizontal && m_pHorizontalScrollBar ) {
  563. delete m_pHorizontalScrollBar;
  564. m_pHorizontalScrollBar = NULL;
  565. }
  566. NeedUpdate();
  567. }
  568. CScrollBarUI* CContainerUI::GetVerticalScrollBar() const
  569. {
  570. return m_pVerticalScrollBar;
  571. }
  572. CScrollBarUI* CContainerUI::GetHorizontalScrollBar() const
  573. {
  574. return m_pHorizontalScrollBar;
  575. }
  576. int CContainerUI::FindSelectable(int iIndex, bool bForward /*= true*/) const
  577. {
  578. // NOTE: This is actually a helper-function for the list/combo/ect controls
  579. // that allow them to find the next enabled/available selectable item
  580. if( GetCount() == 0 ) return -1;
  581. iIndex = CLAMP(iIndex, 0, GetCount() - 1);
  582. if( bForward ) {
  583. for( int i = iIndex; i < GetCount(); i++ ) {
  584. if( GetItemAt(i)->GetInterface(_T("ListItem")) != NULL
  585. && GetItemAt(i)->IsVisible()
  586. && GetItemAt(i)->IsEnabled() ) return i;
  587. }
  588. return -1;
  589. }
  590. else {
  591. for( int i = iIndex; i >= 0; --i ) {
  592. if( GetItemAt(i)->GetInterface(_T("ListItem")) != NULL
  593. && GetItemAt(i)->IsVisible()
  594. && GetItemAt(i)->IsEnabled() ) return i;
  595. }
  596. return FindSelectable(0, true);
  597. }
  598. }
  599. RECT CContainerUI::GetClientPos() const
  600. {
  601. RECT rc = m_rcItem;
  602. RECT rcInset = GetInset();
  603. rc.left += rcInset.left;
  604. rc.top += rcInset.top;
  605. rc.right -= rcInset.right;
  606. rc.bottom -= rcInset.bottom;
  607. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  608. rc.top -= m_pVerticalScrollBar->GetScrollPos();
  609. rc.bottom -= m_pVerticalScrollBar->GetScrollPos();
  610. rc.bottom += m_pVerticalScrollBar->GetScrollRange();
  611. rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  612. }
  613. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  614. rc.left -= m_pHorizontalScrollBar->GetScrollPos();
  615. rc.right -= m_pHorizontalScrollBar->GetScrollPos();
  616. rc.right += m_pHorizontalScrollBar->GetScrollRange();
  617. rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  618. }
  619. return rc;
  620. }
  621. void CContainerUI::Move(SIZE szOffset, bool bNeedInvalidate)
  622. {
  623. CControlUI::Move(szOffset, bNeedInvalidate);
  624. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) m_pVerticalScrollBar->Move(szOffset, false);
  625. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) m_pHorizontalScrollBar->Move(szOffset, false);
  626. for( int it = 0; it < m_items.GetSize(); it++ ) {
  627. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  628. if( pControl != NULL && pControl->IsVisible() ) pControl->Move(szOffset, false);
  629. }
  630. }
  631. void CContainerUI::SetPos(RECT rc, bool bNeedInvalidate)
  632. {
  633. CControlUI::SetPos(rc, bNeedInvalidate);
  634. if( m_items.IsEmpty() ) return;
  635. rc = m_rcItem;
  636. RECT rcInset = GetInset();
  637. rc.left += rcInset.left;
  638. rc.top += rcInset.top;
  639. rc.right -= rcInset.right;
  640. rc.bottom -= rcInset.bottom;
  641. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  642. rc.top -= m_pVerticalScrollBar->GetScrollPos();
  643. rc.bottom -= m_pVerticalScrollBar->GetScrollPos();
  644. rc.bottom += m_pVerticalScrollBar->GetScrollRange();
  645. rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  646. }
  647. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  648. rc.left -= m_pHorizontalScrollBar->GetScrollPos();
  649. rc.right -= m_pHorizontalScrollBar->GetScrollPos();
  650. rc.right += m_pHorizontalScrollBar->GetScrollRange();
  651. rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  652. }
  653. for( int it = 0; it < m_items.GetSize(); it++ ) {
  654. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  655. if( !pControl->IsVisible() ) continue;
  656. if( pControl->IsFloat() ) {
  657. SetFloatPos(it);
  658. }
  659. else {
  660. SIZE sz = { rc.right - rc.left, rc.bottom - rc.top };
  661. if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
  662. if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
  663. if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
  664. if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
  665. RECT rcCtrl = { rc.left, rc.top, rc.left + sz.cx, rc.top + sz.cy };
  666. pControl->SetPos(rcCtrl, false);
  667. }
  668. }
  669. }
  670. void CContainerUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  671. {
  672. if( _tcsicmp(pstrName, _T("inset")) == 0 ) {
  673. RECT rcInset = { 0 };
  674. LPTSTR pstr = NULL;
  675. rcInset.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  676. rcInset.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  677. rcInset.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  678. rcInset.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  679. SetInset(rcInset);
  680. }
  681. else if( _tcsicmp(pstrName, _T("mousechild")) == 0 ) SetMouseChildEnabled(_tcsicmp(pstrValue, _T("true")) == 0);
  682. else if( _tcsicmp(pstrName, _T("vscrollbar")) == 0 ) {
  683. EnableScrollBar(_tcsicmp(pstrValue, _T("true")) == 0, GetHorizontalScrollBar() != NULL);
  684. }
  685. else if( _tcsicmp(pstrName, _T("vscrollbarstyle")) == 0 ) {
  686. m_sVerticalScrollBarStyle = pstrValue;
  687. EnableScrollBar(TRUE, GetHorizontalScrollBar() != NULL);
  688. if( GetVerticalScrollBar() ) {
  689. LPCTSTR pStyle = m_pManager->GetStyle(m_sVerticalScrollBarStyle);
  690. if( pStyle ) {
  691. GetVerticalScrollBar()->ApplyAttributeList(pStyle);
  692. }
  693. else {
  694. GetVerticalScrollBar()->ApplyAttributeList(pstrValue);
  695. }
  696. }
  697. }
  698. else if( _tcsicmp(pstrName, _T("hscrollbar")) == 0 ) {
  699. EnableScrollBar(GetVerticalScrollBar() != NULL, _tcsicmp(pstrValue, _T("true")) == 0);
  700. }
  701. else if( _tcsicmp(pstrName, _T("hscrollbarstyle")) == 0 ) {
  702. m_sHorizontalScrollBarStyle = pstrValue;
  703. EnableScrollBar(TRUE, GetHorizontalScrollBar() != NULL);
  704. if( GetHorizontalScrollBar() ) {
  705. LPCTSTR pStyle = m_pManager->GetStyle(m_sHorizontalScrollBarStyle);
  706. if( pStyle ) {
  707. GetHorizontalScrollBar()->ApplyAttributeList(pStyle);
  708. }
  709. else {
  710. GetHorizontalScrollBar()->ApplyAttributeList(pstrValue);
  711. }
  712. }
  713. }
  714. else if( _tcsicmp(pstrName, _T("childpadding")) == 0 ) SetChildPadding(_ttoi(pstrValue));
  715. else if( _tcscmp(pstrName, _T("childalign")) == 0 ) {
  716. if( _tcscmp(pstrValue, _T("left")) == 0 ) m_iChildAlign = DT_LEFT;
  717. else if( _tcscmp(pstrValue, _T("center")) == 0 ) m_iChildAlign = DT_CENTER;
  718. else if( _tcscmp(pstrValue, _T("right")) == 0 ) m_iChildAlign = DT_RIGHT;
  719. }
  720. else if( _tcscmp(pstrName, _T("childvalign")) == 0 ) {
  721. if( _tcscmp(pstrValue, _T("top")) == 0 ) m_iChildVAlign = DT_TOP;
  722. else if( _tcscmp(pstrValue, _T("vcenter")) == 0 ) m_iChildVAlign = DT_VCENTER;
  723. else if( _tcscmp(pstrValue, _T("bottom")) == 0 ) m_iChildVAlign = DT_BOTTOM;
  724. }
  725. else if( _tcsicmp(pstrName, _T("scrollstepsize")) == 0 ) SetScrollStepSize(_ttoi(pstrValue));
  726. else if (_tcsicmp(pstrName, _T("fixedscrollbar")) == 0) SetFixedScrollbar(_tcsicmp(pstrValue, _T("true")) == 0);
  727. else if (_tcsicmp(pstrName, _T("showscrollbar")) == 0) SetShowScrollbar(_tcsicmp(pstrValue, _T("true")) == 0);
  728. else CControlUI::SetAttribute(pstrName, pstrValue);
  729. }
  730. void CContainerUI::SetManager(CPaintManagerUI* pManager, CControlUI* pParent, bool bInit)
  731. {
  732. for( int it = 0; it < m_items.GetSize(); it++ ) {
  733. static_cast<CControlUI*>(m_items[it])->SetManager(pManager, this, bInit);
  734. }
  735. if( m_pVerticalScrollBar != NULL ) m_pVerticalScrollBar->SetManager(pManager, this, bInit);
  736. if( m_pHorizontalScrollBar != NULL ) m_pHorizontalScrollBar->SetManager(pManager, this, bInit);
  737. CControlUI::SetManager(pManager, pParent, bInit);
  738. }
  739. CControlUI* CContainerUI::FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags)
  740. {
  741. if( (uFlags & UIFIND_VISIBLE) != 0 && !IsVisible() ) return NULL;
  742. if( (uFlags & UIFIND_ENABLED) != 0 && !IsEnabled() ) return NULL;
  743. if( (uFlags & UIFIND_HITTEST) != 0 && !::PtInRect(&m_rcItem, *(static_cast<LPPOINT>(pData))) ) return NULL;
  744. if( (uFlags & UIFIND_UPDATETEST) != 0 && Proc(this, pData) != NULL ) return NULL;
  745. CControlUI* pResult = NULL;
  746. if( (uFlags & UIFIND_ME_FIRST) != 0 ) {
  747. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = Proc(this, pData);
  748. }
  749. if( pResult == NULL && m_pVerticalScrollBar != NULL ) {
  750. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = m_pVerticalScrollBar->FindControl(Proc, pData, uFlags);
  751. }
  752. if( pResult == NULL && m_pHorizontalScrollBar != NULL ) {
  753. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = m_pHorizontalScrollBar->FindControl(Proc, pData, uFlags);
  754. }
  755. if( pResult != NULL ) return pResult;
  756. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseChildEnabled() ) {
  757. RECT rc = m_rcItem;
  758. RECT rcInset = GetInset();
  759. rc.left += rcInset.left;
  760. rc.top += rcInset.top;
  761. rc.right -= rcInset.right;
  762. rc.bottom -= rcInset.bottom;
  763. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  764. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  765. if( (uFlags & UIFIND_TOP_FIRST) != 0 ) {
  766. for( int it = m_items.GetSize() - 1; it >= 0; it-- ) {
  767. pResult = static_cast<CControlUI*>(m_items[it])->FindControl(Proc, pData, uFlags);
  768. if( pResult != NULL ) {
  769. if( (uFlags & UIFIND_HITTEST) != 0 && !pResult->IsFloat() && !::PtInRect(&rc, *(static_cast<LPPOINT>(pData))) )
  770. continue;
  771. else
  772. return pResult;
  773. }
  774. }
  775. }
  776. else {
  777. for( int it = 0; it < m_items.GetSize(); it++ ) {
  778. pResult = static_cast<CControlUI*>(m_items[it])->FindControl(Proc, pData, uFlags);
  779. if( pResult != NULL ) {
  780. if( (uFlags & UIFIND_HITTEST) != 0 && !pResult->IsFloat() && !::PtInRect(&rc, *(static_cast<LPPOINT>(pData))) )
  781. continue;
  782. else
  783. return pResult;
  784. }
  785. }
  786. }
  787. }
  788. pResult = NULL;
  789. if( pResult == NULL && (uFlags & UIFIND_ME_FIRST) == 0 ) {
  790. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = Proc(this, pData);
  791. }
  792. return pResult;
  793. }
  794. bool CContainerUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
  795. {
  796. RECT rcTemp = { 0 };
  797. if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true;
  798. CRenderClip clip;
  799. CRenderClip::GenerateClip(hDC, rcTemp, clip);
  800. CControlUI::DoPaint(hDC, rcPaint, pStopControl);
  801. if( m_items.GetSize() > 0 ) {
  802. RECT rcInset = GetInset();
  803. RECT rc = m_rcItem;
  804. rc.left += rcInset.left;
  805. rc.top += rcInset.top;
  806. rc.right -= rcInset.right;
  807. rc.bottom -= rcInset.bottom;
  808. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  809. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  810. if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) {
  811. for( int it = 0; it < m_items.GetSize(); it++ ) {
  812. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  813. if( pControl == pStopControl ) return false;
  814. if( !pControl->IsVisible() ) continue;
  815. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  816. if( pControl ->IsFloat() ) {
  817. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  818. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  819. }
  820. }
  821. }
  822. else {
  823. CRenderClip childClip;
  824. CRenderClip::GenerateClip(hDC, rcTemp, childClip);
  825. for( int it = 0; it < m_items.GetSize(); it++ ) {
  826. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  827. if( pControl == pStopControl ) return false;
  828. if( !pControl->IsVisible() ) continue;
  829. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  830. if( pControl->IsFloat() ) {
  831. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  832. CRenderClip::UseOldClipBegin(hDC, childClip);
  833. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  834. CRenderClip::UseOldClipEnd(hDC, childClip);
  835. }
  836. else {
  837. if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue;
  838. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  839. }
  840. }
  841. }
  842. }
  843. if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() ) {
  844. if( m_pVerticalScrollBar == pStopControl ) return false;
  845. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) {
  846. if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  847. }
  848. }
  849. if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() ) {
  850. if( m_pHorizontalScrollBar == pStopControl ) return false;
  851. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) {
  852. if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  853. }
  854. }
  855. return true;
  856. }
  857. void CContainerUI::SetFloatPos(int iIndex)
  858. {
  859. // 因为CControlUI::SetPos对float的操作影响,这里不能对float组件添加滚动条的影响
  860. if( iIndex < 0 || iIndex >= m_items.GetSize() ) return;
  861. CControlUI* pControl = static_cast<CControlUI*>(m_items[iIndex]);
  862. if( !pControl->IsVisible() ) return;
  863. if( !pControl->IsFloat() ) return;
  864. SIZE szXY = pControl->GetFixedXY();
  865. SIZE sz = {pControl->GetFixedWidth(), pControl->GetFixedHeight()};
  866. int nParentWidth = m_rcItem.right - m_rcItem.left;
  867. int nParentHeight = m_rcItem.bottom - m_rcItem.top;
  868. UINT uAlign = pControl->GetFloatAlign();
  869. if(uAlign != 0) {
  870. RECT rcCtrl = {0, 0, sz.cx, sz.cy};
  871. if((uAlign & DT_CENTER) != 0) {
  872. ::OffsetRect(&rcCtrl, (nParentWidth - sz.cx) / 2, 0);
  873. }
  874. else if((uAlign & DT_RIGHT) != 0) {
  875. ::OffsetRect(&rcCtrl, nParentWidth - sz.cx, 0);
  876. }
  877. else {
  878. ::OffsetRect(&rcCtrl, szXY.cx, 0);
  879. }
  880. if((uAlign & DT_VCENTER) != 0) {
  881. ::OffsetRect(&rcCtrl, 0, (nParentHeight - sz.cy) / 2);
  882. }
  883. else if((uAlign & DT_BOTTOM) != 0) {
  884. ::OffsetRect(&rcCtrl, 0, nParentHeight - sz.cy);
  885. }
  886. else {
  887. ::OffsetRect(&rcCtrl, 0, szXY.cy);
  888. }
  889. ::OffsetRect(&rcCtrl, m_rcItem.left, m_rcItem.top);
  890. pControl->SetPos(rcCtrl, false);
  891. }
  892. else {
  893. TPercentInfo rcPercent = pControl->GetFloatPercent();
  894. LONG width = m_rcItem.right - m_rcItem.left;
  895. LONG height = m_rcItem.bottom - m_rcItem.top;
  896. LONG left = szXY.cx < 0 ? m_rcItem.right : m_rcItem.left;
  897. LONG top = szXY.cy < 0 ? m_rcItem.bottom : m_rcItem.top;
  898. RECT rcCtrl = { 0 };
  899. rcCtrl.left = (LONG)(width*rcPercent.left) + szXY.cx + left;
  900. rcCtrl.top = (LONG)(height*rcPercent.top) + szXY.cy + top;
  901. rcCtrl.right = (LONG)(width*rcPercent.right) + szXY.cx + sz.cx + left;
  902. rcCtrl.bottom = (LONG)(height*rcPercent.bottom) + szXY.cy + sz.cy + top;
  903. pControl->SetPos(rcCtrl, false);
  904. }
  905. }
  906. void CContainerUI::ProcessScrollBar(RECT rc, int cxRequired, int cyRequired)
  907. {
  908. bool bNeedUpdate = false;
  909. while (m_pHorizontalScrollBar)
  910. {
  911. // Scroll needed
  912. if (cxRequired > rc.right - rc.left && !m_pHorizontalScrollBar->IsVisible())
  913. {
  914. m_pHorizontalScrollBar->SetVisible(true);
  915. m_pHorizontalScrollBar->SetScrollRange(cxRequired - (rc.right - rc.left));
  916. m_pHorizontalScrollBar->SetScrollPos(0);
  917. bNeedUpdate = true;
  918. break;
  919. }
  920. // No scrollbar required
  921. if (!m_pHorizontalScrollBar->IsVisible()) break;
  922. // Scroll not needed anymore?
  923. int cxScroll = cxRequired - (rc.right - rc.left);
  924. if (cxScroll <= 0)
  925. {
  926. m_pHorizontalScrollBar->SetVisible(false);
  927. m_pHorizontalScrollBar->SetScrollPos(0);
  928. m_pHorizontalScrollBar->SetScrollRange(0);
  929. bNeedUpdate = true;
  930. }
  931. else
  932. {
  933. RECT rcScrollBarPos = { rc.left, rc.bottom, rc.right, rc.bottom + m_pHorizontalScrollBar->GetFixedHeight() };
  934. m_pHorizontalScrollBar->SetPos(rcScrollBarPos);
  935. if (m_pHorizontalScrollBar->GetScrollRange() != cxScroll)
  936. {
  937. int iScrollPos = m_pHorizontalScrollBar->GetScrollPos();
  938. m_pHorizontalScrollBar->SetScrollRange(::abs(cxScroll)); // if scrollpos>range then scrollpos=range
  939. if (iScrollPos > m_pHorizontalScrollBar->GetScrollPos())
  940. {
  941. bNeedUpdate = true;
  942. }
  943. }
  944. }
  945. break;
  946. }
  947. while (m_pVerticalScrollBar)
  948. {
  949. // Scroll needed
  950. if (cyRequired > rc.bottom - rc.top && !m_pVerticalScrollBar->IsVisible())
  951. {
  952. m_pVerticalScrollBar->SetVisible(true);
  953. m_pVerticalScrollBar->SetScrollRange(cyRequired - (rc.bottom - rc.top));
  954. m_pVerticalScrollBar->SetScrollPos(0);
  955. bNeedUpdate = true;
  956. break;
  957. }
  958. // No scrollbar required
  959. if (!m_pVerticalScrollBar->IsVisible()) break;
  960. // Scroll not needed anymore?
  961. int cyScroll = cyRequired - (rc.bottom - rc.top);
  962. if (cyScroll <= 0)
  963. {
  964. m_pVerticalScrollBar->SetVisible(false);
  965. m_pVerticalScrollBar->SetScrollPos(0);
  966. m_pVerticalScrollBar->SetScrollRange(0);
  967. bNeedUpdate = true;
  968. break;
  969. }
  970. RECT rcScrollBarPos = { rc.right, rc.top, rc.right + m_pVerticalScrollBar->GetFixedWidth(), rc.bottom };
  971. m_pVerticalScrollBar->SetPos(rcScrollBarPos);
  972. if (m_pVerticalScrollBar->GetScrollRange() != cyScroll)
  973. {
  974. int iScrollPos = m_pVerticalScrollBar->GetScrollPos();
  975. m_pVerticalScrollBar->SetScrollRange(::abs(cyScroll)); // if scrollpos>range then scrollpos=range
  976. if (iScrollPos > m_pVerticalScrollBar->GetScrollPos())
  977. {
  978. bNeedUpdate = true;
  979. }
  980. }
  981. break;
  982. }
  983. if (bNeedUpdate)
  984. {
  985. NeedUpdate();
  986. }
  987. }
  988. bool CContainerUI::SetSubControlText( LPCTSTR pstrSubControlName,LPCTSTR pstrText )
  989. {
  990. CControlUI* pSubControl=NULL;
  991. pSubControl=this->FindSubControl(pstrSubControlName);
  992. if (pSubControl!=NULL) {
  993. pSubControl->SetText(pstrText);
  994. return TRUE;
  995. }
  996. else return FALSE;
  997. }
  998. bool CContainerUI::SetSubControlFixedHeight( LPCTSTR pstrSubControlName,int cy )
  999. {
  1000. CControlUI* pSubControl=NULL;
  1001. pSubControl=this->FindSubControl(pstrSubControlName);
  1002. if (pSubControl!=NULL) {
  1003. pSubControl->SetFixedHeight(cy);
  1004. return TRUE;
  1005. }
  1006. else return FALSE;
  1007. }
  1008. bool CContainerUI::SetSubControlFixedWdith( LPCTSTR pstrSubControlName,int cx )
  1009. {
  1010. CControlUI* pSubControl=NULL;
  1011. pSubControl=this->FindSubControl(pstrSubControlName);
  1012. if (pSubControl!=NULL) {
  1013. pSubControl->SetFixedWidth(cx);
  1014. return TRUE;
  1015. }
  1016. else return FALSE;
  1017. }
  1018. bool CContainerUI::SetSubControlUserData( LPCTSTR pstrSubControlName,LPCTSTR pstrText )
  1019. {
  1020. CControlUI* pSubControl=NULL;
  1021. pSubControl=this->FindSubControl(pstrSubControlName);
  1022. if (pSubControl!=NULL) {
  1023. pSubControl->SetUserData(pstrText);
  1024. return TRUE;
  1025. }
  1026. else return FALSE;
  1027. }
  1028. DuiLib::CDuiString CContainerUI::GetSubControlText( LPCTSTR pstrSubControlName )
  1029. {
  1030. CControlUI* pSubControl=NULL;
  1031. pSubControl=this->FindSubControl(pstrSubControlName);
  1032. if (pSubControl==NULL)
  1033. return _T("");
  1034. else
  1035. return pSubControl->GetText();
  1036. }
  1037. int CContainerUI::GetSubControlFixedHeight( LPCTSTR pstrSubControlName )
  1038. {
  1039. CControlUI* pSubControl=NULL;
  1040. pSubControl=this->FindSubControl(pstrSubControlName);
  1041. if (pSubControl==NULL) return -1;
  1042. else return pSubControl->GetFixedHeight();
  1043. }
  1044. int CContainerUI::GetSubControlFixedWdith( LPCTSTR pstrSubControlName )
  1045. {
  1046. CControlUI* pSubControl=NULL;
  1047. pSubControl=this->FindSubControl(pstrSubControlName);
  1048. if (pSubControl==NULL) return -1;
  1049. else return pSubControl->GetFixedWidth();
  1050. }
  1051. const CDuiString CContainerUI::GetSubControlUserData( LPCTSTR pstrSubControlName )
  1052. {
  1053. CControlUI* pSubControl=NULL;
  1054. pSubControl=this->FindSubControl(pstrSubControlName);
  1055. if (pSubControl==NULL) return _T("");
  1056. else return pSubControl->GetUserData();
  1057. }
  1058. CControlUI* CContainerUI::FindSubControl( LPCTSTR pstrSubControlName )
  1059. {
  1060. CControlUI* pSubControl=NULL;
  1061. pSubControl = static_cast<CControlUI*>(GetManager()->FindSubControlByName(this, pstrSubControlName));
  1062. return pSubControl;
  1063. }
  1064. } // namespace DuiLib