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

对话框与窗口

开发平台:

Visual C++

  1. // XTMenuListBox.cpp : implementation of the CXTMenuListBox class.
  2. //
  3. // This file is a part of the XTREME CONTROLS 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/XTPColorManager.h"
  22. #include "Common/XTPImageManager.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "XTDefines.h"
  25. #include "XTUtil.h"
  26. #include "XTGlobal.h"
  27. #include "XTVC50Helpers.h"
  28. #include "XTMenuListBox.h"
  29. #include "XTMenuListBoxTheme.h"
  30. #include "XTThemeManager.h"
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36. //////////////////////////////////////////////////////////////////////////
  37. // CXTMenuListBox::CONTENT_ITEM
  38. CXTMenuListBox::CONTENT_ITEM::CONTENT_ITEM()
  39. {
  40. m_pIcon = NULL;
  41. }
  42. CXTMenuListBox::CONTENT_ITEM::~CONTENT_ITEM()
  43. {
  44. if (m_pIcon)
  45. delete m_pIcon;
  46. }
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CXTMenuListBox
  49. /////////////////////////////////////////////////////////////////////////////
  50. IMPLEMENT_THEME_HOST(CXTMenuListBox)
  51. IMPLEMENT_THEME_REFRESH(CXTMenuListBox, CListBox)
  52. CXTMenuListBox::CXTMenuListBox()
  53. : CXTThemeManagerStyleHost(GetThemeFactoryClass())
  54. , m_bNoBorder(false)
  55. , m_bHilight(true)
  56. , m_bNoUnderline(true)
  57. , m_hCursor(NULL)
  58. , m_bHilightItemID(-1)
  59. , m_bTimerActive(false)
  60. , m_nPrevIndex(-1)
  61. {
  62. }
  63. CXTMenuListBox::~CXTMenuListBox()
  64. {
  65. while (!m_arContentItems.IsEmpty())
  66. {
  67. CONTENT_ITEM* pCI = m_arContentItems.RemoveHead();
  68. delete pCI;
  69. }
  70. }
  71. IMPLEMENT_DYNAMIC(CXTMenuListBox, CListBox)
  72. BEGIN_MESSAGE_MAP(CXTMenuListBox, CListBox)
  73. //{{AFX_MSG_MAP(CXTMenuListBox)
  74. ON_WM_LBUTTONDOWN()
  75. ON_WM_LBUTTONUP()
  76. ON_WM_MOUSEMOVE()
  77. ON_WM_WINDOWPOSCHANGED()
  78. ON_WM_ERASEBKGND()
  79. ON_WM_PAINT()
  80. ON_WM_SETCURSOR()
  81. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  82. //}}AFX_MSG_MAP
  83. END_MESSAGE_MAP()
  84. // Checks mouse movement, sets point member, sets timer.
  85. BOOL CXTMenuListBox::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  86. {
  87. if (m_hCursor != NULL)
  88. {
  89. CONTENT_ITEM* pCI = GetMenuItem(m_nPrevIndex);
  90. if (pCI && pCI->m_bEnabled)
  91. {
  92. SetCursor(m_hCursor);
  93. return TRUE;
  94. }
  95. }
  96. return CListBox::OnSetCursor(pWnd, nHitTest, message);
  97. }
  98. void CXTMenuListBox::RedrawItem(int iIndex)
  99. {
  100. CRect rcItem;
  101. GetItemRect(iIndex, &rcItem);
  102. InvalidateRect(&rcItem);
  103. }
  104. void CXTMenuListBox::RedrawItem(CPoint point)
  105. {
  106. BOOL bOutSide;
  107. int nIndex = ItemFromPoint(point, bOutSide);
  108. if (!bOutSide)
  109. {
  110. RedrawItem(nIndex);
  111. }
  112. }
  113. void CXTMenuListBox::OnMouseMove(UINT /*nFlags*/, CPoint point)
  114. {
  115. BOOL bOutSide;
  116. int nIndex = ItemFromPoint (point, bOutSide);
  117. CRect rcItem;
  118. GetItemRect(nIndex, &rcItem);
  119. if ((m_nPrevIndex != -1) && (m_nPrevIndex != nIndex))
  120. {
  121. RedrawItem(m_nPrevIndex);
  122. }
  123. if (bOutSide || !rcItem.PtInRect(point))
  124. {
  125. RedrawItem(nIndex);
  126. nIndex = -1;
  127. }
  128. if (nIndex != GetCurSel())
  129. {
  130. SetCurSel(nIndex);
  131. if (nIndex != -1)
  132. {
  133. RedrawItem(nIndex);
  134. TRACKMOUSEEVENT tme =
  135. {
  136. sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, 0
  137. };
  138. _TrackMouseEvent(&tme);
  139. }
  140. }
  141. m_nPrevIndex = nIndex;
  142. }
  143. void CXTMenuListBox::OnLButtonDown(UINT nFlags, CPoint point)
  144. {
  145. CListBox::OnLButtonDown(nFlags, point);
  146. RedrawItem(point);
  147. }
  148. void CXTMenuListBox::OnLButtonUp(UINT nFlags, CPoint point)
  149. {
  150. CListBox::OnLButtonUp(nFlags, point);
  151. RedrawItem(point);
  152. CONTENT_ITEM* pCI = GetMenuItem(GetCurSel());
  153. if (pCI && !pCI->m_bEnabled)
  154. return;
  155. CWnd* pWndOwner = GetOwner();
  156. ASSERT(pWndOwner);
  157. if (pWndOwner) pWndOwner->SendMessage(XTWM_OUTBAR_NOTIFY,
  158. (LPARAM)GetCurSel(), (WPARAM)GetDlgCtrlID());
  159. }
  160. // Sets the highlight flag based on cursor position.
  161. void CXTMenuListBox::OnMouseLeave()
  162. {
  163. //reset mouse vars
  164. OnMouseMove(0, CPoint(-1, -1));
  165. }
  166. // Initial draw routine, draws button on mouse over,
  167. // on mouse press, and on mouse out.
  168. void CXTMenuListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  169. {
  170. GetTheme()->DrawItem(this, lpDIS);
  171. }
  172. int CXTMenuListBox::GetTextHeight(LPCTSTR lspzItem) const
  173. {
  174. CWindowDC dc(NULL);
  175. CXTStringHelper strItem(lspzItem);
  176. // get the height for a single line text item.
  177. CFont* pOldFont = dc.SelectObject(GetFont());
  178. CSize size = dc.GetTextExtent(strItem);
  179. dc.SelectObject(pOldFont);
  180. // set the height of the item with single line text.
  181. int iTextHeight = size.cy;
  182. // for each newline character we need to adjust the height.
  183. for (int i = 0; i < strItem.GetLength(); ++i)
  184. {
  185. if (strItem[i] == _T('n'))
  186. {
  187. iTextHeight += size.cy;
  188. }
  189. }
  190. return iTextHeight;
  191. }
  192. // Sets item height
  193. void CXTMenuListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
  194. {
  195. // get the text height.
  196. int iTextHeight = GetTextHeight((LPCTSTR)lpMIS->itemData);
  197. // calculate the total height of the item.
  198. lpMIS->itemHeight = GetTheme()->m_cyEdge + GetTheme()->m_cyIcon + GetTheme()->m_cyEdge +
  199. iTextHeight + GetTheme()->m_cyEdge;
  200. }
  201. void CXTMenuListBox::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
  202. {
  203. CListBox::OnWindowPosChanged(lpwndpos);
  204. InvalidateRect(NULL);
  205. }
  206. BOOL CXTMenuListBox::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
  207. {
  208. // Make sure that the control is owner drawn.
  209. dwStyle |= LBS_OWNERDRAWVARIABLE | LBS_NOINTEGRALHEIGHT;
  210. if (!CListBox::Create(dwStyle, rect, pParentWnd, nID))
  211. return FALSE;
  212. // Set the font used by the Outlook bar.
  213. SetFont(CFont::FromHandle((HFONT)
  214. ::GetStockObject(DEFAULT_GUI_FONT)));
  215. return TRUE;
  216. }
  217. BOOL CXTMenuListBox::EnableMenuItem(int iItem, BOOL bEnabled)
  218. {
  219. CONTENT_ITEM* pCI = GetMenuItem(iItem);
  220. if (pCI != NULL)
  221. {
  222. pCI->m_bEnabled = bEnabled;
  223. return TRUE;
  224. }
  225. return FALSE;
  226. }
  227. int CXTMenuListBox::AddMenuItem(UINT nIconID, LPCTSTR lpszText, BOOL bEnabled/*= TRUE*/)
  228. {
  229. CONTENT_ITEM* pCI = new CONTENT_ITEM;
  230. ASSERT(pCI != NULL);
  231. pCI->m_nIndex = AddString(lpszText);
  232. pCI->m_strText = lpszText;
  233. pCI->m_bEnabled = bEnabled;
  234. /*// Load the icon for the menu item.
  235. HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(nIconID), RT_GROUP_ICON);
  236. pCI->m_hIcon = (HICON)::LoadImage(hInst, MAKEINTRESOURCE(nIconID),
  237. IMAGE_ICON, GetTheme()->m_cxIcon, GetTheme()->m_cyIcon, LR_DEFAULTCOLOR);*/
  238. pCI->m_pIcon = new CXTPImageManagerIcon(nIconID, 0, 0);
  239. pCI->m_pIcon->SetIcon(nIconID, GetTheme()->m_cxIcon, GetTheme()->m_cyIcon);
  240. m_arContentItems.AddTail(pCI);
  241. return pCI->m_nIndex;
  242. }
  243. int CXTMenuListBox::InsertMenuItem(int iIndex, UINT nIconID, LPCTSTR lpszText, BOOL bEnabled/*= TRUE*/)
  244. {
  245. CONTENT_ITEM* pCI = new CONTENT_ITEM;
  246. ASSERT(pCI != NULL);
  247. pCI->m_nIndex = InsertString(iIndex, lpszText);
  248. pCI->m_strText = lpszText;
  249. pCI->m_bEnabled = bEnabled;
  250. // Load the icon for the menu item.
  251. //  HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(nIconID), RT_GROUP_ICON);
  252. //  pCI->m_hIcon = (HICON)::LoadImage(hInst, MAKEINTRESOURCE(nIconID),
  253. //      IMAGE_ICON, GetTheme()->m_cxIcon, GetTheme()->m_cyIcon, LR_DEFAULTCOLOR);
  254. pCI->m_pIcon = new CXTPImageManagerIcon(nIconID, 0, 0);
  255. pCI->m_pIcon->SetIcon(nIconID, GetTheme()->m_cxIcon, GetTheme()->m_cyIcon);
  256. POSITION pos = m_arContentItems.FindIndex(pCI->m_nIndex);
  257. if (pos != NULL)
  258. {
  259. m_arContentItems.InsertBefore(pos, pCI);
  260. }
  261. else
  262. {
  263. m_arContentItems.AddTail(pCI);
  264. }
  265. return pCI->m_nIndex;
  266. }
  267. BOOL CXTMenuListBox::OnEraseBkgnd(CDC* /*pDC*/)
  268. {
  269. return FALSE;
  270. }
  271. void CXTMenuListBox::OnPaint()
  272. {
  273. CPaintDC dc(this); // device context for painting
  274. // Get the client rect.
  275. CXTPClientRect rcClient(this);
  276. // Paint to a memory device context to help
  277. // eliminate screen flicker.
  278. CXTPBufferDC memDC(dc);
  279. memDC.FillSolidRect(rcClient, GetTheme()->m_crgBack);
  280. // Now let the window do its default painting...
  281. CWnd::DefWindowProc (WM_PAINT, (WPARAM)memDC.m_hDC, 0);
  282. }
  283. CXTMenuListBox::CONTENT_ITEM* CXTMenuListBox::GetMenuItem(int iItem)
  284. {
  285. CONTENT_ITEM* pCI = NULL;
  286. // Get the menu item.
  287. POSITION pos = m_arContentItems.FindIndex(iItem);
  288. if (pos != NULL)
  289. {
  290. pCI = m_arContentItems.GetAt(pos);
  291. }
  292. return pCI;
  293. }
  294. void CXTMenuListBox::SetHilightCursor(UINT nIDCursor, bool bNoBorder/*= false*/, bool bNoUnderline/*= false*/)
  295. {
  296. // load the new cursor.
  297. m_hCursor = AfxGetApp()->LoadCursor(nIDCursor);
  298. // display a border or text underline when highlighted ?
  299. m_bNoBorder = bNoBorder;
  300. m_bNoUnderline = bNoUnderline;
  301. }
  302. void CXTMenuListBox::SetColors(COLORREF clrText, COLORREF clrBack, COLORREF clrBackDark/*= COLORREF_NULL*/)
  303. {
  304. GetTheme()->m_crItemText.SetCustomValue(clrText);  // Must be custom value used to prevent reset color in RefreshMetrics.
  305. GetTheme()->m_crgBack.SetCustomValue(clrBack, clrBackDark);
  306. }