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

对话框与窗口

开发平台:

Visual C++

  1. // XTPPopupBar.cpp : implementation of the CXTPPopupBar class.
  2. //
  3. // This file is a part of the XTREME COMMANDBARS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPVC80Helpers.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "Common/XTPColorManager.h"
  25. #include "Common/XTPImageManager.h"
  26. #include "Common/XTPToolTipContext.h"
  27. #include "Common/XTPHookManager.h"
  28. #include "XTPPopupBar.h"
  29. #include "XTPPaintManager.h"
  30. #include "XTPControls.h"
  31. #include "XTPControl.h"
  32. #include "XTPControlButton.h"
  33. #include "XTPShortcutManager.h"
  34. #include "XTPControlPopup.h"
  35. #include "XTPToolBar.h"
  36. #include "XTPCommandBars.h"
  37. #include "XTPMouseManager.h"
  38. #include "XTPSoundManager.h"
  39. #ifdef _DEBUG
  40. #define new DEBUG_NEW
  41. #undef THIS_FILE
  42. static char THIS_FILE[] = __FILE__;
  43. #endif
  44. double CXTPPopupBar::m_dMaxWidthDivisor = 1.0/3.0;
  45. #ifndef EVENT_SYSTEM_MENUPOPUPSTART
  46. #define EVENT_SYSTEM_MENUPOPUPSTART     0x0006
  47. #define EVENT_SYSTEM_MENUPOPUPEND       0x0007
  48. #define OBJID_MENU 0xFFFFFFFD
  49. #endif
  50. #define TID_HOVERUP 5001
  51. #define TID_HOVERDOWN 5002
  52. #define TID_TEAROFFSELECTED 5003
  53. #define TID_EXPANDHOVER 5004
  54. class CXTPPopupBar::CControlExpandButton: public CXTPControlButton
  55. {
  56. public:
  57. CControlExpandButton()
  58. {
  59. m_controlType = xtpControlButton;
  60. m_dwFlags = xtpFlagManualUpdate | xtpFlagNoMovable | xtpFlagSkipFocus | xtpFlagShowPopupBarTip;
  61. }
  62. void Draw(CDC* pDC);
  63. virtual void OnExecute();
  64. };
  65. void CXTPPopupBar::CControlExpandButton::Draw(CDC* pDC)
  66. {
  67. GetPaintManager()->DrawSpecialControl(pDC, xtpButtonExpandMenu, this, m_pParent, TRUE, NULL);
  68. }
  69. void CXTPPopupBar::CControlExpandButton::OnExecute()
  70. {
  71. ((CXTPPopupBar*)m_pParent)->ExpandBar();
  72. }
  73. IMPLEMENT_XTP_COMMANDBAR(CXTPPopupBar, CXTPCommandBar)
  74. CXTPPopupBar::CXTPPopupBar()
  75. {
  76. m_scrollInfo.Init(this, TID_HOVERUP, TID_HOVERDOWN);
  77. m_barType = xtpBarTypePopup;
  78. m_barPosition = xtpBarPopup;
  79. m_pControlPopup = 0;
  80. m_ptPopup = 0;
  81. m_rcExclude.SetRectEmpty();
  82. m_rcTearOffGripper.SetRectEmpty();
  83. m_rcResizeGripper.SetRectEmpty();
  84. m_bResizable = FALSE;
  85. m_popupFlags = xtpPopupRight;
  86. m_bDynamicLayout = FALSE;
  87. m_bTearOffPopup = FALSE;
  88. m_bTearOffTracking = FALSE;
  89. m_nTearOffID = 0;
  90. m_nTearOffWidth = 0;
  91. m_bShowShadow = TRUE;
  92. m_rcBorders = CRect(2, 4, 2, 4);
  93. m_bExpanding = FALSE;
  94. m_nMRUWidth = 0;
  95. m_bDoubleGripper = FALSE;
  96. m_pTearOffBar = NULL;
  97. m_szTearOffBar = CSize(0, 0);
  98. m_nTearOffTimer = 0;
  99. m_bContextMenu = FALSE;
  100. }
  101. CXTPPopupBar* CXTPPopupBar::CreatePopupBar(CXTPCommandBars* pCommandBars)
  102. {
  103. CXTPPopupBar* pPopupBar = (CXTPPopupBar*)CXTPCommandBars::m_pPopupBarClass->CreateObject();
  104. pPopupBar->SetCommandBars(pCommandBars);
  105. return pPopupBar;
  106. }
  107. CXTPPopupBar::~CXTPPopupBar()
  108. {
  109. }
  110. void CXTPPopupBar::SetTearOffPopup(LPCTSTR strCaption, UINT nID, int nWidth)
  111. {
  112. if (nID == 0)
  113. {
  114. m_bTearOffPopup = FALSE;
  115. }
  116. else
  117. {
  118. m_bTearOffPopup = TRUE;
  119. m_strTearOffCaption = strCaption;
  120. m_nTearOffID = nID;
  121. m_nTearOffWidth = nWidth;
  122. }
  123. }
  124. BOOL CXTPPopupBar::IsTearOffPopup(CString& strCaption, UINT& nID, int& nWidth)
  125. {
  126. strCaption = m_strTearOffCaption;
  127. nID = m_nTearOffID;
  128. nWidth = m_nTearOffWidth;
  129. return m_bTearOffPopup;
  130. }
  131. BOOL CXTPPopupBar::IsVisible() const
  132. {
  133. return (m_hWnd != 0) && IsWindowVisible();
  134. }
  135. void CXTPPopupBar::ExpandBar()
  136. {
  137. if (m_bExpanded == FALSE && m_bCollapsed == TRUE)
  138. {
  139. SAFE_CALLPTR(m_pToolTipContext, CancelToolTips());
  140. m_bExpanding = TRUE;
  141. m_bExpanded = TRUE;
  142. SetPopuped(-1);
  143. SetSelected(-1);
  144. OnRecalcLayout();
  145. XTPMouseManager()->SetForceExpanded(TRUE);
  146. XTPMouseManager()->IgnoreLButtonUp();
  147. }
  148. }
  149. BOOL CXTPPopupBar::Create()
  150. {
  151. if (m_hWnd)
  152. return TRUE;
  153. CXTPCommandBars* pCommandBars = GetCommandBars();
  154. UINT nClassStyle = !pCommandBars || pCommandBars->GetCommandBarsOptions()->bUseSystemSaveBitsStyle ? CS_SAVEBITS | CS_DBLCLKS : CS_DBLCLKS;
  155. CXTPDrawHelpers::RegisterWndClass(0, _T("XTPPopupBar"), nClassStyle);
  156. int nLayoutRTL = pCommandBars && pCommandBars->IsLayoutRTL() ? WS_EX_LAYOUTRTL : 0;
  157. if (!pCommandBars && GetImageManager()->IsDrawReverted() == 1) nLayoutRTL = WS_EX_LAYOUTRTL;
  158. if (!CreateEx(WS_EX_TOOLWINDOW | nLayoutRTL, _T("XTPPopupBar"), 0, MFS_SYNCACTIVE | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CRect(0, 0, 0, 0), GetSite(), 0))
  159. return FALSE;
  160. SetWindowText(m_strTitle);
  161. return TRUE;
  162. }
  163. #ifndef SPI_GETMENUANIMATION
  164. #define SPI_GETMENUANIMATION                0x1002
  165. #endif
  166. #ifndef SPI_GETMENUFADE
  167. #define SPI_GETMENUFADE                     0x1012
  168. #endif
  169. XTPAnimationType CXTPPopupBar::GetAnimationType() const
  170. {
  171. CXTPCommandBars* pCommandBars = GetCommandBars();
  172. if (pCommandBars)
  173. {
  174. if (GetWindow(GW_CHILD))
  175. return xtpAnimateNone;
  176. XTPAnimationType animationType = pCommandBars->GetCommandBarsOptions()->animationType;
  177. switch (animationType)
  178. {
  179. case xtpAnimateWindowsDefault:
  180. {
  181. BOOL bEnabled = FALSE;
  182. if (!SystemParametersInfo(SPI_GETMENUANIMATION, 0, &bEnabled, 0))
  183. return xtpAnimateNone;
  184. if (!bEnabled)
  185. return xtpAnimateNone;
  186. BOOL bFadeAnimation = FALSE;
  187. if (!SystemParametersInfo(SPI_GETMENUFADE, 0, &bFadeAnimation, 0))
  188. return xtpAnimateSlide;
  189. animationType = bFadeAnimation ? xtpAnimateFade : xtpAnimateSlide;
  190. }
  191. break;
  192. // choose any animation based on a random number
  193. case xtpAnimateRandom:
  194. {
  195. switch (RAND_S() % 3)
  196. {
  197. case 0:
  198. animationType = xtpAnimateFade;
  199. break;
  200. case 1:
  201. animationType = xtpAnimateSlide;
  202. break;
  203. default:
  204. animationType = xtpAnimateUnfold;
  205. break;
  206. }
  207. }
  208. break;
  209. }
  210. return animationType;
  211. }
  212. return xtpAnimateNone;
  213. }
  214. void CXTPPopupBar::OnControlsChanged()
  215. {
  216. m_nSelected = -1;
  217. m_nPopuped = -1;
  218. OnRecalcLayout();
  219. }
  220. void CXTPPopupBar::RecalcSizeLayout()
  221. {
  222. if (!m_bDynamicLayout && GetSafeHwnd() && IsTrackingMode())
  223. {
  224. CSize sz = CalcDynamicLayout(0, 0);
  225. CXTPWindowRect rcWindow(this);
  226. BOOL bRTL = GetExStyle() & WS_EX_LAYOUTRTL;
  227. CRect rc = !bRTL ? CRect(CPoint(rcWindow.left, rcWindow.top), sz) : CRect(CPoint(rcWindow.right - sz.cx, rcWindow.top), sz);
  228. if (rc == rcWindow)
  229. {
  230. Redraw();
  231. return;
  232. }
  233. CXTPCommandBars* pCommandBars = GetCommandBars();
  234. BOOL bShowKeyboardTips = IsKeyboardTipsVisible();
  235. if (bShowKeyboardTips && pCommandBars) pCommandBars->HideKeyboardTips();
  236. SetWindowRgn(NULL, FALSE);
  237. CXTPPaintManager* pPaintManager = GetPaintManager();
  238. SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
  239. pPaintManager->SetCommandBarRegion(this);
  240. pPaintManager->GetShadowManager()->OffsetShadow(this, rc.Size() - rcWindow.Size());
  241. Redraw();
  242. }
  243. }
  244. void CXTPPopupBar::OnRecalcLayout()
  245. {
  246. if (!m_bDynamicLayout && GetSafeHwnd() && IsTrackingMode())
  247. {
  248. UpdateShortcuts();
  249. UpdateFlags();
  250. CRect rc = CalculatePopupRect(m_ptPopup, CalcDynamicLayout(0, 0));
  251. CXTPWindowRect rcWindow(this);
  252. if (!m_bExpanding && rc == rcWindow)
  253. {
  254. Redraw();
  255. return;
  256. }
  257. CXTPCommandBars* pCommandBars = GetCommandBars();
  258. BOOL bShowKeyboardTips = IsKeyboardTipsVisible();
  259. if (bShowKeyboardTips && pCommandBars) pCommandBars->HideKeyboardTips();
  260. CXTPPaintManager* pPaintManager = GetPaintManager();
  261. pPaintManager->GetShadowManager()->RemoveShadow(this);
  262. BOOL bChanged = FALSE;
  263. if (m_bExpanding)
  264. {
  265. BOOL bExpandDown = rcWindow.bottom < rc.bottom;
  266. XTPAnimationType animationType = GetAnimationType();
  267. if (IsAnimateType(animationType))
  268. {
  269. CDC* pDC = GetDesktopWindow()->GetDC();
  270. CBitmap bmp;
  271. bmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
  272. CXTPCompatibleDC dcWindow(pDC, &bmp);
  273. dcWindow.BitBlt(0, 0, rc.Width(), rc.Height(), pDC, rc.left, rc.top, SRCCOPY);
  274. GetDesktopWindow()->ReleaseDC(pDC);
  275. ShowWindow(SW_HIDE);
  276. GetSite()->UpdateWindow();
  277. SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOREDRAW);
  278. pPaintManager->SetCommandBarRegion(this);
  279. bChanged = TRUE;
  280. CWindowDC paintDC(this);
  281. CXTPClientRect rcClientPost(this);
  282. BOOL dwLayout = CXTPDrawHelpers::IsContextRTL(&paintDC);
  283. CXTPDrawHelpers::SetContextRTL(&paintDC, FALSE);
  284. paintDC.BitBlt(0, 0, rc.Width(), rc.Height(), &dcWindow, 0, 0, SRCCOPY);
  285. CXTPDrawHelpers::SetContextRTL(&paintDC, dwLayout);
  286. CXTPBufferDC animationDC(paintDC, rcClientPost);
  287. DrawCommandBar(&animationDC, rcClientPost);
  288. // Animation
  289. pPaintManager->AnimateExpanding(this, &paintDC, &animationDC, bExpandDown);
  290. }
  291. XTPSoundManager()->PlaySystemSound(xtpSoundMenuPopup);
  292. }
  293. if (!bChanged)
  294. {
  295. SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
  296. pPaintManager->SetCommandBarRegion(this);
  297. }
  298. if (m_barPosition == xtpBarPopup && m_bShowShadow && pPaintManager->m_bShowShadow && !IsCustomizeMode())
  299. pPaintManager->GetShadowManager()->SetShadow(this, m_rcExclude);
  300. if (m_pControlPopup)
  301. m_pControlPopup->UpdateShadow();
  302. Redraw();
  303. if (bShowKeyboardTips)
  304. {
  305. PostMessage(WM_TIMER, XTP_TID_SHOWKEYBOARDTIPS);
  306. }
  307. m_bExpanding = FALSE;
  308. }
  309. }
  310. void CXTPPopupBar::_MakeSameWidth(int nStart, int nLast, int nWidth)
  311. {
  312. for (int i = nStart; i < nLast; i++)
  313. {
  314. CXTPControl* pControl = GetControl(i);
  315. if (!pControl || pControl->GetParent() != this || !pControl->IsVisible())
  316. continue;
  317. CRect rc = pControl->GetRect();
  318. pControl->SetRect(CRect(rc.left, rc.top, rc.left + nWidth, rc.bottom));
  319. }
  320. }
  321. CRect CXTPPopupBar::GetBorders()
  322. {
  323. if (m_barType == xtpBarTypeNormal)
  324. return m_rcBorders;
  325. return GetPaintManager()->GetCommandBarBorders(this);
  326. }
  327. CSize CXTPPopupBar::CalcDynamicLayout(int nLength, DWORD /*nMode*/)
  328. {
  329. m_bDynamicLayout = TRUE;
  330. CClientDC dc(this);
  331. CXTPFontDC font(&dc, GetPaintManager()->GetCommandBarFont(this));
  332. RECT rcWork;
  333. SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcWork, 0);
  334. CRect rcBorders = GetBorders();
  335. CSize szTearOffGripper(0);
  336. if (m_bTearOffPopup)
  337. {
  338. szTearOffGripper = GetPaintManager()->DrawTearOffGripper(&dc, 0, FALSE, FALSE);
  339. rcBorders.top += szTearOffGripper.cy;
  340. }
  341. if (m_barType == xtpBarTypeNormal)
  342. {
  343. UpdateShortcuts();
  344. CSize sz = m_pControls->CalcDynamicSize(&dc, GetWidth(), LM_COMMIT | LM_HORZ | LM_POPUP, rcBorders);
  345. m_rcTearOffGripper.SetRect(rcBorders.left, rcBorders.top - szTearOffGripper.cy, sz.cx - rcBorders.right, rcBorders.top);
  346. m_rcResizeGripper.SetRectEmpty();
  347. m_bDynamicLayout = FALSE;
  348. return sz;
  349. }
  350. CXTPControl* pControlGallery = GetControls()->FindControl(xtpControlGallery, -1, TRUE, FALSE);
  351. m_bResizable = pControlGallery ? pControlGallery->IsCustomizeResizeAllow() : 0;
  352. CSize szResizeGripper(0);
  353. if (m_bResizable)
  354. {
  355. szResizeGripper.cy = m_bResizable != 2 ? 11 : 8;
  356. rcBorders.bottom += szResizeGripper.cy;
  357. }
  358. if (nLength == 0)
  359. {
  360. for (int i = 0; i < GetControlCount(); i++)
  361. {
  362. CXTPControl* pControl = GetControl(i);
  363. if (!pControl || pControl->GetParent() != this)
  364. continue;
  365. pControl->OnCalcDynamicSize(0);
  366. }
  367. UpdateExpandingState();
  368. UpdateShortcuts();
  369. }
  370. CXTPControl* pButtonExpand = m_pControls->FindControl(XTP_ID_POPUPBAR_EXPAND);
  371. CSize szButtonExpand(0);
  372. if (m_bCollapsed)
  373. {
  374. szButtonExpand = GetPaintManager()->DrawSpecialControl(&dc, xtpButtonExpandMenu, NULL, this, FALSE, NULL);
  375. rcBorders.bottom += szButtonExpand.cy;
  376. if (!pButtonExpand)
  377. pButtonExpand = m_pControls->Add(new CControlExpandButton(), XTP_ID_POPUPBAR_EXPAND, _T(""), -1, TRUE);
  378. pButtonExpand->SetHideFlags(xtpHideGeneric);
  379. }
  380. else if (pButtonExpand) pButtonExpand->SetHideFlags(xtpHideGeneric);
  381. CSize sz = m_pControls->CalcPopupSize(&dc, nLength, GetWidth(), rcBorders);
  382. if (m_bCollapsed)
  383. {
  384. pButtonExpand->SetHideFlags(xtpNoHide);
  385. pButtonExpand->SetRect(CRect(rcBorders.left, sz.cy - rcBorders.bottom, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom + szButtonExpand.cy));
  386. }
  387. m_rcTearOffGripper.SetRect(rcBorders.left, rcBorders.top - szTearOffGripper.cy, sz.cx - rcBorders.right, rcBorders.top);
  388. m_rcResizeGripper.SetRect(rcBorders.left, sz.cy - rcBorders.bottom, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom + szResizeGripper.cy);
  389. m_bDynamicLayout = FALSE;
  390. return sz;
  391. }
  392. CRect CXTPPopupBar::CalculatePopupRect(CPoint ptPopup, CSize sz)
  393. {
  394. RECT rcWork = m_rcExclude.IsRectEmpty() ? XTPMultiMonitor()->GetWorkArea(ptPopup) : XTPMultiMonitor()->GetWorkArea(m_rcExclude);
  395. RECT rcScreen = m_rcExclude.IsRectEmpty() ? XTPMultiMonitor()->GetScreenArea(ptPopup) : XTPMultiMonitor()->GetScreenArea(m_rcExclude);
  396. // If point is on the screen, but not in the work area, then the point
  397. // must be inside an AppBar.
  398. if (m_rcExclude.IsRectEmpty() && PtInRect(&rcScreen, ptPopup) && !PtInRect(&rcWork, ptPopup))
  399. {
  400. rcWork = rcScreen;
  401. }
  402. if (!m_rcExclude.IsRectEmpty() && !CRect().IntersectRect(&rcWork, m_rcExclude) && CRect().IntersectRect(&rcScreen, m_rcExclude))
  403. {
  404. rcWork = rcScreen;
  405. }
  406. rcWork.bottom -= 5;  // for shadow
  407. CPoint ptCenterRect = m_rcExclude.CenterPoint();
  408. BOOL bScroll = FALSE, bWrap = FALSE;
  409. CXTPCommandBars* pCommandars = GetCommandBars();
  410. BOOL bNoScroll = (pCommandars ? pCommandars->GetCommandBarsOptions()->bWrapLargePopups : FALSE) || m_bMultiLine;
  411. if (m_rcExclude.Height() == 0 && (m_popupFlags & xtpPopupUp))
  412. ptPopup.y = ptPopup.y - sz.cy;
  413. if (m_rcExclude.Height() == 0 && ptPopup.y > rcWork.bottom)
  414. {
  415. ptPopup.y = ptPopup.y - sz.cy;
  416. }
  417. else if (ptPopup.y + sz.cy > rcWork.bottom)
  418. {
  419. if (m_rcExclude.Height() == 0)
  420. {
  421. ptPopup.y = (ptPopup.y < (rcWork.bottom - rcWork.top)/2 ? rcWork.bottom : ptPopup.y)- sz.cy;
  422. }
  423. else
  424. {
  425. if (m_popupFlags & xtpPopupDown)
  426. {
  427. ptPopup.y = m_rcExclude.top - sz.cy;
  428. if (ptPopup.y < rcWork.top)
  429. {
  430. if (bNoScroll)
  431. {
  432. m_popupFlags &= ~xtpPopupDown;
  433. if (m_pControlPopup && (m_pControlPopup->GetType() != xtpControlComboBox || GetParentCommandBar()->GetType() == xtpBarTypePopup))
  434. {
  435. m_rcExclude = m_pControlPopup->GetRect();
  436. AdjustExcludeRect(m_rcExclude, TRUE);
  437. GetParentCommandBar()->ClientToScreen(m_rcExclude);
  438. }
  439. if (m_popupFlags & xtpPopupLeft)
  440. {
  441. ptPopup.y = rcWork.bottom - sz.cy;
  442. }
  443. else
  444. {
  445. ptPopup.x = m_rcExclude.right;
  446. ptPopup.y = rcWork.bottom - sz.cy;
  447. }
  448. }
  449. else
  450. {
  451. bScroll = TRUE;
  452. if (ptCenterRect.y > (rcWork.bottom - rcWork.top)/2)
  453. {
  454. ptPopup.y = rcWork.top;
  455. sz.cy = m_rcExclude.top - rcWork.top;
  456. }
  457. else
  458. {
  459. ptPopup.y = m_rcExclude.bottom;
  460. sz.cy = rcWork.bottom - ptPopup.y;
  461. }
  462. }
  463. }
  464. }
  465. else
  466. {
  467. ptPopup.y = rcWork.bottom - sz.cy;
  468. }
  469. }
  470. if (ptPopup.y < rcWork.top) ptPopup.y = rcWork.top;
  471. if (ptPopup.y + sz.cy > rcWork.bottom && ptPopup.y == rcWork.top)
  472. {
  473. if (bNoScroll)
  474. {
  475. bWrap = TRUE;
  476. }
  477. else
  478. {
  479. sz.cy = rcWork.bottom - ptPopup.y;
  480. bScroll = TRUE;
  481. }
  482. }
  483. }
  484. if (bWrap && !m_bMultiLine && (GetType() == xtpBarTypePopup))
  485. {
  486. sz = CalcDynamicLayout(rcWork.bottom - rcWork.top, 0);
  487. }
  488. if (m_popupFlags == (xtpPopupLeft | xtpPopupDown) && m_rcExclude.Width() != 0)
  489. ptPopup.x = m_rcExclude.right - sz.cx;
  490. else if (m_popupFlags & xtpPopupLeft && m_rcExclude.Width() != 0)
  491. ptPopup.x = m_rcExclude.left - sz.cx;
  492. else if ((m_popupFlags & xtpPopupLeft) && m_rcExclude.Width() == 0)
  493. ptPopup.x -= sz.cx;
  494. if (ptPopup.x + sz.cx > rcWork.right)
  495. {
  496. if (m_rcExclude.Width() == 0 && ptPopup.x > rcWork.right)
  497. ptPopup.x = ptPopup.x - sz.cx;
  498. else if (m_rcExclude.Width() == 0)
  499. ptPopup.x = rcWork.right - sz.cx;
  500. else
  501. {
  502. ptPopup.x = (m_popupFlags & xtpPopupDown ? rcWork.right : m_rcExclude.left) - sz.cx ;
  503. m_popupFlags |= xtpPopupLeft;
  504. }
  505. if (ptPopup.x < rcWork.left)
  506. ptPopup.x = rcWork.left;
  507. }
  508. else if (ptPopup.x < rcWork.left)
  509. {
  510. if (m_rcExclude.Width() != 0)
  511. {
  512. ptPopup.x = m_popupFlags & xtpPopupDown ? rcWork.left : m_rcExclude.right;
  513. m_popupFlags &= ~xtpPopupLeft;
  514. }
  515. else if (m_popupFlags & xtpPopupLeft)
  516. {
  517. ptPopup.x = rcWork.left;
  518. m_popupFlags &= ~xtpPopupLeft;
  519. }
  520. }
  521. m_scrollInfo.bScroll = bScroll && (GetType() == xtpBarTypePopup && GetPosition() == xtpBarPopup);
  522. if (m_scrollInfo.bScroll)
  523. {
  524. m_scrollInfo.nScrollFirst = 0;
  525. AdjustScrolling(&sz);
  526. }
  527. return CRect(ptPopup, sz);
  528. }
  529. void CXTPPopupBar::UpdateLocation(CSize sz)
  530. {
  531. CRect rc = CalculatePopupRect(m_ptPopup, sz);
  532. SetWindowPos(&CWnd::wndTopMost, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_SHOWWINDOW | (IsWindowVisible() ? SWP_NOZORDER : 0));
  533. }
  534. void CXTPPopupBar::AdjustScrolling(LPSIZE lpSize, BOOL bDown, BOOL bInvalidate)
  535. {
  536. CSize sz = lpSize ? *lpSize : CXTPWindowRect(this).Size();
  537. m_scrollInfo.btnDown.m_rc.SetRectEmpty();
  538. m_scrollInfo.btnUp.m_rc.SetRectEmpty();
  539. int nCount = GetControlCount();
  540. CRect rcBorders = GetBorders();
  541. int nSeparator = GetPaintManager()->DrawCommandBarSeparator(NULL, this, NULL, FALSE).cy;
  542. CSize szTearOffGripper(0);
  543. if (m_bTearOffPopup)
  544. {
  545. szTearOffGripper = GetPaintManager()->DrawTearOffGripper(NULL, 0, FALSE, FALSE);
  546. rcBorders.top += szTearOffGripper.cy;
  547. }
  548. if (m_bResizable)
  549. {
  550. rcBorders.bottom += m_rcResizeGripper.Height();
  551. }
  552. CXTPControl* pButtonExpand = m_pControls->FindControl(XTP_ID_POPUPBAR_EXPAND);
  553. CSize szButtonExpand(0);
  554. if (m_bCollapsed)
  555. {
  556. szButtonExpand = GetPaintManager()->DrawSpecialControl(NULL, xtpButtonExpandMenu, NULL, this, FALSE, NULL);
  557. rcBorders.bottom += szButtonExpand.cy;
  558. if (!pButtonExpand)
  559. pButtonExpand = m_pControls->Add(new CControlExpandButton(), XTP_ID_POPUPBAR_EXPAND, _T(""), -1, TRUE);
  560. pButtonExpand->SetHideFlags(xtpHideGeneric);
  561. }
  562. else if (pButtonExpand) pButtonExpand->SetHideFlags(xtpHideGeneric);
  563. int nScrollHeight = 16;
  564. int i;
  565. if (!bDown)
  566. {
  567. if (m_scrollInfo.nScrollFirst == 1)
  568. m_scrollInfo.nScrollFirst = 0;
  569. int nPos = rcBorders.top;
  570. if (m_scrollInfo.nScrollFirst != 0)
  571. {
  572. nPos += nScrollHeight;
  573. m_scrollInfo.btnDown.m_rc.SetRect(rcBorders.left, rcBorders.top, sz.cx - rcBorders.right, nPos);
  574. }
  575. ASSERT(m_scrollInfo.nScrollFirst < nCount && m_scrollInfo.nScrollFirst >= 0);
  576. BOOL bFirst = TRUE;
  577. for (i = m_scrollInfo.nScrollFirst; i < nCount ; i++)
  578. {
  579. CXTPControl* pControl = GetControl(i);
  580. pControl->SetHideFlag(xtpHideScroll, FALSE);
  581. if (!pControl->IsVisible())
  582. continue;
  583. int nItemHeight = pControl->GetRect().Height();
  584. if (pControl->GetBeginGroup()) nPos += nSeparator;
  585. if (sz.cy - (nPos + nItemHeight) < nScrollHeight + rcBorders.bottom)
  586. {
  587. if (!bFirst)
  588. break;
  589. else
  590. nItemHeight = sz.cy - rcBorders.bottom - rcBorders.top;
  591. }
  592. bFirst = FALSE;
  593. pControl->SetRect(CRect(rcBorders.left, nPos, sz.cx - rcBorders.right, nPos + nItemHeight));
  594. nPos += nItemHeight;
  595. }
  596. for (int j = i; j < nCount; j++)
  597. {
  598. GetControl(j)->SetHideFlag(xtpHideScroll, TRUE);
  599. }
  600. m_scrollInfo.nScrollLast = i;
  601. if (i != nCount)
  602. {
  603. m_scrollInfo.btnUp.m_rc.SetRect(rcBorders.left, sz.cy - rcBorders.bottom - nScrollHeight, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom);
  604. }
  605. }
  606. else
  607. {
  608. if (m_scrollInfo.nScrollLast == nCount - 1)
  609. m_scrollInfo.nScrollLast = nCount;
  610. int nPos = sz.cy - rcBorders.bottom;
  611. if (m_scrollInfo.nScrollLast != nCount)
  612. {
  613. nPos -= nScrollHeight;
  614. m_scrollInfo.btnUp.m_rc.SetRect(rcBorders.left, sz.cy - rcBorders.bottom - nScrollHeight, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom);
  615. }
  616. ASSERT(m_scrollInfo.nScrollLast <= nCount && m_scrollInfo.nScrollLast > 0);
  617. for (i = m_scrollInfo.nScrollLast - 1 ; i >= 0 ; i--)
  618. {
  619. CXTPControl* pControl = GetControl(i);
  620. pControl->SetHideFlag(xtpHideScroll, FALSE);
  621. if (!pControl->IsVisible())
  622. continue;
  623. int nItemHeight = pControl->GetRect().Height();
  624. if (nPos - nItemHeight < nScrollHeight)
  625. {
  626. break;
  627. }
  628. pControl->SetRect(CRect(rcBorders.left, nPos - nItemHeight, sz.cx - rcBorders.right, nPos));
  629. nPos -= nItemHeight;
  630. if (pControl->GetBeginGroup()) nPos -= nSeparator;
  631. }
  632. for (int j = i; j >= 0; j--)
  633. {
  634. GetControl(j)->SetHideFlag(xtpHideScroll, TRUE);
  635. }
  636. m_scrollInfo.nScrollFirst = i + 1;
  637. if (i != -1)
  638. {
  639. m_scrollInfo.btnDown.m_rc.SetRect(rcBorders.left, rcBorders.top, sz.cx - rcBorders.right, rcBorders.top + nScrollHeight);
  640. }
  641. }
  642. if (m_bCollapsed)
  643. {
  644. pButtonExpand->SetHideFlags(xtpNoHide);
  645. pButtonExpand->SetRect(CRect(rcBorders.left, sz.cy - rcBorders.bottom, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom +  szButtonExpand.cy));
  646. }
  647. m_rcTearOffGripper.SetRect(rcBorders.left, rcBorders.top - szTearOffGripper.cy, sz.cx - rcBorders.right, rcBorders.top);
  648. if (m_bResizable) m_rcResizeGripper.SetRect(rcBorders.left, sz.cy - rcBorders.bottom, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom + m_rcResizeGripper.Height());
  649. if (bInvalidate) Redraw();
  650. }
  651. void CXTPCommandBar::UpdateShortcuts()
  652. {
  653. CXTPCommandBars* pCommandBars = GetCommandBars();
  654. if (!pCommandBars)
  655. return;
  656. if (!pCommandBars->GetCommandBarsOptions()->bAutoUpdateShortcuts)
  657. return;
  658. for (int i = 0; i < GetControlCount(); i++)
  659. {
  660. CXTPControl* pControl = GetControl(i);
  661. if (!pControl || pControl->GetParent() != this || !pControl->IsVisible())
  662. continue;
  663. CString strShortcut;
  664. if (pControl->GetID() != 0)
  665. {
  666. pCommandBars->GetShortcutManager()->FindDefaultAccelerator(pControl->GetID(), strShortcut);
  667. pControl->m_strShortcutTextAuto = strShortcut;
  668. }
  669. }
  670. }
  671. void CXTPPopupBar::AdjustExcludeRect(CRect& rc, BOOL bVertical)
  672. {
  673. m_pControlPopup->AdjustExcludeRect(rc, bVertical);
  674. }
  675. AFX_INLINE BOOL IsVerticalPosition(CXTPCommandBar* pCommandBar)
  676. {
  677. return IsVerticalPosition(pCommandBar->GetPosition()) ||
  678. (pCommandBar->GetType() == xtpBarTypePopup && pCommandBar->GetPosition() == xtpBarFloating);
  679. }
  680. void CXTPPopupBar::UpdateFlags()
  681. {
  682. if (m_pControlPopup)
  683. {
  684. BOOL bLayoutRTL = IsLayoutRTL();
  685. CXTPCommandBar* pParent = GetParentCommandBar();
  686. ASSERT(pParent);
  687. if (!pParent)
  688. return;
  689. m_popupFlags = xtpPopupRight;
  690. if (m_pControlPopup->m_dwFlags & xtpFlagLeftPopup || bLayoutRTL) m_popupFlags |= xtpPopupLeft;
  691. if (pParent->GetFlags() & xtpFlagSmartLayout && pParent->GetPosition() == xtpBarPopup)
  692. {
  693. m_popupFlags |= xtpPopupDown;
  694. }
  695. else if (!IsVerticalPosition(pParent))
  696. {
  697. m_popupFlags |= xtpPopupDown;
  698. }
  699. else
  700. {
  701. if (pParent->GetPosition() == xtpBarRight || (pParent->GetType() == xtpBarTypePopup &&
  702. pParent->IsPopupBar() && ((CXTPPopupBar*)pParent)->m_popupFlags & xtpPopupLeft))
  703. m_popupFlags = xtpPopupLeft;
  704. }
  705. m_rcExclude = m_pControlPopup->GetRect();
  706. if (m_pControlPopup->GetType() == xtpControlComboBox && pParent->GetType() != xtpBarTypePopup)
  707. {
  708. m_popupFlags |= xtpPopupDown;
  709. }
  710. else AdjustExcludeRect(m_rcExclude, IsVerticalPosition(pParent));
  711. pParent->ClientToScreen(m_rcExclude);
  712. m_ptPopup.x = (m_popupFlags & xtpPopupDown) ? m_rcExclude.left : m_rcExclude.right;
  713. m_ptPopup.y = (m_popupFlags & xtpPopupDown) ? m_rcExclude.bottom : m_rcExclude.top;
  714. }
  715. }
  716. void CXTPPopupBar::UpdateExpandingState()
  717. {
  718. CXTPCommandBars* pCommandBars = GetCommandBars();
  719. if (!pCommandBars)
  720. return;
  721. int i;
  722. if (pCommandBars->GetCommandBarsOptions()->bAlwaysShowFullMenus)
  723. {
  724. for (i = 0; i < GetControlCount(); i++)
  725. {
  726. CXTPControl* pControl = GetControl(i);
  727. if (!pControl || pControl->GetParent() != this)
  728. continue;
  729. pControl->SetExpanded(FALSE);
  730. }
  731. m_bExpanded = TRUE;
  732. return;
  733. }
  734. m_bCollapsed = FALSE;
  735. BOOL bCollapsedExists = FALSE;
  736. for (i = 0; i < GetControlCount(); i++)
  737. {
  738. CXTPControl* pControl = GetControl(i);
  739. if (!pControl || pControl->GetParent() != this)
  740. continue;
  741. BOOL bVisible = pControl->IsVisible(xtpHideExpand | xtpHideScroll);
  742. if (pCommandBars->IsControlHidden(pControl))
  743. {
  744. pControl->SetExpanded(bVisible);
  745. }
  746. else
  747. {
  748. pControl->SetExpanded(FALSE);
  749. if (pControl->GetID() != XTP_ID_POPUPBAR_EXPAND && bVisible)
  750. bCollapsedExists = TRUE;
  751. }
  752. }
  753. for (i = 0; i < GetControlCount(); i++)
  754. {
  755. CXTPControl* pControl = GetControl(i);
  756. if (!pControl || pControl->GetParent() != this)
  757. continue;
  758. pControl->SetHideFlag(xtpHideExpand, FALSE);
  759. if (pControl->GetExpanded())
  760. {
  761. if (!m_bExpanded && bCollapsedExists)
  762. {
  763. pControl->SetHideFlag(xtpHideExpand, TRUE);
  764. m_bCollapsed = TRUE;
  765. }
  766. }
  767. }
  768. }
  769. void CXTPPopupBar::Animate()
  770. {
  771. CXTPCommandBar* pParentCommandBar = GetParentCommandBar();
  772. BOOL bAnimate = pParentCommandBar ? pParentCommandBar->m_bAnimatePopup : TRUE;
  773. if (bAnimate)
  774. {
  775. if (IsCustomizeMode() || GetWindow(GW_CHILD))
  776. bAnimate = FALSE;
  777. }
  778. BOOL bRegionChanged = FALSE;
  779. if (bAnimate)
  780. {
  781. XTPAnimationType animationType = GetAnimationType();
  782. if (IsAnimateType(animationType))
  783. {
  784. if (m_pControlPopup)
  785. {
  786. m_pControlPopup->RedrawParent();
  787. m_pControlPopup->GetParent()->UpdateWindow();
  788. }
  789. GetSite()->UpdateWindow();
  790. CClientDC paintDC(this);
  791. CXTPClientRect rcClient(this);
  792. CXTPWindowRect rcWindow(this);
  793. CXTPBufferDC animationDC(paintDC, rcClient);
  794. DrawCommandBar(&animationDC, rcClient);
  795. CDC* pDC = GetDesktopWindow()->GetDC();
  796. BOOL dwLayout = CXTPDrawHelpers::IsContextRTL(&paintDC);
  797. CXTPDrawHelpers::SetContextRTL(&paintDC, FALSE);
  798. paintDC.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDC, rcWindow.left, rcWindow.top, SRCCOPY);
  799. GetDesktopWindow()->ReleaseDC(pDC);
  800. CXTPDrawHelpers::SetContextRTL(&paintDC, dwLayout);
  801. GetPaintManager()->SetCommandBarRegion(this);
  802. bRegionChanged = TRUE;
  803. // Animation
  804. GetPaintManager()->Animate(&paintDC, &animationDC, rcClient, animationType);
  805. }
  806. }
  807. if (pParentCommandBar) pParentCommandBar->m_bAnimatePopup = FALSE;
  808. if (!bRegionChanged) GetPaintManager()->SetCommandBarRegion(this);
  809. }
  810. BOOL CXTPPopupBar::Popup(CXTPControlPopup* pControlPopup, BOOL bSelectFirst)
  811. {
  812. m_pControlPopup = pControlPopup;
  813. if (!Create())
  814. return FALSE;
  815. if (m_pToolTipContext)
  816. {
  817. m_pToolTipContext->CancelToolTips();
  818. }
  819. LockRedraw();
  820. CWnd* pWndOwner = GetOwnerSite();
  821. if (pWndOwner) pWndOwner->SendMessage(WM_XTP_INITCOMMANDSPOPUP, 0, (LPARAM)this);
  822. m_bTearOffSelected = FALSE;
  823. m_bCollapsed = FALSE;
  824. m_bExpanded = IsCustomizeMode() || XTPMouseManager()->IsForceExpanded();
  825. UpdateFlags();
  826. UpdateLocation(CalcDynamicLayout(0, 0));
  827. if (!m_hWnd)
  828. {
  829. UnlockRedraw();
  830. return FALSE;
  831. }
  832. if (m_pControlPopup && m_pControlPopup->m_pParent->GetSafeHwnd() == NULL)
  833. {
  834. UnlockRedraw();
  835. DestroyWindow();
  836. return FALSE;
  837. }
  838. SetTrackingMode(TRUE, bSelectFirst, bSelectFirst);
  839. m_nIdleFlags &= ~xtpIdleLayout;
  840. OnIdleUpdateCmdUI(TRUE, 0L);
  841. if (!m_hWnd)
  842. {
  843. UnlockRedraw();
  844. return FALSE;
  845. }
  846. Animate();
  847. XTPSoundManager()->PlaySystemSound(xtpSoundMenuPopup);
  848. CXTPPaintManager* pPaintManager = GetPaintManager();
  849. if (pPaintManager && m_barPosition == xtpBarPopup && m_bShowShadow && pPaintManager->m_bShowShadow && !IsCustomizeMode())
  850. {
  851. pPaintManager->GetShadowManager()->RemoveShadow(this);
  852. pPaintManager->GetShadowManager()->SetShadow(this, m_rcExclude);
  853. }
  854. m_nIdleFlags |= xtpIdleLayout;
  855. UnlockRedraw();
  856. return TRUE;
  857. }
  858. BOOL CXTPPopupBar::Popup(int x, int y, LPCRECT rcExclude)
  859. {
  860. m_ptPopup = CPoint(x, y);
  861. if (rcExclude) m_rcExclude = *rcExclude;
  862. return Popup(NULL);
  863. }
  864. BEGIN_MESSAGE_MAP(CXTPPopupBar, CXTPCommandBar)
  865. ON_WM_MOUSEMOVE()
  866. ON_WM_MOUSEACTIVATE()
  867. ON_WM_LBUTTONDOWN()
  868. ON_WM_SETCURSOR()
  869. ON_WM_TIMER()
  870. ON_WM_NCACTIVATE()
  871. ON_WM_NCCREATE()
  872. ON_MESSAGE(WM_FLOATSTATUS, OnFloatStatus)
  873. END_MESSAGE_MAP()
  874. void CXTPPopupBar::SwitchTearOffTracking(BOOL bShow, CPoint point)
  875. {
  876. CXTPCommandBars* pCommandBars = GetCommandBars();
  877. ASSERT(pCommandBars);
  878. if (!pCommandBars)
  879. return;
  880. ShowWindow(bShow ? SW_SHOWNA : SW_HIDE);
  881. if (!bShow)
  882. {
  883. if (m_pTearOffBar == NULL)
  884. {
  885. m_pTearOffBar = pCommandBars->GetToolBar(m_nTearOffID);
  886. if (m_pTearOffBar != NULL)
  887. {
  888. m_pTearOffBar->SetPosition(xtpBarFloating);
  889. m_pTearOffBar->SetVisible(TRUE);
  890. pCommandBars->RecalcFrameLayout();
  891. }
  892. }
  893. if (m_pTearOffBar == NULL)
  894. {
  895. m_pTearOffBar = pCommandBars->AddCustomBar(m_strTearOffCaption, m_nTearOffID, TRUE);
  896. m_pTearOffBar->m_nMRUWidth = m_nTearOffWidth;
  897. for (int i = 0; i < GetControlCount(); i++)
  898. {
  899. CXTPControl* pControl = GetControl(i);
  900. if (!pControl || pControl->GetParent() != this)
  901. continue;
  902. if (pControl->GetID() != XTP_ID_POPUPBAR_EXPAND)
  903. {
  904. CXTPControl* pControlClone = m_pTearOffBar->GetControls()->AddClone(pControl);
  905. pControlClone->SetHideFlags(pControlClone->GetHideFlags() & ~(xtpHideScroll | xtpHideExpand));
  906. }
  907. }
  908. }
  909. ASSERT(m_pTearOffBar);
  910. pCommandBars->GetSite()->SendMessage(WM_XTP_TEAROFFDONE, (WPARAM)m_pTearOffBar, (LPARAM)this);
  911. m_szTearOffBar = m_pTearOffBar->CalcDynamicLayout(-1, LM_MRUWIDTH | LM_HORZ | LM_COMMIT);
  912. CPoint pt(point.x - m_szTearOffBar.cx / 2, point.y - 10);
  913. m_pTearOffBar->MoveWindow(pt.x, pt.y, m_szTearOffBar.cx, m_szTearOffBar.cy);
  914. m_pTearOffBar->OnInitialUpdate();
  915. m_pTearOffBar->Redraw();
  916. }
  917. else
  918. {
  919. if (m_pTearOffBar)
  920. {
  921. m_pTearOffBar->SetVisible(FALSE);
  922. m_pTearOffBar = 0;
  923. }
  924. }
  925. }
  926. void CXTPPopupBar::TrackResize()
  927. {
  928. // don't handle if capture already set
  929. if (::GetCapture() != NULL)
  930. return;
  931. BOOL bLayoutRTL = IsLayoutRTL();
  932. CXTPControl* pControl = GetControls()->FindControl(xtpControlGallery, -1, TRUE, FALSE);
  933. if (!pControl)
  934. return;
  935. CSize szControl(pControl->GetWidth(), pControl->GetRect().Height());
  936. CSize szControlInit = szControl;
  937. CSize szControlMin(pControl->GetCustomizeMinWidth(), pControl->GetCustomizeMinHeight());
  938. SetPopuped(-1);
  939. SetSelected(-1);
  940. BOOL bResizeWidth = m_bResizable & 1;
  941. BOOL bResizeHeight = m_bResizable & 2;
  942. // set capture to the window which received this message
  943. SetCapture();
  944. ASSERT(m_hWnd == ::GetCapture());
  945. CPoint pt(0, 0);
  946. GetCursorPos(&pt);
  947. // get messages until capture lost or cancelled/accepted
  948. while (::GetCapture() == m_hWnd)
  949. {
  950. MSG msg;
  951. while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
  952. {
  953. if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
  954. break;
  955. DispatchMessage(&msg);
  956. }
  957. if (!::GetMessage(&msg, NULL, 0, 0))
  958. {
  959. AfxPostQuitMessage((int)msg.wParam);
  960. break;
  961. }
  962. if (msg.message == WM_LBUTTONUP)
  963. break;
  964. else if (msg.message == WM_MOUSEMOVE && pt != msg.pt)
  965. {
  966. if (bLayoutRTL)
  967. szControl += CSize(pt.x - msg.pt.x, msg.pt.y - pt.y);
  968. else
  969. szControl += CSize(msg.pt.x - pt.x, msg.pt.y - pt.y);
  970. if (bResizeWidth) pControl->SetWidth(max(szControl.cx, szControlMin.cx));
  971. if (bResizeHeight) pControl->SetHeight(max(szControl.cy, szControlMin.cy));
  972. RecalcSizeLayout();
  973. pt = msg.pt;
  974. }
  975. else if (msg.message == WM_KEYDOWN)
  976. {
  977. if (msg.wParam == VK_ESCAPE)
  978. {
  979. if (bResizeWidth) pControl->SetWidth(szControlInit.cx);
  980. if (bResizeHeight) pControl->SetHeight(szControlInit.cy);
  981. RecalcSizeLayout();
  982. break;
  983. }
  984. }
  985. else
  986. DispatchMessage(&msg);
  987. }
  988. ReleaseCapture();
  989. }
  990. void CXTPPopupBar::TrackTearOff()
  991. {
  992. m_pTearOffBar = NULL;
  993. CRect rcGripper = m_rcTearOffGripper;
  994. ClientToScreen(&rcGripper);
  995. BOOL bShow = TRUE;
  996. // don't handle if capture already set
  997. if (::GetCapture() != NULL)
  998. return;
  999. // set capture to the window which received this message
  1000. SetCapture();
  1001. ASSERT(this == CWnd::GetCapture());
  1002. CPoint pt(0, 0);
  1003. // get messages until capture lost or cancelled/accepted
  1004. while (CWnd::GetCapture() == this)
  1005. {
  1006. MSG msg;
  1007. while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
  1008. {
  1009. if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
  1010. break;
  1011. DispatchMessage(&msg);
  1012. }
  1013. if (!::GetMessage(&msg, NULL, 0, 0))
  1014. {
  1015. AfxPostQuitMessage((int)msg.wParam);
  1016. break;
  1017. }
  1018. if (msg.message == WM_LBUTTONUP)
  1019. break;
  1020. else if (msg.message == WM_MOUSEMOVE && pt != msg.pt)
  1021. {
  1022. pt = msg.pt;
  1023. BOOL bState = !(pt.x > rcGripper.right + 10 || pt.x < rcGripper.left - 10 ||
  1024. pt.y > rcGripper.bottom + 10 || pt.y < rcGripper.top - 10);
  1025. if (bState != bShow)
  1026. {
  1027. bShow = bState;
  1028. SwitchTearOffTracking(bState, pt);
  1029. }
  1030. if (m_pTearOffBar != NULL)
  1031. {
  1032. CPoint point(pt.x - m_szTearOffBar.cx / 2, pt.y - 10);
  1033. m_pTearOffBar->MoveWindow(point.x, point.y, m_szTearOffBar.cx, m_szTearOffBar.cy);
  1034. }
  1035. }
  1036. else if (msg.message == WM_KEYDOWN)
  1037. {
  1038. if (msg.wParam == VK_ESCAPE)
  1039. {
  1040. break;
  1041. }
  1042. }
  1043. else
  1044. DispatchMessage(&msg);
  1045. }
  1046. ReleaseCapture();
  1047. if (m_pTearOffBar)
  1048. {
  1049. GetCommandBars()->ClosePopups();
  1050. }
  1051. }
  1052. BOOL CXTPPopupBar::_MouseInResizeGripper(const POINT& pt)
  1053. {
  1054. if (m_rcResizeGripper.PtInRect(pt))
  1055. {
  1056. if (m_bResizable == 2)
  1057. {
  1058. return TRUE;
  1059. }
  1060. CRect rcResizeGripper(m_rcResizeGripper);
  1061. rcResizeGripper.left = rcResizeGripper.right - rcResizeGripper.Height();
  1062. if (rcResizeGripper.PtInRect(pt))
  1063. {
  1064. return TRUE;
  1065. }
  1066. }
  1067. return FALSE;
  1068. }
  1069. BOOL CXTPPopupBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  1070. {
  1071. if (m_bResizable)
  1072. {
  1073. POINT pt;
  1074. GetCursorPos(&pt);
  1075. ScreenToClient(&pt);
  1076. if (_MouseInResizeGripper(pt))
  1077. {
  1078. SetCursor(AfxGetApp()->LoadStandardCursor(m_bResizable == 2 ? IDC_SIZENS : IsLayoutRTL() ? IDC_SIZENESW : IDC_SIZENWSE));
  1079. return TRUE;
  1080. }
  1081. }
  1082. return CXTPCommandBar::OnSetCursor(pWnd, nHitTest, message);
  1083. }
  1084. void CXTPPopupBar::OnLButtonDown(UINT nFlags, CPoint point)
  1085. {
  1086. if (m_bTearOffPopup && m_rcTearOffGripper.PtInRect(point) && !IsCustomizeMode())
  1087. {
  1088. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
  1089. CXTPMouseManager* pMouseManager = XTPMouseManager();
  1090. pMouseManager->LockMouseMove();
  1091. m_bTearOffTracking = TRUE;
  1092. TrackTearOff();
  1093. m_bTearOffTracking = FALSE;
  1094. pMouseManager->UnlockMouseMove();
  1095. pMouseManager->RefreshCursor();
  1096. return;
  1097. }
  1098. if (m_bResizable && _MouseInResizeGripper(point))
  1099. {
  1100. CXTPMouseManager* pMouseManager = XTPMouseManager();
  1101. pMouseManager->LockMouseMove();
  1102. TrackResize();
  1103. pMouseManager->UnlockMouseMove();
  1104. pMouseManager->RefreshCursor();
  1105. return;
  1106. }
  1107. CXTPCommandBar::OnLButtonDown(nFlags, point);
  1108. }
  1109. BOOL CXTPPopupBar::DestroyWindow()
  1110. {
  1111. if (!GetSafeHwnd())
  1112. return CXTPCommandBar::DestroyWindow();
  1113. CWnd* pWnd = GetWindow(GW_CHILD);
  1114. if (!pWnd)
  1115. return CXTPCommandBar::DestroyWindow();
  1116. CWnd* pWndParent = GetSite();
  1117. while (pWnd)
  1118. {
  1119. CWnd* pWndNext = pWnd->GetWindow(GW_HWNDNEXT);
  1120. pWnd->ShowWindow(SW_HIDE);
  1121. pWnd->SetParent(pWndParent);
  1122. pWnd = pWndNext;
  1123. }
  1124. return CXTPCommandBar::DestroyWindow();
  1125. }
  1126. BOOL CXTPPopupBar::SetTrackingMode(int bMode, BOOL bSelectFirst, BOOL bKeyboard)
  1127. {
  1128. if (!CXTPCommandBar::SetTrackingMode(bMode, bSelectFirst, bKeyboard))
  1129. return FALSE;
  1130. CWnd* pWnd = GetSite();
  1131. if (!bMode)
  1132. {
  1133. AccessibleNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, m_hWnd, OBJID_MENU, 0);
  1134. DestroyWindow();
  1135. CXTPCommandBar* pParentCommandBar = GetParentCommandBar();
  1136. if (pParentCommandBar)
  1137. pParentCommandBar->SetPopuped(-1);
  1138. if (pWnd && ::IsWindow(pWnd->m_hWnd)) pWnd->SendMessage(WM_XTP_UNINITCOMMANDSPOPUP, 0, (LPARAM)this);
  1139. Sleep(1);
  1140. m_pControlPopup = 0;
  1141. }
  1142. else
  1143. {
  1144. AccessibleNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, m_hWnd, OBJID_MENU, 0);
  1145. }
  1146. if (pWnd && ::IsWindow(pWnd->m_hWnd)) pWnd->UpdateWindow();
  1147. return TRUE;
  1148. }
  1149. void CXTPPopupBar::OnMouseMove(UINT nFlags, CPoint point)
  1150. {
  1151. if (m_nLockRecurse > 0)
  1152. return;
  1153. if (GetParentCommandBar() != NULL && CXTPClientRect(this).PtInRect(point))
  1154. {
  1155. // restore selection
  1156. GetParentCommandBar()->SetSelected(m_pControlPopup->GetIndex());
  1157. }
  1158. if (m_scrollInfo.bScroll)
  1159. {
  1160. if (m_scrollInfo.btnUp.OnMouseMove(point) ||
  1161. m_scrollInfo.btnDown.OnMouseMove(point))
  1162. {
  1163. SetPopuped(-1);
  1164. }
  1165. }
  1166. if (m_bTearOffPopup && !IsCustomizeMode() && m_rcTearOffGripper.PtInRect(point) && !m_bTearOffSelected)
  1167. {
  1168. SetSelected(-1);
  1169. SetPopuped(-1);
  1170. m_nTearOffTimer = SetTimer(TID_TEAROFFSELECTED, 80, NULL);
  1171. }
  1172. CXTPCommandBar::OnMouseMove(nFlags, point);
  1173. }
  1174. CXTPCommandBar* CXTPPopupBar::GetParentCommandBar() const
  1175. {
  1176. return m_pControlPopup ? m_pControlPopup->GetParent() : NULL;
  1177. }
  1178. int CXTPPopupBar::OnMouseActivate(CWnd* /*pDesktopWnd*/, UINT /*nHitTest*/, UINT /*message*/)
  1179. {
  1180. return MA_NOACTIVATE;
  1181. }
  1182. BOOL CXTPPopupBar::OnNcActivate(BOOL bActive)
  1183. {
  1184. return bActive ? FALSE : CWnd::OnNcActivate(bActive);
  1185. }
  1186. BOOL CXTPPopupBar::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
  1187. {
  1188. if (!CXTPCommandBar::OnNcCreate(lpCreateStruct))
  1189. return FALSE;
  1190. if (GetStyle() & MFS_SYNCACTIVE)
  1191. {
  1192. // syncronize activation state with top level parent
  1193. CWnd* pParentWnd = GetTopLevelParent();
  1194. ASSERT(pParentWnd != NULL);
  1195. if (!pParentWnd)
  1196. return FALSE;
  1197. CWnd* pActiveWnd = GetForegroundWindow();
  1198. BOOL bActive = (pParentWnd == pActiveWnd) ||
  1199. (pParentWnd->GetLastActivePopup() == pActiveWnd &&
  1200. pActiveWnd->SendMessage(WM_FLOATSTATUS, FS_SYNCACTIVE) != 0);
  1201. // the WM_FLOATSTATUS does the actual work
  1202. SendMessage(WM_FLOATSTATUS, bActive ? FS_ACTIVATE : FS_DEACTIVATE);
  1203. }
  1204. return TRUE;
  1205. }
  1206. LRESULT CXTPPopupBar::OnFloatStatus(WPARAM wParam, LPARAM)
  1207. {
  1208. // FS_SYNCACTIVE is used to detect MFS_SYNCACTIVE windows
  1209. LRESULT lResult = ((GetStyle() & MFS_SYNCACTIVE) && (wParam & FS_SYNCACTIVE));
  1210. return lResult;
  1211. }
  1212. void CXTPPopupBar::DrawCommandBar(CDC* pDC, CRect rcClipBox)
  1213. {
  1214. CXTPCommandBar::DrawCommandBar(pDC, rcClipBox);
  1215. if (m_scrollInfo.bScroll)
  1216. {
  1217. if (!m_scrollInfo.btnUp.m_rc.IsRectEmpty())
  1218. {
  1219. CPoint pt = m_scrollInfo.btnUp.m_rc.CenterPoint();
  1220. GetPaintManager()->Triangle(pDC, CPoint(pt.x - 3, pt.y), CPoint(pt.x + 3, pt.y), CPoint(pt.x, pt.y + 3), GetXtremeColor(COLOR_BTNTEXT));
  1221. }
  1222. if (!m_scrollInfo.btnDown.m_rc.IsRectEmpty())
  1223. {
  1224. CPoint pt = m_scrollInfo.btnDown.m_rc.CenterPoint();
  1225. GetPaintManager()->Triangle(pDC, CPoint(pt.x - 3, pt.y), CPoint(pt.x + 3, pt.y), CPoint(pt.x, pt.y - 3), GetXtremeColor(COLOR_BTNTEXT));
  1226. }
  1227. }
  1228. if (m_bTearOffPopup && GetControlCount() > 0)
  1229. {
  1230. GetPaintManager()->DrawTearOffGripper(pDC, m_rcTearOffGripper, m_bTearOffSelected, TRUE);
  1231. }
  1232. if (!m_rcResizeGripper.IsRectEmpty() && m_bResizable)
  1233. {
  1234. GetPaintManager()->DrawPopupResizeGripper(pDC, m_rcResizeGripper, m_bResizable);
  1235. }
  1236. }
  1237. BOOL CXTPPopupBar::SetSelected(int nSelected, BOOL bKeyboard)
  1238. {
  1239. if (!CXTPCommandBar::SetSelected(nSelected, bKeyboard))
  1240. return FALSE;
  1241. if (m_nSelected != -1 && !bKeyboard && (GetControl(m_nSelected)->GetID() == XTP_ID_POPUPBAR_EXPAND))
  1242. {
  1243. CXTPCommandBars* pCommandBars = GetCommandBars();
  1244. ASSERT(pCommandBars);
  1245. if (pCommandBars->GetCommandBarsOptions()->bShowFullAfterDelay)
  1246. {
  1247. SetTimer(TID_EXPANDHOVER, s_nExpandHoverDelay, NULL);
  1248. }
  1249. }
  1250. else
  1251. {
  1252. KillTimer(TID_EXPANDHOVER);
  1253. }
  1254. if (m_scrollInfo.bScroll && m_nSelected != -1)
  1255. {
  1256. if (GetControl(m_nSelected)->GetHideFlags() & xtpHideScroll)
  1257. {
  1258. if (m_nSelected >= m_scrollInfo.nScrollLast)
  1259. {
  1260. m_scrollInfo.nScrollLast = m_nSelected + 1;
  1261. AdjustScrolling(NULL, TRUE, TRUE);
  1262. }
  1263. else
  1264. {
  1265. m_scrollInfo.nScrollFirst = m_nSelected;
  1266. AdjustScrolling(NULL, FALSE, TRUE);
  1267. }
  1268. }
  1269. }
  1270. return TRUE;
  1271. }
  1272. void CXTPPopupBar::OnTimer(UINT_PTR nIDEvent)
  1273. {
  1274. int nCount = GetControlCount();
  1275. switch (nIDEvent)
  1276. {
  1277. case TID_HOVERUP:
  1278. if (m_scrollInfo.nScrollLast == nCount)
  1279. {
  1280. m_scrollInfo.btnUp.KillTimer();
  1281. return;
  1282. }
  1283. m_scrollInfo.nScrollLast++;
  1284. AdjustScrolling(NULL, TRUE, TRUE);
  1285. break;
  1286. case TID_HOVERDOWN:
  1287. if (m_scrollInfo.nScrollFirst == 0)
  1288. {
  1289. m_scrollInfo.btnDown.KillTimer() ;
  1290. return;
  1291. }
  1292. m_scrollInfo.nScrollFirst--;
  1293. AdjustScrolling(NULL, FALSE, TRUE);
  1294. break;
  1295. case TID_TEAROFFSELECTED:
  1296. {
  1297. CPoint pt;
  1298. GetCursorPos(&pt);
  1299. ScreenToClient(&pt);
  1300. if (!m_bTearOffSelected && m_rcTearOffGripper.PtInRect(pt))
  1301. {
  1302. m_bTearOffSelected = TRUE;
  1303. Redraw();
  1304. }
  1305. if (m_bTearOffSelected && !m_rcTearOffGripper.PtInRect(pt) && !m_bTearOffTracking)
  1306. {
  1307. m_bTearOffSelected = FALSE;
  1308. Redraw();
  1309. KillTimer(m_nTearOffTimer);
  1310. }
  1311. }
  1312. break;
  1313. case TID_EXPANDHOVER:
  1314. if (m_nSelected != -1 && GetControl(m_nSelected)->GetID() == XTP_ID_POPUPBAR_EXPAND)
  1315. {
  1316. GetControl(m_nSelected)->OnExecute();
  1317. }
  1318. KillTimer(TID_EXPANDHOVER);
  1319. break;
  1320. }
  1321. CXTPCommandBar::OnTimer(nIDEvent);
  1322. }
  1323. BOOL CXTPPopupBar::OnHookKeyDown(UINT nChar, LPARAM lParam)
  1324. {
  1325. if (m_bCollapsed)
  1326. {
  1327. if (nChar == VK_DOWN)
  1328. {
  1329. if (GetKeyState(VK_CONTROL) < 0 || m_pControls->GetNext(m_nSelected, +1) <= m_nSelected)
  1330. {
  1331. ExpandBar();
  1332. }
  1333. }
  1334. }
  1335. return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
  1336. }
  1337. void CXTPPopupBar::SetDefaultItem(UINT uItem, BOOL fByPos)
  1338. {
  1339. CXTPControl* pControl = fByPos ? m_pControls->GetAt(uItem) : m_pControls->FindControl(xtpControlError, uItem, TRUE, FALSE);
  1340. if (pControl)
  1341. {
  1342. pControl->SetItemDefault(TRUE);
  1343. }
  1344. }
  1345. UINT CXTPPopupBar::GetDefaultItem(UINT /*gmdiFlags*/, BOOL fByPos)
  1346. {
  1347. for (int i = 0; i < GetControlCount(); i++)
  1348. {
  1349. CXTPControl* pControl = GetControl(i);
  1350. if (!pControl || pControl->GetParent() != this || !pControl->IsVisible())
  1351. continue;
  1352. if (pControl->IsItemDefault())
  1353. {
  1354. return fByPos ? pControl->GetIndex() : pControl->GetID();
  1355. }
  1356. }
  1357. return (UINT)-1;
  1358. }
  1359. void CXTPPopupBar::Copy(CXTPCommandBar* pCommandBar, BOOL bRecursive)
  1360. {
  1361. ASSERT_KINDOF(CXTPPopupBar, pCommandBar);
  1362. CXTPCommandBar::Copy(pCommandBar, bRecursive);
  1363. m_bTearOffPopup = ((CXTPPopupBar*)pCommandBar)->m_bTearOffPopup;
  1364. m_strTearOffCaption = ((CXTPPopupBar*)pCommandBar)->m_strTearOffCaption;
  1365. m_nTearOffID = ((CXTPPopupBar*)pCommandBar)->m_nTearOffID;
  1366. m_nTearOffWidth = ((CXTPPopupBar*)pCommandBar)->m_nTearOffWidth;
  1367. m_bShowShadow = ((CXTPPopupBar*)pCommandBar)->m_bShowShadow;
  1368. m_rcBorders = ((CXTPPopupBar*)pCommandBar)->m_rcBorders;
  1369. m_bContextMenu = ((CXTPPopupBar*)pCommandBar)->m_bContextMenu;
  1370. }
  1371. void CXTPPopupBar::SetPopupToolBar(BOOL bToolBarType)
  1372. {
  1373. m_barType = bToolBarType ? xtpBarTypeNormal : xtpBarTypePopup;
  1374. }
  1375. ////////////////////////////////////////////////////////////////////////////
  1376. //
  1377. IMPLEMENT_XTP_COMMANDBAR(CXTPPopupToolBar, CXTPPopupBar)
  1378. CXTPPopupToolBar::CXTPPopupToolBar()
  1379. {
  1380. m_barType = xtpBarTypeNormal;
  1381. }
  1382. CSize CXTPPopupToolBar::CalcDynamicLayout(int, DWORD /*nMode*/)
  1383. {
  1384. return CXTPPopupBar::CalcDynamicLayout(0, 0);
  1385. }
  1386. CXTPPopupToolBar* CXTPPopupToolBar::CreatePopupToolBar(CXTPCommandBars* pCommandBars)
  1387. {
  1388. CXTPPopupToolBar* pPopupBar = (CXTPPopupToolBar*)CXTPCommandBars::m_pPopupToolBarClass->CreateObject();
  1389. pPopupBar->SetCommandBars(pCommandBars);
  1390. return pPopupBar;
  1391. }