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

对话框与窗口

开发平台:

Visual C++

  1. // XTPStatusBar.cpp : implementation of the CXTPStatusBar 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 "Common/XTPDrawHelpers.h"
  22. #include "Common/XTPColorManager.h"
  23. #include "Common/XTPVC80Helpers.h"
  24. #include "Common/XTPImageManager.h"
  25. #include "Common/XTPToolTipContext.h"
  26. #include "Common/XTPMarkupRender.h"
  27. #include "Common/XTPResourceManager.h"
  28. #include "XTPStatusBar.h"
  29. #include "XTPPaintManager.h"
  30. #include "XTPToolBar.h"
  31. #include "XTPCommandBars.h"
  32. #include "XTPPopupBar.h"
  33. #include "XTPControlButton.h"
  34. #include "XTPMouseManager.h"
  35. #ifdef _XTP_INCLUDE_RIBBON
  36. #include "XTPOffice2007FrameHook.h"
  37. #endif
  38. #ifdef _DEBUG
  39. #define new DEBUG_NEW
  40. #undef THIS_FILE
  41. static char THIS_FILE[] = __FILE__;
  42. #endif
  43. #define SBPF_UPDATE 0x0001  // pending update of text
  44. #define CX_PANE_BORDER 2    // 3 pixels on each side of each pane
  45. //////////////////////////////////////////////////////////////////////////
  46. // CXTPStatusBarPane
  47. IMPLEMENT_DYNAMIC(CXTPStatusBarPane, CCmdTarget)
  48. CXTPStatusBarPane::CXTPStatusBarPane()
  49. {
  50. m_nID = 0;
  51. m_cxText = 0;
  52. m_nStyle = 0;
  53. m_nBestFit = 0;
  54. m_nIndex = -1;
  55. m_pStatusBar = NULL;
  56. m_hWndPane = NULL;
  57. m_bAutoDeleteWnd = FALSE;
  58. m_dwHideFlags = 0;
  59. m_clrText = (COLORREF)-1;
  60. m_clrBackground = (COLORREF)-1;
  61. m_nIconIndex = -1;
  62. m_nAlignment = DT_LEFT;
  63. m_rcMargins.SetRect(0, 0, 0, 0);
  64. m_rcPadding.SetRect(3, 1, 3, 1);
  65. m_bButton = FALSE;
  66. m_bPressed = FALSE;
  67. m_pMarkupUIElement = NULL;
  68. m_rcPane.SetRectEmpty();
  69. m_bBeginGroup = TRUE;
  70. }
  71. CXTPStatusBarPane::~CXTPStatusBarPane()
  72. {
  73. CWnd* pWnd = CWnd::FromHandlePermanent(m_hWndPane);
  74. if (pWnd && ::IsWindow(pWnd->GetSafeHwnd()))
  75. {
  76. pWnd->DestroyWindow();
  77. if (m_bAutoDeleteWnd)
  78. {
  79. delete pWnd;
  80. }
  81. }
  82. XTPMarkupReleaseElement(m_pMarkupUIElement);
  83. }
  84. void CXTPStatusBarPane::SetButton(BOOL bButton)
  85. {
  86. m_bButton = bButton;
  87. ShowBorders(FALSE);
  88. }
  89. BOOL CXTPStatusBarPane::IsButton() const
  90. {
  91. return m_bButton;
  92. }
  93. CRect CXTPStatusBarPane::GetRect() const
  94. {
  95. return m_rcPane;
  96. }
  97. void CXTPStatusBarPane::Redraw() const
  98. {
  99. if (this && m_pStatusBar && m_pStatusBar->GetSafeHwnd() && IsVisible())
  100. {
  101. m_pStatusBar->InvalidateRect(GetRect());
  102. }
  103. }
  104. CRect CXTPStatusBarPane::GetMargins() const
  105. {
  106. return m_rcMargins;
  107. }
  108. CRect CXTPStatusBarPane::GetPadding() const
  109. {
  110. return m_rcPadding;
  111. }
  112. void CXTPStatusBarPane::SetMargins(int nLeft, int nTop, int nRight, int nBottom)
  113. {
  114. m_rcMargins.SetRect(nLeft, nTop, nRight, nBottom);
  115. }
  116. void CXTPStatusBarPane::SetPadding(int nLeft, int nTop, int nRight, int nBottom)
  117. {
  118. m_rcPadding.SetRect(nLeft, nTop, nRight, nBottom);
  119. }
  120. void CXTPStatusBarPane::SetText(LPCTSTR lpszText)
  121. {
  122. if (m_strText == lpszText)
  123. return;
  124. XTPMarkupReleaseElement(m_pMarkupUIElement);
  125. m_strText = lpszText;
  126. if (m_pStatusBar->GetMarkupContext())
  127. {
  128. m_pMarkupUIElement = XTPMarkupParseText(m_pStatusBar->GetMarkupContext(), lpszText);
  129. }
  130. if (!IsVisible())
  131. return;
  132. if (m_cxText == 0 && m_nBestFit != GetBestFit())
  133. {
  134. m_pStatusBar->RecalcLayout();
  135. }
  136. else
  137. {
  138. Redraw();
  139. }
  140. }
  141. CString CXTPStatusBarPane::GetText() const
  142. {
  143. return m_strText;
  144. }
  145. void CXTPStatusBarPane::SetWidth(int cxText)
  146. {
  147. if (m_cxText != cxText)
  148. {
  149. m_cxText = cxText;
  150. m_pStatusBar->RecalcLayout();
  151. }
  152. }
  153. int CXTPStatusBarPane::GetWidth()
  154. {
  155. return m_cxText <= 0 ? GetBestFit() : m_cxText;
  156. }
  157. void CXTPStatusBarPane::SetStyle(UINT nStyle)
  158. {
  159. if (m_nStyle != nStyle)
  160. {
  161. // if the pane is changing SBPS_STRETCH, then...
  162. if ((m_nStyle ^ nStyle) & SBPS_STRETCH)
  163. {
  164. // ... we need to re-layout the panes
  165. m_nStyle = nStyle;
  166. m_pStatusBar->RecalcLayout();
  167. }
  168. // use SetPaneText, since it updates the style and text
  169. m_nStyle = nStyle;
  170. Redraw();
  171. }
  172. }
  173. UINT CXTPStatusBarPane::GetStyle() const
  174. {
  175. return m_nStyle;
  176. }
  177. UINT CXTPStatusBarPane::GetID() const
  178. {
  179. return m_nID;
  180. }
  181. int CXTPStatusBarPane::GetIndex() const
  182. {
  183. return m_nIndex;
  184. }
  185. CXTPStatusBar* CXTPStatusBarPane::GetStatusBar() const
  186. {
  187. return m_pStatusBar;
  188. }
  189. void CXTPStatusBarPane::Remove()
  190. {
  191. m_pStatusBar->RemoveAt(m_nIndex);
  192. }
  193. void CXTPStatusBarPane::SetVisible(BOOL bVisible)
  194. {
  195. DWORD dwHideFlags = bVisible ? m_dwHideFlags &~ xtpHideGeneric : m_dwHideFlags | xtpHideGeneric;
  196. if (m_dwHideFlags != dwHideFlags)
  197. {
  198. m_dwHideFlags = dwHideFlags;
  199. m_pStatusBar->RecalcLayout();
  200. }
  201. }
  202. BOOL CXTPStatusBarPane::IsVisible() const
  203. {
  204. return m_dwHideFlags == xtpNoHide;
  205. }
  206. void CXTPStatusBarPane::OnDraw(CDC* pDC, CRect rcItem)
  207. {
  208. CXTPPaintManager* pPaintManager = m_pStatusBar->GetPaintManager();
  209. if (pPaintManager)
  210. {
  211. pPaintManager->DrawStatusBarPaneEntry(pDC, rcItem, this);
  212. }
  213. }
  214. void CXTPStatusBarPane::BestFit()
  215. {
  216. SetWidth(GetBestFit());
  217. }
  218. int CXTPStatusBarPane::GetBestFit()
  219. {
  220. int cxText = 0;
  221. if (m_pMarkupUIElement)
  222. {
  223. XTPMarkupSetDefaultFont(m_pStatusBar->m_pMarkupContext, (HFONT)GetTextFont()->GetSafeHandle(), COLORREF_NULL);
  224. cxText = XTPMarkupMeasureElement(m_pMarkupUIElement).cx + m_rcPadding.left + m_rcPadding.right;
  225. }
  226. else
  227. {
  228. CClientDC dc(m_pStatusBar);
  229. CXTPFontDC font(&dc, GetTextFont());
  230. cxText = dc.GetTextExtent(m_strText).cx + m_rcPadding.left + m_rcPadding.right;
  231. }
  232. CXTPImageManagerIcon* pIcon = GetImage();
  233. if (pIcon) cxText += pIcon->GetWidth() + (!m_strText.IsEmpty() ? 2 : 0);
  234. return cxText;
  235. }
  236. void CXTPStatusBarPane::SetTextColor(COLORREF clrText)
  237. {
  238. m_clrText = clrText;
  239. Redraw();
  240. }
  241. COLORREF CXTPStatusBarPane::GetTextColor() const
  242. {
  243. return m_clrText;
  244. }
  245. void CXTPStatusBarPane::SetBackgroundColor(COLORREF clrBackground)
  246. {
  247. m_clrBackground = clrBackground;
  248. Redraw();
  249. }
  250. COLORREF CXTPStatusBarPane::GetBackgroundColor() const
  251. {
  252. return m_clrBackground;
  253. }
  254. CFont* CXTPStatusBarPane::GetTextFont()
  255. {
  256. ASSERT(m_pStatusBar);
  257. return (m_pStatusBar && m_fntText.m_hObject == NULL) ?
  258. m_pStatusBar->GetFont(): &m_fntText;
  259. }
  260. void CXTPStatusBarPane::SetTextFont(CFont* pFntText)
  261. {
  262. ASSERT(pFntText);
  263. if (!pFntText)
  264. return;
  265. LOGFONT lf;
  266. pFntText->GetLogFont(&lf);
  267. SetTextFont(&lf);
  268. }
  269. void CXTPStatusBarPane::SetTextFont(PLOGFONT pLogfText)
  270. {
  271. ASSERT(pLogfText);
  272. m_fntText.DeleteObject();
  273. m_fntText.CreateFontIndirect(pLogfText);
  274. Redraw();
  275. }
  276. CXTPImageManagerIcon* CXTPStatusBarPane::GetImage() const
  277. {
  278. if (m_nIconIndex != -1)
  279. return m_pStatusBar->GetImageManager()->GetImage(m_nIconIndex, 0);
  280. return NULL;
  281. }
  282. int CXTPStatusBarPane::GetIconIndex() const
  283. {
  284. return m_nIconIndex;
  285. }
  286. void CXTPStatusBarPane::SetIconIndex(int nIconIndex)
  287. {
  288. m_nIconIndex = nIconIndex;
  289. m_pStatusBar->RecalcLayout();
  290. }
  291. void CXTPStatusBarPane::SetTextAlignment(int nAlign)
  292. {
  293. m_nAlignment = nAlign;
  294. Redraw();
  295. }
  296. int CXTPStatusBarPane::GetTextAlignment() const
  297. {
  298. return m_nAlignment;
  299. }
  300. void CXTPStatusBarPane::SetTooltip(LPCTSTR lpszTooltip)
  301. {
  302. m_strToolTip = lpszTooltip;
  303. }
  304. CString CXTPStatusBarPane::GetTooltip() const
  305. {
  306. return m_strToolTip;
  307. }
  308. void CXTPStatusBarPane::SetEnabled(BOOL bEnabled)
  309. {
  310. SetStyle(bEnabled ? GetStyle() & ~SBPS_DISABLED : GetStyle() | SBPS_DISABLED);
  311. }
  312. BOOL CXTPStatusBarPane::IsEnabled() const
  313. {
  314. return ((m_nStyle & SBPS_DISABLED) == 0);
  315. }
  316. BOOL CXTPStatusBarPane::IsChecked() const
  317. {
  318. return ((m_nStyle & SBPS_POPOUT) == SBPS_POPOUT);
  319. }
  320. void CXTPStatusBarPane::SetChecked(BOOL bChecked)
  321. {
  322. SetStyle(!bChecked ? GetStyle() & ~SBPS_POPOUT : GetStyle() | SBPS_POPOUT);
  323. }
  324. void CXTPStatusBarPane::OnMouseMove(CPoint /*point*/)
  325. {
  326. }
  327. INT_PTR CXTPStatusBarPane::OnToolHitTest(CPoint /*point*/, TOOLINFO* /*pTI*/) const
  328. {
  329. return -1;
  330. }
  331. void CXTPStatusBarPane::OnLButtonDown(CPoint point)
  332. {
  333. if (!m_bButton)
  334. return;
  335. m_bPressed = TRUE;
  336. Redraw();
  337. m_pStatusBar->SetCapture();
  338. CRect rcButton = GetRect();
  339. BOOL  bClick = FALSE;
  340. while (::GetCapture() == m_pStatusBar->GetSafeHwnd())
  341. {
  342. BOOL bPressed = rcButton.PtInRect(point);
  343. if (bPressed != m_bPressed)
  344. {
  345. m_bPressed = bPressed;
  346. Redraw();
  347. }
  348. MSG msg;
  349. if (!::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
  350. continue;
  351. VERIFY(::GetMessage(&msg, NULL, 0, 0));
  352. switch (msg.message)
  353. {
  354. case WM_MOUSEMOVE:
  355. point = CPoint((short signed)LOWORD(msg.lParam), (short signed)HIWORD(msg.lParam));
  356. break;
  357. case WM_LBUTTONUP:
  358. bClick = m_bPressed;
  359. goto ExitLoop;
  360. case WM_KEYDOWN:
  361. if (msg.wParam != VK_ESCAPE)
  362. break;
  363. case WM_CANCELMODE:
  364. case WM_RBUTTONDOWN:
  365. goto ExitLoop;
  366. default:
  367. DispatchMessage (&msg);
  368. break;
  369. }
  370. }
  371. ExitLoop:
  372. ReleaseCapture();
  373. m_bPressed = FALSE;
  374. Redraw();
  375. if (bClick)
  376. {
  377. m_pStatusBar->OnPaneClick(this);
  378. }
  379. }
  380. //////////////////////////////////////////////////////////////////////////
  381. // CXTPStatusBar
  382. IMPLEMENT_DYNAMIC(CXTPStatusBar, CControlBar)
  383. CXTPStatusBar::CXTPStatusBar()
  384. {
  385. // setup default border/margin depending on type of system
  386. m_cyTopBorder = 2;
  387. m_cxLeftBorder = 0;
  388. m_cxRightBorder = 0;
  389. m_cyBottomBorder = 0;
  390. m_cxPaneSpacing = 2;
  391. m_bCustomizable = FALSE;
  392. m_nMinHeight = 20;
  393. m_pCommandBars = NULL;
  394. m_bDrawDisabledText = TRUE;
  395. m_pToolTipContext = new CXTPToolTipContext;
  396. m_pHighlightedPane = NULL;
  397. m_bShowSizeGripper = FALSE;
  398. m_nRibbonDividerIndex = 0;
  399. m_pMarkupContext = NULL;
  400. }
  401. BOOL CXTPStatusBar::IsWin4()
  402. {
  403. #if (_MSC_VER >= 1300)
  404. return TRUE;
  405. #else
  406. DWORD dwVersion = ::GetVersion();
  407. return (BYTE)dwVersion >= 4;
  408. #endif
  409. }
  410. CXTPStatusBar::~CXTPStatusBar()
  411. {
  412. RemoveAll();
  413. CMDTARGET_RELEASE(m_pToolTipContext);
  414. XTPMarkupReleaseContext(m_pMarkupContext);
  415. }
  416. void CXTPStatusBar::EnableMarkup(BOOL bEnableMarkup)
  417. {
  418. XTPMarkupReleaseContext(m_pMarkupContext);
  419. if (bEnableMarkup)
  420. {
  421. m_pMarkupContext = XTPMarkupCreateContext(m_hWnd);
  422. }
  423. }
  424. CXTPImageManager* CXTPStatusBar::GetImageManager() const
  425. {
  426. if (m_pCommandBars)
  427. return m_pCommandBars->GetImageManager();
  428. return XTPImageManager();
  429. }
  430. CXTPStatusBarPane* CXTPStatusBar::HitTest(CPoint pt, CRect* lpRect) const
  431. {
  432. for (int i = 0; i < GetPaneCount(); i++)
  433. {
  434. CXTPStatusBarPane* pPane = GetPane(i);
  435. if (!pPane->IsVisible())
  436. continue;
  437. CRect rc = pPane->GetRect();
  438. if (rc.PtInRect(pt))
  439. {
  440. if (lpRect)
  441. *lpRect = rc;
  442. return pPane;
  443. }
  444. }
  445. return NULL;
  446. }
  447. void CXTPStatusBar::RemoveAll()
  448. {
  449. for (int i = 0; i < (int)m_arrPanes.GetSize(); i++)
  450. {
  451. m_arrPanes[i]->InternalRelease();
  452. }
  453. m_arrPanes.RemoveAll();
  454. m_pHighlightedPane = NULL;
  455. RecalcLayout();
  456. }
  457. CXTPStatusBarPane* CXTPStatusBar::GetPane(int nIndex) const
  458. {
  459. ASSERT(nIndex >= 0 && nIndex < GetPaneCount());
  460. return nIndex >= 0 && nIndex < GetPaneCount() ? m_arrPanes[nIndex]: NULL;
  461. }
  462. CXTPStatusBarPane* CXTPStatusBar::FindPane(UINT nID) const
  463. {
  464. for (int i = 0; i < GetPaneCount(); i++)
  465. {
  466. if (GetPane(i)->m_nID == nID)
  467. return GetPane(i);
  468. }
  469. return NULL;
  470. }
  471. int CXTPStatusBar::GetVisiblePaneCount() const
  472. {
  473. int nCount = 0;
  474. for (int i = 0; i < GetPaneCount(); i++)
  475. {
  476. if (m_arrPanes[i]->IsVisible()) nCount++;
  477. }
  478. return nCount;
  479. }
  480. /////////////////////////////////////////////////////////////////////////////
  481. // CXTPStatusBar creation, etc
  482. BOOL CXTPStatusBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
  483. {
  484. return CreateEx(pParentWnd, 0, dwStyle, nID);
  485. }
  486. CFont* CXTPStatusBar::GetFont()
  487. {
  488. if (m_fontStatus.GetSafeHandle())
  489. return &m_fontStatus;
  490. return &GetPaintManager()->m_fontToolTip;
  491. }
  492. void CXTPStatusBar::SetFont(CFont* pFont, BOOL bRedraw /* = TRUE */)
  493. {
  494. m_fontStatus.DeleteObject();
  495. if (pFont)
  496. {
  497. LOGFONT lf;
  498. pFont->GetLogFont(&lf);
  499. m_fontStatus.CreateFontIndirect(&lf);
  500. }
  501. if (bRedraw)
  502. {
  503. Invalidate(FALSE);
  504. }
  505. }
  506. BOOL CXTPStatusBar::CreateEx(CWnd* pParentWnd, DWORD dwCtrlStyle, DWORD dwStyle, UINT nID)
  507. {
  508. ASSERT_VALID(pParentWnd);   // must have a parent
  509. // save the style (some of these style bits are MFC specific)
  510. m_dwStyle = (dwStyle & CBRS_ALL);
  511. // translate MFC style bits to windows style bits
  512. dwStyle &= ~CBRS_ALL;
  513. dwStyle |= CCS_NOPARENTALIGN | CCS_NOMOVEY | CCS_NODIVIDER | CCS_NORESIZE;
  514. if ((pParentWnd->GetStyle() & WS_THICKFRAME))
  515.  m_bShowSizeGripper = TRUE;
  516. dwStyle |= dwCtrlStyle;
  517. CXTPDrawHelpers::RegisterWndClass(0, _T("XTPStatusBar"), CS_DBLCLKS);
  518. // create the HWND
  519. CRect rect;
  520. rect.SetRectEmpty();
  521. return CWnd::Create(_T("XTPStatusBar"), NULL, dwStyle, rect, pParentWnd, nID);
  522. }
  523. BOOL CXTPStatusBar::PreCreateWindow(CREATESTRUCT& cs)
  524. {
  525. // in Win4, status bars do not have a border at all, since it is
  526. //  provided by the client area.
  527. if (IsWin4() &&
  528. (m_dwStyle & (CBRS_ALIGN_ANY | CBRS_BORDER_ANY)) == CBRS_BOTTOM)
  529. {
  530. m_dwStyle &= ~(CBRS_BORDER_ANY | CBRS_BORDER_3D);
  531. }
  532. return CControlBar::PreCreateWindow(cs);
  533. }
  534. BOOL CXTPStatusBar::SetIndicators(const UINT* lpIDArray, int nIDCount)
  535. {
  536. ASSERT_VALID(this);
  537. ASSERT(nIDCount >= 1);  // must be at least one of them
  538. ASSERT(lpIDArray == NULL ||
  539. AfxIsValidAddress(lpIDArray, sizeof(UINT) * nIDCount, FALSE));
  540. ASSERT(::IsWindow(m_hWnd));
  541. RemoveAll();
  542. // copy initial data from indicator array
  543. BOOL bResult = TRUE;
  544. if (lpIDArray != NULL)
  545. {
  546. for (int i = 0; i < nIDCount; i++)
  547. {
  548. CXTPStatusBarPane* pPane = new CXTPStatusBarPane();
  549. m_arrPanes.Add(pPane);
  550. pPane->m_pStatusBar = this;
  551. pPane->m_nID = *lpIDArray++;
  552. if (pPane->m_nID != 0)
  553. {
  554. if (!pPane->m_strText.LoadString(pPane->m_nID))
  555. {
  556. TRACE1("Warning: failed to load indicator string 0x%04X.n",
  557. pPane->m_nID);
  558. bResult = FALSE;
  559. break;
  560. }
  561. }
  562. else if (i == 0)
  563. {
  564. pPane->m_cxText = 1;
  565. pPane->m_nStyle |= (SBPS_STRETCH | SBPS_NOBORDERS);
  566. }
  567. }
  568. }
  569. RecalcLayout();
  570. return bResult;
  571. }
  572. void CXTPStatusBar::CalcInsideRect(CRect& rect, BOOL bHorz) const
  573. {
  574. ASSERT_VALID(this);
  575. ASSERT(::IsWindow(m_hWnd));
  576. ASSERT(bHorz);  // vertical status bar not supported
  577. // subtract standard CControlBar borders
  578. CControlBar::CalcInsideRect(rect, bHorz);
  579. CXTPPaintManager* pPaintManager = GetPaintManager();
  580. rect.DeflateRect(pPaintManager->m_rcStatusBarBorder);
  581. // subtract size grip if present
  582. if (m_bShowSizeGripper && !::IsZoomed(::GetParent(m_hWnd)))
  583. {
  584. // size grip uses a border + size of scrollbar + cx border
  585. rect.right -= m_cxRightBorder + ::GetSystemMetrics(SM_CXVSCROLL) +
  586. ::GetSystemMetrics(SM_CXBORDER) * 2;
  587. }
  588. }
  589. void CXTPStatusBar::RecalcLayout()
  590. {
  591. if (!GetSafeHwnd())
  592. return;
  593. // get border information and client work area
  594. CRect rect;
  595. GetWindowRect(rect);
  596. rect.OffsetRect(-rect.left, -rect.top);
  597. CalcInsideRect(rect, TRUE);
  598. // determine extra space for stretchy pane
  599. int cxExtra = rect.Width();
  600. int nStretchyCount = 0, i;
  601. BOOL bSeparator = FALSE, bFirstVisible = TRUE;
  602. for (i = 0; i < GetPaneCount(); i++)
  603. {
  604. CXTPStatusBarPane* pPane = GetPane(i);
  605. pPane->m_nIndex = i;
  606. pPane->m_dwHideFlags &= ~xtpHideWrap;
  607. if (pPane->GetBeginGroup() && !bFirstVisible) bSeparator = TRUE;
  608. if (!pPane->IsVisible())
  609. continue;
  610. pPane->m_nBestFit = pPane->GetWidth();
  611. if (pPane->m_nStyle & SBPS_STRETCH)
  612. ++nStretchyCount;
  613. cxExtra -= (pPane->m_nBestFit + (pPane->HasBorders() ? CX_PANE_BORDER : 0) + (bSeparator ? m_cxPaneSpacing : 0)
  614.  + pPane->m_rcMargins.left + pPane->m_rcMargins.right);
  615. bSeparator = FALSE;
  616. bFirstVisible = FALSE;
  617. }
  618. int left = m_cxLeftBorder;
  619. BOOL bHideAll = FALSE;
  620. bSeparator = FALSE;
  621. bFirstVisible = TRUE;
  622. for (i = 0; i < GetPaneCount(); i++)
  623. {
  624. CXTPStatusBarPane* pPane = GetPane(i);
  625. if (bHideAll)
  626. pPane->m_dwHideFlags |= xtpHideWrap;
  627. if (pPane->GetBeginGroup() && !bFirstVisible) bSeparator = TRUE;
  628. if (!pPane->IsVisible())
  629. {
  630. pPane->m_rcPane.SetRectEmpty();
  631. continue;
  632. }
  633. if (bSeparator)
  634. left += m_cxPaneSpacing;
  635. int nPaneWidth = pPane->m_nBestFit;
  636. int right = left + pPane->m_rcMargins.left;
  637. // determine size of the pane
  638. ASSERT(nPaneWidth >= 0);
  639. right += nPaneWidth + (pPane->HasBorders() ? CX_PANE_BORDER : 0);
  640. if ((pPane->m_nStyle & SBPS_STRETCH) && cxExtra > 0)
  641. {
  642. ASSERT(nStretchyCount != 0);
  643. int cxAddExtra = cxExtra / nStretchyCount;
  644. right += cxAddExtra;
  645. --nStretchyCount;
  646. cxExtra -= cxAddExtra;
  647. }
  648. if (right > rect.right)
  649. {
  650. if (pPane->m_nStyle & SBPS_STRETCH)
  651. {
  652. right = rect.right;
  653. }
  654. else
  655. {
  656. bHideAll = TRUE;
  657. pPane->m_dwHideFlags |= xtpHideWrap;
  658. pPane->m_rcPane.SetRectEmpty();
  659. continue;
  660. }
  661. }
  662. bSeparator = FALSE;
  663. bFirstVisible = FALSE;
  664. pPane->m_rcPane.SetRect(left, rect.top + pPane->m_rcMargins.top, right, rect.bottom - pPane->m_rcMargins.bottom);
  665. left = right + pPane->m_rcMargins.right;
  666. }
  667. m_pHighlightedPane = NULL;
  668. Invalidate(FALSE);
  669. PositionControls();
  670. }
  671. void CXTPStatusBar::UpdateAllPanes(BOOL bUpdateRects, BOOL /*bUpdateText*/)
  672. {
  673. if (bUpdateRects)
  674. {
  675. RecalcLayout();
  676. }
  677. }
  678. /////////////////////////////////////////////////////////////////////////////
  679. // CXTPStatusBar attribute access
  680. int CXTPStatusBar::CommandToIndex(UINT nIDFind) const
  681. {
  682. ASSERT_VALID(this);
  683. if (GetPaneCount() <= 0)
  684. return -1;
  685. for (int i = 0; i < GetPaneCount(); i++)
  686. {
  687. if (GetPane(i)->m_nID == nIDFind)
  688. return i;
  689. }
  690. return -1;
  691. }
  692. UINT CXTPStatusBar::GetItemID(int nIndex) const
  693. {
  694. ASSERT_VALID(this);
  695. CXTPStatusBarPane* pPane = GetPane(nIndex);
  696. ASSERT(pPane);
  697. if (!pPane)
  698. return 0;
  699. return pPane->m_nID;
  700. }
  701. void CXTPStatusBar::GetItemRect(int nIndex, LPRECT lpRect) const
  702. {
  703. ASSERT_VALID(this);
  704. ASSERT(::IsWindow(m_hWnd));
  705. if (!lpRect)
  706. return;
  707. CXTPStatusBarPane* pPane = GetPane(nIndex);
  708. if (!pPane)
  709. {
  710. ::SetRectEmpty(lpRect);
  711. return;
  712. }
  713. *lpRect = pPane->GetRect();
  714. }
  715. UINT CXTPStatusBar::GetPaneStyle(int nIndex) const
  716. {
  717. CXTPStatusBarPane* pPane = GetPane(nIndex);
  718. ASSERT(pPane);
  719. if (!pPane)
  720. return 0;
  721. return pPane->m_nStyle;
  722. }
  723. void CXTPStatusBar::SetPaneStyle(int nIndex, UINT nStyle)
  724. {
  725. CXTPStatusBarPane* pPane = GetPane(nIndex);
  726. ASSERT(pPane);
  727. if (pPane) pPane->SetStyle(nStyle);
  728. }
  729. void CXTPStatusBar::GetPaneInfo(int nIndex, UINT& nID, UINT& nStyle,
  730. int& cxWidth) const
  731. {
  732. ASSERT_VALID(this);
  733. CXTPStatusBarPane* pPane = GetPane(nIndex);
  734. nID = pPane->m_nID;
  735. nStyle = pPane->m_nStyle;
  736. cxWidth = pPane->GetWidth();
  737. }
  738. void CXTPStatusBar::SetPaneInfo(int nIndex, UINT nID, UINT nStyle, int cxWidth)
  739. {
  740. ASSERT_VALID(this);
  741. BOOL bChanged = FALSE;
  742. CXTPStatusBarPane* pPane = GetPane(nIndex);
  743. pPane->m_nID = nID;
  744. if (pPane->m_nStyle != nStyle)
  745. {
  746. if ((pPane->m_nStyle ^ nStyle) & SBPS_STRETCH)
  747. bChanged = TRUE;
  748. else
  749. {
  750. pPane->m_nStyle = nStyle;
  751. pPane->Redraw();
  752. }
  753. pPane->m_nStyle = nStyle;
  754. }
  755. if (cxWidth != pPane->m_cxText)
  756. {
  757. // change width of one pane -> invalidate the entire status bar
  758. pPane->m_cxText = cxWidth;
  759. bChanged = TRUE;
  760. }
  761. if (bChanged)
  762. RecalcLayout();
  763. }
  764. void CXTPStatusBar::GetPaneText(int nIndex, CString& s) const
  765. {
  766. ASSERT_VALID(this);
  767. CXTPStatusBarPane* pPane = GetPane(nIndex);
  768. ASSERT(pPane);
  769. if (!pPane)
  770. return;
  771. s = pPane->m_strText;
  772. }
  773. CString CXTPStatusBar::GetPaneText(int nIndex) const
  774. {
  775. ASSERT_VALID(this);
  776. CXTPStatusBarPane* pPane = GetPane(nIndex);
  777. ASSERT(pPane);
  778. if (!pPane)
  779. return _T("");
  780. return pPane->m_strText;
  781. }
  782. void CXTPStatusBar::SetPaneWidth(int nIndex, int cxText)
  783. {
  784. CXTPStatusBarPane* pPane = GetPane(nIndex);
  785. ASSERT(pPane);
  786. if (!pPane)
  787. return;
  788. pPane->SetWidth(cxText);
  789. }
  790. BOOL CXTPStatusBar::SetPaneText(int nIndex, const CString& lpszNewText)
  791. {
  792. ASSERT_VALID(this);
  793. ASSERT(::IsWindow(m_hWnd));
  794. CXTPStatusBarPane* pPane = GetPane(nIndex);
  795. ASSERT(pPane);
  796. if (!pPane)
  797. return FALSE;
  798. pPane->SetText(lpszNewText);
  799. return TRUE;
  800. }
  801. /////////////////////////////////////////////////////////////////////////////
  802. // CXTPStatusBar implementation
  803. CSize CXTPStatusBar::CalcFixedLayout(BOOL, BOOL /*bHorz*/)
  804. {
  805. ASSERT_VALID(this);
  806. ASSERT(::IsWindow(m_hWnd));
  807. // determine size of font being used by the status bar
  808. CSize szText(0, 0);
  809. {
  810. CClientDC dc(NULL);
  811. CXTPFontDC font(&dc, GetFont());
  812. szText = dc.GetTextExtent(_T("X"), 1);
  813. }
  814. CXTPPaintManager* pPaintManager = GetPaintManager();
  815. // determine size, including borders
  816. CSize size;
  817. size.cx = 32767;
  818. size.cy = szText.cy + m_cyBottomBorder + m_cyTopBorder + ::GetSystemMetrics(SM_CYBORDER) * 2 + pPaintManager->m_rcStatusBarBorder.top
  819.  + pPaintManager->m_rcStatusBarBorder.bottom;
  820. if (size.cy < m_nMinHeight)
  821. size.cy = m_nMinHeight;
  822. if (size.cy < pPaintManager->m_nStatusBarMinHeight)
  823. size.cy = pPaintManager->m_nStatusBarMinHeight;
  824. return size;
  825. }
  826. /////////////////////////////////////////////////////////////////////////////
  827. // CXTPStatusBar message handlers
  828. BEGIN_MESSAGE_MAP(CXTPStatusBar, CControlBar)
  829. //{{AFX_MSG_MAP(CXTPStatusBar)
  830. ON_WM_NCHITTEST_EX()
  831. ON_WM_NCPAINT()
  832. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  833. ON_WM_PAINT()
  834. ON_WM_CREATE()
  835. ON_WM_ERASEBKGND()
  836. ON_WM_NCCALCSIZE()
  837. ON_WM_SIZE()
  838. ON_WM_LBUTTONDOWN()
  839. ON_WM_RBUTTONUP()
  840. ON_WM_LBUTTONDBLCLK()
  841. ON_WM_MOUSEMOVE()
  842. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  843. ON_WM_WINDOWPOSCHANGING()
  844. ON_MESSAGE(WM_SETTEXT, OnSetText)
  845. ON_MESSAGE(WM_GETTEXT, OnGetText)
  846. ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLength)
  847. ON_MESSAGE(SB_SETMINHEIGHT, OnSetMinHeight)
  848. ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
  849. ON_WM_WINDOWPOSCHANGED()
  850. ON_WM_SYSCOMMAND()
  851. //}}AFX_MSG_MAP
  852. END_MESSAGE_MAP()
  853. int CXTPStatusBar::OnCreate(LPCREATESTRUCT lpcs)
  854. {
  855. if (CControlBar::OnCreate(lpcs) == -1)
  856. return -1;
  857. return 0;
  858. }
  859. void CXTPStatusBar::OnSysCommand(UINT nID, LPARAM lParam)
  860. {
  861. if (nID == SC_SIZE + HTBOTTOM - HTSIZEFIRST + 1)
  862. {
  863. ::SendMessage(::GetParent(m_hWnd), WM_SYSCOMMAND, (WPARAM)nID, lParam);
  864. return;
  865. }
  866. CControlBar::OnSysCommand(nID, lParam);
  867. }
  868. LRESULT CXTPStatusBar::OnNcHitTest(CPoint point)
  869. {
  870. if (m_bShowSizeGripper && !::IsZoomed(::GetParent(m_hWnd)))
  871. {
  872. CXTPWindowRect rc(this);
  873. int dxGripper = (m_cxRightBorder + ::GetSystemMetrics(SM_CXVSCROLL) + ::GetSystemMetrics(SM_CXBORDER) * 2);
  874. if (GetExStyle() & WS_EX_LAYOUTRTL)
  875. {
  876. if (point.x < rc.left + dxGripper)
  877. return (LRESULT)HTBOTTOMLEFT;
  878. }
  879. else
  880. {
  881. if (point.x > rc.right - dxGripper)
  882. return (LRESULT)HTBOTTOMRIGHT;
  883. }
  884. #ifdef _XTP_INCLUDE_RIBBON
  885. if (point.y >= rc.bottom - 3 && GetPaintManager()->BaseTheme() == xtpThemeRibbon && CXTPOffice2007FrameHook::m_nMsgQueryFrameHook != 0)
  886. {
  887. CXTPOffice2007FrameHook* pFrame = (CXTPOffice2007FrameHook*)::SendMessage(::GetParent(m_hWnd), CXTPOffice2007FrameHook::m_nMsgQueryFrameHook, 0, 0);
  888. if (pFrame && pFrame->IsFrameHasStatusBar())
  889. {
  890. return (LRESULT)HTBOTTOM;
  891. }
  892. }
  893. #endif
  894. }
  895. return (LRESULT)HTCLIENT;
  896. }
  897. void CXTPStatusBarPane::SetCustomizationVisible(BOOL bVisible)
  898. {
  899. DWORD dwHideFlags = bVisible ? m_dwHideFlags &~ xtpHideCustomize : m_dwHideFlags | xtpHideCustomize;
  900. if (m_dwHideFlags != dwHideFlags)
  901. {
  902. m_dwHideFlags = dwHideFlags;
  903. m_pStatusBar->RecalcLayout();
  904. }
  905. }
  906. BOOL CXTPStatusBarPane::GetCustomizationVisible() const
  907. {
  908. return (m_dwHideFlags & xtpHideCustomize) == 0;
  909. }
  910. class CXTPStatusBar::CControlCustomization : public CXTPControlButton
  911. {
  912. public:
  913. CControlCustomization(CXTPStatusBarPane* pPane)
  914. {
  915. m_pPane = pPane;
  916. }
  917. void OnExecute()
  918. {
  919. m_pPane->SetCustomizationVisible(!m_pPane->GetCustomizationVisible());
  920. SetChecked(!GetChecked());
  921. }
  922. protected:
  923. CXTPStatusBarPane* m_pPane;
  924. };
  925. CXTPPopupBar* CXTPStatusBar::GetStatusBarPopup()
  926. {
  927. CXTPPopupBar* pPopup = CXTPPopupBar::CreatePopupBar(m_pCommandBars);
  928. CXTPControl* pControl = pPopup->GetControls()->Add(xtpControlLabel, XTP_IDS_CUSTOMIZE_STATUSBAR);
  929. pControl->SetItemDefault(TRUE);
  930. pControl->SetDescription(_T(""));
  931. for (int i = 0; i < GetPaneCount(); i++)
  932. {
  933. CXTPStatusBarPane* pPane = GetPane(i);
  934. if (pPane->GetID() == 0)
  935. continue;
  936. pControl = pPopup->GetControls()->Add(new CControlCustomization(pPane));
  937. pControl->SetCaption(pPane->m_strCaption.IsEmpty() ? pPane->m_strText : pPane->m_strCaption);
  938. pControl->SetShortcutText(pPane->m_strValue);
  939. pControl->SetBeginGroup(pPane->GetBeginGroup() && i > 0);
  940. pControl->SetChecked(pPane->GetCustomizationVisible());
  941. }
  942. return pPopup;
  943. }
  944. void CXTPStatusBar::OnRButtonUp(UINT /*nFlags*/, CPoint point)
  945. {
  946. if (m_bCustomizable)
  947. {
  948. ClientToScreen(&point);
  949. OnMouseLeave();
  950. CXTPPopupBar* pPopup = GetStatusBarPopup();
  951. if (pPopup && pPopup->GetControlCount() > 0)
  952. {
  953. CXTPCommandBars::TrackPopupMenu(pPopup, 0, point.x, point.y, this);
  954. }
  955. CMDTARGET_RELEASE(pPopup);
  956. }
  957. }
  958. void CXTPStatusBar::OnMouseLeave()
  959. {
  960. OnMouseMove(0, CPoint(-1, -1));
  961. }
  962. void CXTPStatusBar::OnMouseMove(UINT nFlags, CPoint point)
  963. {
  964. CXTPStatusBarPane* pPane = XTPMouseManager()->IsTrackedLock() ? NULL : HitTest(point);
  965. if (pPane && (!pPane->IsButton() || !pPane->IsEnabled()))
  966. pPane = NULL;
  967. if (pPane != m_pHighlightedPane)
  968. {
  969. CXTPStatusBarPane* pHighlightedPane = m_pHighlightedPane;
  970. m_pHighlightedPane = pPane;
  971. if (pHighlightedPane) pHighlightedPane->Redraw();
  972. if (m_pHighlightedPane) m_pHighlightedPane->Redraw();
  973. if (m_pHighlightedPane)
  974. {
  975. TRACKMOUSEEVENT tme =
  976. {
  977. sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd
  978. };
  979. _TrackMouseEvent(&tme);
  980. }
  981. if (pHighlightedPane)
  982. {
  983. pHighlightedPane->OnMouseMove(CPoint(-1, -1));
  984. }
  985. }
  986. if (m_pHighlightedPane)
  987. {
  988. m_pHighlightedPane->OnMouseMove(point);
  989. }
  990. CControlBar::OnMouseMove(nFlags, point);
  991. }
  992. void CXTPStatusBar::OnLButtonDblClk(UINT nFlags, CPoint point)
  993. {
  994. CControlBar::OnLButtonDblClk(nFlags, point);
  995. if (m_pHighlightedPane)
  996. {
  997. m_pHighlightedPane->OnLButtonDown(point);
  998. }
  999. }
  1000. void CXTPStatusBar::OnLButtonDown(UINT nFlags, CPoint point)
  1001. {
  1002. CControlBar::OnLButtonDown(nFlags, point);
  1003. if (m_pHighlightedPane)
  1004. {
  1005. m_pHighlightedPane->OnLButtonDown(point);
  1006. }
  1007. }
  1008. void CXTPStatusBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp)
  1009. {
  1010. // calculate border space (will add to top/bottom, subtract from right/bottom)
  1011. CRect rect;
  1012. rect.SetRectEmpty();
  1013. CControlBar::CalcInsideRect(rect, TRUE);
  1014. ASSERT(rect.top >= 2);
  1015. // adjust non-client area for border space
  1016. lpncsp->rgrc[0].left += rect.left;
  1017. lpncsp->rgrc[0].top += rect.top - 2;
  1018. lpncsp->rgrc[0].right += rect.right;
  1019. lpncsp->rgrc[0].bottom += rect.bottom;
  1020. }
  1021. void CXTPStatusBar::OnBarStyleChange(DWORD dwOldStyle, DWORD dwNewStyle)
  1022. {
  1023. if (m_hWnd != NULL &&
  1024. ((dwOldStyle & CBRS_BORDER_ANY) != (dwNewStyle & CBRS_BORDER_ANY)))
  1025. {
  1026. // recalc non-client area when border styles change
  1027. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
  1028. }
  1029. }
  1030. void CXTPStatusBar::OnNcPaint()
  1031. {
  1032. EraseNonClient();
  1033. }
  1034. void CXTPStatusBar::OnSize(UINT nType, int cx, int cy)
  1035. {
  1036. ASSERT_VALID(this);
  1037. ASSERT(::IsWindow(m_hWnd));
  1038. CControlBar::OnSize(nType, cx, cy);
  1039. // need to adjust pane right edges (because of stretchy pane)
  1040. RecalcLayout();
  1041. }
  1042. void CXTPStatusBar::OnWindowPosChanging(LPWINDOWPOS lpWndPos)
  1043. {
  1044. // not necessary to invalidate the borders
  1045. DWORD dwStyle = m_dwStyle;
  1046. m_dwStyle &= ~(CBRS_BORDER_ANY);
  1047. CControlBar::OnWindowPosChanging(lpWndPos);
  1048. m_dwStyle = dwStyle;
  1049. }
  1050. LRESULT CXTPStatusBar::OnSetText(WPARAM, LPARAM lParam)
  1051. {
  1052. ASSERT_VALID(this);
  1053. ASSERT(::IsWindow(m_hWnd));
  1054. int nIndex = CommandToIndex(0);
  1055. if (nIndex < 0)
  1056. return -1;
  1057. return SetPaneText(nIndex, (LPCTSTR)lParam) ? 0 : -1;
  1058. }
  1059. LRESULT CXTPStatusBar::OnGetText(WPARAM wParam, LPARAM lParam)
  1060. {
  1061. ASSERT_VALID(this);
  1062. ASSERT(::IsWindow(m_hWnd));
  1063. int nMaxLen = (int)wParam;
  1064. if (nMaxLen == 0)
  1065. return 0;       // nothing copied
  1066. LPTSTR lpszDest = (LPTSTR)lParam;
  1067. int nLen = 0;
  1068. int nIndex = CommandToIndex(0); // use pane with ID zero
  1069. if (nIndex >= 0)
  1070. {
  1071. CXTPStatusBarPane* pPane = GetPane(nIndex);
  1072. nLen = pPane->m_strText.GetLength();
  1073. if (nLen > nMaxLen)
  1074. nLen = nMaxLen - 1; // number of characters to copy (less term.)
  1075. MEMCPY_S(lpszDest, (LPCTSTR)pPane->m_strText, nLen*sizeof(TCHAR));
  1076. }
  1077. lpszDest[nLen] = '';
  1078. return nLen + 1;      // number of bytes copied
  1079. }
  1080. LRESULT CXTPStatusBar::OnGetTextLength(WPARAM, LPARAM)
  1081. {
  1082. ASSERT_VALID(this);
  1083. ASSERT(::IsWindow(m_hWnd));
  1084. int nLen = 0;
  1085. int nIndex = CommandToIndex(0); // use pane with ID zero
  1086. if (nIndex >= 0)
  1087. {
  1088. CXTPStatusBarPane* pPane = GetPane(nIndex);
  1089. nLen = pPane->m_strText.GetLength();
  1090. }
  1091. return nLen;
  1092. }
  1093. LRESULT CXTPStatusBar::OnSetMinHeight(WPARAM wParam, LPARAM)
  1094. {
  1095. LRESULT lResult = Default();
  1096. m_nMinHeight = (int)wParam;
  1097. return lResult;
  1098. }
  1099. /////////////////////////////////////////////////////////////////////////////
  1100. // CXTPStatusBar idle update through CStatusCmdUI class
  1101. class CXTPStatusBar::CStatusCmdUI : public CCmdUI      // class private to this file!
  1102. {
  1103. public: // re-implementations only
  1104. virtual void Enable(BOOL bOn);
  1105. virtual void SetCheck(int nCheck);
  1106. virtual void SetText(LPCTSTR lpszText);
  1107. };
  1108. void CXTPStatusBar::CStatusCmdUI::Enable(BOOL bOn)
  1109. {
  1110. m_bEnableChanged = TRUE;
  1111. CXTPStatusBar* pStatusBar = (CXTPStatusBar*)m_pOther;
  1112. ASSERT(pStatusBar != NULL);
  1113. if (!pStatusBar)
  1114. return;
  1115. ASSERT_KINDOF(CXTPStatusBar, pStatusBar);
  1116. ASSERT(m_nIndex < m_nIndexMax);
  1117. CXTPStatusBarPane* pPane = pStatusBar->GetPane(m_nIndex);
  1118. if (pPane) pPane->SetEnabled(bOn);
  1119. }
  1120. void CXTPStatusBar::CStatusCmdUI::SetCheck(int nCheck) // "checking" will pop out the text
  1121. {
  1122. CXTPStatusBar* pStatusBar = (CXTPStatusBar*)m_pOther;
  1123. ASSERT(pStatusBar != NULL);
  1124. if (!pStatusBar)
  1125. return;
  1126. ASSERT_KINDOF(CXTPStatusBar, pStatusBar);
  1127. ASSERT(m_nIndex < m_nIndexMax);
  1128. UINT nNewStyle = pStatusBar->GetPaneStyle(m_nIndex) & ~SBPS_POPOUT;
  1129. if (nCheck != 0)
  1130. nNewStyle |= SBPS_POPOUT;
  1131. pStatusBar->SetPaneStyle(m_nIndex, nNewStyle);
  1132. }
  1133. void CXTPStatusBar::CStatusCmdUI::SetText(LPCTSTR lpszText)
  1134. {
  1135. CXTPStatusBar* pStatusBar = (CXTPStatusBar*)m_pOther;
  1136. ASSERT(pStatusBar != NULL);
  1137. if (!pStatusBar)
  1138. return;
  1139. ASSERT_KINDOF(CXTPStatusBar, pStatusBar);
  1140. ASSERT(m_nIndex < m_nIndexMax);
  1141. pStatusBar->SetPaneText(m_nIndex, lpszText);
  1142. }
  1143. void CXTPStatusBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  1144. {
  1145. CStatusCmdUI state;
  1146. state.m_pOther = this;
  1147. state.m_nIndexMax = (UINT)GetPaneCount();
  1148. for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
  1149. state.m_nIndex++)
  1150. {
  1151. state.m_nID = GetPane(state.m_nIndex)->m_nID;
  1152. // allow the statusbar itself to have update handlers
  1153. if (CWnd::OnCmdMsg(state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL))
  1154. continue;
  1155. // allow target (owner) to handle the remaining updates
  1156. state.DoUpdate(pTarget, FALSE);
  1157. }
  1158. // update the dialog controls added to the status bar
  1159. UpdateDialogControls(pTarget, bDisableIfNoHndler);
  1160. }
  1161. /////////////////////////////////////////////////////////////////////////////
  1162. // CXTPStatusBar diagnostics
  1163. #ifdef _DEBUG
  1164. void CXTPStatusBar::AssertValid() const
  1165. {
  1166. CControlBar::AssertValid();
  1167. }
  1168. void CXTPStatusBar::Dump(CDumpContext& dc) const
  1169. {
  1170. CControlBar::Dump(dc);
  1171. if (dc.GetDepth() > 0)
  1172. {
  1173. for (int i = 0; i < GetPaneCount(); i++)
  1174. {
  1175. dc << "nstatus pane[" << i << "] = {";
  1176. dc << "ntnID = " << GetPane(i)->m_nID;
  1177. dc << "ntnStyle = " << GetPane(i)->m_nStyle;
  1178. dc << "ntcxText = " << GetPane(i)->m_cxText;
  1179. dc << "ntstrText = " << GetPane(i)->m_strText;
  1180. dc << "nt}";
  1181. }
  1182. }
  1183. dc << "n";
  1184. }
  1185. #endif //_DEBUG
  1186. CXTPPaintManager* CXTPStatusBar::GetPaintManager() const
  1187. {
  1188. if (m_pCommandBars)
  1189. return m_pCommandBars->GetPaintManager();
  1190. return XTPPaintManager();
  1191. }
  1192. void CXTPStatusBar::DrawPaneEntry(CDC* pDC, int nIndex, CRect rcItem)
  1193. {
  1194. CXTPStatusBarPane* pPane = GetPane(nIndex);
  1195. if (pPane)
  1196. {
  1197. pPane->OnDraw(pDC, rcItem);
  1198. }
  1199. }
  1200. void CXTPStatusBar::OnPaint()
  1201. {
  1202. CPaintDC dcPaint (this);
  1203. CXTPBufferDC dc(dcPaint);
  1204. OnDraw(&dc);
  1205. }
  1206. LRESULT CXTPStatusBar::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
  1207. {
  1208. if (GetPaintManager() == NULL)
  1209. {
  1210. return Default();
  1211. }
  1212. CDC* pDC = CDC::FromHandle((HDC)wParam);
  1213. if (pDC)
  1214. {
  1215. OnDraw(pDC);
  1216. }
  1217. return TRUE;
  1218. }
  1219. void CXTPStatusBar::OnDraw(CDC* pDC)
  1220. {
  1221. CXTPClientRect rcClient(this);
  1222. CXTPPaintManager* pPaintManager = GetPaintManager();
  1223. pPaintManager->FillStatusBar(pDC, this);
  1224. int nCount = GetPaneCount(), nGripperPane;
  1225. for (nGripperPane = nCount - 1; nGripperPane >= 0; nGripperPane--)
  1226. {
  1227. if (m_arrPanes[nGripperPane]->IsVisible())
  1228. break;
  1229. }
  1230. BOOL bSeparator = FALSE, bFirstVisible = TRUE;
  1231. for (int i = 0; i < nCount; i++)
  1232. {
  1233. CXTPStatusBarPane* pPane = GetPane(i);
  1234. if (pPane->GetBeginGroup() && !bFirstVisible) bSeparator = TRUE;
  1235. if (!pPane->IsVisible())
  1236. continue;
  1237. CRect rcItem = pPane->GetRect();
  1238. BOOL bGripperPane = (i == nGripperPane);
  1239. if (pPane->HasBorders())
  1240. {
  1241. pPaintManager->DrawStatusBarPaneBorder(pDC, rcItem, pPane, bGripperPane);
  1242. }
  1243. else if (bSeparator)
  1244. {
  1245. pPaintManager->DrawStatusBarPaneSeparator(pDC, rcItem, pPane);
  1246. }
  1247. DrawPaneEntry(pDC, i, rcItem);
  1248. bSeparator = FALSE;
  1249. bFirstVisible = FALSE;
  1250. }
  1251. if (m_bShowSizeGripper && !::IsZoomed(::GetParent(m_hWnd)))
  1252. DrawStretch(pDC, rcClient);
  1253. }
  1254. BOOL CXTPStatusBar::OnEraseBkgnd(CDC* /*pDC*/)
  1255. {
  1256. return TRUE;
  1257. }
  1258. void CXTPStatusBar::DrawStretch(CDC* pDC, CRect& rcClient)
  1259. {
  1260. GetPaintManager()->DrawStatusBarGripper(pDC, rcClient);
  1261. }
  1262. /////////////////////////////////////////////////////////////////////////////
  1263. // CXTPStatusBar message handlers
  1264. BOOL CXTPStatusBar::RemoveIndicator(UINT nID)
  1265. {
  1266. int nIndex = CommandToIndex(nID);
  1267. if (nIndex == -1)
  1268. {
  1269. TRACE1("WARNING: Pane ID %d was not found in the status bar.n", nID);
  1270. return FALSE;
  1271. }
  1272. return RemoveAt(nIndex);
  1273. }
  1274. BOOL CXTPStatusBar::RemoveAt(int nIndex)
  1275. {
  1276. CXTPStatusBarPane* pPane = GetPane(nIndex);
  1277. if (!pPane)
  1278. return FALSE;
  1279. if (m_pHighlightedPane == pPane)
  1280. {
  1281. m_pHighlightedPane = NULL;
  1282. }
  1283. m_arrPanes.RemoveAt(nIndex);
  1284. pPane->InternalRelease();
  1285. UpdateAllPanes(TRUE, TRUE);
  1286. return TRUE;
  1287. }
  1288. CXTPStatusBarPane* CXTPStatusBar::AddIndicator(CXTPStatusBarPane* pPane, UINT nID, int nIndex)
  1289. {
  1290. if (nIndex < 0 || nIndex > GetPaneCount())
  1291. {
  1292. TRACE0("WARNING: Pane index out of range.n");
  1293. nIndex = GetPaneCount();
  1294. }
  1295. if (CommandToIndex(nID) != -1)
  1296. {
  1297. TRACE1("WARNING: Pane ID %d already exists in the status bar.n", nID);
  1298. }
  1299. m_arrPanes.InsertAt(nIndex, pPane);
  1300. pPane->m_nID = nID;
  1301. pPane->m_pStatusBar = this;
  1302. if (nID != 0)
  1303. {
  1304. CString strText;
  1305. if (strText.LoadString(nID))
  1306. {
  1307. pPane->m_strText = strText;
  1308. }
  1309. }
  1310. else if (nIndex == 0)
  1311. {
  1312. pPane->m_cxText = 1;
  1313. pPane->m_nStyle |= (SBPS_STRETCH | SBPS_NOBORDERS);
  1314. }
  1315. RecalcLayout();
  1316. return pPane;
  1317. }
  1318. CXTPStatusBarPane* CXTPStatusBar::AddIndicator(UINT nID, int nIndex)
  1319. {
  1320. if (nIndex < 0 || nIndex > GetPaneCount())
  1321. {
  1322. nIndex = GetPaneCount();
  1323. }
  1324. if (CommandToIndex(nID) != -1)
  1325. {
  1326. TRACE1("WARNING: Pane ID %d already exists in the status bar.n", nID);
  1327. return NULL;
  1328. }
  1329. return AddIndicator(new CXTPStatusBarPane(), nID, nIndex);
  1330. }
  1331. void CXTPStatusBar::PositionControls()
  1332. {
  1333. CXTPClientRect rcClient(this);
  1334. int cx = ::GetSystemMetrics(SM_CXEDGE);
  1335. for (int i = 0; i < GetPaneCount(); i++)
  1336. {
  1337. CXTPStatusBarPane* pPane = GetPane(i);
  1338. if (pPane->m_hWndPane == NULL || !IsWindow(pPane->m_hWndPane))
  1339. continue;
  1340. CRect rcPane = pPane->GetRect();
  1341. if (rcPane.IsRectEmpty() || !pPane->IsVisible())
  1342. {
  1343. ::SetWindowPos(pPane->m_hWndPane, 0, 0, 0, 0, 0, SWP_HIDEWINDOW);
  1344. }
  1345. else
  1346. {
  1347. if (pPane->HasBorders())
  1348. {
  1349. rcPane.DeflateRect(cx, cx);
  1350. }
  1351. ::SetWindowPos(pPane->m_hWndPane, 0, rcPane.left, rcPane.top, rcPane.Width(), rcPane.Height(), SWP_NOZORDER | SWP_SHOWWINDOW);
  1352. ::InvalidateRect(pPane->m_hWndPane, 0, FALSE);
  1353. }
  1354. }
  1355. }
  1356. BOOL CXTPStatusBar::AddControl(CWnd* pWnd, UINT nID, BOOL bAutoDelete)
  1357. {
  1358. int nIndex = CommandToIndex (nID);
  1359. if (nIndex == -1)
  1360. return FALSE;
  1361. CXTPStatusBarPane* pPane = GetPane(nIndex);
  1362. if (!pPane)
  1363. return FALSE;
  1364. pPane->m_hWndPane = pWnd->GetSafeHwnd();
  1365. pPane->m_bAutoDeleteWnd = bAutoDelete;
  1366. PositionControls();
  1367. return TRUE;
  1368. }
  1369. void CXTPStatusBar::OnWindowPosChanged(WINDOWPOS* lpwndpos)
  1370. {
  1371. CControlBar::OnWindowPosChanged(lpwndpos);
  1372. CXTPPaintManager* pPaintManager = GetPaintManager();
  1373. if (pPaintManager && pPaintManager->BaseTheme() == xtpThemeRibbon)
  1374. {
  1375. if ((lpwndpos->flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) != 0)
  1376. {
  1377. GetParentFrame()->SetWindowPos(0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
  1378. }
  1379. }
  1380. }
  1381. LRESULT CXTPStatusBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM)
  1382. {
  1383. // handle delay hide/show
  1384. BOOL bVis = GetStyle() & WS_VISIBLE;
  1385. UINT swpFlags = 0;
  1386. if ((m_nStateFlags & delayHide) && bVis)
  1387. swpFlags = SWP_HIDEWINDOW;
  1388. else if ((m_nStateFlags & delayShow) && !bVis)
  1389. swpFlags = SWP_SHOWWINDOW;
  1390. m_nStateFlags &= ~(delayShow | delayHide);
  1391. if (swpFlags != 0)
  1392. {
  1393. SetWindowPos(NULL, 0, 0, 0, 0, swpFlags |
  1394. SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  1395. }
  1396. // the style must be visible and if it is docked
  1397. // the dockbar style must also be visible
  1398. if ((GetStyle() & WS_VISIBLE) &&
  1399. (m_pDockBar == NULL || (m_pDockBar->GetStyle() & WS_VISIBLE)))
  1400. {
  1401. // MFCBUG: removed check for IsFrameWnd so we can update statusbar
  1402. // for dialog based applications as well as doc/view apps.
  1403. CFrameWnd* pTarget = (CFrameWnd*)GetOwner();
  1404. if (pTarget == NULL)
  1405. pTarget = (CFrameWnd*)GetParent();
  1406. if (pTarget != NULL)
  1407. OnUpdateCmdUI(pTarget, (BOOL)wParam);
  1408. }
  1409. return 0L;
  1410. }
  1411. INT_PTR CXTPStatusBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  1412. {
  1413. ASSERT_VALID(this);
  1414. ASSERT(::IsWindow(m_hWnd));
  1415. // check child windows first by calling CControlBar
  1416. INT_PTR nHit = CControlBar::OnToolHitTest(point, pTI);
  1417. if (nHit != -1)
  1418. return nHit;
  1419. CRect rcPane;
  1420. CXTPStatusBarPane* pPane = HitTest(point, &rcPane);
  1421. if (pPane)
  1422. {
  1423. nHit = pPane->OnToolHitTest(point, pTI);
  1424. if (nHit != -1)
  1425. return nHit;
  1426. nHit = pPane->GetID();
  1427. CString strTip = pPane->GetTooltip();
  1428. if (strTip.IsEmpty())
  1429. return -1;
  1430. CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, rcPane, nHit, strTip);
  1431. return nHit;
  1432. }
  1433. return -1;
  1434. }
  1435. void CXTPStatusBar::OnPaneClick(CXTPStatusBarPane* pPane)
  1436. {
  1437. GetParentFrame()->SendMessage(WM_COMMAND, pPane->GetID());
  1438. }
  1439. void CXTPStatusBar::OnSwitchPaneClick(CXTPStatusBarPane* pPane, long Id)
  1440. {
  1441. pPane;
  1442. GetParentFrame()->SendMessage(WM_COMMAND, Id);
  1443. }
  1444. BOOL CXTPStatusBar::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  1445. {
  1446. if (m_pMarkupContext)
  1447. {
  1448. for (int i = 0; i < GetPaneCount(); i++)
  1449. {
  1450. CXTPStatusBarPane* pPane = GetPane(i);
  1451. if (pPane->IsVisible() && pPane->GetMarkupUIElement())
  1452. {
  1453. if (XTPMarkupRelayMessage(pPane->GetMarkupUIElement(), message, wParam, lParam, pResult))
  1454. return TRUE;
  1455. }
  1456. }
  1457. }
  1458. if (m_pToolTipContext)
  1459. {
  1460. m_pToolTipContext->FilterToolTipMessage(this, message, wParam, lParam);
  1461. }
  1462. return CControlBar::OnWndMsg(message, wParam, lParam, pResult);
  1463. }
  1464. void CXTPStatusBar::EnableCustomization(BOOL bEnable)
  1465. {
  1466. m_bCustomizable = bEnable;
  1467. }
  1468. void CXTPStatusBar::LoadState(LPCTSTR lpszProfileName)
  1469. {
  1470. if (!AfxGetApp()->GetProfileInt(lpszProfileName, _T("StatusBar"), TRUE))
  1471. {
  1472. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_HIDEWINDOW);
  1473. DelayShow(FALSE);
  1474. }
  1475. if (m_bCustomizable)
  1476. {
  1477. CString strValue = AfxGetApp()->GetProfileString(lpszProfileName,  _T("StatusBarPanes"));
  1478. while (!strValue.IsEmpty())
  1479. {
  1480. CString strPane;
  1481. int nIndex = strValue.Find(_T('n'));
  1482. if (nIndex == -1)
  1483. {
  1484. strPane = strValue;
  1485. strValue.Empty();
  1486. }
  1487. else
  1488. {
  1489. strPane = strValue.Left(nIndex);
  1490. strValue = strValue.Mid(nIndex + 1);
  1491. }
  1492. int nID, bVisible = 0;
  1493. int nResult = SCANF_S(strPane, _T("%i=%i"), &nID, &bVisible);
  1494. CXTPStatusBarPane* pPane = (nResult == 2) && (nID != 0) ? FindPane(nID) : NULL;
  1495. if (pPane)
  1496. {
  1497. pPane->SetCustomizationVisible(bVisible);
  1498. }
  1499. }
  1500. }
  1501. }
  1502. void CXTPStatusBar::SaveState(LPCTSTR lpszProfileName)
  1503. {
  1504. if (GetSafeHwnd() && !IsVisible())
  1505. {
  1506. AfxGetApp()->WriteProfileInt(lpszProfileName, _T("StatusBar"), FALSE);
  1507. }
  1508. else
  1509. {
  1510. AfxGetApp()->WriteProfileString(lpszProfileName, _T("StatusBar"), NULL);
  1511. }
  1512. if (m_bCustomizable)
  1513. {
  1514. int nCount = GetPaneCount();
  1515. CString strValue;
  1516. for (int i = 0; i < nCount; i++)
  1517. {
  1518. CXTPStatusBarPane* pPane = GetPane(i);
  1519. CString strPaneState;
  1520. strPaneState.Format(_T("%i=%i"), pPane->GetID(), pPane->GetCustomizationVisible() ? 1 : 0);
  1521. strValue += (strValue.IsEmpty() ? _T("") : _T("n")) + strPaneState;
  1522. }
  1523. AfxGetApp()->WriteProfileString(lpszProfileName, _T("StatusBarPanes"), strValue.IsEmpty() ? (LPCTSTR)NULL : (LPCTSTR)strValue);
  1524. }
  1525. else
  1526. {
  1527. AfxGetApp()->WriteProfileString(lpszProfileName, _T("StatusBarPanes"), NULL);
  1528. }
  1529. }
  1530. //////////////////////////////////////////////////////////////////////////
  1531. // CXTPStatusBarSwitchPane
  1532. IMPLEMENT_DYNAMIC(CXTPStatusBarSwitchPane, CXTPStatusBarPane)
  1533. CXTPStatusBarSwitchPane::CXTPStatusBarSwitchPane()
  1534. {
  1535. m_nStyle |= SBPS_NOBORDERS;
  1536. m_pHighlighted = NULL;
  1537. m_bButton = TRUE;
  1538. m_rcMargins.SetRect(0, 0, 0, 0);
  1539. m_rcPadding.SetRect(0, 0, 0, 0);
  1540. }
  1541. CXTPStatusBarSwitchPane::~CXTPStatusBarSwitchPane()
  1542. {
  1543. RemoveAll();
  1544. }
  1545. void CXTPStatusBarSwitchPane::RemoveAll()
  1546. {
  1547. for (int i = 0; i < m_arrSwitches.GetSize(); i++)
  1548. {
  1549. delete m_arrSwitches[i];
  1550. }
  1551. m_arrSwitches.RemoveAll();
  1552. m_pHighlighted = NULL;
  1553. }
  1554. BOOL CXTPStatusBarSwitchPane::SetSwitches(const UINT* lpIDArray, int nIDCount)
  1555. {
  1556. for (int i = 0; i < nIDCount; i++)
  1557. {
  1558. if (!AddSwitch(lpIDArray[i]))
  1559. return FALSE;
  1560. }
  1561. m_pStatusBar->RecalcLayout();
  1562. return TRUE;
  1563. }
  1564. CXTPStatusBarSwitchPane::SWITCH* CXTPStatusBarSwitchPane::AddSwitch(UINT nID)
  1565. {
  1566. CString strToolTip;
  1567. strToolTip.LoadString(nID);
  1568. return AddSwitch(nID, strToolTip);
  1569. }
  1570. CXTPStatusBarSwitchPane::SWITCH* CXTPStatusBarSwitchPane::AddSwitch(UINT nID, LPCTSTR lpszToolTip)
  1571. {
  1572. SWITCH* pSwitch = new SWITCH();
  1573. pSwitch->nWidth = 0;
  1574. pSwitch->strToolTip = lpszToolTip;
  1575. pSwitch->nID = nID;
  1576. pSwitch->bHighlighted = FALSE;
  1577. pSwitch->bChecked = FALSE;
  1578. pSwitch->bPressed = FALSE;
  1579. m_arrSwitches.Add(pSwitch);
  1580. return pSwitch;
  1581. }
  1582. void CXTPStatusBarSwitchPane::RemoveSwitch(UINT nID)
  1583. {
  1584. for (int i = 0; i < m_arrSwitches.GetSize(); i++)
  1585. {
  1586. if (m_arrSwitches[i]->nID == nID)
  1587. {
  1588. delete m_arrSwitches[i];
  1589. m_arrSwitches.RemoveAt(i);
  1590. return;
  1591. }
  1592. }
  1593. }
  1594. int CXTPStatusBarSwitchPane::GetWidth()
  1595. {
  1596. CXTPPaintManager* pPaintManager = m_pStatusBar->GetPaintManager();
  1597. if (!pPaintManager)
  1598. return 0 ;
  1599. return m_cxText = pPaintManager->DrawStatusBarSwitchPane(NULL, CRect(0, 0, 0, 0), this);
  1600. }
  1601. void CXTPStatusBarSwitchPane::OnDraw(CDC* pDC, CRect rcItem)
  1602. {
  1603. CXTPPaintManager* pPaintManager = m_pStatusBar->GetPaintManager();
  1604. if (pPaintManager)
  1605. {
  1606. pPaintManager->DrawStatusBarSwitchPane(pDC, rcItem, this);
  1607. }
  1608. }
  1609. int CXTPStatusBarSwitchPane::GetSwitchCount() const
  1610. {
  1611. return (int)m_arrSwitches.GetSize();
  1612. }
  1613. CXTPStatusBarSwitchPane::SWITCH* CXTPStatusBarSwitchPane::GetSwitch(int nIndex) const
  1614. {
  1615. return m_arrSwitches[nIndex];
  1616. }
  1617. CXTPStatusBarSwitchPane::SWITCH* CXTPStatusBarSwitchPane::HitTest(CPoint point, CRect& rcItem) const
  1618. {
  1619. rcItem = GetRect();
  1620. for (int i = 0; i < m_arrSwitches.GetSize(); i++)
  1621. {
  1622. rcItem.right = rcItem.left + m_arrSwitches[i]->nWidth;
  1623. if (rcItem.PtInRect(point))
  1624. return m_arrSwitches[i];
  1625. rcItem.left = rcItem.right;
  1626. }
  1627. return NULL;
  1628. }
  1629. INT_PTR CXTPStatusBarSwitchPane::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  1630. {
  1631. CRect rcItem(0, 0, 0, 0);
  1632. SWITCH* pHighlighted = HitTest(point, rcItem);
  1633. if (!pHighlighted)
  1634. return -1;
  1635. INT_PTR nHit = pHighlighted->nID;
  1636. CString strTip = pHighlighted->strToolTip;
  1637. if (strTip.IsEmpty())
  1638. return -1;
  1639. CXTPToolTipContext::FillInToolInfo(pTI, m_pStatusBar->m_hWnd, rcItem, nHit, strTip);
  1640. return nHit;
  1641. }
  1642. void CXTPStatusBarSwitchPane::OnMouseMove(CPoint point)
  1643. {
  1644. CRect rcItem(0, 0, 0, 0);
  1645. SWITCH* pHighlighted = HitTest(point, rcItem);
  1646. if (pHighlighted != m_pHighlighted)
  1647. {
  1648. if (m_pHighlighted)
  1649. {
  1650. m_pHighlighted->bHighlighted = FALSE;
  1651. }
  1652. m_pHighlighted = pHighlighted;
  1653. if (m_pHighlighted)
  1654. {
  1655. m_pHighlighted->bHighlighted = TRUE;
  1656. }
  1657. Redraw();
  1658. }
  1659. }
  1660. void CXTPStatusBarSwitchPane::OnLButtonDown(CPoint point)
  1661. {
  1662. CRect rcItem;
  1663. SWITCH* pHighlighted = HitTest(point, rcItem);
  1664. if (!pHighlighted)
  1665. return;
  1666. pHighlighted->bPressed = TRUE;
  1667. Redraw();
  1668. m_pStatusBar->SetCapture();
  1669. BOOL  bClick = FALSE;
  1670. while (::GetCapture() == m_pStatusBar->GetSafeHwnd())
  1671. {
  1672. BOOL bPressed = rcItem.PtInRect(point);
  1673. if (bPressed != pHighlighted->bPressed)
  1674. {
  1675. pHighlighted->bPressed = bPressed;
  1676. Redraw();
  1677. }
  1678. MSG msg;
  1679. if (!::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
  1680. continue;
  1681. VERIFY(::GetMessage(&msg, NULL, 0, 0));
  1682. switch (msg.message)
  1683. {
  1684. case WM_MOUSEMOVE:
  1685. point = CPoint((short signed)LOWORD(msg.lParam), (short signed)HIWORD(msg.lParam));
  1686. break;
  1687. case WM_LBUTTONUP:
  1688. bClick = pHighlighted->bPressed;
  1689. goto ExitLoop;
  1690. case WM_KEYDOWN:
  1691. if (msg.wParam != VK_ESCAPE)
  1692. break;
  1693. case WM_CANCELMODE:
  1694. case WM_RBUTTONDOWN:
  1695. goto ExitLoop;
  1696. default:
  1697. DispatchMessage (&msg);
  1698. break;
  1699. }
  1700. }
  1701. ExitLoop:
  1702. ReleaseCapture();
  1703. pHighlighted->bPressed = FALSE;
  1704. Redraw();
  1705. if (bClick)
  1706. {
  1707. m_pStatusBar->OnSwitchPaneClick(this, pHighlighted->nID);
  1708. }
  1709. }
  1710. void CXTPStatusBarSwitchPane::SetChecked(UINT nID)
  1711. {
  1712. for (int i = 0; i < m_arrSwitches.GetSize(); i++)
  1713. {
  1714. SWITCH* pSwitch = m_arrSwitches[i];
  1715. BOOL bChecked = pSwitch->nID == nID;
  1716. if (pSwitch->bChecked != bChecked)
  1717. {
  1718. pSwitch->bChecked = bChecked;
  1719. Redraw();
  1720. }
  1721. }
  1722. }
  1723. //////////////////////////////////////////////////////////////////////////
  1724. // CXTPStatusBarScrollBarPane
  1725. IMPLEMENT_DYNAMIC(CXTPStatusBarScrollBarPane, CXTPStatusBarPane)
  1726. CXTPStatusBarScrollBarPane::CXTPStatusBarScrollBarPane()
  1727. {
  1728. m_nMax = 100;
  1729. m_nMin = 0;
  1730. m_nValue = 0;
  1731. m_nPage = 0;
  1732. m_nStyle |= SBPS_NOBORDERS;
  1733. m_bButton = TRUE;
  1734. m_rcMargins.SetRect(0, 0, 0, 0);
  1735. m_rcPadding.SetRect(0, 0, 0, 0);
  1736. m_spi.fVert = FALSE;
  1737. }
  1738. CXTPStatusBarScrollBarPane::~CXTPStatusBarScrollBarPane()
  1739. {
  1740. }
  1741. CRect CXTPStatusBarScrollBarPane::GetScrollBarRect()
  1742. {
  1743. CRect rcItem(GetRect());
  1744. rcItem.DeflateRect(m_rcPadding);
  1745. int nHeight = GetScrollBarPaintManager()->m_cyHScroll;
  1746. if (rcItem.Height() > nHeight)
  1747. {
  1748. rcItem.top = (rcItem.top + rcItem.bottom - nHeight) / 2;
  1749. rcItem.bottom = rcItem.top + nHeight;
  1750. }
  1751. return rcItem;
  1752. }
  1753. void CXTPStatusBarScrollBarPane::GetScrollInfo(SCROLLINFO* psi)
  1754. {
  1755. psi->cbSize = sizeof(SCROLLINFO);
  1756. psi->fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
  1757. psi->nMax = m_nMax;
  1758. psi->nMin = m_nMin;
  1759. psi->nPage = m_nPage;
  1760. psi->nPos = m_nValue;
  1761. }
  1762. BOOL CXTPStatusBarScrollBarPane::IsScrollBarEnabled() const
  1763. {
  1764. return IsEnabled();
  1765. }
  1766. CWnd* CXTPStatusBarScrollBarPane::GetParentWindow() const
  1767. {
  1768. return m_pStatusBar;
  1769. }
  1770. CXTPScrollBarPaintManager* CXTPStatusBarScrollBarPane::GetScrollBarPaintManager() const
  1771. {
  1772. return (CXTPScrollBarPaintManager*)m_pStatusBar->GetPaintManager()->GetGalleryPaintManager();
  1773. }
  1774. void CXTPStatusBarScrollBarPane::OnDraw(CDC* pDC, CRect /*rcItem*/)
  1775. {
  1776. if (!m_pSBTrack || !m_pSBTrack->bTrackThumb)
  1777. SetupScrollInfo();
  1778. GetScrollBarPaintManager()->DrawScrollBar(pDC, this);
  1779. }
  1780. void CXTPStatusBarScrollBarPane::DoScroll(int cmd, int pos)
  1781. {
  1782. CWnd* pParent = m_pStatusBar->GetParent();
  1783. NMXTPSCROLL nmScroll;
  1784. nmScroll.hdr.code = XTP_SBN_SCROLL;
  1785. nmScroll.hdr.idFrom = GetID();
  1786. nmScroll.hdr.hwndFrom = m_pStatusBar->GetSafeHwnd();
  1787. nmScroll.pSender = this;
  1788. nmScroll.nPos = pos;
  1789. nmScroll.nSBCode = cmd;
  1790. LRESULT lResult = 0;
  1791. AFX_NOTIFY notify;
  1792. notify.pResult = &lResult;
  1793. notify.pNMHDR = (NMHDR*)&nmScroll.hdr;
  1794. pParent->OnCmdMsg(GetID(), MAKELONG(XTP_SBN_SCROLL, WM_NOTIFY), &notify, NULL);
  1795. }
  1796. void CXTPStatusBarScrollBarPane::RedrawScrollBar()
  1797. {
  1798. Redraw();
  1799. }
  1800. void CXTPStatusBarScrollBarPane::OnMouseMove(CPoint point)
  1801. {
  1802. int ht = HitTestScrollBar(point);
  1803. if (ht != m_spi.ht)
  1804. {
  1805. m_spi.ht = ht;
  1806. Redraw();
  1807. }
  1808. }
  1809. void CXTPStatusBarScrollBarPane::OnLButtonDown(CPoint point)
  1810. {
  1811. PerformTrackInit(m_pStatusBar->m_hWnd, point, &m_spi, (GetKeyState(VK_SHIFT) < 0) ? TRUE : FALSE);
  1812. }
  1813. void CXTPStatusBarScrollBarPane::SetPos(int nValue)
  1814. {
  1815. if (m_nValue != nValue)
  1816. {
  1817. m_nValue = nValue;
  1818. Redraw();
  1819. }
  1820. }
  1821. int CXTPStatusBarScrollBarPane::GetPos() const
  1822. {
  1823. return m_nValue;
  1824. }
  1825. void CXTPStatusBarScrollBarPane::SetRange(int nMin, int nMax)
  1826. {
  1827. m_nMin = nMin;
  1828. m_nMax = nMax;
  1829. }
  1830. INT_PTR CXTPStatusBarScrollBarPane::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  1831. {
  1832. int ht = HitTestScrollBar(point);
  1833. if (ht < XTP_HTSCROLLUP || ht > XTP_HTSCROLLTHUMB)
  1834. return -1;
  1835. CString strTip = m_strToolTipPart[ht - XTP_HTSCROLLUP];
  1836. if (strTip.IsEmpty())
  1837. return -1;
  1838. CXTPToolTipContext::FillInToolInfo(pTI, m_pStatusBar->m_hWnd, GetScrollBarPartRect(ht), ht, strTip);
  1839. return ht;
  1840. }
  1841. void CXTPStatusBarScrollBarPane::SetTooltipPart(int nPart, LPCTSTR lpszTooltip)
  1842. {
  1843. if (nPart >= XTP_HTSCROLLUP && nPart <= XTP_HTSCROLLTHUMB)
  1844. {
  1845. m_strToolTipPart[nPart - XTP_HTSCROLLUP] = lpszTooltip;
  1846. }
  1847. else
  1848. {
  1849. if (nPart == SB_LINELEFT) m_strToolTipPart[0] = lpszTooltip;
  1850. if (nPart == SB_LINERIGHT) m_strToolTipPart[1] = lpszTooltip;
  1851. if (nPart == SB_PAGELEFT) m_strToolTipPart[2] = lpszTooltip;
  1852. if (nPart == SB_PAGERIGHT) m_strToolTipPart[3] = lpszTooltip;
  1853. if (nPart == SB_THUMBTRACK) m_strToolTipPart[4] = lpszTooltip;
  1854. }
  1855. }
  1856. //////////////////////////////////////////////////////////////////////////
  1857. // CXTPStatusBarSliderPane
  1858. IMPLEMENT_DYNAMIC(CXTPStatusBarSliderPane, CXTPStatusBarScrollBarPane)
  1859. CXTPStatusBarSliderPane::CXTPStatusBarSliderPane()
  1860. {
  1861. }
  1862. CXTPStatusBarSliderPane::~CXTPStatusBarSliderPane()
  1863. {
  1864. }
  1865. CXTPScrollBarPaintManager* CXTPStatusBarSliderPane::GetScrollBarPaintManager() const
  1866. {
  1867. return m_pStatusBar->GetPaintManager()->GetSliderPaintManager();
  1868. }
  1869. void CXTPStatusBarSliderPane::SetTicks(double* pTicks, int nCount)
  1870. {
  1871. SAFE_DELETE(m_pTicks);
  1872. if (nCount)
  1873. {
  1874. m_pTicks = new SLIDERTICKS(pTicks, nCount);
  1875. }
  1876. }
  1877. //////////////////////////////////////////////////////////////////////////
  1878. // CXTPStatusBarProgressPane
  1879. IMPLEMENT_DYNAMIC(CXTPStatusBarProgressPane, CXTPStatusBarPane)
  1880. CXTPStatusBarProgressPane::CXTPStatusBarProgressPane()
  1881. {
  1882. m_nStyle |= SBPS_NOBORDERS;
  1883. m_rcMargins.SetRect(0, 0, 0, 0);
  1884. m_rcPadding.SetRect(0, 0, 0, 0);
  1885. m_cxText = 100;
  1886. }
  1887. CXTPStatusBarProgressPane::~CXTPStatusBarProgressPane()
  1888. {
  1889. }
  1890. CXTPProgressPaintManager* CXTPStatusBarProgressPane::GetProgressPaintManager() const
  1891. {
  1892. return m_pStatusBar->GetPaintManager()->GetProgressPaintManager();
  1893. }
  1894. void CXTPStatusBarProgressPane::RedrawProgress()
  1895. {
  1896. Redraw();
  1897. }
  1898. CRect CXTPStatusBarProgressPane::GetProgressRect()
  1899. {
  1900. CRect rcItem(GetRect());
  1901. rcItem.DeflateRect(m_rcPadding);
  1902. int nHeight = GetProgressPaintManager()->m_cyProgress;
  1903. if (rcItem.Height() > nHeight)
  1904. {
  1905. rcItem.top = (rcItem.top + rcItem.bottom - nHeight) / 2;
  1906. rcItem.bottom = rcItem.top + nHeight;
  1907. }
  1908. return rcItem;
  1909. }
  1910. void CXTPStatusBarProgressPane::OnDraw(CDC* pDC, CRect /*rcItem*/)
  1911. {
  1912. CXTPProgressPaintManager* pPaintManager = GetProgressPaintManager();
  1913. if (pPaintManager)
  1914. {
  1915. pPaintManager->DrawProgress(pDC, this);
  1916. }
  1917. }