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

对话框与窗口

开发平台:

Visual C++

  1. // XTPDockBar.cpp : implementation of the CXTPDockBar 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 <afxpriv.h>
  22. #include "Common/XTPDrawHelpers.h"
  23. #include "XTPDockBar.h"
  24. #include "XTPToolBar.h"
  25. #include "XTPCommandBars.h"
  26. #include "XTPDockContext.h"
  27. #include "XTPPaintManager.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. // CXTPDockBar
  34. IMPLEMENT_DYNCREATE(CXTPDockBar, CWnd)
  35. CXTPDockBar::CXTPDockBar()
  36. {
  37. m_arrBars.Add(NULL);
  38. m_dwStyle = 0;
  39. m_pCommandBars = NULL;
  40. CXTPDrawHelpers::RegisterWndClass(0, _T("XTPDockBar"), 0);
  41. }
  42. CXTPDockBar::~CXTPDockBar()
  43. {
  44. }
  45. BEGIN_MESSAGE_MAP(CXTPDockBar, CWnd)
  46. ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
  47. ON_WM_PAINT()
  48. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  49. ON_WM_ERASEBKGND()
  50. ON_WM_RBUTTONDOWN()
  51. ON_WM_NCHITTEST_EX()
  52. END_MESSAGE_MAP()
  53. // CXTPDockBar message handlers
  54. LRESULT CXTPDockBar::OnNcHitTest(CPoint point)
  55. {
  56. if (GetPosition() == xtpBarTop && m_pCommandBars->GetMenuBar() != NULL && m_pCommandBars->GetMenuBar()->IsRibbonBar() &&
  57. FindBar(m_pCommandBars->GetMenuBar()) != -1)
  58. {
  59. return HTTRANSPARENT;
  60. }
  61. return (LRESULT)CWnd::OnNcHitTest(point);
  62. }
  63. BOOL CXTPDockBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
  64. {
  65. ASSERT(pParentWnd != NULL);
  66. // save the xtp
  67. m_dwStyle = (dwStyle & CBRS_ALL);
  68. XTPBarPosition barPosition = GetPosition();
  69. CString strWindowName = barPosition == xtpBarTop ? _T("xtpBarTop") :
  70. barPosition == xtpBarLeft ? _T("xtpBarLeft") :
  71. barPosition == xtpBarBottom ? _T("xtpBarBottom") : _T("xtpBarRight");
  72. return CWnd::Create(_T("XTPDockBar"), strWindowName, dwStyle, CXTPEmptyRect(), pParentWnd, nID);
  73. }
  74. BOOL CXTPDockBar::PreCreateWindow(CREATESTRUCT& cs)
  75. {
  76. if (!CWnd::PreCreateWindow(cs))
  77. return FALSE;
  78. // force clipsliblings (otherwise will cause repaint problems)
  79. cs.style |= WS_CLIPSIBLINGS;
  80. return TRUE;
  81. }
  82. CSize CXTPDockBar::CalcFixedLayout(BOOL /*bStretch*/, BOOL /*bHorz*/, AFX_SIZEPARENTPARAMS* /*lpLayout*/)
  83. {
  84. return 0;
  85. }
  86. struct CXTPDockBar::DOCK_INFO
  87. {
  88. DOCK_INFO(CXTPToolBar* p = 0, CRect rc = 0, int n = 0)
  89. {
  90. pBar = p;
  91. rcMRUPos = rcBar = rc;
  92. nIndex = n;
  93. nMinWidth = 0;
  94. nTotlaMinWidth = 0;
  95. }
  96. CXTPToolBar* pBar;
  97. CRect rcBar;
  98. CRect rcMRUPos;
  99. int nIndex;
  100. int nMinWidth;
  101. int nTotlaMinWidth;
  102. };
  103. class CXTPDockBar::CDockInfoArray : public CArray<DOCK_INFO, DOCK_INFO&>
  104. {
  105. public:
  106. void Sort()
  107. {
  108. qsort(GetData(), GetSize(), sizeof(DOCK_INFO), CompareFunc);
  109. }
  110. static int _cdecl CompareFunc(const void* elem1, const void* elem2)
  111. {
  112. return ((DOCK_INFO*)elem1)->rcBar.left < ((DOCK_INFO*)elem2)->rcBar.left ? -1 : 1;
  113. }
  114. void _swap(LONG& A, LONG& B)
  115. {
  116. int C = B;
  117. B = A;
  118. A = C;
  119. }
  120. void InvertRects()
  121. {
  122. for (int nPos = 0; nPos < GetSize(); nPos++)
  123. {
  124. CRect& rect = ElementAt(nPos).rcBar;
  125. _swap(rect.left, rect.top);
  126. _swap(rect.right, rect.bottom);
  127. }
  128. }
  129. };
  130. int CXTPDockBar::_GetMode(BOOL bHorz, CXTPToolBar* pBar)
  131. {
  132. DWORD dwMode = bHorz ? LM_HORZ | LM_HORZDOCK : LM_VERTDOCK;
  133. if (pBar->GetFlags() & xtpFlagStretched) dwMode |= LM_STRETCH;
  134. if ((!m_pCommandBars->IsCustomizeMode() || m_pCommandBars->IsQuickCustomizeMode()) && pBar->GetFlags() & xtpFlagHideWrap)
  135. return dwMode | LM_HIDEWRAP;
  136. return dwMode;
  137. }
  138. int CXTPDockBar::_AdjustRow(CToolBarArray& arrRow, CPoint pt, int nLength, BOOL bHorz, AFX_SIZEPARENTPARAMS* lpLayout, int& nRemove)
  139. {
  140. CDockInfoArray arrInfo;
  141. int nPos;
  142. // Step 1. Getting maximum available size;
  143. for (nPos = 0; nPos < arrRow.GetSize(); nPos++)
  144. {
  145. CXTPToolBar* pBar = arrRow[nPos];
  146. CSize sizeBar = pBar->CalcDockingLayout(nLength, _GetMode(bHorz, pBar));
  147. CPoint p = bHorz ? CPoint(pBar->m_pDockContext->m_rectMRUDockPos.left, pt.y) :
  148. CPoint(pt.x, pBar->m_pDockContext->m_rectMRUDockPos.top);
  149. DOCK_INFO dockInfo(pBar, CRect(p, sizeBar), nPos);
  150. arrInfo.Add(dockInfo);
  151. }
  152. ASSERT(arrInfo.GetSize() == arrRow.GetSize());
  153. if (!bHorz) arrInfo.InvertRects();
  154. arrInfo.Sort();
  155. // Step 2. if Total length is more than available, fill empty area.
  156. int nIndex = -1;
  157. int nLen = 0;
  158. BOOL bMove = TRUE;
  159. for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
  160. {
  161. CRect& rect = arrInfo[nPos].rcBar;
  162. bMove = (rect.left < nLen && (nIndex < arrInfo[nPos].nIndex || bMove));
  163. if (bMove) rect.OffsetRect(nLen - rect.left, 0);
  164. nLen = rect.right;
  165. nIndex = arrInfo[nPos].nIndex;
  166. }
  167. nLen = nLength;
  168. nIndex = -1;
  169. bMove = TRUE;
  170. for (nPos = (int)arrInfo.GetSize() - 1; nPos >= 0; nPos--)
  171. {
  172. CRect& rect = arrInfo[nPos].rcBar;
  173. bMove = (rect.right - nLen > 0 && (nIndex < arrInfo[nPos].nIndex || bMove));
  174. if (bMove) rect.OffsetRect(nLen - rect.right, 0);
  175. nLen = rect.left;
  176. nIndex = arrInfo[nPos].nIndex;
  177. }
  178. nLen = 0;
  179. for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
  180. {
  181. CRect& rect = arrInfo[nPos].rcBar;
  182. if (rect.left < nLen)
  183. rect.OffsetRect(nLen - rect.left, 0);
  184. nLen = rect.left + rect.Width();
  185. }
  186. // Step 3. if Total length is more than available, make it expandable.
  187. if (nLen > nLength)
  188. {
  189. int nSum = 0;
  190. for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
  191. {
  192. CXTPToolBar* pBar = arrInfo[nPos].pBar;
  193. if (!(_GetMode(bHorz, pBar) & LM_HIDEWRAP))
  194. arrInfo[nPos].nMinWidth = nLength;
  195. else
  196. {
  197. CSize sz = pBar->CalcDockingLayout(1, _GetMode(bHorz, pBar));
  198. arrInfo[nPos].nMinWidth = bHorz ? sz.cx : sz.cy;
  199. }
  200. arrInfo[nPos].nTotlaMinWidth = nSum;
  201. nSum += arrInfo[nPos].nMinWidth;
  202. }
  203. nLen = nLength;
  204. for (nPos = (int)arrInfo.GetSize() - 1; nPos >= 0; nPos--)
  205. {
  206. CRect& rect = arrInfo[nPos].rcBar;
  207. int nLeft = bHorz ? arrInfo[nPos].rcMRUPos.left : arrInfo[nPos].rcMRUPos.top;
  208. if (nLeft > rect.left) nLeft = rect.left;
  209. if (nLeft < nLen - rect.Width()) nLeft = nLen - rect.Width();
  210. if (nLeft < arrInfo[nPos].nTotlaMinWidth) nLeft = arrInfo[nPos].nTotlaMinWidth;
  211. if (nLen - nLeft < arrInfo[nPos].nMinWidth) nLeft = nLen - arrInfo[nPos].nMinWidth;
  212. if ((nLen - nLeft < arrInfo[nPos].nMinWidth || nLeft < arrInfo[nPos].nTotlaMinWidth)
  213. && arrInfo.GetSize() != 1)
  214. {
  215. nRemove = arrInfo[arrInfo.GetSize() - 1].nIndex;
  216. return -1;
  217. }
  218. rect.right = nLen;
  219. nLen = rect.left = max(0, nLeft);
  220. }
  221. }
  222. if (!bHorz) arrInfo.InvertRects();
  223. int nWidth = 0;
  224. // Calculate total width
  225. for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
  226. {
  227. CXTPToolBar* pBar = arrInfo[nPos].pBar;
  228. CRect& rect = arrInfo[nPos].rcBar;
  229. CSize sizeBar = pBar->CalcDockingLayout(bHorz ? rect.Width() : rect.Height(), _GetMode(bHorz, pBar));
  230. nWidth = max(nWidth, bHorz ? sizeBar.cy : sizeBar.cx);
  231. }
  232. if (lpLayout->hDWP == 0)
  233. return nWidth;
  234. // Step 4. Move it.
  235. for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
  236. {
  237. CXTPToolBar* pBar = arrInfo[nPos].pBar;
  238. CRect& rect = arrInfo[nPos].rcBar;
  239. int nMode = _GetMode(bHorz, pBar) | LM_COMMIT;
  240. if (pBar->GetFlags() & xtpFlagStretchedShared)
  241. {
  242. if (bHorz)
  243. {
  244. rect.right = nPos == arrInfo.GetSize() - 1 ? nLength : arrInfo[nPos + 1].rcBar.left;
  245. rect.left = nPos == 0 ? 0 : min(arrInfo[nPos - 1].rcBar.right, rect.left);
  246. }
  247. else
  248. {
  249. rect.bottom = nPos == arrInfo.GetSize() - 1 ? nLength : arrInfo[nPos + 1].rcBar.top;
  250. rect.top = nPos == 0 ? 0 : min(arrInfo[nPos - 1].rcBar.bottom, rect.top);
  251. }
  252. nMode |= LM_STRETCH;
  253. }
  254. CSize sz = pBar->CalcDockingLayout(bHorz ? rect.Width() : rect.Height(), nMode, nWidth);
  255. rect = CRect(rect.TopLeft(), sz);
  256. pBar->m_pDockContext->m_uMRUDockPosition = GetPosition();
  257. CXTPWindowRect rectOld(pBar);
  258. ScreenToClient(&rectOld);
  259. if (!::EqualRect(rectOld, rect))
  260. {
  261. AfxRepositionWindow(lpLayout, pBar->m_hWnd, &rect);
  262. pBar->Redraw();
  263. }
  264. }
  265. return nWidth;
  266. }
  267. int CXTPDockBar::AdjustRow(CToolBarArray& arrRow, CPoint pt, int nLength, BOOL bHorz, AFX_SIZEPARENTPARAMS* lpLayout)
  268. {
  269. int nTotalWidth = 0;
  270. CToolBarArray arrNext;
  271. for (;;)
  272. {
  273. int nRemove = -1;
  274. ASSERT(arrRow.GetSize() > 0);
  275. int nWidth = _AdjustRow(arrRow, pt, nLength, bHorz, lpLayout, nRemove);
  276. if (nWidth == -1)
  277. {
  278. ASSERT(nRemove != -1);
  279. arrNext.Add(arrRow[nRemove]);
  280. arrRow.RemoveAt(nRemove);
  281. }
  282. else
  283. {
  284. nTotalWidth += nWidth;
  285. if (bHorz)
  286. pt.y += nWidth;
  287. else
  288. pt.x += nWidth;
  289. if (arrNext.GetSize() > 0)
  290. {
  291. arrRow.Copy(arrNext);
  292. arrNext.RemoveAll();
  293. continue;
  294. }
  295. break;
  296. }
  297. }
  298. return nTotalWidth;
  299. }
  300. CSize CXTPDockBar::CalcDynamicLayout(int nLength, DWORD nMode, AFX_SIZEPARENTPARAMS* lpLayout)
  301. {
  302. BOOL bHorz = nMode & LM_HORZ;
  303. BOOL bStretch = nMode & LM_STRETCH;
  304. CSize sizeFixed (bStretch && bHorz ? 32767 : 0, bStretch && !bHorz ? 32767 : 0);
  305. BOOL bLayoutQuery = (lpLayout->hDWP == NULL);
  306. // prepare for layout
  307. AFX_SIZEPARENTPARAMS layout;
  308. layout.hDWP = bLayoutQuery ? 0 : ::BeginDeferWindowPos((int)m_arrBars.GetSize());
  309. CPoint pt(0, 0);
  310. // layout all the control bars
  311. for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  312. {
  313. CToolBarArray lst;
  314. CXTPToolBar* pBar = GetDockedCommandBar(nPos);
  315. while (pBar)
  316. {
  317. if (pBar->IsVisible()) lst.Add(pBar);
  318. pBar = GetDockedCommandBar(++nPos);
  319. }
  320. int nWidth = 0;
  321. if (lst.GetSize() != 0)
  322. {
  323. nWidth = AdjustRow(lst, pt, nLength, bHorz, &layout);
  324. lst.RemoveAll();
  325. }
  326. if (pBar == NULL && nWidth != 0)
  327. {
  328. // end of row because pBar == NULL
  329. if (bHorz)
  330. {
  331. pt.y += nWidth;
  332. sizeFixed.cy = max(sizeFixed.cy, pt.y);
  333. }
  334. else
  335. {
  336. pt.x += nWidth;
  337. sizeFixed.cx = max(sizeFixed.cx, pt.x);
  338. }
  339. }
  340. }
  341. if (!bLayoutQuery)
  342. {
  343. // move and resize all the windows at once!
  344. if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP))
  345. TRACE0("Warning: DeferWindowPos failed - low system resources.n");
  346. }
  347. return sizeFixed;
  348. }
  349. LRESULT CXTPDockBar::OnSizeParent(WPARAM, LPARAM lParam)
  350. {
  351. AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
  352. DWORD dwStyle = GetStyle();
  353. if (dwStyle & WS_VISIBLE)
  354. {
  355. // align the control bar
  356. CRect rect;
  357. rect.CopyRect(&lpLayout->rect);
  358. CSize sizeAvail = rect.Size();  // maximum size available
  359. // get maximum requested size
  360. DWORD dwMode = lpLayout->bStretch ? LM_STRETCH : 0;
  361. if ((m_dwStyle & CBRS_SIZE_DYNAMIC) && m_dwStyle & CBRS_FLOATING)
  362. dwMode |= LM_HORZ | LM_MRUWIDTH;
  363. else if (dwStyle & CBRS_ORIENT_HORZ)
  364. dwMode |= LM_HORZ | LM_HORZDOCK;
  365. else
  366. dwMode |= LM_VERTDOCK;
  367. int nLength = (dwStyle & CBRS_ORIENT_HORZ ? sizeAvail.cx : sizeAvail.cy) /*- 2 * GetSystemMetrics(SM_CXBORDER)*/;
  368. CSize size = CalcDynamicLayout(nLength, dwMode, lpLayout);
  369. size.cx = min(size.cx, sizeAvail.cx);
  370. size.cy = min(size.cy, sizeAvail.cy);
  371. if (dwStyle & CBRS_ORIENT_HORZ)
  372. {
  373. lpLayout->sizeTotal.cy += size.cy;
  374. lpLayout->sizeTotal.cx = max(lpLayout->sizeTotal.cx, size.cx);
  375. if (dwStyle & CBRS_ALIGN_TOP)
  376. lpLayout->rect.top += size.cy;
  377. else if (dwStyle & CBRS_ALIGN_BOTTOM)
  378. {
  379. rect.top = rect.bottom - size.cy;
  380. lpLayout->rect.bottom -= size.cy;
  381. }
  382. }
  383. else
  384. {
  385. lpLayout->sizeTotal.cx += size.cx;
  386. lpLayout->sizeTotal.cy = max(lpLayout->sizeTotal.cy, size.cy);
  387. if (dwStyle & CBRS_ALIGN_LEFT)
  388. lpLayout->rect.left += size.cx;
  389. else if (dwStyle & CBRS_ALIGN_RIGHT)
  390. {
  391. rect.left = rect.right - size.cx;
  392. lpLayout->rect.right -= size.cx;
  393. }
  394. }
  395. rect.right = rect.left + size.cx;
  396. rect.bottom = rect.top + size.cy;
  397. // only resize the window if doing layout and not just rect query
  398. if (lpLayout->hDWP != NULL)
  399. AfxRepositionWindow(lpLayout, m_hWnd, &rect);
  400. Invalidate(FALSE);
  401. }
  402. return 0;
  403. }
  404. void CXTPDockBar::OnPaint()
  405. {
  406. CPaintDC dc(this);
  407. m_pCommandBars->GetPaintManager()->FillDockBar(&dc, this);
  408. }
  409. LRESULT CXTPDockBar::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
  410. {
  411. CDC* pDC = CDC::FromHandle((HDC)wParam);
  412. if (pDC)
  413. {
  414. m_pCommandBars->GetPaintManager()->FillDockBar(pDC, this);
  415. }
  416. return TRUE;
  417. }
  418. BOOL CXTPDockBar::OnEraseBkgnd(CDC* /*pDC*/)
  419. {
  420. return TRUE;
  421. }
  422. void CXTPDockBar::AdjustStretchBars()
  423. {
  424. for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  425. {
  426. CXTPToolBar* pBar = GetDockedCommandBar(nPos);
  427. if (pBar && pBar->GetFlags() & xtpFlagStretched)
  428. {
  429. if (nPos > 0 && GetDockedCommandBar(nPos - 1) != NULL)
  430. {
  431. m_arrBars.InsertAt(nPos, (CXTPToolBar*)NULL);
  432. nPos++;
  433. }
  434. if (nPos < m_arrBars.GetSize() -1 && GetDockedCommandBar(nPos + 1) != NULL)
  435. {
  436. m_arrBars.InsertAt(nPos + 1, (CXTPToolBar*)NULL);
  437. nPos++;
  438. }
  439. }
  440. }
  441. }
  442. void CXTPDockBar::DockCommandBar(CXTPToolBar* pBar, LPCRECT lpRect)
  443. {
  444. ASSERT_VALID(this);
  445. ASSERT_VALID(pBar);
  446. ASSERT_KINDOF(CXTPToolBar, pBar);
  447. CRect rectBar;
  448. pBar->GetWindowRect(&rectBar);
  449. if (pBar->m_pDockBar == this && (lpRect == NULL || rectBar == *lpRect))
  450. {
  451. // already docked and no change in position
  452. return;
  453. }
  454. int nPos = -1;
  455. if (lpRect != NULL)
  456. {
  457. // insert into appropriate row
  458. CRect rect(lpRect);
  459. ScreenToClient(&rect);
  460. CPoint ptMid(rect.left + rect.Width()/2, rect.top + rect.Height()/2);
  461. nPos = Insert(pBar, rect, ptMid);
  462. pBar->m_pDockContext->m_rectMRUDockPos = rect;
  463. }
  464. else
  465. {
  466. // always add on current row, then create new one
  467. m_arrBars.Add(pBar);
  468. m_arrBars.Add(NULL);
  469. pBar->m_pDockContext->m_rectMRUDockPos.SetRectEmpty();
  470. }
  471. // attach it to the docking site
  472. if (pBar->GetParent() != this)
  473. pBar->SetParent(this);
  474. if (pBar->m_pDockBar == this)
  475. pBar->m_pDockBar->RemoveCommandBar(pBar, nPos);
  476. else if (pBar->m_pDockBar != NULL)
  477. pBar->m_pDockBar->RemoveCommandBar(pBar, -1);
  478. pBar->m_pDockBar = this;
  479. AdjustStretchBars();
  480. // get parent frame for recalc layout
  481. m_pCommandBars->RecalcFrameLayout(TRUE);
  482. }
  483. BOOL CXTPDockBar::RemoveCommandBar(CXTPToolBar* pBar, int nPosExclude)
  484. {
  485. ASSERT_VALID(this);
  486. ASSERT(pBar != NULL);
  487. if (!pBar)
  488. return FALSE;
  489. int nPos = FindBar(pBar, nPosExclude);
  490. ASSERT(nPos > 0);
  491. if (nPos <= 0)
  492. return FALSE;
  493. m_arrBars.RemoveAt(nPos);
  494. if (m_arrBars[nPos-1] == NULL && m_arrBars[nPos] == NULL)
  495. m_arrBars.RemoveAt(nPos);
  496. pBar->m_pDockBar = NULL;
  497. // get parent frame for recalc layout/frame destroy
  498. m_pCommandBars->RecalcFrameLayout(TRUE);
  499. return TRUE;
  500. }
  501. CXTPToolBar* CXTPDockBar::GetDockedCommandBar(int nPos) const
  502. {
  503. CXTPToolBar* pResult = (CXTPToolBar*)m_arrBars[nPos];
  504. ASSERT(pResult == 0 || HIWORD(pResult) != 0); // XTPLibrary don't use placeholder
  505. return pResult;
  506. }
  507. int CXTPDockBar::GetDockedCount() const
  508. {
  509. int nCount = 0;
  510. for (int i = 0; i < m_arrBars.GetSize(); i++)
  511. {
  512. if (GetDockedCommandBar(i) != NULL)
  513. nCount++;
  514. }
  515. return nCount;
  516. }
  517. int CXTPDockBar::GetDockedVisibleCount() const
  518. {
  519. int nCount = 0;
  520. for (int i = 0; i < m_arrBars.GetSize(); i++)
  521. {
  522. CXTPToolBar* pBar = GetDockedCommandBar(i);
  523. if (pBar != NULL && pBar->IsVisible())
  524. nCount++;
  525. }
  526. return nCount;
  527. }
  528. int CXTPDockBar::FindBar(CXTPToolBar* pBar, int nPosExclude)
  529. {
  530. for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  531. {
  532. if (nPos != nPosExclude && m_arrBars[nPos] == pBar)
  533. return nPos;
  534. }
  535. return -1;
  536. }
  537. int CXTPDockBar::Insert(CXTPToolBar* pBarIns, CRect /*rect*/, CPoint ptMid)
  538. {
  539. ASSERT_VALID(this);
  540. ASSERT(pBarIns != NULL);
  541. int nPos = 0;
  542. int nPosInsAfter = 0;
  543. int nWidth = 0;
  544. int nTotalWidth = 0;
  545. //int nPosInsBefore = 0;
  546. BOOL bHorz = m_dwStyle & CBRS_ORIENT_HORZ;
  547. BOOL bAllowTopMost = m_pCommandBars->GetMenuBar() == NULL ||
  548. !m_pCommandBars->GetMenuBar()->IsRibbonBar() || FindBar(m_pCommandBars->GetMenuBar()) == -1;
  549. for (nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  550. {
  551. CXTPToolBar* pBar = GetDockedCommandBar(nPos);
  552. if (pBar && !pBar->IsVisible())
  553. continue;
  554. if (pBar != NULL)
  555. {
  556. CRect rectBar;
  557. pBar->GetWindowRect(&rectBar);
  558. ScreenToClient(&rectBar);
  559. nWidth = max(nWidth,
  560. bHorz ? rectBar.bottom : rectBar.right);
  561. }
  562. else // end of row because pBar == NULL
  563. {
  564. if ((bHorz ? ptMid.y : ptMid.x) < nWidth && (bAllowTopMost || nPosInsAfter > 1))
  565. {
  566. if (nPos == 0 || ((bHorz ? ptMid.y : ptMid.x) == nTotalWidth)) // first section
  567. m_arrBars.InsertAt(nPosInsAfter + 1, (CXTPToolBar*)NULL);
  568. m_arrBars.InsertAt(nPosInsAfter + 1, pBarIns);
  569. return nPosInsAfter + 1;
  570. }
  571. nTotalWidth = nWidth;
  572. nWidth = 0;
  573. nPosInsAfter = nPos;
  574. }
  575. }
  576. // create a new row
  577. m_arrBars.InsertAt(nPosInsAfter + 1, (CXTPToolBar*)NULL);
  578. m_arrBars.InsertAt(nPosInsAfter + 1, pBarIns);
  579. return nPosInsAfter + 1;
  580. }
  581. XTPBarPosition CXTPDockBar::GetPosition() const
  582. {
  583. if (m_dwStyle & CBRS_TOP) return xtpBarTop;
  584. if (m_dwStyle & CBRS_BOTTOM) return xtpBarBottom;
  585. if (m_dwStyle & CBRS_LEFT) return xtpBarLeft;
  586. return xtpBarRight;
  587. }
  588. BOOL CXTPDockBar::IsVerticalPosition() const
  589. {
  590. return !(m_dwStyle & CBRS_ORIENT_HORZ);
  591. }
  592. void CXTPDockBar::OnRButtonDown(UINT /*nFlags*/, CPoint point)
  593. {
  594. ClientToScreen(&point);
  595. m_pCommandBars->ContextMenu(NULL, point);
  596. }
  597. void CXTPDockBar::GetVisibleToolbars(int nPos, CToolBarArray& arrBars)
  598. {
  599. ASSERT(nPos != -1);
  600. ASSERT(m_arrBars[nPos]);
  601. while (m_arrBars[nPos] != NULL && nPos > 0)
  602. {
  603. nPos--;
  604. }
  605. nPos++;
  606. CDockInfoArray arrInfo;
  607. while (m_arrBars[nPos] != NULL)
  608. {
  609. CXTPToolBar* pBar = m_arrBars[nPos++];
  610. if (pBar->IsVisible())
  611. {
  612. DOCK_INFO dockInfo(pBar, CXTPWindowRect(pBar), nPos);
  613. arrInfo.Add(dockInfo);
  614. }
  615. }
  616. if (m_dwStyle & CBRS_LEFT || m_dwStyle & CBRS_RIGHT) arrInfo.InvertRects();
  617. arrInfo.Sort();
  618. for (int i = 0; i < arrInfo.GetSize(); i++)
  619. {
  620. arrBars.Add(arrInfo[i].pBar);
  621. }
  622. }