XTPControls.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:42k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPControls.cpp : implementation of the CXTPControls class.
  2. //
  3. // This file is a part of the XTREME COMMANDBARS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPImageManager.h"
  23. #include "Common/XTPResourceManager.h"
  24. #include "XTPControls.h"
  25. #include "XTPCommandBar.h"
  26. #include "XTPPopupBar.h"
  27. #include "XTPControl.h"
  28. #include "XTPControlButton.h"
  29. #include "XTPControlPopup.h"
  30. #include "XTPControlComboBox.h"
  31. #include "XTPControlEdit.h"
  32. #include "XTPControlCustom.h"
  33. #include "XTPControlGallery.h"
  34. #include "XTPControlExt.h"
  35. #include "XTPToolBar.h"
  36. #include "XTPCommandBars.h"
  37. #include "XTPPaintManager.h"
  38. #ifdef _DEBUG
  39. #define new DEBUG_NEW
  40. #undef THIS_FILE
  41. static char THIS_FILE[] = __FILE__;
  42. #endif
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CCommandBarControls
  45. IMPLEMENT_DYNCREATE(CXTPControls, CCmdTarget)
  46. IMPLEMENT_DYNCREATE(CXTPOriginalControls, CXTPControls)
  47. CXTPControls::CXTPControls()
  48. {
  49. EnableAutomation();
  50. m_pParent = 0;
  51. m_pCommandBars = 0;
  52. m_pOriginalControls = 0;
  53. m_bOriginalControls = FALSE;
  54. }
  55. CXTPControls::~CXTPControls()
  56. {
  57. RemoveAll();
  58. CMDTARGET_RELEASE(m_pOriginalControls);
  59. }
  60. CXTPOriginalControls::CXTPOriginalControls()
  61. {
  62. m_bOriginalControls = TRUE;
  63. }
  64. CXTPCommandBars* CXTPControls::GetCommandBars() const
  65. {
  66. return m_pParent ? m_pParent->GetCommandBars() : m_pCommandBars;
  67. }
  68. void CXTPControls::SetCommandBars(CXTPCommandBars* pCommandBars)
  69. {
  70. m_pCommandBars = pCommandBars;
  71. }
  72. void CXTPControls::RefreshIndexes()
  73. {
  74. for (int nIndex = 0; nIndex < GetCount(); nIndex++)
  75. {
  76. CXTPControl* pControl = GetAt(nIndex);
  77. pControl->m_nIndex = nIndex;
  78. pControl->m_pControls = this;
  79. pControl->SetParent(m_pParent);
  80. }
  81. if (m_pParent)
  82. {
  83. m_pParent->OnControlsChanged();
  84. }
  85. }
  86. void CXTPControls::SetParent(CXTPCommandBar* pParent)
  87. {
  88. m_pParent = pParent;
  89. if (GetCount() > 0) RefreshIndexes();
  90. }
  91. CXTPControl* CXTPControls::AddMenuItem(CMenu* pMenu, int nIndex)
  92. {
  93. CMenu* pPopupMenu = pMenu->GetSubMenu(nIndex);
  94. CXTPControl* pControl = NULL;
  95. UINT nID = pMenu->GetMenuItemID(nIndex);
  96. BOOL bDefaultItem = (int)::GetMenuDefaultItem(pMenu->m_hMenu, TRUE, GMDI_USEDISABLED) == nIndex;
  97. if (nID == AFX_IDM_FIRST_MDICHILD)
  98. return NULL;
  99. CString strCaption;
  100. XTPResourceManager()->GetMenuLocaleString(pMenu, nIndex, strCaption, MF_BYPOSITION);
  101. if (pPopupMenu)
  102. {
  103. int iPos = strCaption.Find(_T('t'));
  104. if (pPopupMenu &&  iPos > 0)
  105. {
  106. nID = _ttoi(strCaption.Mid(iPos + 1));
  107. if (nID > 0) strCaption.ReleaseBuffer(iPos);
  108. }
  109. }
  110. CWnd* pSite = m_pCommandBars ? m_pCommandBars->GetSite() :
  111. m_pParent ? m_pParent->GetOwnerSite() : NULL;
  112. CXTPCommandBars* pCommandBars = GetCommandBars();
  113. XTPControlType controlType = pPopupMenu ? xtpControlPopup : xtpControlButton;
  114. XTPButtonStyle buttonStyle = xtpButtonAutomatic;
  115. XTP_COMMANDBARS_CREATECONTROL cs;
  116. if (pSite)
  117. {
  118. cs.nID = nID;
  119. cs.pControl = NULL;
  120. cs.bToolBar = FALSE;
  121. cs.pCommandBar = m_pParent;
  122. cs.pMenu = pMenu;
  123. cs.nIndex = nIndex;
  124. cs.strCaption = strCaption;
  125. cs.controlType = controlType;
  126. cs.buttonStyle = buttonStyle;
  127. if (pSite->SendMessage(WM_XTP_BEFORECREATECONTROL, 0, (LPARAM)&cs) != 0)
  128. {
  129. pControl = cs.pControl;
  130. controlType = cs.controlType;
  131. strCaption = cs.strCaption;
  132. nID = cs.nID;
  133. buttonStyle = cs.buttonStyle;
  134. }
  135. }
  136. if (pControl == NULL)
  137. {
  138. switch (controlType)
  139. {
  140. case xtpControlButton:
  141. if (nID == XTP_ID_WINDOWLIST) pControl = (CXTPControl*)CXTPControlWindowList::CreateObject();
  142. else if (nID == XTP_ID_WORKSPACE_ACTIONS) pControl = (CXTPControl*)CXTPControlWorkspaceActions::CreateObject();
  143. else if (nID == ID_VIEW_TOOLBAR) pControl = (CXTPControl*)CXTPControlToolbars::CreateObject();
  144. else if (nID == ID_OLE_VERB_FIRST && strCaption == _T("<<OLE VERBS GO HERE>>")) pControl = (CXTPControl*)CXTPControlOleItems::CreateObject();
  145. else if (nID == ID_FILE_MRU_FILE1) pControl = (CXTPControl*)CXTPControlRecentFileList::CreateObject();
  146. else pControl = (CXTPControl*)CXTPControlButton::CreateObject();
  147. break;
  148. case xtpControlComboBox:
  149. pControl = (CXTPControl*)CXTPControlComboBox::CreateObject();
  150. break;
  151. case xtpControlEdit:
  152. pControl = (CXTPControl*)CXTPControlEdit::CreateObject();
  153. break;
  154. case xtpControlLabel:
  155. pControl = (CXTPControl*)CXTPControlLabel::CreateObject();
  156. break;
  157. case xtpControlCheckBox:
  158. pControl = (CXTPControl*)CXTPControlCheckBox::CreateObject();
  159. break;
  160. case xtpControlRadioButton:
  161. pControl = (CXTPControl*)CXTPControlRadioButton::CreateObject();
  162. break;
  163. case xtpControlGallery:
  164. pControl = (CXTPControl*)CXTPControlGallery::CreateObject();
  165. break;
  166. case xtpControlPopup:
  167. case xtpControlSplitButtonPopup:
  168. case xtpControlButtonPopup:
  169. pControl = CXTPControlPopup::CreateControlPopup(controlType);
  170. CXTPPopupBar* pPopupBar = 0;
  171. CString strCaptionPopup(strCaption);
  172. CXTPPaintManager::StripMnemonics(strCaptionPopup);
  173. if (pSite)
  174. {
  175. XTP_COMMANDBARS_CREATEBAR cb;
  176. ZeroMemory(&cb, sizeof(cb));
  177. cb.bPopup = TRUE;
  178. cb.lpcstrCaption = strCaptionPopup;
  179. cb.nID = nID;
  180. if (pSite->SendMessage(WM_XTP_CREATECOMMANDBAR, 0, (LPARAM)&cb) != 0)
  181. {
  182. pPopupBar = DYNAMIC_DOWNCAST(CXTPPopupBar, cb.pCommandBar);
  183. strCaptionPopup = cb.lpcstrCaption;
  184. }
  185. }
  186. if (pPopupBar == NULL) pPopupBar = CXTPPopupBar::CreatePopupBar(pCommandBars);
  187. pPopupBar->SetTitle(strCaptionPopup);
  188. CMenu menu;
  189. if (!pPopupMenu && nID > 0 && menu.LoadMenu(nID))
  190. {
  191. pPopupMenu = menu.GetSubMenu(0);
  192. }
  193. if (pPopupMenu) pPopupBar->LoadMenu(pPopupMenu, FALSE);
  194. ((CXTPControlPopup*)pControl)->m_pCommandBar = pPopupBar;
  195. break;
  196. }
  197. ASSERT(pControl);
  198. if (!pControl)
  199. return NULL;
  200. pControl->m_controlType = controlType;
  201. pControl->SetStyle(buttonStyle);
  202. }
  203. CXTPControlAction* pAction = pCommandBars->FindAction(nID);
  204. if (pControl->GetAction() != NULL)
  205. {
  206. }
  207. else if (pAction || (pCommandBars->IsActionsEnabled() && nID > 0 && nID < 0xFFFFFFF))
  208. {
  209. if (pAction == NULL) pAction = pCommandBars->CreateAction(nID);
  210. pControl->SetAction(pAction);
  211. if (pAction->m_strCaption.IsEmpty())
  212. pAction->SetCaption(strCaption);
  213. }
  214. else
  215. {
  216. pControl->SetID(nID);
  217. pControl->SetCaption(strCaption);
  218. }
  219. if (bDefaultItem) pControl->SetItemDefault(bDefaultItem);
  220. m_arrControls.InsertAt(GetCount(), pControl);
  221. OnControlAdded(pControl);
  222. if (pSite)
  223. {
  224. cs.pControl = pControl;
  225. pSite->SendMessage(WM_XTP_AFTERCREATECONTROL, 0, (LPARAM)&cs);
  226. }
  227. return pControl;
  228. }
  229. void CXTPControls::OnControlAdded(CXTPControl* /*pControl*/)
  230. {
  231. RefreshIndexes();
  232. }
  233. void CXTPControls::OnControlRemoved(CXTPControl* pControl)
  234. {
  235. pControl->m_pControls = NULL;
  236. pControl->OnRemoved();
  237. pControl->m_pParent = NULL;
  238. RefreshIndexes();
  239. }
  240. CXTPControl* CXTPControls::Add(XTPControlType controlType, int nId, LPCTSTR strParameter, int nBefore, BOOL bTemporary)
  241. {
  242. CXTPControl* pControl = NULL;
  243. CXTPCommandBars* pCommandBars = GetCommandBars();
  244. switch (controlType)
  245. {
  246. case xtpControlCustom:
  247. return Add(new CXTPControlCustom(), nId, strParameter, nBefore, bTemporary);
  248. case xtpControlButton:
  249. if (nId == XTP_ID_WINDOWLIST) pControl = (CXTPControl*)CXTPControlWindowList::CreateObject();
  250. else if (nId == XTP_ID_WORKSPACE_ACTIONS) pControl = (CXTPControl*)CXTPControlWorkspaceActions::CreateObject();
  251. else if (nId == ID_VIEW_TOOLBAR) pControl = (CXTPControl*)CXTPControlToolbars::CreateObject();
  252. else if (nId == XTP_ID_FILE_MRU) pControl = (CXTPControl*)CXTPControlRecentFileList::CreateObject();
  253. else
  254. pControl = (CXTPControl*)CXTPControlButton::CreateObject();
  255. break;
  256. case xtpControlComboBox:
  257. pControl = (CXTPControl*)CXTPControlComboBox::CreateObject();
  258. break;
  259. case xtpControlLabel:
  260. pControl = (CXTPControl*)CXTPControlLabel::CreateObject();
  261. break;
  262. case xtpControlCheckBox:
  263. pControl = (CXTPControl*)CXTPControlCheckBox::CreateObject();
  264. break;
  265. case xtpControlRadioButton:
  266. pControl = (CXTPControl*)CXTPControlRadioButton::CreateObject();
  267. break;
  268. case xtpControlGallery:
  269. pControl = (CXTPControl*)CXTPControlGallery::CreateObject();
  270. break;
  271. case xtpControlEdit:
  272. pControl = (CXTPControl*)CXTPControlEdit::CreateObject();
  273. break;
  274. case xtpControlPopup:
  275. case xtpControlSplitButtonPopup:
  276. case xtpControlButtonPopup:
  277. CXTPControlPopup* pControlPopup = (CXTPControlPopup*)CXTPControlPopup::CreateObject();
  278. CXTPPopupBar* pPopupBar = 0;
  279. CMenu menu;
  280. if (nId > 0)
  281. {
  282. CString strCaption;
  283. CMenu* pPopupMenu = NULL;
  284. if (menu.LoadMenu(nId))
  285. {
  286. pPopupMenu = menu.GetSubMenu(0);
  287. XTPResourceManager()->GetMenuLocaleString(&menu, 0, strCaption, MF_BYPOSITION);
  288. }
  289. CWnd* pSite = m_pCommandBars ? m_pCommandBars->GetSite() :
  290. m_pParent ? m_pParent->GetOwnerSite() : NULL;
  291. if (pSite)
  292. {
  293. XTP_COMMANDBARS_CREATEBAR cs;
  294. ZeroMemory(&cs, sizeof(cs));
  295. cs.bPopup = TRUE;
  296. cs.lpcstrCaption = strCaption;
  297. cs.nID = nId;
  298. if (pSite->SendMessage(WM_XTP_CREATECOMMANDBAR, 0, (LPARAM)&cs) != 0)
  299. {
  300. pPopupBar = DYNAMIC_DOWNCAST(CXTPPopupBar, cs.pCommandBar);
  301. }
  302. }
  303. if (pPopupBar == NULL) pPopupBar = CXTPPopupBar::CreatePopupBar(GetCommandBars());
  304. pControlPopup->SetCaption(strCaption);
  305. if (pPopupMenu)
  306. {
  307. pPopupBar->LoadMenu(pPopupMenu);
  308. }
  309. }
  310. if (pPopupBar == NULL) pPopupBar = CXTPPopupBar::CreatePopupBar(pCommandBars);
  311. pControlPopup->m_pCommandBar = pPopupBar;
  312. pControl = pControlPopup;
  313. break;
  314. }
  315. ASSERT(pControl);
  316. if (!pControl)
  317. return NULL;
  318. pControl->m_controlType = controlType;
  319. return Add(pControl, nId, strParameter, nBefore, bTemporary);
  320. }
  321. CXTPControl* CXTPControls::Add(CXTPControl* pControl, int nId, LPCTSTR strParameter, int nBefore, BOOL bTemporary)
  322. {
  323. ASSERT(pControl);
  324. if (!pControl)
  325. return NULL;
  326. pControl->m_strParameter = strParameter;
  327. pControl->m_bTemporary = bTemporary;
  328. CXTPCommandBars* pCommandBars = GetCommandBars();
  329. CXTPControlAction* pAction = pCommandBars->FindAction(nId);
  330. if (pControl->GetAction() != NULL)
  331. {
  332. }
  333. else if (pAction != NULL)
  334. {
  335. pControl->SetAction(pAction);
  336. }
  337. else if (pCommandBars->IsActionsEnabled() && nId > 0 && nId < 0xFFFFFFF)
  338. {
  339. if ((nId >= XTP_COMMANDBARS_RESOURCE_FIRST && nId <= XTP_COMMANDBARS_RESOURCE_LAST)
  340. || (nId >= 35000 && nId <= 35003))
  341. {
  342. if (!pAction)
  343. {
  344. pControl->SetID(nId);
  345. }
  346. }
  347. else
  348. {
  349. pAction = pCommandBars->CreateAction(nId);
  350. pControl->SetAction(pAction);
  351. }
  352. }
  353. else
  354. {
  355. pControl->SetID(nId);
  356. }
  357. return InsertAt(pControl, nBefore);
  358. }
  359. CXTPControl* CXTPControls::InsertAt(CXTPControl* pControl, int nBefore)
  360. {
  361. if (nBefore < 0 || nBefore >= GetCount())
  362. nBefore = GetCount();
  363. ASSERT(pControl);
  364. m_arrControls.InsertAt(nBefore, pControl);
  365. OnControlAdded(pControl);
  366. return pControl;
  367. }
  368. CXTPControl* CXTPControls::Add(CXTPControl* pControl)
  369. {
  370. return InsertAt(pControl, -1);
  371. }
  372. CXTPControl* CXTPControls::AddClone(CXTPControl* pControl, int nBefore, BOOL bRecursive)
  373. {
  374. CXTPControl* pClone = (CXTPControl*)pControl->GetRuntimeClass()->CreateObject();
  375. ASSERT(pClone);
  376. if (!pClone)
  377. return NULL;
  378. InsertAt(pClone, nBefore);
  379. pClone->Copy(pControl, bRecursive);
  380. return pClone;
  381. }
  382. void CXTPControls::RemoveAll()
  383. {
  384. for (int nIndex = GetCount() - 1; nIndex >= 0; nIndex--)
  385. {
  386. CXTPControl* pControl = GetAt(nIndex);
  387. if (OnControlRemoving(pControl))
  388. continue;
  389. m_arrControls.RemoveAt(nIndex);
  390. OnControlRemoved(pControl);
  391. pControl->SetParent(NULL);
  392. pControl->InternalRelease();
  393. }
  394. }
  395. CXTPControl* CXTPControls::GetFirst() const
  396. {
  397. return GetCount() > 0 ? GetAt(0) : NULL;
  398. }
  399. void CXTPControls::GetNext(CXTPControl*& pControl) const
  400. {
  401. pControl = (!pControl || pControl->m_nIndex >= GetCount() - 1) ? 0 : GetAt(pControl->m_nIndex + 1);
  402. }
  403. CXTPControl* CXTPControls::FindControl(int nId) const
  404. {
  405. return FindControl(xtpControlError, nId, FALSE, FALSE);
  406. }
  407. CXTPControl* CXTPControls::FindControl(XTPControlType type, int nId, BOOL bVisible, BOOL bRecursive) const
  408. {
  409. for (int nIndex = 0; nIndex < GetCount(); nIndex++)
  410. {
  411. CXTPControl* pControl = GetAt(nIndex);
  412. if ((type == xtpControlError || pControl->GetType() == type) &&
  413. (!bVisible || pControl->IsVisible()) &&
  414. (nId == -1 || nId == pControl->GetID()))
  415. return pControl;
  416. if (bRecursive)
  417. {
  418. CXTPCommandBar* pBar = pControl->GetCommandBar();
  419. if (pBar)
  420. {
  421. pControl = pBar->GetControls()->FindControl(type, nId, bVisible, bRecursive);
  422. if (pControl != NULL) return pControl;
  423. }
  424. }
  425. }
  426. return NULL;
  427. }
  428. BOOL CXTPControls::OnControlRemoving(CXTPControl* /*pControl*/)
  429. {
  430. return FALSE;
  431. }
  432. void CXTPControls::Remove(CXTPControl* pControl)
  433. {
  434. if (pControl && pControl->m_pControls == this)
  435. {
  436. if (pControl->GetSelected())
  437. m_pParent->SetSelected(-1);
  438. ASSERT(pControl->m_pControls == this);
  439. //Ensure the index falls within the correct range.
  440. if ((pControl->m_nIndex >= 0) && (pControl->m_nIndex < GetCount()))
  441. {
  442. ASSERT(m_arrControls[pControl->m_nIndex] == pControl);
  443. if (OnControlRemoving(pControl))
  444. return;
  445. m_arrControls.RemoveAt(pControl->m_nIndex);
  446. OnControlRemoved(pControl);
  447. pControl->SetParent(NULL);
  448. pControl->InternalRelease();
  449. }
  450. }
  451. }
  452. void CXTPControls::Remove(int nIndex)
  453. {
  454. CXTPControl* pControl = GetAt(nIndex);
  455. Remove(pControl);
  456. }
  457. CXTPControl* CXTPControls::SetControlType(int nIndex, XTPControlType type)
  458. {
  459. return SetControlType(GetAt(nIndex), type);
  460. }
  461. CXTPControl* CXTPControls::SetControlType(CXTPControl* pControl, XTPControlType type)
  462. {
  463. ASSERT(pControl->m_pControls == this);
  464. ASSERT(pControl);
  465. if (IsPopupControlType(pControl->GetType()) && IsPopupControlType(type))
  466. {
  467. pControl->m_controlType = type;
  468. return pControl;
  469. }
  470. CXTPControl* pNew = Add(type, 0, _T(""), pControl->GetIndex() + 1, FALSE);
  471. pNew->CXTPControl::Copy(pControl, FALSE);
  472. pNew->m_controlType = type;
  473. Remove(pControl);
  474. return pNew;
  475. }
  476. long CXTPControls::GetNext(long nIndex, int nDirection, BOOL bKeyboard, BOOL bSkipTemporary, BOOL bSkipCollapsed) const
  477. {
  478. ASSERT(nDirection == +1 || nDirection == -1);
  479. if (GetCount() == 0) return -1;
  480. long nNext = nIndex + nDirection;
  481. if (nDirection == -1 && nIndex == -1)
  482. {
  483. nNext = GetCount() - 1;
  484. }
  485. DWORD nSkipVisible = xtpHideScroll | (!bSkipCollapsed ? xtpHideExpand : 0);
  486. BOOL bCircle = FALSE;
  487. while (nNext != nIndex)
  488. {
  489. if (nNext >= GetCount())
  490. {
  491. if ((nIndex == -1 && nDirection == +1) || bCircle) return -1;
  492. nNext = 0;
  493. bCircle = TRUE;
  494. }
  495. if (nNext < 0)
  496. {
  497. if ((nIndex == -1 && nDirection == -1) || bCircle) return -1;
  498. nNext = GetCount() - 1;
  499. bCircle = TRUE;
  500. }
  501. if ((GetAt(nNext)->IsVisible(nSkipVisible)) && (!bKeyboard || !(GetAt(nNext)->m_dwFlags & xtpFlagSkipFocus)))
  502. {
  503. if (!bSkipTemporary || !GetAt(nNext)->m_bTemporary)
  504. return nNext;
  505. }
  506. nNext += nDirection;
  507. }
  508. return nNext;
  509. }
  510. CXTPControl* CXTPControls::HitTest(CPoint point) const
  511. {
  512. for (int i = 0; i < GetCount(); i++)
  513. {
  514. CXTPControl* pControl = GetAt(i);
  515. if (pControl->IsVisible())
  516. {
  517. if (pControl->m_rcControl.PtInRect(point))
  518. return pControl;
  519. }
  520. }
  521. return NULL;
  522. }
  523. struct CXTPControls::XTPBUTTONINFO  // struct for CalcDynamicSize ;
  524. {
  525. CRect rcControl;
  526. CRect rcRow;
  527. CSize szControl;
  528. BOOL bVisible;
  529. BOOL bWrap;
  530. BOOL bHide;
  531. BOOL bBeginGroup;
  532. XTPButtonStyle buttonStyle;
  533. CXTPControl* pControl;
  534. CSize szSeparators;
  535. int nWrapMargin;
  536. void EnsureButtonSize(CDC* pDC)
  537. {
  538. if (buttonStyle != pControl->GetStyle())
  539. {
  540. buttonStyle = pControl->GetStyle();
  541. szControl = pControl->GetSize(pDC);
  542. }
  543. }
  544. void Attach(CDC* pDC, CXTPControl* p)
  545. {
  546. pControl = p;
  547. bHide = bWrap = FALSE;
  548. rcRow.SetRectEmpty();
  549. szControl = pControl->GetSize(pDC);
  550. rcControl = pControl->GetRect();
  551. bBeginGroup = pControl->GetBeginGroup();
  552. bVisible = pControl->IsVisible(xtpHideWrap);
  553. buttonStyle = pControl->GetStyle();
  554. }
  555. void Detach()
  556. {
  557. pControl->SetHideWrap(bHide);
  558. pControl->SetRowRect(rcRow);
  559. if (!bHide)
  560. pControl->SetRect(rcControl);
  561. pControl->SetWrap(bWrap);
  562. }
  563. };
  564. CSize CXTPControls::_CalcSize(XTPBUTTONINFO* pData, BOOL bVert)
  565. {
  566. const CSize& szSeparators = pData->szSeparators;
  567. const int nWrapMargin = pData->nWrapMargin;
  568. CPoint cur(0, 0);
  569. CSize sizeResult(0, 0);
  570. int nRow = 0;
  571. BOOL bFirst = TRUE;
  572. for (int i = 0; i < GetCount(); i++)
  573. {
  574. XTPBUTTONINFO* pControl = &pData[i];
  575. if (!pControl->bVisible || pControl->bHide)
  576. continue;
  577. CSize szControl = pControl->szControl;
  578. if (bVert)
  579. {
  580. if (pControl->bBeginGroup && !pControl->bWrap && !bFirst)
  581. cur.y += szSeparators.cx;
  582. if (pControl->bWrap)
  583. {
  584. cur.x -= nRow + (pControl->bBeginGroup ? szSeparators.cy : nWrapMargin);
  585. nRow = cur.y = 0;
  586. }
  587. nRow = max(nRow, szControl.cx);
  588. pControl->rcControl.SetRect(cur.x - szControl.cx, cur.y, cur.x , cur.y + szControl.cy);
  589. sizeResult.cx = max(szControl.cx - cur.x, sizeResult.cx);
  590. sizeResult.cy = max(cur.y + szControl.cy, sizeResult.cy);
  591. cur.y += szControl.cy;
  592. }
  593. else
  594. {
  595. if (pControl->bBeginGroup && !pControl->bWrap && !bFirst)
  596. cur.x += szSeparators.cx;
  597. if (pControl->bWrap)
  598. {
  599. cur.y += nRow + (pControl->bBeginGroup ? szSeparators.cy : nWrapMargin);
  600. nRow = cur.x = 0;
  601. }
  602. nRow = max(nRow, szControl.cy);
  603. pControl->rcControl.SetRect(cur.x, cur.y, cur.x + szControl.cx, cur.y + szControl.cy);
  604. sizeResult.cx = max(cur.x + szControl.cx, sizeResult.cx);
  605. sizeResult.cy = max(cur.y + szControl.cy, sizeResult.cy);
  606. cur.x += szControl.cx;
  607. }
  608. bFirst = FALSE;
  609. }
  610. return sizeResult;
  611. }
  612. int CXTPControls::_WrapToolBar(XTPBUTTONINFO* pData, int nWidth, DWORD& dwMode)
  613. {
  614. int nResult = 0, x = 0;
  615. BOOL bVert = dwMode & LM_VERTDOCK;
  616. BOOL bFirst = TRUE;
  617. int nSeparator = bVert ? pData->szSeparators.cy : pData->szSeparators.cx;
  618. for (int i = 0; i < GetCount(); i++)
  619. {
  620. XTPBUTTONINFO* pControl = &pData[i];
  621. pControl->bHide = FALSE;
  622. pControl->bWrap = FALSE;
  623. if (!pControl->bVisible)
  624. continue;
  625. int dx = bVert ? pControl->szControl.cy : pControl->szControl.cx;
  626. if (pControl->bBeginGroup && !bFirst)
  627. dx += nSeparator;
  628. BOOL bWrap = (x + dx > nWidth) || ((dwMode & LM_POPUP) && pControl->bBeginGroup && !bFirst);
  629. BOOL bRowWrap = FALSE;
  630. if (pControl->pControl->GetFlags() & xtpFlagWrapRow)
  631. bRowWrap = TRUE;
  632. if (bRowWrap)
  633. {
  634. x = bVert ? pData[i].szControl.cy : pData[i].szControl.cx;
  635. pControl->bWrap = TRUE;
  636. nResult++;
  637. }
  638. else if (bWrap)
  639. {
  640. if (dwMode & LM_HIDEWRAP && !bFirst)
  641. {
  642. BOOL bWrapRowFound = FALSE;
  643. for (int j = i; j < GetCount(); j++)
  644. {
  645. if (pData[j].pControl->GetFlags() & xtpFlagWrapRow)
  646. {
  647. bWrapRowFound = TRUE;
  648. i = j - 1;
  649. break;
  650. }
  651. pData[j].bHide = TRUE;
  652. }
  653. dwMode |= LM_STRETCH;
  654. if (bWrapRowFound)
  655. continue;
  656. return nResult;
  657. }
  658. for (int j = i; j >= 0 && pData[j].bWrap == FALSE; j--)
  659. {
  660. // Find last separator
  661. if (pData[j].bBeginGroup && pData[j].bVisible)
  662. {
  663. i = j;
  664. break;
  665. }
  666. }
  667. x = bVert ? pData[i].szControl.cy : pData[i].szControl.cx;
  668. pData[i].bWrap = TRUE;
  669. if (!(dwMode & LM_HIDEWRAP)) dwMode |= LM_STRETCH;
  670. nResult++;
  671. }
  672. else
  673. x += dx;
  674. bFirst = FALSE;
  675. }
  676. return nResult + 1;
  677. }
  678. void  CXTPControls::_SizePopupToolBar(XTPBUTTONINFO* pData, DWORD dwMode)
  679. {
  680. CSize sizeMax, sizeMin, sizeMid;
  681. // Wrap ToolBar vertically
  682. _WrapToolBar(pData, 0, dwMode);
  683. sizeMin = _CalcSize(pData, FALSE);
  684. // Wrap ToolBar horizontally
  685. _WrapToolBar(pData, 32767, dwMode);
  686. sizeMax = _CalcSize(pData, FALSE);
  687. while (sizeMin.cx < sizeMax.cx)
  688. {
  689. sizeMid.cx = (sizeMin.cx + sizeMax.cx) / 2;
  690. _WrapToolBar(pData, sizeMid.cx, dwMode);
  691. sizeMid = _CalcSize(pData, FALSE);
  692. if (sizeMid.cy > sizeMid.cx)
  693. {
  694. if (sizeMin == sizeMid)
  695. return;
  696. sizeMin = sizeMid;
  697. }
  698. else if (sizeMid.cy < sizeMid.cx)
  699. sizeMax = sizeMid;
  700. else
  701. return;
  702. }
  703. }
  704. void  CXTPControls::_SizeFloatableBar(XTPBUTTONINFO* pData, int nLength, DWORD dwMode)
  705. {
  706. if (! (dwMode & LM_LENGTHY))
  707. {
  708. int nMin, nMax, nTarget, nCurrent, nMid;
  709. // Wrap ToolBar as specified
  710. nMax = nLength;
  711. nTarget = _WrapToolBar(pData, nMax, dwMode);
  712. // Wrap ToolBar vertically
  713. nMin = 0;
  714. nCurrent = _WrapToolBar(pData, nMin, dwMode);
  715. if (nCurrent != nTarget)
  716. {
  717. while (nMin < nMax)
  718. {
  719. nMid = (nMin + nMax) / 2;
  720. nCurrent = _WrapToolBar(pData, nMid, dwMode);
  721. if (nCurrent == nTarget)
  722. nMax = nMid;
  723. else
  724. {
  725. if (nMin == nMid)
  726. {
  727. _WrapToolBar(pData, nMax, dwMode);
  728. break;
  729. }
  730. nMin = nMid;
  731. }
  732. }
  733. }
  734. CSize size = _CalcSize(pData, FALSE);
  735. _WrapToolBar(pData, size.cx, dwMode);
  736. }
  737. else
  738. {
  739. CSize sizeMax, sizeMin, sizeMid;
  740. // Wrap ToolBar vertically
  741. _WrapToolBar(pData, 0, dwMode);
  742. sizeMin = _CalcSize(pData, FALSE);
  743. // Wrap ToolBar horizontally
  744. _WrapToolBar(pData, 32767, dwMode);
  745. sizeMax = _CalcSize(pData, FALSE);
  746. while (sizeMin.cx < sizeMax.cx)
  747. {
  748. sizeMid.cx = (sizeMin.cx + sizeMax.cx) / 2;
  749. _WrapToolBar(pData, sizeMid.cx, dwMode);
  750. sizeMid = _CalcSize(pData, FALSE);
  751. if (nLength < sizeMid.cy)
  752. {
  753. if (sizeMin == sizeMid)
  754. {
  755. _WrapToolBar(pData, sizeMax.cx, dwMode);
  756. return;
  757. }
  758. sizeMin = sizeMid;
  759. }
  760. else if (nLength > sizeMid.cy)
  761. sizeMax = sizeMid;
  762. else
  763. return;
  764. }
  765. }
  766. }
  767. void CXTPControls::_CenterControlsInRow(XTPBUTTONINFO* pData, int nFirst, int nLast, int nHeight, BOOL bVert, CSize sizeResult, CRect rcBorder)
  768. {
  769. for (int i = nFirst; i < nLast; i++)
  770. {
  771. XTPBUTTONINFO* pControl = &pData[i];
  772. CRect rc = pControl->rcControl;
  773. if (bVert)
  774. {
  775. pControl->rcRow.SetRect(rc.right - nHeight, rcBorder.top, rc.right, sizeResult.cy + rcBorder.top);
  776. if (!(m_pParent->GetFlags() & xtpFlagSmartLayout)) pControl->rcControl.OffsetRect(-(nHeight - rc.Width())/2, 0);
  777. }
  778. else
  779. {
  780. pControl->rcRow.SetRect(rcBorder.left, rc.top, sizeResult.cx + rcBorder.left, rc.top + nHeight);
  781. if (!(m_pParent->GetFlags() & xtpFlagSmartLayout)) pControl->rcControl.OffsetRect(0, (nHeight - rc.Height())/2);
  782. }
  783. }
  784. }
  785. void CXTPControls::_AdjustBorders(XTPBUTTONINFO* pData, CSize& sizeResult, DWORD dwMode, CRect rcBorder)
  786. {
  787. if (dwMode & LM_COMMIT)
  788. {
  789. BOOL bVert = dwMode & LM_VERTDOCK;
  790. int nFirstInRow = 0;
  791. int nHeight = 0;
  792. int nBarHeight = 0;
  793. for (int i = 0; i < GetCount(); i++)
  794. {
  795. XTPBUTTONINFO* pControl = &pData[i];
  796. if (!pControl->bVisible || pControl->bHide)
  797. continue;
  798. pControl->rcControl.OffsetRect(rcBorder.left, rcBorder.top);
  799. if (bVert) pControl->rcControl.OffsetRect(sizeResult.cx, 0);
  800. if (pControl->bWrap)
  801. {
  802. _CenterControlsInRow(pData, nFirstInRow, i, nHeight, bVert, sizeResult, rcBorder);
  803. nFirstInRow = i;
  804. nHeight = 0;
  805. }
  806. nBarHeight = bVert ? sizeResult.cx : sizeResult.cy;
  807. nHeight = max(nHeight, bVert ? pControl->rcControl.Width() : pControl->rcControl.Height());
  808. }
  809. _CenterControlsInRow(pData, nFirstInRow, GetCount(), nFirstInRow == 0 ? nBarHeight : nHeight, bVert, sizeResult, rcBorder);
  810. }
  811. sizeResult += CSize(rcBorder.left + rcBorder.right, rcBorder.top + rcBorder.bottom);
  812. }
  813. void CXTPControls::_MoveRightAlligned(XTPBUTTONINFO* pData, CSize sizeResult, CRect rcBorder, DWORD dwMode)
  814. {
  815. BOOL bVert = dwMode & LM_VERTDOCK;
  816. int nRight = bVert ? sizeResult.cy - rcBorder.bottom : sizeResult.cx - rcBorder.right;
  817. int i;
  818. for (i = GetCount() - 1; i >= 0; i--)
  819. {
  820. XTPBUTTONINFO* pControl = &pData[i];
  821. if (!pControl->bVisible || pControl->bHide)
  822. continue;
  823. if (!(GetAt(i)->m_dwFlags & xtpFlagRightAlign))
  824. break;
  825. CRect rc = pControl->rcControl;
  826. if (!bVert)
  827. {
  828. if (nRight - rc.Width() < rcBorder.right)
  829. break;
  830. pControl->rcControl.SetRect(nRight - rc.Width(), rc.top, nRight, rc.bottom);
  831. nRight -= rc.Width();
  832. }
  833. else
  834. {
  835. if (nRight - rc.Height() < rcBorder.top)
  836. break;
  837. pControl->rcControl.SetRect(rc.left, nRight - rc.Height(), rc.right, nRight);
  838. nRight -= rc.Height();
  839. }
  840. if (pControl->bWrap)
  841. break;
  842. }
  843. int nStretchAvail = -1;
  844. int nStretchedCount = 0;
  845. BOOL bSkipRightAligned = FALSE;
  846. nRight = bVert ? sizeResult.cy - rcBorder.bottom : sizeResult.cx - rcBorder.right;
  847. int nLastInRow = GetCount() - 1;
  848. for (i = GetCount() - 1; i >= 0; i--)
  849. {
  850. XTPBUTTONINFO* pControl = &pData[i];
  851. if (pControl->bVisible && !pControl->bHide)
  852. {
  853. if (!bSkipRightAligned && (GetAt(i)->m_dwFlags & xtpFlagRightAlign))
  854. {
  855. nRight = pControl->rcControl.left;
  856. nLastInRow = i - 1;
  857. }
  858. else if (GetAt(i)->m_dwFlags & xtpFlagControlStretched)
  859. {
  860. nStretchedCount++;
  861. bSkipRightAligned = TRUE;
  862. }
  863. if ((nStretchAvail == -1) && (nLastInRow >= i))
  864. {
  865. nStretchAvail = nRight - (!bVert ? pControl->rcControl.right : pControl->rcControl.bottom);
  866. }
  867. }
  868. if ((pControl->bVisible && !pControl->bHide && pControl->bWrap) || (i == 0))
  869. {
  870. if (nStretchedCount > 0 && nStretchAvail > 0)
  871. {
  872. int nOffset = 0;
  873. for (int j = i; j <= nLastInRow; j++)
  874. {
  875. pControl = &pData[j];
  876. if (!pControl->bVisible || pControl->bHide)
  877. continue;
  878. CRect rc = pControl->rcControl;
  879. if (!bVert)
  880. pControl->rcControl.SetRect(nOffset + rc.left, rc.top, nOffset + rc.right, rc.bottom);
  881. else
  882. pControl->rcControl.SetRect(rc.left, nOffset + rc.top, rc.right, nOffset + rc.bottom);
  883. if ((GetAt(j)->m_dwFlags & xtpFlagControlStretched) && (nStretchedCount > 0))
  884. {
  885. int nStretchedOffset = nStretchAvail / nStretchedCount;
  886. if (!bVert)
  887. pControl->rcControl.right += nStretchedOffset;
  888. else
  889. pControl->rcControl.bottom += nStretchedOffset;
  890. nStretchAvail -= nStretchedOffset;
  891. nStretchedCount--;
  892. nOffset += nStretchedOffset;
  893. }
  894. }
  895. }
  896. nRight = bVert ? sizeResult.cy - rcBorder.bottom : sizeResult.cx - rcBorder.right;
  897. bSkipRightAligned = TRUE;
  898. nLastInRow = i - 1;
  899. nStretchAvail = -1;
  900. nStretchedCount = 0;
  901. }
  902. }
  903. }
  904. int CXTPControls::GetVisibleCount(BOOL bIgnoreWraps) const
  905. {
  906. DWORD nFlags = bIgnoreWraps ? 0 : xtpHideWrap;
  907. int nCount = 0;
  908. for (int i = 0; i < GetCount(); i++)
  909. {
  910. if (GetAt(i)->IsVisible(nFlags)) nCount++;
  911. }
  912. return nCount;
  913. }
  914. CXTPControl* CXTPControls::GetVisibleAt(int nIndex, BOOL bIgnoreWraps) const
  915. {
  916. DWORD nFlags = bIgnoreWraps ? 0 : xtpHideWrap;
  917. for (int i = 0; i < GetCount(); i++)
  918. {
  919. if (GetAt(i)->IsVisible(nFlags))
  920. {
  921. if (nIndex == 0)
  922. return GetAt(i);
  923. nIndex--;
  924. }
  925. }
  926. return NULL;
  927. }
  928. CSize CXTPControls::_ReduceSmartLayoutToolBar(CDC* pDC, XTPBUTTONINFO* pData, int nWidth, DWORD& dwMode)
  929. {
  930. CSize sizeResult(0, 0);
  931. BOOL bReduced = FALSE;
  932. BOOL bVert = dwMode & LM_VERTDOCK;
  933. do
  934. {
  935. bReduced = FALSE;
  936. if (!bReduced)
  937. {
  938. for (int i = GetCount() - 1; i >= 2; i--)
  939. {
  940. XTPBUTTONINFO* pControl = &pData[i];
  941. if (!pControl->bVisible || pControl->bBeginGroup)
  942. continue;
  943. int nItems = 0;
  944. int nButtons[3] = {0, 0, 0};
  945. for (int j = i; j  >= 0; j--)
  946. {
  947. pControl = &pData[j];
  948. if (!pControl->bVisible)
  949. continue;
  950. if ((nItems == 2 || !pControl->bBeginGroup) && GetAt(j)->m_buttonStyle == xtpButtonIconAndCaptionBelow)
  951. {
  952. nButtons[nItems] = j;
  953. nItems += 1;
  954. }
  955. else
  956. {
  957. break;
  958. }
  959. if (nItems == 3)
  960. break;
  961. }
  962. if (nItems == 3)
  963. {
  964. GetAt(nButtons[0])->m_buttonStyle = xtpButtonIconAndCaption;
  965. GetAt(nButtons[1])->m_buttonStyle = xtpButtonIconAndCaption;
  966. GetAt(nButtons[2])->m_buttonStyle = xtpButtonIconAndCaption;
  967. bReduced = TRUE;
  968. break;
  969. }
  970. }
  971. }
  972. if (!bReduced)
  973. {
  974. for (int i = GetCount() - 1; i >= 2; i--)
  975. {
  976. XTPBUTTONINFO* pControl = &pData[i];
  977. if (!pControl->bVisible || pControl->bBeginGroup)
  978. continue;
  979. int nItems = 0;
  980. int nButtons[3] = {0, 0, 0};
  981. BOOL bFound = FALSE;
  982. int j;
  983. for (j = i; j  >= 0; j--)
  984. {
  985. pControl = &pData[j];
  986. if (!pControl->bVisible)
  987. continue;
  988. if ((nItems == 2 || !pControl->bBeginGroup))
  989. {
  990. nButtons[nItems] = j;
  991. nItems += 1;
  992. bFound = bFound || GetAt(j)->m_buttonStyle == xtpButtonIconAndCaptionBelow;
  993. }
  994. else
  995. {
  996. break;
  997. }
  998. if (nItems == 3)
  999. break;
  1000. }
  1001. i = j;
  1002. if (nItems == 3 && bFound)
  1003. {
  1004. GetAt(nButtons[0])->m_buttonStyle = xtpButtonIconAndCaption;
  1005. GetAt(nButtons[1])->m_buttonStyle = xtpButtonIconAndCaption;
  1006. GetAt(nButtons[2])->m_buttonStyle = xtpButtonIconAndCaption;
  1007. bReduced = TRUE;
  1008. break;
  1009. }
  1010. }
  1011. }
  1012. if (!bReduced)
  1013. {
  1014. for (int i = GetCount() - 1; i >= 2; i--)
  1015. {
  1016. XTPBUTTONINFO* pControl = &pData[i];
  1017. if (!pControl->bVisible || pControl->bBeginGroup)
  1018. continue;
  1019. int nItems = 0;
  1020. int nButtons[3] = {0, 0, 0};
  1021. int nLeft = 0;
  1022. for (int j = i; j  >= 0; j--)
  1023. {
  1024. pControl = &pData[j];
  1025. if (!pControl->bVisible)
  1026. continue;
  1027. int nOffset = (bVert ? pControl->rcControl.top : pControl->rcControl.left);
  1028. if (nItems != 0 && (nOffset != nLeft))
  1029. break;
  1030. if ((nItems == 2 || !pControl->bBeginGroup) && GetAt(j)->m_buttonStyle == xtpButtonIconAndCaption)
  1031. {
  1032. nButtons[nItems] = j;
  1033. nItems += 1;
  1034. nLeft = nOffset;
  1035. }
  1036. else
  1037. {
  1038. break;
  1039. }
  1040. if (nItems == 3)
  1041. break;
  1042. }
  1043. if (nItems == 3)
  1044. {
  1045. GetAt(nButtons[0])->m_buttonStyle = xtpButtonIcon;
  1046. GetAt(nButtons[1])->m_buttonStyle = xtpButtonIcon;
  1047. GetAt(nButtons[2])->m_buttonStyle = xtpButtonIcon;
  1048. bReduced = TRUE;
  1049. break;
  1050. }
  1051. }
  1052. }
  1053. sizeResult = _CalcSmartLayoutToolBar(pDC, pData, dwMode);
  1054. if ((bVert ? sizeResult.cy : sizeResult.cx) < nWidth)
  1055. return sizeResult;
  1056. }
  1057. while (bReduced);
  1058. if (dwMode & LM_HIDEWRAP)
  1059. {
  1060. BOOL bFirst = TRUE;
  1061. for (int i = 0; i < GetCount(); i++)
  1062. {
  1063. XTPBUTTONINFO* pControl = &pData[i];
  1064. if (!pControl->bVisible)
  1065. continue;
  1066. if (!bFirst && ((bVert ? pControl->rcControl.bottom : pControl->rcControl.right) > nWidth))
  1067. {
  1068. GetAt(i)->m_buttonStyle = xtpButtonIcon;
  1069. pControl->bHide = TRUE;
  1070. }
  1071. bFirst = FALSE;
  1072. }
  1073. return _CalcSmartLayoutToolBar(pDC, pData, dwMode);
  1074. }
  1075. return sizeResult;
  1076. }
  1077. CSize CXTPControls::_CalcSmartLayoutToolBar(CDC* pDC, XTPBUTTONINFO* pData, DWORD& dwMode)
  1078. {
  1079. BOOL bFirst = TRUE;
  1080. BOOL bVert = dwMode & LM_VERTDOCK;
  1081. CSize szLargeIcon = m_pParent->GetLargeIconSize(TRUE);
  1082. int nResultHeight = szLargeIcon.cy + 7 + m_pParent->GetPaintManager()->GetSplitDropDownHeight();
  1083. CSize sizeResult(0, nResultHeight);
  1084. int dyPrev = 0, dxPrev = 0, x = 0;
  1085. for (int i = 0; i < GetCount(); i++)
  1086. {
  1087. XTPBUTTONINFO* pControl = &pData[i];
  1088. if (!pControl->bVisible || pControl->bHide)
  1089. continue;
  1090. BOOL bFullRow = GetAt(i)->m_buttonStyle == xtpButtonIconAndCaptionBelow;
  1091. pControl->EnsureButtonSize(pDC);
  1092. CSize szControl = pControl->szControl;
  1093. int dx = bVert ? szControl.cy : szControl.cx;
  1094. int dy = !bVert ? szControl.cy : szControl.cx;
  1095. BOOL bBeginGroup = pControl->bBeginGroup && !bFirst;
  1096. if (bBeginGroup)
  1097. x += 6;
  1098. if (!bFirst && !bBeginGroup && !bFullRow && dyPrev + dy <= nResultHeight)
  1099. {
  1100. if (bVert)
  1101. pControl->rcControl.SetRect(-dyPrev - dy, x, -dyPrev,  x + dx);
  1102. else
  1103. pControl->rcControl.SetRect(x, dyPrev, x + dx, dyPrev + dy);
  1104. dxPrev = max(dxPrev, dx);
  1105. }
  1106. else
  1107. {
  1108. x += dxPrev;
  1109. if (bVert)
  1110. pControl->rcControl.SetRect(-dy, x, 0, x + dx);
  1111. else
  1112. pControl->rcControl.SetRect(x, 0, x + dx, dy);
  1113. sizeResult.cy = max(dy, sizeResult.cy);
  1114. dxPrev = dx;
  1115. }
  1116. sizeResult.cx = max(x + dx, sizeResult.cx);
  1117. bFirst = FALSE;
  1118. dyPrev = bVert ? -pControl->rcControl.left : pControl->rcControl.bottom;
  1119. }
  1120. return bVert ? CSize(sizeResult.cy, sizeResult.cx) : sizeResult;
  1121. }
  1122. CSize CXTPControls::_WrapSmartLayoutToolBar(CDC* pDC, XTPBUTTONINFO* pData, int nWidth, DWORD& dwMode)
  1123. {
  1124. BOOL bVert = dwMode & LM_VERTDOCK;
  1125. CSize szLargeIcon = m_pParent->GetLargeIconSize(FALSE);
  1126. for (int i = 0; i < GetCount(); i++)
  1127. {
  1128. XTPBUTTONINFO* pControl = &pData[i];
  1129. if (!pControl->bVisible)
  1130. continue;
  1131. BOOL bDrawImage = GetAt(i)->GetIconId() > 0 ?
  1132. GetAt(i)->GetImageManager()->IsPrimaryImageExists(GetAt(i)->GetIconId(), szLargeIcon.cx) != NULL: FALSE;
  1133. pControl->bHide = FALSE;
  1134. pControl->bWrap = FALSE;
  1135. GetAt(i)->m_buttonStyle = bDrawImage? xtpButtonIconAndCaptionBelow : xtpButtonIconAndCaption;
  1136. }
  1137. CSize sizeResult = _CalcSmartLayoutToolBar(pDC, pData, dwMode);
  1138. if ((bVert ? sizeResult.cy : sizeResult.cx) > nWidth)
  1139. {
  1140. sizeResult = _ReduceSmartLayoutToolBar(pDC, pData, nWidth, dwMode);
  1141. dwMode |= LM_STRETCH;
  1142. }
  1143. return sizeResult;
  1144. }
  1145. CSize CXTPControls::CalcDynamicSize(CDC* pDC, int nLength, DWORD dwMode, const CRect& rcBorder, int nWidth)
  1146. {
  1147. CSize sizeResult(0, 0);
  1148. CSize szSeparators(m_pParent->GetPaintManager()->DrawCommandBarSeparator(pDC, m_pParent, NULL, FALSE));
  1149. int i;
  1150. for (i = GetCount() - 1; i >= 0; i--)
  1151. {
  1152. GetAt(i)->OnCalcDynamicSize(dwMode);
  1153. }
  1154. if (GetVisibleCount() > 0)
  1155. {
  1156. XTPBUTTONINFO* pData = new XTPBUTTONINFO[GetCount()];
  1157. for (int j = 0; j < GetCount(); j++)
  1158. pData[j].Attach(pDC, GetAt(j));
  1159. pData->szSeparators = szSeparators;
  1160. pData->nWrapMargin = m_pParent->m_nWrapMargin;
  1161. if (dwMode & LM_MRUWIDTH)
  1162. {
  1163. nLength = m_pParent->m_nMRUWidth;
  1164. }
  1165. if ((m_pParent->GetFlags() & xtpFlagSmartLayout))
  1166. {
  1167. if (dwMode & LM_VERTDOCK)
  1168. {
  1169. sizeResult = _WrapSmartLayoutToolBar(pDC, pData, nLength - rcBorder.top - rcBorder.bottom, dwMode);
  1170. }
  1171. else
  1172. {
  1173. sizeResult = _WrapSmartLayoutToolBar(pDC, pData, nLength - rcBorder.right - rcBorder.left, dwMode);
  1174. }
  1175. }
  1176. else
  1177. {
  1178. if (dwMode & LM_POPUP)
  1179. {
  1180. _WrapToolBar(pData, m_pParent->m_nMRUWidth, dwMode);
  1181. CSize sz = _CalcSize(pData, FALSE);
  1182. if ((sz.cy > sz.cx * 3) && (m_pParent->m_nMRUWidth <= 0))
  1183. {
  1184. _SizePopupToolBar(pData, dwMode);
  1185. }
  1186. else
  1187. {
  1188. _WrapToolBar(pData, sz.cx , dwMode);
  1189. }
  1190. }
  1191. else if (dwMode & LM_HORZDOCK)
  1192. {
  1193. _WrapToolBar(pData, nLength - rcBorder.right - rcBorder.left, dwMode);
  1194. }
  1195. else if (dwMode & LM_VERTDOCK)
  1196. {
  1197. _WrapToolBar(pData, nLength - rcBorder.top - rcBorder.bottom, dwMode);
  1198. }
  1199. else
  1200. {
  1201. _SizeFloatableBar(pData, nLength - ((dwMode & LM_LENGTHY) ? rcBorder.top + rcBorder.bottom : rcBorder.right + rcBorder.left), dwMode);
  1202. }
  1203. sizeResult = _CalcSize(pData, dwMode & LM_VERTDOCK);
  1204. }
  1205. if (nWidth > 0)
  1206. {
  1207. if (dwMode & LM_HORZDOCK)
  1208. sizeResult.cy = max(nWidth - rcBorder.top - rcBorder.bottom, sizeResult.cy);
  1209. else
  1210. sizeResult.cx = max(nWidth - rcBorder.right - rcBorder.left, sizeResult.cx);
  1211. }
  1212. if (dwMode & LM_STRETCH)
  1213. {
  1214. if (dwMode & LM_VERTDOCK)
  1215. sizeResult.cy = max(nLength - rcBorder.top - rcBorder.bottom, sizeResult.cy);
  1216. else
  1217. sizeResult.cx = max(nLength - rcBorder.right - rcBorder.left, sizeResult.cx);
  1218. }
  1219. _AdjustBorders(pData, sizeResult, dwMode, rcBorder);
  1220. if (dwMode & LM_COMMIT)
  1221. {
  1222. if (!(m_pParent->GetFlags() & xtpFlagSmartLayout))
  1223. _MoveRightAlligned(pData, sizeResult, rcBorder, dwMode);
  1224. for (i = 0; i < GetCount(); i++) pData[i].Detach();
  1225. }
  1226. delete[] pData;
  1227. }
  1228. else
  1229. {
  1230. sizeResult = CSize (23, 22) + CSize(rcBorder.left + rcBorder.right, rcBorder.top + rcBorder.bottom);
  1231. if (dwMode & LM_HORZDOCK) sizeResult.cy = max(nWidth, sizeResult.cy);
  1232. else sizeResult.cx = max(nWidth, sizeResult.cx);
  1233. }
  1234. return sizeResult;
  1235. }
  1236. void CXTPControls::_MakeSameWidth(int nStart, int nLast, int nWidth)
  1237. {
  1238. for (int i = nStart; i < nLast; i++)
  1239. {
  1240. CXTPControl* pControl = GetAt(i);
  1241. if (!pControl || pControl->GetParent() != m_pParent || !pControl->IsVisible())
  1242. continue;
  1243. CRect rc = pControl->GetRect();
  1244. pControl->SetRect(CRect(rc.left, rc.top, rc.left + nWidth, rc.bottom));
  1245. }
  1246. }
  1247. CSize CXTPControls::CalcPopupSize(CDC* pDC, int nLength, int nMRUWidth, const CRect& rcBorder)
  1248. {
  1249. RECT rcWork;
  1250. SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcWork, 0);
  1251. int i;
  1252. CSize szSeparators(m_pParent->GetPaintManager()->DrawCommandBarSeparator(NULL, m_pParent, NULL, FALSE));
  1253. CRect rcControl;
  1254. int yPos = rcBorder.top, nWidthColumn = 0, xPos = rcBorder.left, nFirstInColumn = 0, nHeight = 0;
  1255. m_pParent->m_bMultiLine = FALSE;
  1256. int nCount = GetCount();
  1257. BOOL bFirst = TRUE;
  1258. for (i = 0; i < nCount; i++)
  1259. {
  1260. CXTPControl* pControl = GetAt(i);
  1261. if (!pControl || pControl->GetParent() != m_pParent)
  1262. continue;
  1263. pControl->SetHideFlag(xtpHideScroll, FALSE);
  1264. if (!pControl->IsVisible())
  1265. continue;
  1266. CXTPFontDC fontControl(pDC, m_pParent->GetPaintManager()->GetCommandBarFont(m_pParent, pControl->IsItemDefault()));
  1267. CSize szControl = pControl->GetSize(pDC);
  1268. pControl->SetWrap(FALSE);
  1269. if ((pControl->GetFlags() & xtpFlagWrapRow && !bFirst) || (nLength > 0 && szControl.cy + yPos > nLength - rcBorder.bottom))
  1270. {
  1271. _MakeSameWidth(nFirstInColumn, i, nWidthColumn);
  1272. nHeight = max(yPos - rcBorder.top, nHeight);
  1273. yPos = rcBorder.top;
  1274. xPos += nWidthColumn + (pControl->GetBeginGroup() ? szSeparators.cx : 0);
  1275. pControl->SetWrap(TRUE);
  1276. nFirstInColumn = i;
  1277. nWidthColumn = 0;
  1278. m_pParent->m_bMultiLine = TRUE;
  1279. }
  1280. else if (pControl->GetBeginGroup() && !bFirst)
  1281. {
  1282. yPos += szSeparators.cy;
  1283. }
  1284. bFirst = FALSE;
  1285. if (!GetParent()->IsResizable() && CXTPPopupBar::m_dMaxWidthDivisor > 0 && szControl.cx > (CXTPPopupBar::m_dMaxWidthDivisor * rcWork.right))
  1286. szControl.cx = int(CXTPPopupBar::m_dMaxWidthDivisor * rcWork.right);
  1287. pControl->SetRect(CRect(xPos, yPos, xPos + szControl.cx, yPos + szControl.cy));
  1288. yPos += szControl.cy;
  1289. if (nWidthColumn < szControl.cx) nWidthColumn = szControl.cx;
  1290. }
  1291. if (nMRUWidth > 0 && nMRUWidth < 30000)
  1292. nWidthColumn = nMRUWidth - rcBorder.left - rcBorder.right;
  1293. _MakeSameWidth(nFirstInColumn, GetCount(), nWidthColumn);
  1294. int nWidth = xPos - rcBorder.left + nWidthColumn;
  1295. nHeight = max(yPos - rcBorder.top, nHeight);
  1296. for (i = 0; i < nCount; i++)
  1297. {
  1298. CXTPControl* pControl = GetAt(i);
  1299. pControl->SetRowRect(CRect(pControl->GetRect().left, rcBorder.top, pControl->GetRect().right, rcBorder.top + nHeight));
  1300. }
  1301. nWidth = max(24, nWidth);
  1302. nHeight = (nHeight == 0 ? 22 : nHeight);
  1303. return CSize(nWidth + rcBorder.left + rcBorder.right, nHeight + rcBorder.bottom + rcBorder.top);
  1304. }
  1305. void CXTPControls::Copy(CXTPControls* pControls, BOOL bRecursive)
  1306. {
  1307. RemoveAll();
  1308. for (int i = 0; i < pControls->GetCount(); i++)
  1309. {
  1310. if (!pControls->GetAt(i)->m_bTemporary)
  1311. AddClone(pControls->GetAt(i), -1, bRecursive);
  1312. }
  1313. if (pControls->m_pOriginalControls)
  1314. {
  1315. SetOriginalControls((CXTPOriginalControls*)pControls->m_pOriginalControls->Duplicate(bRecursive));
  1316. }
  1317. else
  1318. {
  1319. SetOriginalControls(NULL);
  1320. }
  1321. }
  1322. CXTPControls* CXTPControls::Duplicate(BOOL bRecursive)
  1323. {
  1324. CXTPControls* pControls = (CXTPControls*)GetRuntimeClass()->CreateObject();
  1325. for (int i = 0; i < GetCount(); i++)
  1326. {
  1327. if (!GetAt(i)->m_bTemporary)
  1328. pControls->AddClone(GetAt(i), -1, bRecursive);
  1329. }
  1330. if (m_pOriginalControls)
  1331. {
  1332. pControls->SetOriginalControls((CXTPOriginalControls*)m_pOriginalControls->Duplicate(bRecursive));
  1333. }
  1334. return pControls;
  1335. }
  1336. void CXTPControls::ClearOriginalControls()
  1337. {
  1338. CMDTARGET_RELEASE(m_pOriginalControls);
  1339. }
  1340. void CXTPControls::CreateOriginalControls()
  1341. {
  1342. ClearOriginalControls();
  1343. CXTPOriginalControls* pControls = new CXTPOriginalControls();
  1344. for (int i = 0; i < GetCount(); i++)
  1345. {
  1346. if (!GetAt(i)->m_bTemporary)
  1347. pControls->AddClone(GetAt(i), -1, TRUE);
  1348. }
  1349. SetOriginalControls(pControls);
  1350. }
  1351. void CXTPControls::SetOriginalControls(CXTPOriginalControls* pControls)
  1352. {
  1353. ClearOriginalControls();
  1354. m_pOriginalControls = pControls;
  1355. }
  1356. void CXTPControls::MoveBefore(CXTPControl* pControl, int nBefore)
  1357. {
  1358. ASSERT(pControl);
  1359. if (!pControl)
  1360. return;
  1361. ASSERT(pControl->GetControls() == this);
  1362. if (pControl->GetIndex() < nBefore) nBefore--;
  1363. m_arrControls.RemoveAt(pControl->GetIndex());
  1364. m_arrControls.InsertAt(nBefore, pControl);
  1365. RefreshIndexes();
  1366. }
  1367. BOOL CXTPControls::Compare(const CXTPControls* pOther)
  1368. {
  1369. int j = 0, i = 0;
  1370. while (i < GetCount() || j < pOther->GetCount())
  1371. {
  1372. while (i < GetCount() && GetAt(i)->m_bTemporary)
  1373. {
  1374. i++;
  1375. }
  1376. while (j < pOther->GetCount() && pOther->GetAt(j)->m_bTemporary)
  1377. {
  1378. j++;
  1379. }
  1380. if (i < GetCount() && j < pOther->GetCount())
  1381. {
  1382. if (!GetAt(i)->Compare(pOther->GetAt(j)))
  1383. return FALSE;
  1384. }
  1385. else
  1386. {
  1387. if (i < GetCount() || j < pOther->GetCount())
  1388. return FALSE;
  1389. }
  1390. i++;
  1391. j++;
  1392. }
  1393. return TRUE;
  1394. }
  1395. BOOL CXTPControls::IsChanged() const
  1396. {
  1397. if (!m_pOriginalControls)
  1398. return TRUE;
  1399. return !m_pOriginalControls->Compare(this);
  1400. }
  1401. int CXTPControls::CommandToIndex(int nIDFind) const
  1402. {
  1403. for (int iIndex = 0; iIndex < m_arrControls.GetSize(); ++iIndex)
  1404. {
  1405. CXTPControl* pControl = m_arrControls.GetAt(iIndex);
  1406. if (pControl && pControl->GetID() == nIDFind)
  1407. return iIndex;
  1408. }
  1409. return -1;
  1410. }