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

对话框与窗口

开发平台:

Visual C++

  1. // XTPMessageBar.cpp : implementation of the CXTPMessageBar 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/XTPMarkupRender.h"
  22. #include "Common/XTPOffice2007Image.h"
  23. #include "Common/XTPToolTipContext.h"
  24. #include "XTPCommandBars.h"
  25. #include "XTPPaintManager.h"
  26. #include "XTPMessageBar.h"
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. CXTPMessageBarButton::CXTPMessageBarButton()
  33. {
  34. m_rcButton.SetRectEmpty();
  35. m_nID = 0;
  36. m_bPressed = FALSE;
  37. m_bHot = FALSE;
  38. }
  39. void CXTPMessageBarButton::PerformClick(CXTPMessageBar* pBar, CPoint pt)
  40. {
  41. if ((::GetCapture() != NULL))
  42. return;
  43. ::SetCapture(pBar->GetSafeHwnd());
  44. BOOL  bClick = FALSE;
  45. for (;;)
  46. {
  47. BOOL bPressed = m_rcButton.PtInRect(pt);
  48. if (bPressed != m_bPressed)
  49. {
  50. m_bPressed = bPressed;
  51. pBar->InvalidateRect(m_rcButton, FALSE);
  52. }
  53. MSG msg;
  54. if (!::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
  55. continue;
  56. VERIFY(::GetMessage(&msg, NULL, 0, 0));
  57. if (::GetCapture() != pBar->GetSafeHwnd())
  58. {
  59. DispatchMessage (&msg);
  60. goto ExitLoop;
  61. }
  62. switch (msg.message)
  63. {
  64. case WM_MOUSEMOVE:
  65. pt = CPoint((short signed)LOWORD(msg.lParam), (short signed)HIWORD(msg.lParam));
  66. break;
  67. case WM_LBUTTONUP:
  68. bClick = m_bPressed;
  69. goto ExitLoop;
  70. case WM_KEYDOWN:
  71. if (msg.wParam != VK_ESCAPE)
  72. break;
  73. case WM_CANCELMODE:
  74. case WM_RBUTTONDOWN:
  75. goto ExitLoop;
  76. default:
  77. DispatchMessage (&msg);
  78. break;
  79. }
  80. }
  81. ExitLoop:
  82. ReleaseCapture();
  83. m_bPressed = FALSE;
  84. pBar->InvalidateRect(m_rcButton, FALSE);
  85. if (bClick)
  86. {
  87. pBar->Click(this);
  88. }
  89. }
  90. /////////////////////////////////////////////////////////////////////////////
  91. // CXTPMessageBar
  92. CXTPMessageBar::CXTPMessageBar()
  93. {
  94. m_pMarkupContext = NULL;
  95. m_pUIElement = NULL;
  96. m_rcBorder.SetRect(3, 3, 3, 3);
  97. m_rcPadding.SetRect(5, 0, 5, 0);
  98. m_rcContent.SetRectEmpty();
  99. m_pCommandBars = NULL;
  100. m_pHotButton = NULL;
  101. }
  102. CXTPMessageBar::~CXTPMessageBar()
  103. {
  104. XTPMarkupReleaseElement(m_pUIElement);
  105. XTPMarkupReleaseContext(m_pMarkupContext);
  106. RemoveButtons();
  107. }
  108. BOOL CXTPMessageBar::Create(CXTPCommandBars* pCommandBars, DWORD dwStyle, UINT nID)
  109. {
  110. m_dwStyle = (dwStyle & CBRS_ALL);
  111. m_pCommandBars = pCommandBars;
  112. if (!CWnd::Create(AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)), NULL, dwStyle, CRect(0, 0, 0, 0), pCommandBars->GetSite(), nID))
  113. return FALSE;
  114. return TRUE;
  115. }
  116. void CXTPMessageBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  117. {
  118. // update the dialog controls added to the status bar
  119. UpdateDialogControls(pTarget, bDisableIfNoHndler);
  120. }
  121. CSize CXTPMessageBar::CalcFixedLayout(BOOL, BOOL /*bHorz*/)
  122. {
  123. ASSERT_VALID(this);
  124. ASSERT(::IsWindow(m_hWnd));
  125. CSize size(32767, 40);
  126. return size;
  127. }
  128. void CXTPMessageBar::EnableMarkup(BOOL bEnableMarkup)
  129. {
  130. XTPMarkupReleaseContext(m_pMarkupContext);
  131. if (bEnableMarkup)
  132. {
  133. m_pMarkupContext = XTPMarkupCreateContext(m_hWnd);
  134. }
  135. }
  136. void CXTPMessageBar::AddButton(UINT nID, LPCTSTR lpszCaption, LPCTSTR lpszToolTop)
  137. {
  138. CXTPMessageBarButton* pButton = new CXTPMessageBarButton();
  139. pButton->m_nID = nID;
  140. pButton->m_strCaption = lpszCaption;
  141. pButton->m_strToolTip = lpszToolTop;
  142. m_arrButtons.Add(pButton);
  143. Invalidate(FALSE);
  144. }
  145. void CXTPMessageBar::RemoveButtons()
  146. {
  147. for (int i = 0; i < m_arrButtons.GetSize(); i++)
  148. {
  149. delete m_arrButtons[i];
  150. }
  151. m_arrButtons.RemoveAll();
  152. m_pHotButton = NULL;
  153. if (m_hWnd) Invalidate(FALSE);
  154. }
  155. void CXTPMessageBar::SetMessage(LPCTSTR lpszMessage)
  156. {
  157. m_strContent = lpszMessage;
  158. XTPMarkupReleaseElement(m_pUIElement);
  159. if (m_pMarkupContext)
  160. {
  161. m_pUIElement = XTPMarkupParseText(m_pMarkupContext, lpszMessage);
  162. }
  163. Invalidate(FALSE);
  164. }
  165. CXTPPaintManager* CXTPMessageBar::GetPaintManager() const
  166. {
  167. return m_pCommandBars->GetPaintManager();
  168. }
  169. BEGIN_MESSAGE_MAP(CXTPMessageBar, CControlBar)
  170. //{{AFX_MSG_MAP(CXTPMessageBar)
  171. ON_WM_PAINT()
  172. ON_WM_SIZE()
  173. ON_WM_MOUSEMOVE()
  174. ON_WM_LBUTTONDOWN()
  175. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  176. //}}AFX_MSG_MAP
  177. END_MESSAGE_MAP()
  178. /////////////////////////////////////////////////////////////////////////////
  179. // CXTPMessageBar message handlers
  180. void CXTPMessageBar::OnPaint()
  181. {
  182. CPaintDC dcPaint(this); // device context for painting
  183. CXTPBufferDC dc(dcPaint);
  184. CXTPFontDC font(&dc, GetPaintManager()->GetRegularFont());
  185. RecalcLayout(&dc);
  186. FillMessageBar(&dc);
  187. DrawContent(&dc);
  188. DrawButtons(&dc);
  189. }
  190. void CXTPMessageBar::DrawButtons(CDC* pDC)
  191. {
  192. for (int i = 0; i < m_arrButtons.GetSize(); i++)
  193. {
  194. CXTPMessageBarButton* pButton = m_arrButtons.GetAt(i);
  195. DrawButton(pDC, pButton);
  196. }
  197. };
  198. void CXTPMessageBar::DrawButton(CDC* pDC, CXTPMessageBarButton* pButton)
  199. {
  200. BOOL bCloseButton = (pButton->m_nID == SC_CLOSE);
  201. GetPaintManager()->DrawMessageBarButton(pDC, pButton);
  202. if (!bCloseButton)
  203. {
  204. pDC->SetBkMode(TRANSPARENT);
  205. pDC->SetTextColor(GetPaintManager()->m_clrMessageBarText);
  206. pDC->DrawText(pButton->m_strCaption, pButton->m_rcButton, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);
  207. }
  208. }
  209. void CXTPMessageBar::FillMessageBar(CDC* pDC)
  210. {
  211. GetPaintManager()->FillMessageBar(pDC, this);
  212. }
  213. void CXTPMessageBar::DrawContent(CDC* pDC)
  214. {
  215. COLORREF clrText = GetPaintManager()->m_clrMessageBarText;
  216. if (m_pUIElement)
  217. {
  218. XTPMarkupSetDefaultFont(m_pMarkupContext, (HFONT)GetPaintManager()->GetRegularFont()->GetSafeHandle(), clrText);
  219. XTPMarkupRenderElement(m_pUIElement, pDC->GetSafeHdc(), m_rcContent);
  220. }
  221. else
  222. {
  223. pDC->SetBkMode(TRANSPARENT);
  224. pDC->SetTextColor(clrText);
  225. pDC->DrawText(m_strContent, m_rcContent, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX);
  226. }
  227. }
  228. CRect CXTPMessageBar::GetMessageRect()
  229. {
  230. BOOL bCloseButton = FindButton(SC_CLOSE) != NULL;
  231. CXTPClientRect rc(this);
  232. rc.left += m_rcBorder.left;
  233. rc.top += m_rcBorder.top;
  234. rc.right -= m_rcBorder.right + (bCloseButton ? 18 : 0);
  235. rc.bottom -= m_rcBorder.bottom;
  236. return rc;
  237. }
  238. CSize CXTPMessageBar::MeasureContent(CDC* pDC)
  239. {
  240. if (m_pUIElement)
  241. {
  242. XTPMarkupSetDefaultFont(m_pMarkupContext, (HFONT)GetPaintManager()->GetRegularFont()->GetSafeHandle(), COLORREF_NULL);
  243. CSize sz = XTPMarkupMeasureElement(m_pUIElement);
  244. return sz;
  245. }
  246. CSize sz = pDC->GetTextExtent(m_strContent);
  247. return sz;
  248. }
  249. CSize CXTPMessageBar::MeasureButton(CDC* pDC, CXTPMessageBarButton* pButton)
  250. {
  251. if (pButton->m_nID == SC_CLOSE)
  252. return CSize(18, 18);
  253. CSize sz = pDC->GetTextExtent(pButton->m_strCaption);
  254. sz.cy = max(sz.cy + 2, 23);
  255. sz.cx = max(89, sz.cx + 10);
  256. return sz;
  257. }
  258. void CXTPMessageBar::RecalcLayout(CDC* pDC)
  259. {
  260. if (!m_hWnd)
  261. return;
  262. CXTPClientRect rcClient(this);
  263. CSize szContent = MeasureContent(pDC);
  264. m_rcContent = CRect(CPoint(m_rcBorder.left + m_rcPadding.left, (rcClient.Height() - szContent.cy) /2), szContent);
  265. int nLeft = m_rcContent.right, i;
  266. CXTPMessageBarButton* pCloseButton = NULL;
  267. for (i = 0; i < m_arrButtons.GetSize(); i++)
  268. {
  269. CXTPMessageBarButton* pButton = m_arrButtons.GetAt(i);
  270. if (pButton->m_nID == SC_CLOSE)
  271. {
  272. pCloseButton = pButton;
  273. continue;
  274. }
  275. CSize szButton = MeasureButton(pDC, pButton);
  276. pButton->m_rcButton = CRect(CPoint(nLeft + m_rcPadding.right, (rcClient.Height() - szButton.cy) /2), szButton);
  277. nLeft = pButton->m_rcButton.right;
  278. }
  279. int nRight = rcClient.right - m_rcBorder.right - m_rcPadding.right - (pCloseButton ? 18 : 0);
  280. if (nLeft > nRight)
  281. {
  282. nLeft = m_rcBorder.left + m_rcPadding.left;
  283. for (i = (int)m_arrButtons.GetSize() - 1; i >= 0; i--)
  284. {
  285. CXTPMessageBarButton* pButton = m_arrButtons.GetAt(i);
  286. if (pButton->m_nID == SC_CLOSE)
  287. continue;
  288. int nWidth = pButton->m_rcButton.Width();
  289. pButton->m_rcButton.right = nRight;
  290. pButton->m_rcButton.left = nRight - nWidth;
  291. if (pButton->m_rcButton.left < nLeft)
  292. {
  293. pButton->m_rcButton.SetRectEmpty();
  294. }
  295. else
  296. {
  297. nRight = nRight - nWidth - m_rcPadding.right;
  298. }
  299. }
  300. m_rcContent.right = nRight;
  301. }
  302. if (pCloseButton)
  303. {
  304. CSize szButton = MeasureButton(pDC, pCloseButton);
  305. pCloseButton->m_rcButton = CRect(CPoint(rcClient.right - szButton.cx - 1, m_rcBorder.top), szButton);
  306. }
  307. };
  308. void CXTPMessageBar::OnSize(UINT nType, int cx, int cy)
  309. {
  310. CControlBar::OnSize(nType, cx, cy);
  311. Invalidate(FALSE);
  312. }
  313. BOOL CXTPMessageBar::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  314. {
  315. if (m_pUIElement)
  316. {
  317. if (XTPMarkupRelayMessage(m_pUIElement, message, wParam, lParam, pResult))
  318. return TRUE;
  319. }
  320. m_pCommandBars->GetToolTipContext()->FilterToolTipMessage(this, message, wParam, lParam);
  321. return CControlBar::OnWndMsg(message, wParam, lParam, pResult);
  322. }
  323. CXTPMessageBarButton* CXTPMessageBar::FindButton(UINT nID) const
  324. {
  325. for (int i = 0; i < m_arrButtons.GetSize(); i++)
  326. {
  327. CXTPMessageBarButton* pButton = m_arrButtons.GetAt(i);
  328. if (pButton->m_nID == nID)
  329. return pButton;
  330. }
  331. return NULL;
  332. }
  333. CXTPMessageBarButton* CXTPMessageBar::HitTestButton(CPoint point) const
  334. {
  335. for (int i = 0; i < m_arrButtons.GetSize(); i++)
  336. {
  337. CXTPMessageBarButton* pButton = m_arrButtons.GetAt(i);
  338. if (pButton->m_rcButton.PtInRect(point))
  339. return pButton;
  340. }
  341. return NULL;
  342. }
  343. void CXTPMessageBar::OnMouseLeave()
  344. {
  345. OnMouseMove(0, CPoint(-1, -1));
  346. }
  347. void CXTPMessageBar::OnMouseMove(UINT nFlags, CPoint point)
  348. {
  349. CXTPMessageBarButton* pButton = HitTestButton(point);
  350. if (pButton != m_pHotButton)
  351. {
  352. if (m_pHotButton) m_pHotButton->m_bHot = FALSE;
  353. m_pHotButton = pButton;
  354. if (m_pHotButton) m_pHotButton->m_bHot = TRUE;
  355. if (m_pHotButton)
  356. {
  357. TRACKMOUSEEVENT tme =
  358. {
  359. sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd
  360. };
  361. _TrackMouseEvent(&tme);
  362. }
  363. Invalidate(FALSE);
  364. }
  365. CControlBar::OnMouseMove(nFlags, point);
  366. }
  367. void CXTPMessageBar::OnLButtonDown(UINT nFlags, CPoint point)
  368. {
  369. if (m_pHotButton)
  370. {
  371. m_pHotButton->PerformClick(this, point);
  372. return;
  373. }
  374. CControlBar::OnLButtonDown(nFlags, point);
  375. }
  376. INT_PTR CXTPMessageBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  377. {
  378. ASSERT_VALID(this);
  379. ASSERT(::IsWindow(m_hWnd));
  380. // check child windows first by calling CControlBar
  381. INT_PTR nHit = CControlBar::OnToolHitTest(point, pTI);
  382. if (nHit != -1)
  383. return nHit;
  384. if (m_pHotButton)
  385. {
  386. nHit = m_pHotButton->m_nID;
  387. CString strTip = m_pHotButton->m_strToolTip;
  388. if (strTip.IsEmpty())
  389. return -1;
  390. CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, m_pHotButton->m_rcButton, nHit, strTip);
  391. return nHit;
  392. }
  393. return -1;
  394. }
  395. void CXTPMessageBar::Click(CXTPMessageBarButton* pButton)
  396. {
  397. if (pButton->m_nID == SC_CLOSE)
  398. {
  399. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_HIDEWINDOW);
  400. m_pCommandBars->RecalcFrameLayout();
  401. }
  402. else
  403. {
  404. m_pCommandBars->GetSite()->SendMessage(WM_COMMAND, pButton->m_nID);
  405. }
  406. }