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

对话框与窗口

开发平台:

Visual C++

  1. // XTPRibbonBar.cpp : implementation file
  2. //
  3. // This file is a part of the XTREME RIBBON 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 "Common/XTPPropExchange.h"
  25. #include "Common/XTPToolTipContext.h"
  26. #include "CommandBars/resource.h"
  27. #include "CommandBars/XTPShortcutManager.h"
  28. #include "CommandBars/XTPCommandBars.h"
  29. #include "CommandBars/XTPPopupBar.h"
  30. #include "CommandBars/XTPControlExt.h"
  31. #include "CommandBars/XTPMouseManager.h"
  32. #include "CommandBars/XTPControlPopup.h"
  33. #include "CommandBars/XTPControlButton.h"
  34. #include "CommandBars/XTPOffice2007FrameHook.h"
  35. #include "CommandBars/XTPCustomizeTools.h"
  36. #include "XTPRibbonTab.h"
  37. #include "XTPRibbonTheme.h"
  38. #include "XTPRibbonQuickAccessControls.h"
  39. #include "XTPRibbonGroups.h"
  40. #include "XTPRibbonGroup.h"
  41. #include "XTPRibbonControlTab.h"
  42. #include "XTPRibbonBar.h"
  43. #include "XTPRibbonSystemButton.h"
  44. #ifdef _DEBUG
  45. #define new DEBUG_NEW
  46. #undef THIS_FILE
  47. static char THIS_FILE[] = __FILE__;
  48. #endif
  49. IMPLEMENT_XTP_COMMANDBAR(CXTPRibbonBar, CXTPMenuBar)
  50. class CXTPRibbonBar::CControlQuickAccessCommand : public CXTPControlButton
  51. {
  52. public:
  53. CControlQuickAccessCommand(CXTPControls* pQuickAccessControls, CXTPControl* pControlOriginal)
  54. {
  55. m_pControlOriginal = pControlOriginal;
  56. m_pQuickAccessControls = pQuickAccessControls;
  57. m_pQuickAccessControl = 0;
  58. }
  59. void SetQuickAccessControl(CXTPControl* pQuickAccessControl)
  60. {
  61. m_pQuickAccessControl = pQuickAccessControl;
  62. SetChecked(TRUE);
  63. }
  64. void OnExecute()
  65. {
  66. CXTPControlButton::OnExecute();
  67. if (m_pQuickAccessControl)
  68. {
  69. m_pQuickAccessControls->Remove(m_pQuickAccessControl);
  70. }
  71. else
  72. {
  73. CXTPControl* pControl = m_pQuickAccessControls->AddClone(m_pControlOriginal, -1, TRUE);
  74. pControl->SetHideFlag(xtpHideCustomize, FALSE);
  75. }
  76. m_pQuickAccessControls->GetParent()->OnRecalcLayout();
  77. }
  78. protected:
  79. CXTPControl* m_pControlOriginal;
  80. CXTPControl* m_pQuickAccessControl;
  81. CXTPControls* m_pQuickAccessControls;
  82. };
  83. class CXTPRibbonBar::CControlCaptionButton : public CXTPControlButton
  84. {
  85. public:
  86. CControlCaptionButton(CXTPOffice2007FrameHook* pFrame)
  87. {
  88. m_pFrame = pFrame;
  89. m_bTemporary = TRUE;
  90. SetFlags(xtpFlagNoMovable | xtpFlagSkipFocus | xtpFlagManualUpdate);
  91. }
  92. protected:
  93. void Draw(CDC* pDC)
  94. {
  95. ((CXTPRibbonBar*)GetParent())->GetRibbonPaintManager()->
  96. DrawRibbonFrameCaptionButton(pDC, GetRect(), GetID(), GetSelected(), GetPressed(), m_bEnabled && m_pFrame->IsFrameActive());
  97. }
  98. void OnExecute()
  99. {
  100. GetParent()->GetSite()->PostMessage(WM_SYSCOMMAND, GetID(), 0);
  101. }
  102. protected:
  103. CXTPOffice2007FrameHook* m_pFrame;
  104. };
  105. class CXTPRibbonBarControlQuickAccessPopup: public CXTPControlPopup
  106. {
  107. DECLARE_XTP_CONTROL(CXTPRibbonBarControlQuickAccessPopup)
  108. public:
  109. CXTPRibbonBarControlQuickAccessPopup()
  110. {
  111. m_bTemporary = TRUE;
  112. SetFlags(xtpFlagNoMovable | xtpFlagManualUpdate);
  113. }
  114. CSize GetSize(CDC* /*pDC*/)
  115. {
  116. CXTPRibbonTheme* pPaintManager = (CXTPRibbonTheme*)m_pParent->GetPaintManager();
  117. return CSize(pPaintManager->GetEditHeight() * 13 / 22, pPaintManager->GetEditHeight());
  118. }
  119. void Draw(CDC* pDC)
  120. {
  121. ((CXTPRibbonBar*)GetParent()->GetRootParent())->GetRibbonPaintManager()->DrawRibbonQuickAccessButton(pDC, this);
  122. }
  123. BOOL OnSetPopup(BOOL bPopup)
  124. {
  125. if (bPopup)
  126. {
  127. if (m_pCommandBar)
  128. m_pCommandBar->InternalRelease();
  129. CXTPRibbonBar* pRibbonBar = (CXTPRibbonBar*)GetParent()->GetRootParent();
  130. m_pCommandBar = pRibbonBar->CreateContextMenu(this);
  131. }
  132. return CXTPControlPopup::OnSetPopup(bPopup);
  133. }
  134. };
  135. IMPLEMENT_XTP_CONTROL(CXTPRibbonBarControlQuickAccessPopup, CXTPControlPopup)
  136. class CXTPRibbonBar::CControlQuickAccessMorePopup: public CXTPControlPopup
  137. {
  138. public:
  139. CControlQuickAccessMorePopup()
  140. {
  141. m_bTemporary = TRUE;
  142. SetFlags(xtpFlagNoMovable | xtpFlagManualUpdate);
  143. }
  144. CSize GetSize(CDC* /*pDC*/)
  145. {
  146. CXTPRibbonTheme* pPaintManager = (CXTPRibbonTheme*)m_pParent->GetPaintManager();
  147. return CSize(pPaintManager->GetEditHeight() * 13 / 22, pPaintManager->GetEditHeight());
  148. }
  149. void Draw(CDC* pDC)
  150. {
  151. ((CXTPRibbonBar*)GetParent())->GetRibbonPaintManager()->DrawRibbonQuickAccessMoreButton(pDC, this);
  152. }
  153. BOOL OnSetPopup(BOOL bPopup)
  154. {
  155. if (bPopup)
  156. {
  157. if (m_pCommandBar)
  158. m_pCommandBar->InternalRelease();
  159. m_pCommandBar = ((CXTPRibbonBar*)GetParent())->CreateMoreQuickAccessContextMenu();
  160. }
  161. return CXTPControlPopup::OnSetPopup(bPopup);
  162. }
  163. };
  164. /////////////////////////////////////////////////////////////////////////////
  165. // CXTPRibbonBar
  166. CXTPRibbonBar::CXTPRibbonBar()
  167. {
  168. m_pQuickAccessControls = new CXTPRibbonQuickAccessControls;
  169. m_pQuickAccessControls->SetParent(this);
  170. m_pControls->InternalRelease();
  171. m_pControls = new CXTPRibbonControls;
  172. m_pControls->SetParent(this);
  173. m_bShowCaptionAlways = TRUE;
  174. m_pHighlightedGroup = NULL;
  175. m_dwStyle = 0;
  176. m_rcTabControl.SetRectEmpty();
  177. m_rcGroups.SetRectEmpty();
  178. m_rcCaption.SetRectEmpty();
  179. m_rcCaptionText.SetRectEmpty();
  180. m_rcHeader.SetRectEmpty();
  181. m_bMinimizeOnDblClick = FALSE;
  182. InitScrollableBar(this);
  183. m_pControlQuickAccess = m_pControls->Add(new CXTPRibbonBarControlQuickAccessPopup, XTP_ID_RIBBONCONTROLQUICKACCESS, NULL, -1, TRUE);
  184. m_pControlQuickAccessMore = m_pControls->Add(new CControlQuickAccessMorePopup, XTP_ID_RIBBONCONTROLQUICKACCESSMORE, NULL, -1, TRUE);
  185. m_pControlTab = (CXTPRibbonControlTab*)m_pControls->Add(new CXTPRibbonControlTab, XTP_ID_RIBBONCONTROLTAB, NULL, -1, TRUE);
  186. m_dwFlags = xtpFlagIgnoreSetMenuMessage | xtpFlagStretched;
  187. m_bCustomizable = FALSE;
  188. m_bGroupsVisible = TRUE;
  189. m_bTabsVisible = TRUE;
  190. m_nMinVisibleWidth = 250;
  191. m_bMinimized = FALSE;
  192. m_pFrameHook = NULL;
  193. m_pControlSystemButton = NULL;
  194. m_bRibbonBarVisible = TRUE;
  195. m_bGroupReducedChanged = FALSE;
  196. m_bShowQuickAccessBelow = FALSE;
  197. m_bShowQuickAccess = TRUE;
  198. m_pContextHeaders = new CXTPRibbonTabContextHeaders;
  199. m_bMultiLine = TRUE;
  200. m_bAllowQuickAccessDuplicates = FALSE;
  201. m_bAllowQuickAccessCustomization = TRUE;
  202. m_nGroupsHeight = 0;
  203. m_nQuickAccessHeight = 0;
  204. m_nGroupsScrollPos = 0;
  205. m_bAllowMinimize = TRUE;
  206. EnableDoubleBuffer();
  207. EnableAnimation();
  208. }
  209. CXTPRibbonTheme* CXTPRibbonBar::GetRibbonPaintManager() const
  210. {
  211. CXTPPaintManager* pPaintManager = GetPaintManager();
  212. ASSERT(pPaintManager->BaseTheme() == xtpThemeRibbon);
  213. return (CXTPRibbonTheme*)pPaintManager;
  214. }
  215. CXTPRibbonBar::~CXTPRibbonBar()
  216. {
  217. if (m_pControlTab)
  218. {
  219. m_pControlTab->DeleteAllItems();
  220. }
  221. if (m_pQuickAccessControls)
  222. {
  223. m_pQuickAccessControls->RemoveAll();
  224. }
  225. CMDTARGET_RELEASE(m_pQuickAccessControls);
  226. SAFE_DELETE(m_pFrameHook);
  227. SAFE_DELETE(m_pContextHeaders);
  228. }
  229. void CXTPRibbonBar::OnRemoved()
  230. {
  231. SAFE_DELETE(m_pFrameHook);
  232. if (m_pQuickAccessControls)
  233. {
  234. m_pQuickAccessControls->RemoveAll();
  235. }
  236. if (m_pControlTab)
  237. {
  238. m_pControlTab->DeleteAllItems();
  239. }
  240. CXTPMenuBar::OnRemoved();
  241. }
  242. CXTPControlPopup* CXTPRibbonBar::AddSystemButton(int nID)
  243. {
  244. if (m_pControlSystemButton)
  245. return m_pControlSystemButton;
  246. m_pControlSystemButton = (CXTPControlPopup*)GetControls()->InsertAt(new CXTPRibbonControlSystemButton, 0);
  247. if (nID > 0) m_pControlSystemButton->SetID(nID);
  248. CXTPPopupBar* pCommandBar = new CXTPRibbonSystemPopupBar();
  249. pCommandBar->SetCommandBars(GetCommandBars());
  250. m_pControlSystemButton->SetCommandBar(pCommandBar);
  251. pCommandBar->InternalRelease();
  252. return m_pControlSystemButton;
  253. }
  254. void CXTPRibbonBar::EnableFrameTheme(BOOL bEnable)
  255. {
  256. CXTPOffice2007FrameHook* pFrameHook = m_pFrameHook;
  257. if (!bEnable)
  258. {
  259. if (pFrameHook)
  260. {
  261. m_pControls->Remove(m_pControls->FindControl(SC_CLOSE));
  262. m_pControls->Remove(m_pControls->FindControl(SC_RESTORE));
  263. m_pControls->Remove(m_pControls->FindControl(SC_MAXIMIZE));
  264. m_pControls->Remove(m_pControls->FindControl(SC_MINIMIZE));
  265. m_pFrameHook = NULL;
  266. SAFE_DELETE(pFrameHook);
  267. OnRecalcLayout();
  268. }
  269. }
  270. else
  271. {
  272. if (!pFrameHook)
  273. {
  274. m_pFrameHook = new CXTPOffice2007FrameHook();
  275. m_pFrameHook->EnableOffice2007Frame(GetCommandBars());
  276. ASSERT(m_pFrameHook->m_pRibbonBar == this);
  277. }
  278. }
  279. }
  280. BOOL CXTPRibbonBar::IsFrameThemeEnabled() const
  281. {
  282. return m_pFrameHook != NULL;
  283. }
  284. CXTPRibbonTab* CXTPRibbonBar::GetSelectedTab() const
  285. {
  286. if (m_pControlTab == NULL)
  287. return NULL;
  288. return (CXTPRibbonTab*)m_pControlTab->GetSelectedItem();
  289. }
  290. BOOL CXTPRibbonBar::OnTabChanging(CXTPRibbonTab* pTab)
  291. {
  292. NMXTPTABCHANGE nm;
  293. nm.pTab = pTab;
  294. return (BOOL)m_pControlTab->NotifySite(TCN_SELCHANGING, &nm);
  295. }
  296. void CXTPRibbonBar::OnTabChanged(CXTPRibbonTab* pTab)
  297. {
  298. NMXTPTABCHANGE nm;
  299. nm.pTab = pTab;
  300. m_pControlTab->NotifySite(TCN_SELCHANGE, &nm);
  301. }
  302. int CXTPRibbonBar::GetCurSel() const
  303. {
  304. return m_pControlTab->GetCurSel();
  305. }
  306. void CXTPRibbonBar::SetCurSel(int nIndex)
  307. {
  308. m_pControlTab->SetCurSel(nIndex);
  309. }
  310. CXTPRibbonTab* CXTPRibbonBar::InsertTab(int nItem, int nID)
  311. {
  312. CString strCaption;
  313. VERIFY(strCaption.LoadString(nID));
  314. return InsertTab(nItem, strCaption, nID);
  315. }
  316. CXTPRibbonTab* CXTPRibbonBar::InsertTab(int nItem, LPCTSTR lpszCaption, int nID)
  317. {
  318. CXTPRibbonTab* pItem = (CXTPRibbonTab*)m_pControlTab->AddItem(nItem, new CXTPRibbonTab());
  319. pItem->m_pRibbonBar = this;
  320. pItem->m_pParent = this;
  321. pItem->SetCaption(lpszCaption);
  322. pItem->SetID(nID);
  323. if (nItem == 0 && GetCurSel() == -1)
  324. {
  325. SetCurSel(0);
  326. }
  327. m_bTrackOnHover = FALSE;
  328. m_barType = xtpBarTypeRibbon;
  329. return pItem;
  330. }
  331. CXTPRibbonTab* CXTPRibbonBar::AddTab(int nID)
  332. {
  333. return InsertTab(m_pControlTab->GetItemCount(), nID);
  334. }
  335. CXTPRibbonTab* CXTPRibbonBar::AddTab(LPCTSTR lpszCaption)
  336. {
  337. return InsertTab(m_pControlTab->GetItemCount(), lpszCaption, 0);
  338. }
  339. void CXTPRibbonBar::RebuildControls(CXTPRibbonTab* pSelected)
  340. {
  341. m_nGroupsScrollPos = 0;
  342. if (IsRibbonMinimized())
  343. pSelected = NULL;
  344. for (int i = GetControlCount() - 1; i >= 0; i--)
  345. {
  346. CXTPControl* pControl = m_pControls->GetAt(i);
  347. CXTPRibbonGroup* pGroup = pControl->GetRibbonGroup();
  348. if ((pGroup != NULL) && (pGroup->GetParentTab() != pSelected || !pGroup->m_bVisible))
  349. {
  350. pControl->SetHideFlag(xtpHideRibbonTab, TRUE);
  351. }
  352. else
  353. {
  354. pControl->SetHideFlag(xtpHideRibbonTab, FALSE);
  355. }
  356. }
  357. }
  358. BEGIN_MESSAGE_MAP(CXTPRibbonBar, CXTPMenuBar)
  359. //{{AFX_MSG_MAP(CXTPRibbonBar)
  360. ON_WM_LBUTTONDOWN()
  361. ON_WM_RBUTTONUP()
  362. ON_WM_LBUTTONDBLCLK()
  363. ON_WM_SYSCOLORCHANGE()
  364. ON_WM_MOUSEMOVE()
  365. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  366. ON_WM_CREATE()
  367. ON_WM_SETCURSOR()
  368. ON_WM_SHOWWINDOW()
  369. ON_WM_RBUTTONDOWN()
  370. ON_COMMAND_RANGE(XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSBELOW, XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSABOVE, OnCustomizePlaceQuickAccess)
  371. ON_MESSAGE(WM_XTP_COMMAND, OnCustomizeCommand)
  372. ON_WM_NCHITTEST_EX()
  373. //}}AFX_MSG_MAP
  374. END_MESSAGE_MAP()
  375. /////////////////////////////////////////////////////////////////////////////
  376. // CXTPRibbonBar message handlers
  377. int CXTPRibbonBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
  378. {
  379. if (CXTPMenuBar::OnCreate(lpCreateStruct) == -1)
  380. return -1;
  381. SetupHook();
  382. return 0;
  383. }
  384. void CXTPRibbonBar::OnShowWindow(BOOL bShow, UINT nStatus)
  385. {
  386. CXTPMenuBar::OnShowWindow(bShow, nStatus);
  387. if (IsFrameThemeEnabled() && bShow != m_bRibbonBarVisible)
  388. {
  389. m_bRibbonBarVisible = bShow;
  390. m_pFrameHook->RecalcFrameLayout();
  391. }
  392. }
  393. void CXTPRibbonBar::SetVisible(BOOL bVisible)
  394. {
  395. BOOL bOldVisible = IsVisible();
  396. CXTPMenuBar::SetVisible(bVisible);
  397. if (IsFrameThemeEnabled() && bOldVisible != IsVisible())
  398. {
  399. m_pFrameHook->RecalcFrameLayout();
  400. }
  401. }
  402. int CXTPRibbonBar::GetQuickAccessHeight() const
  403. {
  404. return m_nQuickAccessHeight;
  405. }
  406. int CXTPRibbonBar::CalcQuickAccessHeight()
  407. {
  408. CClientDC dc(this);
  409. CXTPFontDC font(&dc, GetPaintManager()->GetCommandBarFont(this, FALSE));
  410. int nQuickAccessHeight = GetButtonSize().cy + 4;
  411. for (int i = 0; i < m_pQuickAccessControls->GetCount(); i++)
  412. {
  413. CXTPControl* pControl = m_pQuickAccessControls->GetAt(i);
  414. if (!pControl->IsVisible())
  415. continue;
  416. int nHeight = pControl->GetSize(&dc).cy + 4;
  417. if (nHeight > nQuickAccessHeight)
  418. nQuickAccessHeight = nHeight;
  419. }
  420. return nQuickAccessHeight;
  421. }
  422. CSize CXTPRibbonBar::CalcDockingLayout(int nLength, DWORD dwMode, int /*nWidth*/)
  423. {
  424. BOOL bRibbonBarVisible = nLength >= m_nMinVisibleWidth;
  425. m_bGroupReducedChanged = FALSE;
  426. CXTPWindowRect rc(GetSite());
  427. if (rc.Height() < m_nMinVisibleWidth)
  428. bRibbonBarVisible = FALSE;
  429. if (bRibbonBarVisible != m_bRibbonBarVisible)
  430. {
  431. m_bRibbonBarVisible =  bRibbonBarVisible;
  432. if (IsFrameThemeEnabled())
  433. {
  434. m_pFrameHook->DelayRecalcFrameLayout();
  435. }
  436. }
  437. if (!bRibbonBarVisible)
  438. {
  439. return CSize(nLength, 0);
  440. }
  441. int nCaptionHeight = GetCaptionHeight() + GetRibbonTopBorder();
  442. int nHeight = nCaptionHeight + GetTabsHeight() + GetGroupsHeight();
  443. m_nQuickAccessHeight = CalcQuickAccessHeight();
  444. if (IsQuickAccessBelowRibbon())
  445. {
  446. nHeight += m_nQuickAccessHeight + 1;
  447. }
  448. if (!IsGroupsVisible() && !IsQuickAccessBelowRibbon())
  449. {
  450. nHeight += 2;
  451. }
  452. if (dwMode & LM_COMMIT)
  453. {
  454. Reposition(nLength, nHeight);
  455. }
  456. if (m_bGroupReducedChanged)
  457. {
  458. OnUpdateCmdUI();
  459. m_bGroupReducedChanged = FALSE;
  460. }
  461. if ((m_nIdleFlags & xtpIdleLayout) && (dwMode & LM_COMMIT))
  462. {
  463. m_nIdleFlags &= ~xtpIdleLayout;
  464. Redraw();
  465. }
  466. return CSize(nLength, nHeight);
  467. }
  468. int CXTPRibbonBar::GetTabsHeight() const
  469. {
  470. return m_bTabsVisible ? GetRibbonPaintManager()->m_nTabsHeight : 2;
  471. }
  472. int CXTPRibbonBar::CalcGroupsHeight()
  473. {
  474. if (m_nGroupsHeight > 0)
  475. return m_nGroupsHeight;
  476. int nHeight = GetRibbonPaintManager()->GetEditHeight() * 3;
  477. int nCaptionHeight = GetRibbonPaintManager()->GetGroupCaptionHeight();
  478. return nHeight + nCaptionHeight + 10;
  479. }
  480. int CXTPRibbonBar::GetGroupsHeight()
  481. {
  482. return IsGroupsVisible() ? CalcGroupsHeight() : 0;
  483. }
  484. BOOL CXTPRibbonBar::IsGroupsVisible() const
  485. {
  486. return m_bGroupsVisible && GetSelectedTab() != NULL && !m_bMinimized;
  487. }
  488. void CXTPRibbonBar::SetGroupsVisible(BOOL bVisible)
  489. {
  490. if (bVisible != m_bGroupsVisible)
  491. {
  492. m_bGroupsVisible = bVisible;
  493. OnRecalcLayout();
  494. }
  495. }
  496. BOOL CXTPRibbonBar::IsTabsVisible() const
  497. {
  498. return m_bTabsVisible;
  499. }
  500. void CXTPRibbonBar::SetTabsVisible(BOOL bVisible)
  501. {
  502. if (bVisible != m_bTabsVisible)
  503. {
  504. m_bTabsVisible = bVisible;
  505. OnRecalcLayout();
  506. }
  507. }
  508. BOOL CXTPRibbonBar::IsQuickAccessControl(CXTPControl* pControl) const
  509. {
  510. if (pControl == m_pControlQuickAccess)
  511. return TRUE;
  512. if (pControl == m_pControlQuickAccessMore)
  513. return TRUE;
  514. if (pControl->GetRibbonGroup())
  515. return FALSE;
  516. if (m_pQuickAccessControls == NULL)
  517. return FALSE;
  518. for (int i = 0; i < m_pQuickAccessControls->GetCount(); i++)
  519. {
  520. if (m_pQuickAccessControls->GetAt(i) == pControl)
  521. return TRUE;
  522. }
  523. return FALSE;
  524. }
  525. int CXTPRibbonBar::GetCaptionHeight() const
  526. {
  527. if (!IsFrameThemeEnabled() && !m_bShowCaptionAlways)
  528. return 0;
  529. int nHeight = GetRibbonPaintManager()->GetRibbonCaptionHeight();
  530. if (!IsQuickAccessVisible() || IsQuickAccessBelowRibbon())
  531. return nHeight;
  532. int nQuickAccessHeight = GetQuickAccessHeight();
  533. nQuickAccessHeight = max(nQuickAccessHeight, GetTabsHeight() - 2);
  534. if (nHeight >= nQuickAccessHeight)
  535. return nHeight;
  536. return nQuickAccessHeight;
  537. }
  538. void CXTPRibbonBar::Reposition(int cx, int cy)
  539. {
  540. CClientDC dc(this);
  541. int nTabsHeight = GetTabsHeight();
  542. int nGroupsHeight = GetGroupsHeight();
  543. BOOL bFrameThemeEnabled = IsFrameThemeEnabled();
  544. BOOL bShowCaption = bFrameThemeEnabled || m_bShowCaptionAlways;
  545. int nQuickAccessHeight = m_nQuickAccessHeight;
  546. int i;
  547. CRect rcTabControl(2, 0, cx - 2, nTabsHeight);
  548. CRect rcRibbonGroups(0, nTabsHeight, cx, nTabsHeight + nGroupsHeight);
  549. int nFrameBorder = 4;
  550. if (bShowCaption)
  551. {
  552. nFrameBorder = m_pFrameHook ? m_pFrameHook->GetFrameBorder() : 0;
  553. int nRibbonTopBorder = GetRibbonTopBorder();
  554. int nCaptionOffset = nRibbonTopBorder - nFrameBorder;
  555. m_rcCaption.SetRect(-nFrameBorder, nCaptionOffset, cx + nFrameBorder, GetCaptionHeight() + nRibbonTopBorder);
  556. rcTabControl.OffsetRect(0, m_rcCaption.Height() + nCaptionOffset);
  557. rcRibbonGroups.OffsetRect(0, m_rcCaption.Height() + nCaptionOffset);
  558. m_rcCaptionText.SetRect(0, 0, cx, m_rcCaption.bottom);
  559. m_rcHeader.SetRect(0, 0, cx, m_rcCaption.bottom);
  560. if (!m_pFrameHook) m_rcCaptionText.SetRectEmpty();
  561. }
  562. else
  563. {
  564. m_rcCaption.SetRectEmpty();
  565. m_rcCaptionText.SetRectEmpty();
  566. m_rcHeader.SetRectEmpty();
  567. }
  568. CArray<CXTPControl*, CXTPControl*> arrFreeControls;
  569. CArray<CXTPControl*, CXTPControl*> arrQuickAccessControls;
  570. for (i = 0; i < GetControlCount(); i++)
  571. {
  572. CXTPControl* pControl = GetControl(i);
  573. if (IsQuickAccessControl(pControl))
  574. {
  575. arrQuickAccessControls.Add(pControl);
  576. }
  577. else
  578. {
  579. if (!pControl->IsVisible())
  580. continue;
  581. if (pControl->GetRibbonGroup() != NULL)
  582. continue;
  583. if (pControl->GetID() >= SC_MINIMIZE && pControl->GetID() <= SC_RESTORE)
  584. continue;
  585. if (pControl == m_pControlSystemButton || pControl == m_pControlScrollGroupsLeft ||
  586. pControl == m_pControlScrollGroupsRight)
  587. continue;
  588. if (pControl == m_pControlTab)
  589. continue;
  590. arrFreeControls.Add(pControl);
  591. }
  592. }
  593. int nCorner = nQuickAccessHeight + nTabsHeight - 3;
  594. if (m_bShowQuickAccess && m_bShowQuickAccessBelow)
  595. {
  596. m_rcQuickAccess.SetRect(0, rcRibbonGroups.bottom, cx, rcRibbonGroups.bottom + nQuickAccessHeight);
  597. }
  598. else
  599. {
  600. m_rcQuickAccess.SetRect(3 + nCorner, m_rcCaption.top + nFrameBorder - 2, m_rcCaption.right, m_rcCaption.top + nFrameBorder - 2 + nQuickAccessHeight - 1);
  601. }
  602. int nLeft = 2;
  603. int nRight = cx - 2;
  604. if (m_pControlSystemButton)
  605. {
  606. CSize szControl(nCorner, nCorner - 1);
  607. int nTop = m_rcCaption.top + nFrameBorder - 1;
  608. if (!bShowCaption)
  609. {
  610. szControl = m_pControlSystemButton->GetSize(&dc);
  611. nTop = rcTabControl.top + (nTabsHeight - szControl.cy) / 2;
  612. }
  613. else if (!m_bTabsVisible)
  614. {
  615. szControl = m_pControlSystemButton->GetSize(&dc);
  616. nTop = m_rcCaption.top + (m_rcCaption.Height() - szControl.cy) / 2;
  617. m_rcQuickAccess.left = 3 + szControl.cx + 12;
  618. }
  619. nLeft = 0;
  620. CRect rcControl(nLeft, nTop, nLeft + szControl.cx, nTop + szControl.cy);
  621. nLeft += szControl.cx;
  622. m_pControlSystemButton->SetHideWrap(!bShowCaption && !m_bTabsVisible);
  623. m_pControlSystemButton->SetRect(rcControl);
  624. m_pControlSystemButton->SetWrap(TRUE);
  625. }
  626. for (i = 0; i < (int)arrFreeControls.GetSize(); i++)
  627. {
  628. CXTPControl* pControl = arrFreeControls.GetAt(i);
  629. if (pControl->GetFlags() & xtpFlagRightAlign)
  630. continue;
  631. pControl->SetHideFlag(xtpHideDockingPosition, !m_bTabsVisible);
  632. if (!pControl->IsVisible())
  633. continue;
  634. CSize szControl = pControl->GetSize(&dc);
  635. int nTop = rcTabControl.top + (nTabsHeight - szControl.cy) / 2;
  636. if (pControl->GetBeginGroup())
  637. nLeft += 6;
  638. CRect rcControl(nLeft, nTop, nLeft + szControl.cx, nTop + szControl.cy);
  639. nLeft += szControl.cx;
  640. pControl->SetHideWrap(FALSE);
  641. pControl->SetRect(rcControl);
  642. pControl->SetRowRect(CRect(2, rcTabControl.top, cy - 2, rcTabControl.bottom));
  643. pControl->SetWrap(FALSE);
  644. }
  645. int nLeftTab = nLeft;
  646. BOOL bQuickAccessNearTabs = m_bShowQuickAccess && !m_bShowQuickAccessBelow && !bShowCaption;
  647. if (bQuickAccessNearTabs)
  648. {
  649. nLeft += 5;
  650. m_rcQuickAccess.left = nLeft;
  651. m_rcQuickAccess.top = rcTabControl.top;
  652. m_rcQuickAccess.bottom = rcTabControl.bottom;
  653. }
  654. else
  655. {
  656. nLeft = m_rcQuickAccess.left + (m_bShowQuickAccessBelow ? 2 : 0);
  657. }
  658. nRight = m_bShowQuickAccess && m_bShowQuickAccessBelow ? cx - 2 - 13 :
  659. IsDwmEnabled() ? cx - 115 : cx - m_rcCaption.Height() * 3;
  660. if (m_pControlQuickAccessMore) m_pControlQuickAccessMore->SetHideFlag(xtpHideGeneric, TRUE);
  661. BOOL bQuickAccessMoreVisible = FALSE;
  662. BOOL bQuickAccessFound = FALSE;
  663. for (i = 0; i < (int)arrQuickAccessControls.GetSize(); i++)
  664. {
  665. CXTPControl* pControl = arrQuickAccessControls.GetAt(i);
  666. if (!m_bShowQuickAccess)
  667. pControl->SetHideFlag(xtpHideWrap, TRUE);
  668. else if (pControl != m_pControlQuickAccessMore)
  669. pControl->SetHideFlag(xtpHideWrap, bQuickAccessMoreVisible);
  670. if (!bShowCaption && !m_bTabsVisible)
  671. pControl->SetHideFlag(xtpHideWrap, TRUE);
  672. if (pControl == m_pControlQuickAccess && bQuickAccessFound &&
  673. !bQuickAccessNearTabs && !m_bShowQuickAccessBelow)
  674. nLeft += 12;
  675. if (!pControl->IsVisible())
  676. continue;
  677. BOOL bSpecial = pControl == m_pControlQuickAccessMore || pControl == m_pControlQuickAccess;
  678. CSize szControl = pControl->GetSize(&dc);
  679. int nTop = m_rcQuickAccess.top + (m_rcQuickAccess.Height() - szControl.cy + 1) / 2;
  680. if (!bSpecial && !m_bShowQuickAccessBelow && !bQuickAccessNearTabs)
  681. {
  682. nTop += 2;
  683. }
  684. if (!bSpecial)
  685. {
  686. bQuickAccessFound = TRUE;
  687. }
  688. if (!bSpecial && (nLeft + szControl.cx > nRight))
  689. {
  690. bQuickAccessMoreVisible = TRUE;
  691. pControl->SetHideFlag(xtpHideWrap, bQuickAccessMoreVisible);
  692. m_pControlQuickAccessMore->SetHideFlag(xtpHideGeneric, FALSE);
  693. continue;
  694. }
  695. CRect rcControl(nLeft, nTop, nLeft + szControl.cx, nTop + szControl.cy);
  696. if (bQuickAccessNearTabs || !bSpecial)
  697. nLeft += szControl.cx;
  698. pControl->SetHideWrap(FALSE);
  699. pControl->SetRect(rcControl);
  700. pControl->SetRowRect(m_rcQuickAccess);
  701. pControl->SetWrap(FALSE);
  702. }
  703. if (!m_bShowQuickAccessBelow) m_rcQuickAccess.right = nLeft;
  704. if (!bQuickAccessNearTabs) nLeft = nLeftTab;
  705. nRight = cx;
  706. for (i = (int)arrFreeControls.GetSize() - 1; i >= 0; i--)
  707. {
  708. CXTPControl* pControl = arrFreeControls.GetAt(i);
  709. if ((pControl->GetFlags() & xtpFlagRightAlign) == 0)
  710. continue;
  711. pControl->SetHideFlag(xtpHideDockingPosition, !m_bTabsVisible);
  712. if (!pControl->IsVisible())
  713. continue;
  714. CSize szControl = pControl->GetSize(&dc);
  715. int nTop = rcTabControl.top + (nTabsHeight - szControl.cy) / 2;
  716. CRect rcControl = CRect(nRight - szControl.cx, nTop, nRight, nTop + szControl.cy);
  717. nRight -= szControl.cx;
  718. pControl->SetHideWrap(FALSE);
  719. pControl->SetRect(rcControl);
  720. pControl->SetRowRect(CRect(2, rcTabControl.top, cy - 2, rcTabControl.bottom));
  721. pControl->SetWrap(TRUE);
  722. pControl->SetBeginGroup(FALSE);
  723. }
  724. if (!m_bTabsVisible) rcTabControl.bottom = rcTabControl.top;
  725. if (nLeft + 6 > nRight)
  726. m_rcTabControl.SetRectEmpty();
  727. else
  728. m_rcTabControl = CRect(nLeft, rcTabControl.top, nRight, rcTabControl.bottom + 1);
  729. if (m_pControlTab)
  730. {
  731. m_pControlTab->SetHideFlag(xtpHideGeneric, !m_bTabsVisible);
  732. m_pControlTab->SetRect(m_rcTabControl);
  733. GetTabPaintManager()->RepositionTabControl(m_pControlTab, &dc, m_rcTabControl);
  734. }
  735. RepositionGroups(&dc, rcRibbonGroups);
  736. RepositionCaptionButtons();
  737. if (bShowCaption)
  738. {
  739. RepositionContextHeaders();
  740. }
  741. }
  742. void CXTPRibbonBar::AddCaptionButton(int nId, BOOL bAdd, BOOL bEnabled, CRect& rcCaption)
  743. {
  744. CXTPControl* pButton = m_pControls->FindControl(nId);
  745. if (!pButton && bAdd)
  746. {
  747. pButton = m_pControls->Add(new CControlCaptionButton(m_pFrameHook), nId, NULL, -1, TRUE);
  748. CString strCaption;
  749. CMenu* pMenu = GetSite()->GetSystemMenu(FALSE);
  750. if (pMenu)
  751. {
  752. pMenu->GetMenuString(nId, strCaption, MF_BYCOMMAND);
  753. int nIndex = strCaption.Find(_T('t'));
  754. if (nIndex > 0)
  755. {
  756. strCaption = strCaption.Left(nIndex);
  757. }
  758. }
  759. if (pButton->GetAction())
  760. {
  761. pButton->GetAction()->SetCaption(_T(""));
  762. pButton->GetAction()->SetDescription(NULL);
  763. }
  764. pButton->SetDescription(NULL);
  765. pButton->SetCaption(_T(""));
  766. pButton->SetTooltip(strCaption);
  767. }
  768. else if (pButton && !bAdd)
  769. {
  770. m_pControls->Remove(pButton);
  771. }
  772. if (bAdd)
  773. {
  774. CRect rcButton(rcCaption.right - rcCaption.Height(), rcCaption.top, rcCaption.right, rcCaption.bottom);
  775. pButton->SetRect(rcButton);
  776. rcCaption.right -= rcButton.Width();
  777. pButton->SetEnabled(bEnabled);
  778. }
  779. }
  780. BOOL CXTPRibbonBar::ShrinkContextHeaders(int nLeft, int nRight)
  781. {
  782. int i, nCount = m_pContextHeaders->GetCount();
  783. for (i = 0; i < nCount; i++)
  784. {
  785. CXTPRibbonTabContextHeader* pHeader =  m_pContextHeaders->GetHeader(i);
  786. if (pHeader->m_rcRect.left < nLeft)
  787. {
  788. pHeader->m_rcRect.left = nLeft;
  789. if (pHeader->m_rcRect.Width()  < 40)
  790. {
  791. pHeader->m_rcRect.right = nLeft + 40;
  792. }
  793. nLeft = pHeader->m_rcRect.right;
  794. }
  795. else break;
  796. }
  797. for (i = nCount - 1; i >= 0; i--)
  798. {
  799. CXTPRibbonTabContextHeader* pHeader =  m_pContextHeaders->GetHeader(i);
  800. if (pHeader->m_rcRect.right > nRight)
  801. {
  802. pHeader->m_rcRect.right = nRight;
  803. if (pHeader->m_rcRect.Width()  < 40)
  804. {
  805. pHeader->m_rcRect.left = nRight - 40;
  806. }
  807. nRight = pHeader->m_rcRect.left;
  808. if (nRight < nLeft)
  809. return FALSE;
  810. }
  811. else break;
  812. }
  813. return TRUE;
  814. }
  815. BOOL CXTPRibbonBar::IsCaptionVisible() const
  816. {
  817. return IsFrameThemeEnabled() || m_bShowCaptionAlways;
  818. }
  819. void CXTPRibbonBar::RepositionContextHeaders()
  820. {
  821. m_pContextHeaders->RemoveAll();
  822. CXTPRibbonTabContextHeader* pPreviousHeader = NULL;
  823. if (!IsCaptionVisible())
  824. return;
  825. int nCount = GetTabCount();
  826. if (nCount == 0)
  827. return;
  828. if (!IsQuickAccessBelowRibbon() && IsQuickAccessVisible() && !m_pFrameHook)
  829. m_rcHeader.left = m_rcQuickAccess.right + (m_pControlQuickAccess ? m_pControlQuickAccess->GetRect().Width() + 2 : 12);
  830. int i;
  831. for (i = 0; i < nCount; i++)
  832. {
  833. CXTPRibbonTab* pTab = GetTab(i);
  834. pTab->m_pContextHeader = NULL;
  835. if (!pTab->IsVisible())
  836. continue;
  837. if (pTab->GetContextColor() == xtpRibbonTabContextColorNone || pTab->GetContextCaption().IsEmpty())
  838. {
  839. pPreviousHeader = NULL;
  840. continue;
  841. }
  842. if (pPreviousHeader && pPreviousHeader->m_color == pTab->GetContextColor() &&
  843. pPreviousHeader->m_strCaption == pTab->GetContextCaption())
  844. {
  845. pPreviousHeader->m_rcRect.right = pTab->GetRect().right;
  846. pPreviousHeader->m_pLastTab = pTab;
  847. pTab->m_pContextHeader = pPreviousHeader;
  848. }
  849. else
  850. {
  851. CXTPRibbonTabContextHeader* pHeader = new CXTPRibbonTabContextHeader(pTab);
  852. pHeader->m_rcRect.SetRect(pTab->GetRect().left, m_rcCaption.top + 4, pTab->GetRect().right, m_rcCaption.bottom);
  853. m_pContextHeaders->Add(pHeader);
  854. pPreviousHeader = pHeader;
  855. }
  856. }
  857. nCount = m_pContextHeaders->GetCount();
  858. if (nCount == 0)
  859. return;
  860. if (!ShrinkContextHeaders(m_rcHeader.left, m_rcHeader.right))
  861. {
  862. m_pContextHeaders->RemoveAll();
  863. return;
  864. }
  865. CRect rcHeaders(m_pContextHeaders->GetHeader(0)->m_rcRect.left, m_rcCaption.top + 6,
  866. m_pContextHeaders->GetHeader(nCount - 1)->m_rcRect.right, m_rcCaption.bottom);
  867. int nCaptionLength = m_rcCaptionText.Width();
  868. CRect rcCaptionText(m_rcCaptionText);
  869. if (CRect().IntersectRect(rcCaptionText, rcHeaders))
  870. {
  871. if (rcCaptionText.CenterPoint().x > rcHeaders.CenterPoint().x)
  872. {
  873. if (m_rcHeader.right - rcHeaders.right < nCaptionLength)
  874. {
  875. m_rcCaptionText.left = rcHeaders.right;
  876. m_rcCaptionText.right = m_rcHeader.right;
  877. }
  878. else
  879. {
  880. m_rcCaptionText.left = rcHeaders.right;
  881. m_rcCaptionText.right = rcHeaders.right + nCaptionLength;
  882. }
  883. }
  884. else
  885. {
  886. if (rcHeaders.left - m_rcHeader.left < nCaptionLength)
  887. {
  888. m_rcCaptionText.left = m_rcHeader.left;
  889. m_rcCaptionText.right = rcHeaders.left;
  890. }
  891. else
  892. {
  893. m_rcCaptionText.left = rcHeaders.left - nCaptionLength;
  894. m_rcCaptionText.right = rcHeaders.left;
  895. }
  896. }
  897. }
  898. }
  899. int CXTPRibbonBar::GetRibbonTopBorder() const
  900. {
  901. return m_pFrameHook && m_pFrameHook->IsDwmEnabled() ? m_pFrameHook->GetFrameBorder() : 0;
  902. }
  903. void CXTPRibbonBar::RepositionCaptionButtons()
  904. {
  905. if (!IsFrameThemeEnabled())
  906. {
  907. return;
  908. }
  909. CRect rcQuickAccess = m_rcQuickAccess;
  910. if (m_bShowQuickAccessBelow || !m_bShowQuickAccess)
  911. {
  912. m_rcHeader.left += 70;
  913. }
  914. else
  915. {
  916. rcQuickAccess.right += (m_pControlQuickAccess ? m_pControlQuickAccess->GetRect().Width() + 2 : 12);
  917. m_rcHeader.left = rcQuickAccess.right;
  918. }
  919. CWnd* pSite = GetSite();
  920. DWORD dwStyle = pSite->GetStyle();
  921. DWORD dwExStyle = pSite->GetExStyle();
  922. BOOL bToolWindow = (dwExStyle & WS_EX_TOOLWINDOW) == WS_EX_TOOLWINDOW;
  923. int nFrameBorder = GetRibbonTopBorder();
  924. m_rcHeader.DeflateRect(0, nFrameBorder, 0, 3);
  925. BOOL bDwmEnabled = m_pFrameHook->IsDwmEnabled();
  926. BOOL bEnableClose = TRUE;
  927. BOOL bMaximized = (dwStyle & WS_MAXIMIZE) == WS_MAXIMIZE;
  928. BOOL bSysMenu = (dwStyle & WS_SYSMENU);
  929. BOOL bEnabledMaximize = ((dwStyle & WS_MAXIMIZEBOX) == WS_MAXIMIZEBOX);
  930. BOOL bEnabledMinimize = ((dwStyle & WS_MINIMIZEBOX) == WS_MINIMIZEBOX);
  931. BOOL bShowMinMaxButtons = !bToolWindow && bSysMenu && (bEnabledMaximize || bEnabledMinimize);
  932. BOOL bShowCloseButton = bSysMenu;
  933. if (bSysMenu && !bToolWindow)
  934. {
  935. CMenu* pMenu = GetSite()->GetSystemMenu(FALSE);
  936. if (pMenu && pMenu->GetMenuState(SC_CLOSE, MF_BYCOMMAND) & (MF_DISABLED | MF_GRAYED)) bEnableClose = FALSE;
  937. }
  938. if (bMaximized && (dwStyle & WS_CHILD))
  939. {
  940. bShowMinMaxButtons = bShowCloseButton = FALSE;
  941. }
  942. AddCaptionButton(SC_CLOSE, !bDwmEnabled && bShowCloseButton, bEnableClose, m_rcHeader);
  943. AddCaptionButton(SC_RESTORE, !bDwmEnabled && bShowMinMaxButtons && bMaximized, bEnabledMaximize, m_rcHeader);
  944. AddCaptionButton(SC_MAXIMIZE, !bDwmEnabled && bShowMinMaxButtons && !bMaximized, bEnabledMaximize, m_rcHeader);
  945. AddCaptionButton(SC_MINIMIZE, !bDwmEnabled && bShowMinMaxButtons, bEnabledMinimize, m_rcHeader);
  946. if (bDwmEnabled)
  947. m_rcHeader.right -= 100;
  948. m_rcCaptionText.SetRect(m_rcCaptionText.left + 70, m_rcHeader.top, m_rcHeader.right, m_rcHeader.bottom);
  949. CClientDC dc(this);
  950. CXTPFontDC font(&dc, &GetRibbonPaintManager()->m_fontFrameCaption);
  951. GetSite()->GetWindowText(m_strCaptionText);
  952. int nCaptionLength = dc.GetTextExtent(m_strCaptionText).cx + 20;
  953. nCaptionLength = min(m_rcCaptionText.Width(), nCaptionLength);
  954. CRect rcCaptionText(m_rcCaptionText);
  955. rcCaptionText.left += (rcCaptionText.Width() - nCaptionLength) / 2;
  956. rcCaptionText.right = rcCaptionText.left + nCaptionLength;
  957. if (CRect().IntersectRect(rcQuickAccess, rcCaptionText))
  958. {
  959. nCaptionLength = min(m_rcHeader.Width(), nCaptionLength);
  960. rcCaptionText.left = m_rcHeader.left + (m_rcHeader.Width() - nCaptionLength) / 2;
  961. rcCaptionText.right = rcCaptionText.left + nCaptionLength;
  962. }
  963. m_rcCaptionText = rcCaptionText;
  964. }
  965. void CXTPRibbonBar::RepositionGroups(CDC* pDC, CRect rcGroups)
  966. {
  967. m_rcGroups = rcGroups;
  968. CXTPRibbonTab* pTab = GetSelectedTab();
  969. if (!pTab)
  970. return;
  971. CXTPRibbonGroups* pGroups = pTab->GetGroups();
  972. pGroups->CalcDynamicSize(pDC, rcGroups.Width(), LM_COMMIT, CRect(rcGroups.left + 4, rcGroups.top + 3, 6, 3));
  973. }
  974. void CXTPRibbonBar::EnsureVisible(CXTPControl* pControl)
  975. {
  976. if (pControl->GetRibbonGroup())
  977. {
  978. if (pControl->GetRibbonGroup()->GetParentTab() != GetSelectedTab())
  979. {
  980. pControl->GetRibbonGroup()->GetParentTab()->Select();
  981. }
  982. }
  983. if (GetSelectedTab() && pControl->GetRibbonGroup() &&
  984. (m_pControlScrollGroupsLeft->IsVisible() || m_pControlScrollGroupsRight->IsVisible()))
  985. {
  986. ShowScrollableRect(GetSelectedTab()->GetGroups(), pControl->GetRect());
  987. }
  988. }
  989. void CXTPRibbonBar::OnGroupsScroll(BOOL bScrollLeft)
  990. {
  991. if (!GetSelectedTab())
  992. return;
  993. GetCommandBars()->ClosePopups();
  994. HideKeyboardTips();
  995. int nGroupsScrollPos = GetSelectedTab()->GetGroups()->m_nGroupsScrollPos;
  996. if (bScrollLeft)
  997. {
  998. nGroupsScrollPos -= 40;
  999. if (nGroupsScrollPos < 0)
  1000. nGroupsScrollPos = 0;
  1001. }
  1002. else
  1003. {
  1004. nGroupsScrollPos += 40;
  1005. }
  1006. if (nGroupsScrollPos != m_nGroupsScrollPos)
  1007. {
  1008. m_nGroupsScrollPos = nGroupsScrollPos;
  1009. OnRecalcLayout();
  1010. }
  1011. }
  1012. CXTPTabPaintManager* CXTPRibbonBar::GetTabPaintManager() const
  1013. {
  1014. return GetRibbonPaintManager()->GetTabPaintManager();
  1015. }
  1016. void CXTPRibbonBar::DrawCommandBar(CDC* pDC, CRect rcClipBox)
  1017. {
  1018. #if 0
  1019. _int64 nPerfomanceEnd;
  1020. _int64 nPerfomanceStart;
  1021. QueryPerformanceCounter((LARGE_INTEGER*)&nPerfomanceStart);
  1022. #endif
  1023. pDC->SetBkMode(TRANSPARENT);
  1024. CXTPPaintManager* pPaintManager = GetPaintManager();
  1025. GetRibbonPaintManager()->FillRibbonBar(pDC, this);
  1026. if (IsFrameThemeEnabled() && CRect().IntersectRect(m_rcCaption, rcClipBox))
  1027. {
  1028. GetRibbonPaintManager()->DrawRibbonFrameCaption(pDC, this, m_pFrameHook->m_bActive);
  1029. }
  1030. else if (m_bShowCaptionAlways && CRect().IntersectRect(m_rcCaption, rcClipBox))
  1031. {
  1032. GetRibbonPaintManager()->DrawRibbonFrameCaptionBar(pDC, this);
  1033. }
  1034. CXTPRibbonTab* pSlectedTab = GetSelectedTab();
  1035. if (IsGroupsVisible())
  1036. {
  1037. GetRibbonPaintManager()->FillGroupRect(pDC, pSlectedTab, m_rcGroups);
  1038. }
  1039. GetTabPaintManager()->m_bDrawTextHidePrefix = !IsKeyboardCuesVisible();
  1040. if (m_pControlTab && CRect().IntersectRect(rcClipBox, m_rcTabControl))
  1041. {
  1042. GetTabPaintManager()->DrawTabControl(m_pControlTab, pDC, m_rcTabControl);
  1043. }
  1044. int i;
  1045. if (pSlectedTab && IsGroupsVisible())
  1046. {
  1047. CXTPRibbonGroups* pGroups = pSlectedTab->GetGroups();
  1048. for (i = 0; i < pGroups->GetCount(); i++)
  1049. {
  1050. CXTPRibbonGroup* pGroup = pGroups->GetAt(i);
  1051. if (pGroup->IsVisible() && CRect().IntersectRect(rcClipBox, pGroup->GetRect()))
  1052. {
  1053. pGroup->Draw(pDC, rcClipBox);
  1054. }
  1055. }
  1056. }
  1057. BOOL bFirst = TRUE;
  1058. for (i = 0; i < GetControlCount(); i++)
  1059. {
  1060. CXTPControl* pControl = GetControl(i);
  1061. if (!pControl->IsVisible())
  1062. continue;
  1063. if (pControl->GetRibbonGroup() != NULL)
  1064. continue;
  1065. if (pControl->GetBeginGroup() && !bFirst)
  1066. {
  1067. pPaintManager->DrawCommandBarSeparator(pDC, this, pControl);
  1068. }
  1069. bFirst = FALSE;
  1070. CRect rc(pControl->GetRect());
  1071. if (CRect().IntersectRect(rcClipBox, rc))
  1072. {
  1073. CXTPFontDC font(pDC, pPaintManager->GetCommandBarFont(this, pControl->IsItemDefault()));
  1074. pControl->Draw(pDC);
  1075. }
  1076. }
  1077. CXTPCommandBars* pCommandBars = GetCommandBars();
  1078. if (pCommandBars && pCommandBars->IsCustomizeMode())
  1079. {
  1080. if (pCommandBars->GetDragControl() && pCommandBars->GetDragControl()->GetParent() == this &&
  1081. pCommandBars->GetDragControl()->IsVisible())
  1082. {
  1083. CRect rc = pCommandBars->GetDragControl()->GetRect();
  1084. pDC->Draw3dRect(rc, 0, 0);
  1085. rc.DeflateRect(1, 1);
  1086. pDC->Draw3dRect(rc, 0, 0);
  1087. }
  1088. if (!m_rcMarker.IsRectEmpty())
  1089. {
  1090. CustomizeDrawMarker(pDC);
  1091. }
  1092. }
  1093. #if 0
  1094. QueryPerformanceCounter((LARGE_INTEGER*)&nPerfomanceEnd);
  1095. TRACE(_T("TotalCounter = %i n"), int(nPerfomanceEnd - nPerfomanceStart));
  1096. #endif
  1097. }
  1098. void CXTPRibbonBar::OnLButtonDblClk(UINT nFlags, CPoint point)
  1099. {
  1100. int nHit = HitTestCaption(point);
  1101. if ((nHit == HTNOWHERE) && IsFrameThemeEnabled() && m_pContextHeaders->HitTest(point))
  1102. nHit = HTCAPTION;
  1103. if (nHit == HTCAPTION)
  1104. {
  1105. CWnd* pSite = GetSite();
  1106. ClientToScreen(&point);
  1107. ::DefWindowProc(pSite->GetSafeHwnd(), WM_NCLBUTTONDBLCLK, nHit, MAKELPARAM(point.x, point.y));
  1108. return;
  1109. }
  1110. CXTPTabManagerItem* pItem = m_pControlTab->HitTest(point);
  1111. if (pItem && pItem == GetSelectedTab() && m_bAllowMinimize)
  1112. {
  1113. if (IsRibbonMinimized())
  1114. {
  1115. SetRibbonMinimized(FALSE);
  1116. }
  1117. else if (m_bMinimizeOnDblClick)
  1118. {
  1119. SetRibbonMinimized(TRUE);
  1120. }
  1121. m_bMinimizeOnDblClick = TRUE;
  1122. }
  1123. CXTPMenuBar::OnLButtonDblClk(nFlags, point);
  1124. }
  1125. int CXTPRibbonBar::HitTestCaption(CPoint point) const
  1126. {
  1127. if (IsCustomizeMode())
  1128. return HTNOWHERE;
  1129. if (!IsFrameThemeEnabled())
  1130. return HTNOWHERE;
  1131. if (m_rcCaption.PtInRect(point) && m_pControls->HitTest(point) == 0)
  1132. {
  1133. if (m_pContextHeaders->HitTest(point))
  1134. return HTNOWHERE;
  1135. DWORD dwStyle = GetSite()->GetStyle();
  1136. if ((point.y < m_rcCaption.top + 5) && (dwStyle & WS_SIZEBOX) && ((dwStyle & WS_MAXIMIZE) == 0))
  1137. return HTTOP;
  1138. return HTCAPTION;
  1139. }
  1140. return HTNOWHERE;
  1141. }
  1142. BOOL CXTPRibbonBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  1143. {
  1144. CPoint pt;
  1145. GetCursorPos(&pt);
  1146. ScreenToClient(&pt);
  1147. int nHit = HitTestCaption(pt);
  1148. if (nHit >= HTSIZEFIRST && nHit <= HTSIZELAST)
  1149. {
  1150. CWnd* pSite = GetSite();
  1151. pSite->SendMessage(WM_SETCURSOR, (WPARAM)pSite->m_hWnd, MAKELPARAM(nHit, message));
  1152. return TRUE;
  1153. }
  1154. return CXTPMenuBar::OnSetCursor(pWnd, nHitTest, message);
  1155. }
  1156. void CXTPRibbonBar::OnLButtonDown(UINT nFlags, CPoint point)
  1157. {
  1158. m_bMinimizeOnDblClick = m_pControlTab->HitTest(point) == GetSelectedTab();
  1159. if (m_bMinimizeOnDblClick && IsRibbonMinimized() && !m_pControlTab->IsPopupBarTracking())
  1160. m_bMinimizeOnDblClick = FALSE;
  1161. CXTPRibbonTabContextHeader* pContextHeader = m_pContextHeaders->HitTest(point);
  1162. if (pContextHeader)
  1163. {
  1164. pContextHeader->m_pFirstTab->Select();
  1165. return;
  1166. }
  1167. int nHit = HitTestCaption(point);
  1168. if (nHit != HTNOWHERE)
  1169. {
  1170. CWnd* pSite = GetSite();
  1171. ClientToScreen(&point);
  1172. GetCommandBars()->ClosePopups();
  1173. UpdateWindow();
  1174. if (pSite->GetStyle() & WS_MAXIMIZE)
  1175. return;
  1176. if (nHit == HTCAPTION)
  1177. {
  1178. ::DefWindowProc(pSite->GetSafeHwnd(), WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
  1179. }
  1180. else if (nHit >= HTSIZEFIRST && nHit <= HTSIZELAST)
  1181. {
  1182. ::DefWindowProc(pSite->GetSafeHwnd(), WM_NCLBUTTONDOWN, nHit, MAKELPARAM(point.x, point.y));
  1183. }
  1184. return;
  1185. }
  1186. if (m_rcTabControl.PtInRect(point))
  1187. {
  1188. GetCommandBars()->ClosePopups();
  1189. }
  1190. if (m_bMinimizeOnDblClick)
  1191. {
  1192. CXTPMenuBar::OnLButtonDown(nFlags, point);
  1193. return;
  1194. }
  1195. if (!m_pControlTab->PerformClick(m_hWnd, point))
  1196. {
  1197. CXTPMenuBar::OnLButtonDown(nFlags, point);
  1198. return;
  1199. }
  1200. else if (IsRibbonMinimized())
  1201. {
  1202. m_pControlTab->ShowPopupBar(FALSE);
  1203. m_bMinimizeOnDblClick = TRUE;
  1204. }
  1205. }
  1206. BOOL CXTPRibbonBar::IsRibbonMinimized() const
  1207. {
  1208. return m_bMinimized;
  1209. }
  1210. void CXTPRibbonBar::SetRibbonMinimized(BOOL bMinimized)
  1211. {
  1212. if (m_bMinimized != bMinimized)
  1213. {
  1214. m_bMinimized = bMinimized;
  1215. if (!m_bMinimized && GetSelectedTab() == NULL)
  1216. {
  1217. m_pControlTab->SetSelectedItem(m_pControlTab->FindNextFocusable(-1, +1));
  1218. }
  1219. RebuildControls(GetSelectedTab());
  1220. //m_pControlTab->RedrawControl(NULL, TRUE);
  1221. OnRecalcLayout();
  1222. GetCommandBars()->ClosePopups();
  1223. }
  1224. }
  1225. void CXTPRibbonBar::OnPopupRButtonUp(CXTPCommandBar* pCommandBar, CPoint point)
  1226. {
  1227. if (!m_bShowQuickAccess)
  1228. return;
  1229. CXTPPopupBar* pPopupBar = DYNAMIC_DOWNCAST(CXTPPopupBar, pCommandBar);
  1230. if (pPopupBar && pPopupBar->GetControlPopup())
  1231. {
  1232. if (pPopupBar->GetControlPopup()->GetID() == XTP_ID_RIBBONCONTROLQUICKACCESS ||
  1233. pPopupBar->GetControlPopup()->GetID() == XTP_ID_RIBBONCONTROLQUICKACCESSMORE)
  1234. return;
  1235. }
  1236. pCommandBar->SetPopuped(-1, FALSE);
  1237. CXTPControl* pControl = pCommandBar->GetControls()->HitTest(point);
  1238. if (pControl)
  1239. {
  1240. ShowContextMenu(point, pControl);
  1241. return;
  1242. }
  1243. CXTPRibbonScrollableBar* pScrollable = GetScrollableBar(pCommandBar);
  1244. if (pScrollable)
  1245. {
  1246. CXTPRibbonGroup* pGroup = pScrollable->HitTestGroup(point);
  1247. if (pGroup && pGroup->GetRect().bottom - GetRibbonPaintManager()->m_nGroupCaptionHeight < point.y)
  1248. {
  1249. ShowContextMenu(point, pGroup->GetControlGroupPopup());
  1250. return;
  1251. }
  1252. }
  1253. }
  1254. void CXTPRibbonBar::OnRButtonUp(UINT nFlags, CPoint point)
  1255. {
  1256. int nHit = HitTestCaption(point);
  1257. if (nHit == HTCAPTION)
  1258. {
  1259. GetCommandBars()->ClosePopups();
  1260. UpdateWindow();
  1261. CWnd* pSite = GetSite();
  1262. ClientToScreen(&point);
  1263. pSite->SendMessage(0x0313, (WPARAM)pSite->GetSafeHwnd(), MAKELPARAM(point.x, point.y));
  1264. return;
  1265. }
  1266. if (IsCustomizeMode())
  1267. return;
  1268. CXTPControl* pControl = m_pControls->HitTest(point);
  1269. if (pControl && GetSite()->SendMessage(WM_XTP_CONTROLRBUTTONUP, (WPARAM)(LPPOINT)&point, (LPARAM)pControl) == TRUE)
  1270. return;
  1271. if (pControl && pControl->OnRButtonUp(point))
  1272. return;
  1273. if (pControl)
  1274. {
  1275. ShowContextMenu(point, pControl);
  1276. return;
  1277. }
  1278. CXTPRibbonGroup* pGroup = HitTestGroup(point);
  1279. if (pGroup && pGroup->GetRect().bottom - GetRibbonPaintManager()->m_nGroupCaptionHeight < point.y)
  1280. {
  1281. ShowContextMenu(point, pGroup->GetControlGroupPopup());
  1282. return;
  1283. }
  1284. if (m_rcQuickAccess.PtInRect(point))
  1285. {
  1286. ShowContextMenu(point, m_pControlTab);
  1287. return;
  1288. }
  1289. CWnd::OnRButtonUp(nFlags, point);
  1290. }
  1291. void CXTPRibbonBar::OnSysColorChange()
  1292. {
  1293. CXTPMenuBar::OnSysColorChange();
  1294. GetRibbonPaintManager()->RefreshMetrics();
  1295. m_pControlTab->Reposition();
  1296. }
  1297. void CXTPRibbonBar::RefreshSysButtons()
  1298. {
  1299. CXTPMenuBar::RefreshSysButtons();
  1300. if (IsFrameThemeEnabled())
  1301. {
  1302. CString strWindowText;
  1303. GetSite()->GetWindowText(strWindowText);
  1304. if (strWindowText != m_strCaptionText)
  1305. DelayLayout();
  1306. }
  1307. }
  1308. INT_PTR CXTPRibbonBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  1309. {
  1310. INT_PTR nHit = m_pControlTab ? m_pControlTab->PerformToolHitTest(m_hWnd, point, pTI) : -1;
  1311. if (nHit != -1)
  1312. return nHit;
  1313. nHit = CXTPMenuBar::OnToolHitTest(point, pTI);
  1314. if (nHit == -1)
  1315. return -1;
  1316. if (pTI != NULL && pTI->cbSize == sizeof(XTP_TOOLTIP_TOOLINFO_EX) && m_pToolTipContext
  1317. && m_pToolTipContext->IsShowTitleAndDescription())
  1318. {
  1319. XTP_TOOLTIP_CONTEXT* tc = ((XTP_TOOLTIP_TOOLINFO_EX*)pTI)->pToolInfo;
  1320. if (tc && tc->pObject && ((CXTPControl*)tc->pObject)->GetRibbonGroup())
  1321. {
  1322. tc->rcExclude = m_rcGroups;
  1323. }
  1324. }
  1325. return nHit;
  1326. }
  1327. CXTPRibbonGroup* CXTPRibbonBar::HitTestGroup(CPoint point) const
  1328. {
  1329. CXTPRibbonTab* pTab = GetSelectedTab();
  1330. if (!pTab)
  1331. return NULL;
  1332. if (!IsGroupsVisible())
  1333. return NULL;
  1334. if (!m_rcGroups.PtInRect(point))
  1335. return NULL;
  1336. if (m_pControlScrollGroupsLeft && m_pControlScrollGroupsLeft->IsVisible() &&
  1337. m_pControlScrollGroupsLeft->GetRect().PtInRect(point))
  1338. return NULL;
  1339. if (m_pControlScrollGroupsRight && m_pControlScrollGroupsRight->IsVisible() &&
  1340. m_pControlScrollGroupsRight->GetRect().PtInRect(point))
  1341. return NULL;
  1342. return pTab->GetGroups()->HitTest(point);
  1343. }
  1344. BOOL CXTPRibbonBar::IsDwmEnabled() const
  1345. {
  1346. return m_pFrameHook && m_pFrameHook->IsDwmEnabled();
  1347. }
  1348. LRESULT CXTPRibbonBar::OnNcHitTest(CPoint point)
  1349. {
  1350. if (IsDwmEnabled())
  1351. {
  1352. LRESULT lResult = 0;
  1353. CXTPWinDwmWrapper().DefWindowProc(GetSite()->GetSafeHwnd(), WM_NCHITTEST, 0, MAKELPARAM(point.x, point.y), &lResult);
  1354. if (lResult == HTMINBUTTON || lResult == HTMAXBUTTON || lResult == HTCLOSE || lResult == HTHELP)
  1355. {
  1356. return HTTRANSPARENT;
  1357. }
  1358. }
  1359. return CXTPMenuBar::OnNcHitTest(point);
  1360. }
  1361. void CXTPRibbonBar::OnMouseMove(UINT nFlags, CPoint point)
  1362. {
  1363. CXTPCommandBars* pCommandBars = GetCommandBars ();
  1364. CXTPMouseManager* pMouseManager = pCommandBars->GetMouseManager();
  1365. BOOL bMouseLocked = pMouseManager->IsMouseLocked() || !pMouseManager->IsTopParentActive(m_hWnd)
  1366. || pMouseManager->IsTrackedLock(this) || m_nPopuped != -1;
  1367. CXTPRibbonGroup* pHighlightedGroup = bMouseLocked || !GetRibbonPaintManager()->m_bHotTrackingGroups ?
  1368. NULL : HitTestGroup(point);
  1369. if (pHighlightedGroup != m_pHighlightedGroup)
  1370. {
  1371. HighlightGroup(pHighlightedGroup);
  1372. if (m_pHighlightedGroup)
  1373. {
  1374. pMouseManager->TrackMouseLeave(*this);
  1375. }
  1376. }
  1377. if (!bMouseLocked && m_pControlTab)
  1378. {
  1379. m_pControlTab->PerformMouseMove(m_hWnd, point);
  1380. }
  1381. CXTPMenuBar::OnMouseMove(nFlags, point);
  1382. }
  1383. void CXTPRibbonBar::OnMouseLeave()
  1384. {
  1385. if (m_pControlTab) m_pControlTab->PerformMouseMove(m_hWnd, CPoint(-1, -1));
  1386. HighlightGroup(NULL);
  1387. CXTPMenuBar::OnMouseLeave();
  1388. }
  1389. CXTPRibbonTab* CXTPRibbonBar::GetTab(int nIndex) const
  1390. {
  1391. return (CXTPRibbonTab*)m_pControlTab->GetItem(nIndex);
  1392. }
  1393. int CXTPRibbonBar::GetTabCount() const
  1394. {
  1395. return m_pControlTab->GetItemCount();
  1396. }
  1397. BOOL CXTPRibbonBar::PreviewAccel(UINT chAccel)
  1398. {
  1399. if (GetKeyState(VK_CONTROL) < 0)
  1400. return FALSE;
  1401. CXTPCommandBars* pCommandBars = GetCommandBars();
  1402. if (chAccel == (UINT)VK_MENU && GetTabCount() > 0)
  1403. {
  1404. pCommandBars->ClosePopups();
  1405. pCommandBars->ShowKeyboardCues(TRUE);
  1406. pCommandBars->m_keyboardTips.nLevel = 1;
  1407. if (IsRibbonMinimized())
  1408. {
  1409. SetTrackingMode(TRUE, TRUE, TRUE);
  1410. }
  1411. else
  1412. {
  1413. SetTrackingMode(TRUE, FALSE, TRUE);
  1414. SetSelected(m_pControlTab->GetIndex(), TRUE);
  1415. m_pControlTab->SetFocused(TRUE);
  1416. }
  1417. return TRUE;
  1418. }
  1419. if (chAccel > '0' && chAccel <= '9')
  1420. {
  1421. int nIndex = chAccel - '0' - 1;
  1422. CXTPControl* pControl = m_pQuickAccessControls->GetVisibleAt(nIndex);
  1423. if (pControl && pControl->GetEnabled())
  1424. {
  1425. nIndex = pControl->GetIndex();
  1426. pCommandBars->ClosePopups();
  1427. pCommandBars->ShowKeyboardCues(TRUE);
  1428. pCommandBars->m_keyboardTips.nLevel = 2;
  1429. SetTrackingMode(TRUE, FALSE, TRUE);
  1430. SetSelected(nIndex, TRUE);
  1431. pControl->OnUnderlineActivate();
  1432. return TRUE;
  1433. }
  1434. }
  1435. for (int i = 0; i < GetTabCount(); i++)
  1436. {
  1437. CXTPRibbonTab* pTab = GetTab(i);
  1438. CString strCaption = pTab->GetCaption();
  1439. if (!strCaption.IsEmpty() && pTab->IsEnabled() && pTab->IsVisible())
  1440. {
  1441. int nAmpIndex = strCaption.Find(_T('&'));
  1442. BOOL bFound = nAmpIndex > -1 && nAmpIndex < strCaption.GetLength() - 1;
  1443. if (bFound && CXTPShortcutManager::CompareAccelKey(strCaption[nAmpIndex + 1], chAccel))
  1444. {
  1445. if (!IsTrackingMode())
  1446. pCommandBars->ClosePopups();
  1447. pCommandBars->ShowKeyboardCues(TRUE);
  1448. m_bKeyboardSelect = TRUE;
  1449. pCommandBars->m_keyboardTips.nLevel = 1;
  1450. SetCurSel(i);
  1451. SetTrackingMode(TRUE, FALSE, TRUE);
  1452. SetSelected(m_pControlTab->GetIndex(), TRUE);
  1453. m_pControlTab->SetFocused(TRUE);
  1454. if (!IsRibbonMinimized()) pCommandBars->ShowKeyboardTips(this, 2);
  1455. m_pControlTab->ShowPopupBar(TRUE);
  1456. return TRUE;
  1457. }
  1458. }
  1459. }
  1460. return FALSE;
  1461. }
  1462. BOOL CXTPRibbonBar::IsKeyboardCuesVisible() const
  1463. {
  1464. CXTPCommandBars* pCommandBars = GetCommandBars();
  1465. if (!pCommandBars)
  1466. return TRUE;
  1467. if (pCommandBars->GetCommandBarsOptions()->bShowKeyboardTips)
  1468. return FALSE;
  1469. return pCommandBars->m_bKeyboardCuesVisible;
  1470. }
  1471. BOOL CXTPRibbonBar::SetTrackingMode(int bMode, BOOL bSelectFirst, BOOL bKeyboard)
  1472. {
  1473. m_pControlTab->PerformMouseMove(m_hWnd, CPoint(-1, -1));
  1474. if (m_bTracking || bMode) HighlightGroup(NULL);
  1475. return CXTPMenuBar::SetTrackingMode(bMode, bSelectFirst, bKeyboard);
  1476. }
  1477. BOOL CXTPRibbonBar::IsAllowQuickAccessControl(CXTPControl* pControl)
  1478. {
  1479. if (!pControl)
  1480. return FALSE;
  1481. if (!m_bAllowQuickAccessDuplicates)
  1482. {
  1483. CXTPControl* pControlQuickAccess = m_pQuickAccessControls->FindDuplicate(pControl);
  1484. if (pControlQuickAccess)
  1485. {
  1486. return FALSE;
  1487. }
  1488. }
  1489. if (pControl->IsKindOf(RUNTIME_CLASS(CXTPRibbonGroupControlPopup)))
  1490. {
  1491. return pControl->GetID() > 0;
  1492. }
  1493. if ((pControl->GetFlags() & xtpFlagNoMovable) == 0)
  1494. return TRUE;
  1495. return FALSE;
  1496. }
  1497. void CXTPRibbonBar::ShowContextMenu(CPoint point, CXTPControl* pSelectedControl)
  1498. {
  1499. if (!pSelectedControl)
  1500. return;
  1501. pSelectedControl->GetParent()->ClientToScreen(&point);
  1502. CXTPPopupBar* pPopupBar = CreateContextMenu(pSelectedControl);
  1503. if (!pPopupBar)
  1504. return;
  1505. CWnd* pSite = m_bShowQuickAccess ? this : GetOwnerSite();
  1506. CXTPMouseManager* pMouseManager = XTPMouseManager();
  1507. if (pPopupBar->GetControls()->GetVisibleCount() > 0)
  1508. {
  1509. BOOL bLocked = pMouseManager->IsMouseLocked();
  1510. if (bLocked) pMouseManager->UnlockMouseMove();
  1511. CXTPCommandBars::TrackPopupMenu(pPopupBar, TPM_RIGHTBUTTON | (pSelectedControl->GetParent() == this ? 0 : TPM_RECURSE),
  1512. point.x, point.y, pSite, NULL, pSite);
  1513. if (bLocked) pMouseManager->LockMouseMove();
  1514. }
  1515. pPopupBar->InternalRelease();
  1516. }
  1517. CXTPPopupBar* CXTPRibbonBar::CreateMoreQuickAccessContextMenu()
  1518. {
  1519. CXTPPopupBar* pPopupBar = new CXTPRibbonBarMorePopupToolBar(this);
  1520. for (int i = 0; i < m_pQuickAccessControls->GetCount(); i++)
  1521. {
  1522. CXTPControl* pControl = m_pQuickAccessControls->GetAt(i);
  1523. if (pControl->GetHideFlags() & xtpHideWrap)
  1524. {
  1525. CXTPControl* pClone = pPopupBar->GetControls()->AddClone(pControl);
  1526. pClone->SetHideFlag(xtpHideWrap, FALSE);
  1527. }
  1528. }
  1529. CXTPControl* pClone = pPopupBar->GetControls()->AddClone(m_pControlQuickAccess);
  1530. pClone->SetHideFlag(xtpHideWrap, FALSE);
  1531. pPopupBar->SetWidth(300);
  1532. return pPopupBar;
  1533. }
  1534. CXTPPopupBar* CXTPRibbonBar::CreateContextMenu(CXTPControl* pSelectedControl)
  1535. {
  1536. if (!m_bShowQuickAccess)
  1537. {
  1538. CXTPPopupBar* pPopupBar = GetCommandBars()->GetToolbarsPopup();
  1539. GetSite()->SendMessage(WM_XTP_TOOLBARCONTEXTMENU, (WPARAM)this, (LPARAM)pPopupBar);
  1540. return pPopupBar;
  1541. }
  1542. if (!pSelectedControl)
  1543. return NULL;
  1544. if (pSelectedControl->GetType() == xtpControlGallery &&
  1545. ((CXTPControlPopup*)pSelectedControl)->GetCommandBar() == NULL &&
  1546. DYNAMIC_DOWNCAST(CXTPPopupBar, pSelectedControl->GetParent()))
  1547. {
  1548. pSelectedControl = ((CXTPPopupBar*)pSelectedControl->GetParent())->GetControlPopup();
  1549. }
  1550. CXTPCommandBars* pCommandBars = GetCommandBars();
  1551. BOOL bMoreMenu = pSelectedControl->GetID() == XTP_ID_RIBBONCONTROLQUICKACCESS;
  1552. CMenu menu;
  1553. if (!XTPResourceManager()->LoadMenu(&menu, bMoreMenu ? XTP_IDR_RIBBONCUSTOMIZEMENUMORE : XTP_IDR_RIBBONCUSTOMIZEMENU))
  1554. return NULL;
  1555. CXTPPopupBar* pPopupBar = CXTPPopupBar::CreatePopupBar(pCommandBars);
  1556. pPopupBar->SetOwner(this);
  1557. pPopupBar->LoadMenu(menu.GetSubMenu(0));
  1558. CXTPControl* pControlToolbars = pPopupBar->GetControls()->InsertAt(new CXTPControlToolbars, bMoreMenu ? 0 : 2);
  1559. pControlToolbars->SetBeginGroup(TRUE);
  1560. BOOL bQuickAccess = IsQuickAccessControl(pSelectedControl);
  1561. BOOL bAllow = IsAllowQuickAccessControl(pSelectedControl);
  1562. BOOL bSystem = (pSelectedControl->GetFlags() & xtpFlagNoMovable) || pSelectedControl->IsTemporary();
  1563. for (int i = 0; i < pPopupBar->GetControlCount(); i++)
  1564. {
  1565. CXTPControl* pControl = pPopupBar->GetControl(i);
  1566. if (pControl->GetID() == XTP_ID_RIBBONCUSTOMIZE_MORE)
  1567. pControl->SetID(XTP_ID_RIBBONCUSTOMIZE);
  1568. if (pControl->GetID() == XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSBELOW_MORE)
  1569. pControl->SetID(XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSBELOW);
  1570. if (pControl->GetID() == XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSABOVE_MORE)
  1571. pControl->SetID(XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSABOVE);
  1572. switch(pControl->GetID())
  1573. {
  1574. case XTP_ID_RIBBONCUSTOMIZE_REMOVE:
  1575. pControl->SetVisible(bQuickAccess && !bSystem && m_bAllowQuickAccessCustomization);
  1576. pControl->SetTag((DWORD_PTR)pSelectedControl);
  1577. break;
  1578. case XTP_ID_RIBBONCUSTOMIZE_ADD:
  1579. pControl->SetVisible(!bQuickAccess && !bSystem && m_bAllowQuickAccessCustomization);
  1580. pControl->SetEnabled(bAllow);
  1581. pControl->SetTag((DWORD_PTR)pSelectedControl);
  1582. break;
  1583. case XTP_ID_RIBBONCUSTOMIZE:
  1584. if (!m_bAllowQuickAccessCustomization)
  1585. {
  1586. if (pCommandBars->IsCustomizeAvail())
  1587. pControl->SetCaption(XTP_IDS_CUSTOMIZE);
  1588. else
  1589. pControl->SetVisible(FALSE);
  1590. }
  1591. break;
  1592. case XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSBELOW:
  1593. pControl->SetVisible(m_bShowQuickAccess && !m_bShowQuickAccessBelow);
  1594. break;
  1595. case XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSABOVE:
  1596. pControl->SetVisible(m_bShowQuickAccess && m_bShowQuickAccessBelow);
  1597. break;
  1598. case XTP_ID_RIBBONCUSTOMIZE_LABEL:
  1599. pControl = pPopupBar->GetControls()->SetControlType(i, xtpControlLabel);
  1600. pControl->SetFlags(xtpFlagSkipFocus);
  1601. pControl->SetItemDefault(TRUE);
  1602. pControl->SetVisible(m_bAllowQuickAccessCustomization && GetQuickAccessControls()->GetOriginalControls());
  1603. break;
  1604. case XTP_ID_RIBBONCUSTOMIZE_MINIMIZE:
  1605. pControl->SetVisible(m_bAllowMinimize);
  1606. pControl->SetChecked(m_bMinimized);
  1607. if (GetTabCount() == 0)
  1608. pControl->SetEnabled(FALSE);
  1609. break;
  1610. case XTP_ID_RIBBONCUSTOMIZE_COMMANDS:
  1611. {
  1612. pControl->SetHideFlags(xtpHideGeneric);
  1613. CXTPControls* pCommands = GetQuickAccessControls()->GetOriginalControls();
  1614. if (!pCommands)
  1615. continue;
  1616. if (!m_bAllowQuickAccessCustomization)
  1617. continue;
  1618. for (int j = 0; j < pCommands->GetCount(); j++)
  1619. {
  1620. CXTPControl* pControlOriginal = pCommands->GetAt(j);
  1621. CControlQuickAccessCommand* pControlCommand = new CControlQuickAccessCommand(GetQuickAccessControls(), pControlOriginal);
  1622. pPopupBar->GetControls()->Add(pControlCommand, 0, NULL, i, TRUE);
  1623. pControlCommand->SetCaption(pControlOriginal->GetCaption());
  1624. CXTPControl* pControlQuickAccess = GetQuickAccessControls()->FindDuplicate(pControlOriginal);
  1625. if (pControlQuickAccess)
  1626. {
  1627. pControlCommand->SetQuickAccessControl(pControlQuickAccess);
  1628. }
  1629. i++;
  1630. }
  1631. }
  1632. break;
  1633. default:
  1634. continue;
  1635. }
  1636. pControl->SetFlags(pControl->GetFlags() | xtpFlagManualUpdate);
  1637. }
  1638. GetSite()->SendMessage(WM_XTP_TOOLBARCONTEXTMENU, (WPARAM)this, (LPARAM)pPopupBar);
  1639. return pPopupBar;
  1640. }
  1641. void CXTPRibbonBar::SelectNextTab(BOOL bNext)
  1642. {
  1643. m_pControlTab->PerformKeyDown(m_hWnd, !bNext ? VK_LEFT : VK_RIGHT);
  1644. }
  1645. int CXTPRibbonBar::OnHookMessage(HWND hWnd, UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
  1646. {
  1647. if (IsTrackingMode() && nMessage == WM_CONTEXTMENU)
  1648. {
  1649. if (lParam != -1)
  1650. return TRUE;
  1651. CXTPControl* pControl = GetControl(m_nSelected);
  1652. if (!pControl)
  1653. return TRUE;
  1654. ShowContextMenu(pControl->GetRect().TopLeft(), pControl);
  1655. return TRUE;
  1656. }
  1657. if (IsTrackingMode() && nMessage == WM_MOUSEWHEEL && !GetCommandBars()->GetMouseManager()->IsMouseLocked()
  1658. && !IsKeyboardTipsVisible())
  1659. {
  1660. SelectNextTab((short)HIWORD(wParam) <= 0);
  1661. return TRUE;
  1662. }
  1663. return CXTPMenuBar::OnHookMessage(hWnd, nMessage, wParam, lParam, lResult);
  1664. }
  1665. void CXTPRibbonBar::OnRButtonDown(UINT nFlags, CPoint point)
  1666. {
  1667. CXTPCommandBars* pCommandBars = GetCommandBars();
  1668. if (!pCommandBars) return;
  1669. if (IsCustomizeMode())
  1670. {
  1671. CXTPCommandBar::OnRButtonDown(nFlags, point);
  1672. return;
  1673. }
  1674. SetTrackingMode(FALSE);
  1675. int nHit = HitTestCaption(point);
  1676. if (nHit != HTNOWHERE)
  1677. return;
  1678. CXTPControl* pControl = m_pControls->HitTest(point);
  1679. if (pControl && pControl->OnRButtonDown(point))
  1680. return;
  1681. }
  1682. void CXTPRibbonBar::OnCustomizePlaceQuickAccess(UINT nCommand)
  1683. {
  1684. GetCommandBars()->ClosePopups();
  1685. ShowQuickAccessBelowRibbon(nCommand == XTP_ID_RIBBONCUSTOMIZE_QUICKACCESSBELOW);
  1686. }
  1687. LRESULT CXTPRibbonBar::OnCustomizeCommand(WPARAM wParam, LPARAM lParam)
  1688. {
  1689. NMXTPCONTROL* tagNMCONTROL = (NMXTPCONTROL*)lParam;
  1690. CXTPControl* pControl = (CXTPControl*)tagNMCONTROL->pControl->GetTag();
  1691. if (wParam == XTP_ID_RIBBONCUSTOMIZE_ADD)
  1692. {
  1693. GetCommandBars()->ClosePopups();
  1694. m_bInRecalcLayout = TRUE;
  1695. pControl = m_pQuickAccessControls->AddClone(pControl, -1, TRUE);
  1696. pControl->SetBeginGroup(FALSE);
  1697. pControl->SetVisible(TRUE);
  1698. if (pControl->GetType() == xtpControlGallery || pControl->GetType() == xtpControlPopup)
  1699. pControl->SetStyle(xtpButtonIcon);
  1700. else
  1701. pControl->SetStyle(xtpButtonAutomatic);
  1702. m_bInRecalcLayout = FALSE;
  1703. OnRecalcLayout();
  1704. return TRUE;
  1705. }
  1706. if (wParam == XTP_ID_RIBBONCUSTOMIZE_REMOVE)
  1707. {
  1708. m_pQuickAccessControls->Remove(pControl);
  1709. OnRecalcLayout();
  1710. return TRUE;
  1711. }
  1712. if (wParam == XTP_ID_RIBBONCUSTOMIZE)
  1713. {
  1714. GetCommandBars()->ClosePopups();
  1715. CWnd* pOwner = GetOwnerSite();
  1716. if (pOwner->SendMessage(WM_XTP_COMMAND, wParam, lParam) == 0)
  1717. {
  1718. pOwner->SendMessage(WM_COMMAND, wParam);
  1719. }
  1720. return TRUE;
  1721. }
  1722. if (wParam == XTP_ID_RIBBONCUSTOMIZE_MINIMIZE)
  1723. {
  1724. SetRibbonMinimized(!IsRibbonMinimized());
  1725. return TRUE;
  1726. }
  1727. return FALSE;
  1728. }
  1729. BOOL CXTPRibbonBar::ShouldSerializeBar()
  1730. {
  1731. return TRUE;
  1732. }
  1733. void CXTPRibbonBar::GenerateCommandBarList(DWORD& nID, CXTPCommandBarList* pCommandBarList, XTP_COMMANDBARS_PROPEXCHANGE_PARAM* pParam)
  1734. {
  1735. if (IsCustomizable())
  1736. {
  1737. CXTPMenuBar::GenerateCommandBarList(nID, pCommandBarList, pParam);
  1738. }
  1739. else
  1740. {
  1741. if (!pCommandBarList->Lookup(this))
  1742. {
  1743. pCommandBarList->Add(this);
  1744. InternalAddRef();
  1745. ASSERT(m_nBarID != 0);
  1746. m_pQuickAccessControls->GenerateCommandBarList(nID, pCommandBarList, pParam);
  1747. }
  1748. }
  1749. }
  1750. void CXTPRibbonBar::RestoreCommandBarList(CXTPCommandBarList* pCommandBarList)
  1751. {
  1752. if (IsCustomizable())
  1753. {
  1754. CXTPMenuBar::RestoreCommandBarList(pCommandBarList);
  1755. }
  1756. else
  1757. {
  1758. m_pQuickAccessControls->RestoreCommandBarList(pCommandBarList);
  1759. }
  1760. }
  1761. void CXTPRibbonBar::DoPropExchange(CXTPPropExchange* pPX)
  1762. {
  1763. if (pPX->IsLoading())
  1764. {
  1765. ASSERT(pPX->m_dwData != 0);
  1766. if (pPX->m_dwData) SetCommandBars(((XTP_COMMANDBARS_PROPEXCHANGE_PARAM*)pPX->m_dwData)->pCommandBars);
  1767. }
  1768. PX_Bool(pPX, _T("ShowQuickAccessBelow"), m_bShowQuickAccessBelow, FALSE);
  1769. if (pPX->GetSchema() > _XTP_SCHEMA_103)
  1770. PX_Bool(pPX, _T("Minimized"), m_bMinimized, FALSE);
  1771. if (pPX->GetSchema() > _XTP_SCHEMA_110)
  1772. PX_Bool(pPX, _T("Customizable"), m_bCustomizable, FALSE);
  1773. if (IsCustomizable())
  1774. {
  1775. CXTPMenuBar::DoPropExchange(pPX);
  1776. CXTPPropExchangeSection secSystemButton(pPX->GetSection(_T("SystemButton")));
  1777. BOOL bSystemButton = m_pControlSystemButton != NULL;
  1778. PX_Bool(&secSystemButton, _T("SystemButton"), bSystemButton, TRUE);
  1779. if (bSystemButton && pPX->IsLoading())
  1780. {
  1781. GetControls()->Remove(m_pControlSystemButton);
  1782. m_pControlSystemButton = NULL;
  1783. PX_Object(&secSystemButton, m_pControlSystemButton, RUNTIME_CLASS(CXTPRibbonControlSystemButton));
  1784. GetControls()->InsertAt(m_pControlSystemButton, 0);
  1785. }
  1786. else if (bSystemButton && pPX->IsStoring())
  1787. {
  1788. PX_Object(&secSystemButton, m_pControlSystemButton, RUNTIME_CLASS(CXTPRibbonControlSystemButton));
  1789. }
  1790. CXTPPropExchangeSection secTabs(pPX->GetSection(_T("Tabs")));
  1791. m_pControlTab->DoPropExchange(&secTabs);
  1792. }
  1793. CXTPPropExchangeSection secControls(pPX->GetSection(_T("QuickAccessControls")));
  1794. m_pQuickAccessControls->DoPropExchange(&secControls);
  1795. }
  1796. void CXTPRibbonBar::Copy(CXTPCommandBar* pCommandBar, BOOL bRecursive /*= FALSE*/)
  1797. {
  1798. CXTPRibbonBar* pRibbonBar = (CXTPRibbonBar*)pCommandBar;
  1799. m_bShowQuickAccessBelow = pRibbonBar->m_bShowQuickAccessBelow;
  1800. m_bMinimized = pRibbonBar->m_bMinimized;
  1801. if (m_bMinimized)
  1802. {
  1803. m_pControlTab->SetSelectedItem(NULL);
  1804. }
  1805. if (pRibbonBar->IsCustomizable())
  1806. {
  1807. CXTPMenuBar::Copy(pCommandBar, bRecursive);
  1808. m_pControlTab->Copy(pRibbonBar->m_pControlTab);
  1809. GetControls()->Remove(m_pControlSystemButton);
  1810. m_pControlSystemButton = NULL;
  1811. if (pRibbonBar->m_pControlSystemButton)
  1812. {
  1813. m_pControlSystemButton = (CXTPControlPopup*)GetControls()->AddClone(pRibbonBar->m_pControlSystemButton,
  1814. 0, TRUE);
  1815. }
  1816. RebuildControls(GetSelectedTab());
  1817. }
  1818. m_pQuickAccessControls->RemoveAll();
  1819. for (int i = 0; i < pRibbonBar->GetQuickAccessControls()->GetCount(); i++)
  1820. {
  1821. m_pQuickAccessControls->AddClone(pRibbonBar->GetQuickAccessControls()->GetAt(i), -1, FALSE);
  1822. }
  1823. }
  1824. void CXTPRibbonBar::MergeToolBar(CXTPCommandBar* pCommandBar, BOOL /*bSilent*/)
  1825. {
  1826. Copy(pCommandBar, FALSE);
  1827. }
  1828. CXTPRibbonTab* CXTPRibbonBar::FindTab(int nId) const
  1829. {
  1830. return m_pControlTab->FindTab(nId);
  1831. }
  1832. CXTPRibbonGroup* CXTPRibbonBar::FindGroup(int nId) const
  1833. {
  1834. for (int i = 0; i < GetTabCount(); i++)
  1835. {
  1836. CXTPRibbonTab* pTab = GetTab(i);
  1837. CXTPRibbonGroup* pGroup = pTab->FindGroup(nId);
  1838. if (pGroup)
  1839. return pGroup;
  1840. }
  1841. return NULL;
  1842. }
  1843. void CXTPRibbonBar::ShowQuickAccessBelowRibbon(BOOL bBelow)
  1844. {
  1845. m_bShowQuickAccessBelow = bBelow;
  1846. OnRecalcLayout();
  1847. if (IsDwmEnabled())
  1848. {
  1849. UpdateWindow();
  1850. m_pFrameHook->UpdateFrameRegion();
  1851. }
  1852. else if (IsFrameThemeEnabled())
  1853. {
  1854. m_pFrameHook->GetSite()->SendMessage(WM_NCPAINT);
  1855. }
  1856. }
  1857. BOOL CXTPRibbonBar::IsQuickAccessBelowRibbon() const
  1858. {
  1859. return m_bShowQuickAccessBelow;
  1860. }
  1861. void CXTPRibbonBar::RemoveAllTabs()
  1862. {
  1863. m_pControlTab->DeleteAllItems();
  1864. }
  1865. void CXTPRibbonBar::RemoveTab(int nIndex)
  1866. {
  1867. CXTPRibbonTab* pTab = GetTab(nIndex);
  1868. if (!pTab)
  1869. return;
  1870. pTab->Remove();
  1871. }
  1872. CSize CXTPRibbonBar::GetButtonSize() const
  1873. {
  1874. if (m_szButtons != CSize(0)) return m_szButtons;
  1875. int nHeight = GetPaintManager()->GetControlHeight();
  1876. return CSize(nHeight, nHeight);
  1877. }
  1878. void CXTPRibbonBar::SetFontHeight(int nFontHeight)
  1879. {
  1880. GetRibbonPaintManager()->SetFontHeight(nFontHeight);
  1881. OnRecalcLayout();
  1882. if (IsDwmEnabled())
  1883. {
  1884. UpdateWindow();
  1885. m_pFrameHook->UpdateFrameRegion();
  1886. }
  1887. if (m_pFrameHook)
  1888. {
  1889. m_pFrameHook->RedrawFrame();
  1890. }
  1891. }
  1892. int CXTPRibbonBar::GetFontHeight() const
  1893. {
  1894. return GetRibbonPaintManager()->GetFontHeight();
  1895. }
  1896. //////////////////////////////////////////////////////////////////////////
  1897. //////////////////////////////////////////////////////////////////////////
  1898. void CXTPRibbonBar::OnKeyboardTip(CXTPCommandBarKeyboardTip* pTip)
  1899. {
  1900. CXTPControl* pControl = DYNAMIC_DOWNCAST(CXTPControl, pTip->m_pOwner);
  1901. if (pControl)
  1902. {
  1903. if (pTip->m_bVisible == FALSE && pControl->GetHideFlags() == xtpHideWrap)
  1904. {
  1905. CXTPRibbonGroup* pGroup = pControl->GetRibbonGroup();
  1906. if (pGroup && pGroup->GetControlGroupPopup())
  1907. {
  1908. EnsureVisible(pGroup->GetControlGroupPopup());
  1909. pGroup->GetControlGroupPopup()->OnUnderlineActivate();
  1910. int nIndex = pGroup->IndexOf(pControl);
  1911. CXTPCommandBar* pPopupToolBar = pGroup->GetControlGroupPopup()->GetCommandBar();
  1912. if (pPopupToolBar && pPopupToolBar->IsTrackingMode() && nIndex >= 0 &&
  1913. nIndex < pPopupToolBar->GetControlCount())
  1914. {
  1915. GetCommandBars()->ShowKeyboardTips(pPopupToolBar);
  1916. pPopupToolBar->GetControl(nIndex)->OnUnderlineActivate();
  1917. }
  1918. }
  1919. return;
  1920. }
  1921. if (pControl->IsVisible())
  1922. {
  1923. pControl->OnUnderlineActivate();
  1924. }
  1925. return;
  1926. }
  1927. CXTPRibbonTab* pTab = DYNAMIC_DOWNCAST(CXTPRibbonTab, pTip->m_pOwner);
  1928. if (pTab)
  1929. {
  1930. SetCurSel(pTab->GetIndex());
  1931. SetTrackingMode(TRUE, FALSE, TRUE);
  1932. SetSelected(m_pControlTab->GetIndex(), TRUE);
  1933. m_pControlTab->SetFocused(TRUE);
  1934. m_pControlTab->ShowPopupBar(TRUE);
  1935. if (!IsRibbonMinimized()) GetCommandBars()->ShowKeyboardTips(this, 2);
  1936. return;
  1937. }
  1938. }
  1939. void CXTPRibbonScrollableBar::CreateControlKeyboardTips(CXTPControl* pControl, LPCTSTR lpszPrefix, BOOL bVisible)
  1940. {
  1941. if (!pControl || (pControl->GetFlags() & xtpFlagSkipFocus))
  1942. return;
  1943. CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars();
  1944. CXTPRibbonTheme* pPaintManager = (CXTPRibbonTheme*)pCommandBars->GetPaintManager();
  1945. CRect rcGroups = GetGroupsRect();
  1946. if (pControl->GetCaption().IsEmpty() && pControl->GetKeyboardTip().IsEmpty())
  1947. return;
  1948. CXTPRibbonGroup* pGroup = pControl->GetRibbonGroup();
  1949. ASSERT(pGroup);
  1950. if (!pGroup)
  1951. return;
  1952. CRect rc(pControl->GetRect());
  1953. CPoint pt(rc.left + 21, pControl->GetRect().bottom - 4);
  1954. DWORD dwAlign = DT_TOP;
  1955. CRect rcGroup = pGroup->GetRect();
  1956. CRect rcCaption(rcGroup.left, rcGroup.bottom - pPaintManager->GetGroupCaptionHeight() + 2, rcGroup.right, rcGroup.bottom);
  1957. rcGroup.bottom = rcCaption.top;
  1958. if (CRect().IntersectRect(rc, rcCaption))
  1959. {
  1960. pt = CPoint(rc.CenterPoint().x, rcGroups.bottom - 6);
  1961. dwAlign = DT_TOP | DT_CENTER;
  1962. }
  1963. else if (pControl->GetStyle() == xtpButtonIconAndCaptionBelow && rc.Height() > rcGroup.Height() / 2)
  1964. {
  1965. pt = CPoint(rc.CenterPoint().x, rcGroup.bottom - 2);
  1966. dwAlign = DT_CENTER | DT_VCENTER;
  1967. }
  1968. else if (pControl->GetType() == xtpControlGallery)
  1969. {
  1970. pt = CPoint(rc.right, rcGroup.bottom - 2);
  1971. dwAlign = DT_CENTER | DT_VCENTER;
  1972. }
  1973. else if (rc.CenterPoint().y < rcGroup.top + rcGroup.Height() * 1 / 3)
  1974. {
  1975. pt = CPoint(rc.left + 11, rcGroup.top + 2);
  1976. dwAlign = DT_LEFT | DT_VCENTER;
  1977. }
  1978. else if (rc.CenterPoint().y > rcGroup.top + rcGroup.Height() * 2 / 3)
  1979. {
  1980. pt = CPoint(rc.left + 11, rcGroup.bottom - 2);
  1981. dwAlign = DT_LEFT | DT_VCENTER;
  1982. }
  1983. else
  1984. {
  1985. pt = CPoint(rc.left + 11, rcGroup.CenterPoint().y - 1);
  1986. dwAlign = DT_LEFT | DT_VCENTER;
  1987. }
  1988. if (pControl->GetType() == xtpControlCheckBox || pControl->GetType() == xtpControlRadioButton)
  1989. {
  1990. pt.x = rc.left + 6;
  1991. }
  1992. if ((pControl->GetType() == xtpControlComboBox || pControl->GetType() == xtpControlEdit)
  1993. && pControl->GetStyle() == xtpButtonAutomatic)
  1994. {
  1995. pt.x = rc.CenterPoint().x;
  1996. dwAlign |= DT_CENTER;
  1997. }
  1998. CXTPCommandBarKeyboardTip* pWnd = new CXTPCommandBarKeyboardTip(pCommandBars, pControl, pControl->GetCaption(), pt, dwAlign, pControl->GetEnabled());
  1999. if (!pControl->GetKeyboardTip().IsEmpty())
  2000. {
  2001. pWnd->m_strTip = pControl->GetKeyboardTip();
  2002. }
  2003. if (lpszPrefix)
  2004. {
  2005. pWnd->m_strPrefix = lpszPrefix;
  2006. }
  2007. CRect rcIntersect; rcIntersect.IntersectRect(rcGroups, rc);
  2008. pWnd->m_bVisible = bVisible && (rcIntersect == rc) && (pControl->IsVisible());
  2009. pCommandBars->m_keyboardTips.arr.Add(pWnd);
  2010. }
  2011. void CXTPRibbonScrollableBar::CreateGroupKeyboardTips(CXTPRibbonTab* pSelectedTab)
  2012. {
  2013. for (int i = 0; i < pSelectedTab->GetGroups()->GetCount(); i++)
  2014. {
  2015. CXTPRibbonGroup* pGroup = pSelectedTab->GetGroups()->GetAt(i);
  2016. BOOL bVisible = pGroup->IsVisible();
  2017. for (int j = 0; j < pGroup->GetCount(); j++)
  2018. {
  2019. CXTPControl* pControl = pGroup->GetAt(j);
  2020. CreateControlKeyboardTips(pControl, NULL, bVisible);
  2021. }
  2022. if ((pGroup->GetControlGroupOption()->GetHideFlags() & xtpHideGeneric) == 0)
  2023. {
  2024. CreateControlKeyboardTips(pGroup->GetControlGroupOption(), NULL, bVisible);
  2025. }
  2026. CreateControlKeyboardTips(pGroup->GetControlGroupPopup(), _T("Z"), bVisible);
  2027. }
  2028. }
  2029. void CXTPRibbonBar::CreateKeyboardTips()
  2030. {
  2031. CXTPCommandBars* pCommandBars = GetCommandBars();
  2032. if (!pCommandBars)
  2033. return;
  2034. if (pCommandBars->m_keyboardTips.nLevel == 1)
  2035. {
  2036. int i;
  2037. int k = 1;
  2038. for (i = 0; i < m_pQuickAccessControls->GetCount(); i++)
  2039. {
  2040. CXTPControl* pControl = m_pQuickAccessControls->GetAt(i);
  2041. if (!pControl->IsVisible())
  2042. continue;
  2043. CPoint pt(pControl->GetRect().CenterPoint().x, pControl->GetRect().bottom - 11);
  2044. CString strCaption;
  2045. if (k < 10)
  2046. {
  2047. strCaption.Format(_T("%i"), k);
  2048. }
  2049. else if (k < 19)
  2050. {
  2051. strCaption.Format(_T("0%i"), k - 9);
  2052. }
  2053. else break;
  2054. k++;
  2055. CXTPCommandBarKeyboardTip* pWnd = new CXTPCommandBarKeyboardTip(pCommandBars, pControl, strCaption, pt, DT_CENTER | DT_TOP, pControl->GetEnabled());
  2056. pCommandBars->m_keyboardTips.arr.Add(pWnd);
  2057. }
  2058. for (i = 0; i < GetTabCount(); i++)
  2059. {
  2060. CXTPRibbonTab* pTab = GetTab(i);
  2061. CString strCaption = pTab->GetCaption();
  2062. if (!strCaption.IsEmpty() && pTab->IsEnabled() && pTab->IsVisible())
  2063. {
  2064. CPoint pt(pTab->GetRect().CenterPoint().x, pTab->GetRect().bottom - 9);
  2065. CXTPCommandBarKeyboardTip* pWnd = new CXTPCommandBarKeyboardTip(pCommandBars, pTab, strCaption, pt, DT_CENTER | DT_TOP, TRUE);
  2066. pCommandBars->m_keyboardTips.arr.Add(pWnd);
  2067. }
  2068. }
  2069. if (m_pControlSystemButton)
  2070. {
  2071. CPoint pt(m_pControlSystemButton->GetRect().CenterPoint().x, m_pControlSystemButton->GetRect().CenterPoint().y);
  2072. CXTPCommandBarKeyboardTip* pWnd = new CXTPCommandBarKeyboardTip(pCommandBars,
  2073. m_pControlSystemButton, m_pControlSystemButton->GetCaption(), pt, DT_VCENTER | DT_CENTER, m_pControlSystemButton->GetEnabled());
  2074. pCommandBars->m_keyboardTips.arr.Add(pWnd);
  2075. }
  2076. }
  2077. if (pCommandBars->m_keyboardTips.nLevel == 2)
  2078. {
  2079. CreateGroupKeyboardTips(GetSelectedTab());
  2080. }
  2081. }
  2082. CSize CXTPRibbonBar::GetIconSize() const
  2083. {
  2084. CXTPCommandBars* pCommandBars = GetCommandBars();
  2085. return m_szIcons != CSize(0) ? m_szIcons:
  2086. (pCommandBars->GetCommandBarsOptions()->szIcons != CSize(0) ?
  2087. pCommandBars->GetCommandBarsOptions()->szIcons : GetAutoIconSize(FALSE));
  2088. }
  2089. void CXTPRibbonBar::OnCustomizeDrop(CXTPControl* pDataObject, DROPEFFECT& dropEffect, CPoint ptDrop, CPoint ptDrag)
  2090. {
  2091. CXTPCommandBars* pCommandBars = GetCommandBars();
  2092. ASSERT(pCommandBars);
  2093. if (!pCommandBars)
  2094. return;
  2095. CRect rcMarker;
  2096. int nDropIndex;
  2097. BOOL bDropAfter;
  2098. CustomizeFindDropIndex (pDataObject, ptDrop, rcMarker, nDropIndex, bDropAfter);
  2099. CXTPControl* pDropControl = nDropIndex != -1 ? GetControl(nDropIndex) : NULL;
  2100. if (nDropIndex == -1 || pDataObject != pDropControl)
  2101. {
  2102. CXTPRibbonGroup* pGroup = pDropControl ? pDropControl->GetRibbonGroup() : NULL;
  2103. if (bDropAfter) nDropIndex++;
  2104. SetPopuped(-1);
  2105. SetSelected(-1);
  2106. BOOL bBeginGroup = FALSE;
  2107. if (bDropAfter == FALSE && nDropIndex >= 0 && nDropIndex < GetControlCount())
  2108. {
  2109. bBeginGroup = GetControl(nDropIndex)->GetBeginGroup();
  2110. if (bBeginGroup)
  2111. {
  2112. GetControl(nDropIndex)->SetBeginGroup(FALSE);
  2113. }
  2114. }
  2115. CXTPControl* pClone = NULL;
  2116. if (pGroup != NULL)
  2117. {
  2118. pClone = pGroup->AddClone(pDataObject, pGroup->IndexOf(pDropControl) + (bDropAfter ? 1 : 0));
  2119. }
  2120. else
  2121. {
  2122. pClone = m_pControls->AddClone(pDataObject, nDropIndex);
  2123. }
  2124. pClone->SetBeginGroup(bBeginGroup);
  2125. pCommandBars->SetDragControl(pClone);
  2126. }
  2127. else
  2128. {
  2129. if (abs(ptDrag.x - ptDrop.x) > 4 || abs(ptDrag.y - ptDrop.y) > 4)
  2130. {
  2131. CXTPControl* pControl = GetControl(nDropIndex);
  2132. ASSERT(pDataObject == pControl);
  2133. pControl->SetBeginGroup(bDropAfter && nDropIndex != 0);
  2134. }
  2135. dropEffect = DROPEFFECT_CANCEL;
  2136. }
  2137. OnRecalcLayout();
  2138. m_rcMarker.SetRectEmpty();
  2139. Redraw();
  2140. }
  2141. #define xtpKeyDown xtpKeyPopup
  2142. #define xtpKeyUp xtpKeyBack
  2143. CRect CXTPRibbonScrollableBar::_GetBoundRect(CXTPControl* pControl, BOOL bSelected, XTPSpecialKey key)
  2144. {
  2145. CRect rc(pControl->GetRect());
  2146. if (pControl->GetRibbonGroup() && DYNAMIC_DOWNCAST(CXTPRibbonGroupOption, pControl))
  2147. {
  2148. rc = pControl->GetRibbonGroup()->GetCaptionRect();
  2149. rc.DeflateRect(4, 0, 4, 0);
  2150. }
  2151. else if (!bSelected && (key == xtpKeyDown || key == xtpKeyUp) && !pControl->GetRibbonGroup() && DYNAMIC_DOWNCAST(CXTPRibbonBarControlQuickAccessPopup, pControl))
  2152. {
  2153. rc.right = CXTPClientRect(pControl->GetParent()).right;
  2154. }
  2155. else if (bSelected && key == xtpKeyUp && DYNAMIC_DOWNCAST(CXTPRibbonControlTab, pControl))
  2156. {
  2157. if (((CXTPRibbonControlTab*)pControl)->GetSelectedItem())
  2158. {
  2159. rc = ((CXTPRibbonControlTab*)pControl)->GetSelectedItem()->GetRect();
  2160. }
  2161. }
  2162. return rc;
  2163. }
  2164. BOOL CXTPRibbonBar::ProcessSpecialKey(XTPSpecialKey key)
  2165. {
  2166. if (key != xtpKeyEscape)
  2167. HideKeyboardTips();
  2168. if (CXTPRibbonScrollableBar::ProcessSpecialKey(key))
  2169. return TRUE;
  2170. return CXTPMenuBar::ProcessSpecialKey(key);
  2171. }
  2172. BOOL CXTPRibbonScrollableBar::ProcessSpecialKey(XTPSpecialKey key)
  2173. {
  2174. CXTPControl* pSelected = m_pParent->GetSelected();
  2175. if (!pSelected)
  2176. return FALSE;
  2177. if (key == xtpKeyReturn || key == xtpKeySpace)
  2178. {
  2179. if (pSelected->IsFocused())
  2180. pSelected->OnClick(TRUE);
  2181. else
  2182. pSelected->OnUnderlineActivate();
  2183. return TRUE;
  2184. }
  2185. if (key != xtpKeyDown && key != xtpKeyUp && key != xtpKeyLeft && key != xtpKeyRight)
  2186. return FALSE;
  2187. CRect rcCondidate(0, 0, 0, 0);
  2188. CRect rcSelected = _GetBoundRect(pSelected, TRUE, key);
  2189. int nSelCenter = rcSelected.CenterPoint().y;
  2190. CXTPControl* pCondidate = NULL;
  2191. CXTPControl* pFirst = NULL;
  2192. int nCount = m_pParent->GetControlCount();
  2193. if (key == xtpKeyRight)
  2194. {
  2195. for (int i = 0; i < nCount; i++)
  2196. {
  2197. CXTPControl* pControl = m_pParent->GetControl(i);
  2198. if (pControl == pSelected || !pControl->IsVisible(xtpHideScroll) || (pControl->GetFlags() & xtpFlagSkipFocus))
  2199. continue;
  2200. CRect rc = _GetBoundRect(pControl, FALSE, key);
  2201. if (((rc.top + 1 >= rcSelected.top && rc.top < rcSelected.bottom) || (rcSelected.top + 1 >= rc.top && rcSelected.top < rc.bottom)))
  2202. {
  2203. if ((rc.left >= rcSelected.right) && ((pCondidate == NULL) || (rc.left < rcCondidate.left) ||
  2204. (rc.left == rcCondidate.left && abs(rc.CenterPoint().y - nSelCenter) < abs(rcCondidate.CenterPoint().y - nSelCenter))))
  2205. {
  2206. pCondidate = pControl;
  2207. rcCondidate = rc;
  2208. }
  2209. if (pFirst == NULL || rc.left < pFirst->GetRect().left ||
  2210. (rc.left == pFirst->GetRect().left && abs(rc.CenterPoint().y - nSelCenter) < abs(pFirst->GetRect().CenterPoint().y - nSelCenter)))
  2211. {
  2212. pFirst = pControl;
  2213. }
  2214. }
  2215. }
  2216. }
  2217. else if (key == xtpKeyLeft)
  2218. {
  2219. for (int i = 0; i < nCount; i++)
  2220. {
  2221. CXTPControl* pControl = m_pParent->GetControl(i);
  2222. if (pControl == pSelected || !pControl->IsVisible(xtpHideScroll) || (pControl->GetFlags() & xtpFlagSkipFocus))
  2223. continue;
  2224. CRect rc = _GetBoundRect(pControl, FALSE, key);
  2225. if (((rc.top + 1 >= rcSelected.top && rc.top < rcSelected.bottom) || (rcSelected.top + 1 >= rc.top && rcSelected.top < rc.bottom)))
  2226. {
  2227. if ((rc.right <= rcSelected.left) && ((pCondidate == NULL) || (rc.right > rcCondidate.right) ||
  2228. (rc.right == rcCondidate.right && abs(rc.CenterPoint().y - nSelCenter) < abs(rcCondidate.CenterPoint().y - nSelCenter))))
  2229. {
  2230. pCondidate = pControl;
  2231. rcCondidate = rc;
  2232. }
  2233. if (pFirst == NULL || rc.right >= pFirst->GetRect().right ||
  2234. (rc.right == pFirst->GetRect().right && abs(rc.CenterPoint().y - nSelCenter) < abs(pFirst->GetRect().CenterPoint().y - nSelCenter)))
  2235. {
  2236. pFirst = pControl;
  2237. }
  2238. }
  2239. }
  2240. }
  2241. else if (key == xtpKeyDown)
  2242. {
  2243. nSelCenter = rcSelected.CenterPoint().x;
  2244. for (int i = 0; i < nCount; i++)
  2245. {
  2246. CXTPControl* pControl = m_pParent->GetControl(i);
  2247. if (pControl == pSelected || !pControl->IsVisible(xtpHideScroll) || (pControl->GetFlags() & xtpFlagSkipFocus))
  2248. continue;
  2249. CRect rc = _GetBoundRect(pControl, FALSE, key);
  2250. if (((rc.left + 1 >= rcSelected.left && rc.left < rcSelected.right) || (rcSelected.left + 1 >= rc.left && rcSelected.left < rc.right)))
  2251. {
  2252. if ((rc.top >= rcSelected.bottom) && ((pCondidate == NULL) || (rc.top < rcCondidate.top) ||
  2253. (rc.top == rcCondidate.top && abs(rc.CenterPoint().x - nSelCenter) < abs(rcCondidate.CenterPoint().x - nSelCenter))))
  2254. {
  2255. pCondidate = pControl;
  2256. rcCondidate = rc;
  2257. }
  2258. }
  2259. }
  2260. }
  2261. else if (key == xtpKeyUp)
  2262. {
  2263. nSelCenter = rcSelected.CenterPoint().x;
  2264. for (int i = 0; i < nCount; i++)
  2265. {
  2266. CXTPControl* pControl = m_pParent->GetControl(i);
  2267. if (pControl == pSelected || !pControl->IsVisible(xtpHideScroll) || (pControl->GetFlags() & xtpFlagSkipFocus))
  2268. continue;
  2269. CRect rc = _GetBoundRect(pControl, FALSE, key);
  2270. if (((rc.left + 1 >= rcSelected.left && rc.left < rcSelected.right) || (rcSelected.left + 1 >= rc.left && rcSelected.left < rc.right)))
  2271. {
  2272. if ((rc.bottom <= rcSelected.top) && ((pCondidate == NULL) || (rc.bottom > rcCondidate.bottom) ||
  2273. (rc.bottom == rcCondidate.bottom && abs(rc.CenterPoint().x - nSelCenter) < abs(rcCondidate.CenterPoint().x - nSelCenter))))
  2274. {
  2275. pCondidate = pControl;
  2276. rcCondidate = rc;
  2277. }
  2278. }
  2279. }
  2280. }
  2281. if (pCondidate)
  2282. {
  2283. m_pParent->SetSelected(pCondidate->GetIndex(), key == xtpKeyRight || key == xtpKeyDown ? TRUE_KEYBOARD_NEXT : TRUE_KEYBOARD_PREV);
  2284. }
  2285. else if (pFirst)
  2286. {
  2287. m_pParent->SetSelected(pFirst->GetIndex(), key == xtpKeyRight || key == xtpKeyDown? TRUE_KEYBOARD_NEXT : TRUE_KEYBOARD_PREV);
  2288. }
  2289. return TRUE;
  2290. }