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

对话框与窗口

开发平台:

Visual C++

  1. // XTPSkinObjectTab.cpp: implementation of the CXTPSkinObjectTab class.
  2. //
  3. // This file is a part of the XTREME SKINFRAMEWORK 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/XTPDrawHelpers.h"
  23. #include "XTPSkinObjectTab.h"
  24. #include "XTPSkinManager.h"
  25. #include "XTPSkinImage.h"
  26. #ifdef _DEBUG
  27. #undef THIS_FILE
  28. static char THIS_FILE[]=__FILE__;
  29. #define new DEBUG_NEW
  30. #endif
  31. #define DT_HIDEPREFIX       0x00100000
  32. AFX_INLINE BOOL IsLeft(DWORD dwStyle)
  33. {
  34. return ((dwStyle & (TCS_VERTICAL|TCS_RIGHT|TCS_BOTTOM)) == TCS_VERTICAL);
  35. }
  36. AFX_INLINE BOOL IsRight(DWORD dwStyle)
  37. {
  38. return ((dwStyle & (TCS_VERTICAL|TCS_RIGHT|TCS_BOTTOM)) == (TCS_VERTICAL|TCS_RIGHT));
  39. }
  40. AFX_INLINE BOOL IsTop(DWORD dwStyle)
  41. {
  42. return ((dwStyle & (TCS_VERTICAL|TCS_RIGHT|TCS_BOTTOM)) == 0);
  43. }
  44. AFX_INLINE BOOL IsBottom(DWORD dwStyle)
  45. {
  46. return ((dwStyle & (TCS_VERTICAL|TCS_RIGHT|TCS_BOTTOM)) == TCS_BOTTOM);
  47. }
  48. AFX_INLINE BOOL IsVert(DWORD dwStyle)
  49. {
  50. return (IsRight(dwStyle) || IsLeft(dwStyle));
  51. }
  52. AFX_INLINE BOOL IsHorz(DWORD dwStyle)
  53. {
  54. return (IsTop(dwStyle) || IsBottom(dwStyle));
  55. }
  56. //////////////////////////////////////////////////////////////////////
  57. // Construction/Destruction
  58. //////////////////////////////////////////////////////////////////////
  59. IMPLEMENT_DYNCREATE(CXTPSkinObjectTab, CXTPSkinObjectFrame)
  60. CXTPSkinObjectTab::CXTPSkinObjectTab()
  61. {
  62. m_strClassName = _T("TAB");
  63. m_nHotItem = -1;
  64. m_bPaint = FALSE;
  65. }
  66. CXTPSkinObjectTab::~CXTPSkinObjectTab()
  67. {
  68. }
  69. BEGIN_MESSAGE_MAP(CXTPSkinObjectTab, CXTPSkinObjectFrame)
  70. //{{AFX_MSG_MAP(CXTPSkinObjectTab)
  71. ON_WM_ERASEBKGND()
  72. ON_WM_PAINT()
  73. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  74. ON_WM_MOUSEMOVE()
  75. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  76. //}}AFX_MSG_MAP
  77. END_MESSAGE_MAP()
  78. /////////////////////////////////////////////////////////////////////////////
  79. // CXTPSkinObjectTab message handlers
  80. BOOL CXTPSkinObjectTab::OnEraseBkgnd(CDC* pDC)
  81. {
  82. CXTPClientRect rc(this);
  83. CXTPBufferDC dcMem(pDC->GetSafeHdc(), rc);
  84. FillClient(&dcMem, rc);
  85. return TRUE;
  86. }
  87. CRect CXTPSkinObjectTab::GetHeaderRect()
  88. {
  89. CRect rcHeader;
  90. GetClientRect(&rcHeader);
  91. CTabCtrl* pTabCtrl = (CTabCtrl*)this;
  92. // get the selected tab item rect.
  93. CRect rcItem;
  94. pTabCtrl->GetItemRect(pTabCtrl->GetCurSel(), &rcItem);
  95. DWORD dwStyle = GetStyle();
  96. if (IsRight(dwStyle))
  97. {
  98. rcHeader.left = rcItem.left;
  99. }
  100. else if (IsLeft(dwStyle))
  101. {
  102. rcHeader.right = rcItem.right;
  103. }
  104. else if (IsBottom(dwStyle))
  105. {
  106. rcHeader.top = rcItem.top;
  107. }
  108. else
  109. {
  110. rcHeader.bottom = (rcHeader.top + rcItem.Height()) * pTabCtrl->GetRowCount() + GetMetrics()->m_cyEdge;
  111. }
  112. return rcHeader;
  113. }
  114. void CXTPSkinObjectTab::FillClient(CDC* pDC, CRect rc)
  115. {
  116. FillBackground(pDC, rc);
  117. if (GetStyle() & TCS_BUTTONS)
  118. return;
  119. CXTPSkinManagerClass* pClass = GetSkinClass();
  120. CRect rcClient(rc);
  121. CRect rcHeader = GetHeaderRect();
  122. DWORD dwStyle = GetStyle();
  123. if (IsRight(dwStyle))
  124. {
  125. rcClient.right = rcHeader.left;
  126. }
  127. else if (IsLeft(dwStyle))
  128. {
  129. rcClient.left = rcHeader.right;
  130. }
  131. else if (IsBottom(dwStyle))
  132. {
  133. rcClient.bottom = rcHeader.top;
  134. }
  135. else
  136. {
  137. rcClient.top = rcHeader.bottom;
  138. }
  139. pClass->DrawThemeBackground(pDC, TABP_PANE, 0, &rcClient);
  140. }
  141. void CXTPSkinObjectTab::FillTabFace(CDC* pDC, CRect rcItem, int iItem, int iCount, BOOL bSelected)
  142. {
  143. if (GetStyle() & TCS_BUTTONS)
  144. {
  145. CXTPSkinManagerClass* pClassButton = GetSkinManager()->GetSkinClass(_T("BUTTON"));
  146. int nState = bSelected? PBS_PRESSED: PBS_NORMAL;
  147. pClassButton->DrawThemeBackground(pDC, BP_PUSHBUTTON, nState, rcItem);
  148. return;
  149. }
  150. if (bSelected)
  151. {
  152. rcItem.InflateRect(2, 2, 2, 2);
  153. }
  154. CXTPSkinManagerClass* pClass = GetSkinClass();
  155. int nStateId = bSelected ? TIS_SELECTED: m_nHotItem == iItem ? TIS_HOT : TIS_NORMAL;
  156. pClass->DrawThemeBackground(pDC, iItem == 0 ? TABP_TOPTABITEMLEFTEDGE :
  157. iItem == iCount - 1 && !bSelected ? TABP_TOPTABITEMRIGHTEDGE : TABP_TOPTABITEM,
  158. nStateId, &rcItem);
  159. }
  160. void CXTPSkinObjectTab::DrawTabIcon(CDC* pDC, CRect& rcItem, int iItem)
  161. {
  162. CTabCtrl* pTabCtrl = (CTabCtrl*)this;
  163. TC_ITEM tci;
  164. tci.mask = TCIF_IMAGE;
  165. if (!pTabCtrl->GetItem(iItem, &tci))
  166. return;
  167. CImageList* pImageList = pTabCtrl->GetImageList();
  168. if (!pImageList || tci.iImage < 0)
  169. return;
  170. CPoint point = rcItem.TopLeft();
  171. DWORD dwStyle = GetStyle();
  172. if (IsHorz(dwStyle))
  173. {
  174. point.Offset(GetMetrics()->m_cxEdge * 2, IsTop(dwStyle) ? GetMetrics()->m_cyEdge : 1);
  175. }
  176. else
  177. {
  178. point.Offset(IsLeft(dwStyle) ? GetMetrics()->m_cxEdge : 1, GetMetrics()->m_cyEdge * 2);
  179. }
  180. // Draw any associated icons.
  181. pImageList->Draw(pDC, tci.iImage, point, ILD_TRANSPARENT);
  182. IMAGEINFO info;
  183. pImageList->GetImageInfo(tci.iImage, &info);
  184. CRect rcImage(info.rcImage);
  185. if (IsHorz(dwStyle))
  186. {
  187. rcItem.left += rcImage.Width() + GetMetrics()->m_cxEdge;
  188. }
  189. else
  190. {
  191. rcItem.top += rcImage.Height() + GetMetrics()->m_cyEdge;
  192. }
  193. }
  194. void CXTPSkinObjectTab::DrawTabText(CDC* pDC, CRect& rcItem, int iItem, int iCount,  BOOL bSelected)
  195. {
  196. CTabCtrl* pTabCtrl = (CTabCtrl*)this;
  197. CString strCaption;
  198. LPTSTR pszText = strCaption.GetBuffer(256);
  199. pszText[0] = 0;
  200. TC_ITEM tci;
  201. tci.mask = TCIF_TEXT;
  202. tci.pszText = pszText;
  203. tci.cchTextMax = 255;
  204. BOOL bResult = pTabCtrl->GetItem(iItem, &tci);
  205. strCaption.ReleaseBuffer();
  206. #ifdef _UNICODE
  207. if (!bResult)
  208. {
  209. char tText[256];
  210. tText[0] = 0;
  211. TC_ITEMA tcia;
  212. ::ZeroMemory(&tcia, sizeof(TC_ITEMA));
  213. tcia.mask = TCIF_TEXT;
  214. // Get the header item text and format
  215. tcia.pszText = tText;
  216. tcia.cchTextMax = 255;
  217. ::SendMessage(pTabCtrl->m_hWnd, TCM_GETITEMA, iItem, (LPARAM)&tcia);
  218. strCaption = tText;
  219. }
  220. #else
  221. if (!bResult)
  222. return;
  223. #endif
  224. if (strCaption.GetLength() == 0)
  225. return;
  226. pDC->SetTextColor(GetColor(COLOR_BTNTEXT));
  227. // Set the font for the tab label.
  228. DWORD dwStyle = GetStyle();
  229. CXTPSkinManagerClass* pClass = GetSkinClass();
  230. int nStateId = bSelected ? TIS_SELECTED: m_nHotItem == iItem ? TIS_HOT : TIS_NORMAL;
  231. int nPartId = iItem == 0 ? TABP_TOPTABITEMLEFTEDGE :
  232. iItem == iCount - 1 && !bSelected ? TABP_TOPTABITEMRIGHTEDGE : TABP_TOPTABITEM;
  233. // Draw the tab label.
  234. if (IsHorz(dwStyle))
  235. {
  236. UINT dsFlags = DT_SINGLELINE | DT_VCENTER | DT_CENTER | DT_END_ELLIPSIS;
  237. if (SendMessage(WM_QUERYUISTATE) & UISF_HIDEACCEL)
  238. {
  239. dsFlags |= DT_HIDEPREFIX;
  240. }
  241. if (!(GetStyle() & TCS_BUTTONS))
  242. {
  243. rcItem.top += bSelected ? -2 : 1;
  244. rcItem.right -= iItem == 0 ? 3 : 0;
  245. }
  246. else
  247. {
  248. rcItem.top += bSelected ? 0 : -1;
  249. }
  250. pClass->DrawThemeText(pDC, nPartId, nStateId, strCaption, dsFlags, &rcItem);
  251. }
  252. else
  253. {
  254. CSize sz = pDC->GetTextExtent(strCaption);
  255. rcItem.left = rcItem.right-(rcItem.Width()-sz.cy + 1)/ 2;
  256. rcItem.top = rcItem.top+(rcItem.Height()-sz.cx + 1)/ 2;
  257. pClass->DrawThemeText(pDC, nPartId, nStateId, strCaption, DT_SINGLELINE | DT_NOCLIP, &rcItem);
  258. }
  259. }
  260. void CXTPSkinObjectTab::DrawTab(CDC* pDC, int iItem)
  261. {
  262. CXTPClientRect rc(this);
  263. CTabCtrl* pTabCtrl = (CTabCtrl*)this;
  264. // Get the current tab selection.
  265. int iCurSel = pTabCtrl->GetCurSel();
  266. // Get the tab item size.
  267. CRect rcItem;
  268. pTabCtrl->GetItemRect(iItem, &rcItem);
  269. if (!CRect().IntersectRect(rcItem, rc))
  270. return;
  271. CRect rcItemFocus(rcItem);
  272. // Draw the tab item.
  273. BOOL bSelected = (iItem == iCurSel);
  274. FillTabFace(pDC, rcItem, iItem, pTabCtrl->GetItemCount(), bSelected);
  275. DrawTabIcon(pDC, rcItem, iItem);
  276. DrawTabText(pDC, rcItem, iItem, iItem, bSelected);
  277. // draw the focus rect
  278. if (bSelected && ::GetFocus() == m_hWnd && (SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) == 0)
  279. {
  280. rcItemFocus.DeflateRect(GetMetrics()->m_cxEdge / 2, GetMetrics()->m_cyEdge / 2);
  281. pDC->DrawFocusRect(&rcItemFocus);
  282. }
  283. }
  284. void CXTPSkinObjectTab::OnPaint()
  285. {
  286. CXTPSkinObjectPaintDC dc(this);
  287. if (dc.m_ps.hdc == 0)
  288. {
  289. FillClient(&dc, CXTPClientRect(this));
  290. }
  291. OnDraw(&dc);
  292. }
  293. LRESULT CXTPSkinObjectTab::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
  294. {
  295. if (m_bPaint)
  296. {
  297. return Default();
  298. }
  299. CDC* pDC = CDC::FromHandle((HDC)wParam);
  300. if (pDC)
  301. {
  302. OnDraw(pDC);
  303. }
  304. return 1;
  305. }
  306. void CXTPSkinObjectTab::OnDraw(CDC* pDC)
  307. {
  308. CRect rc = GetHeaderRect();
  309. DWORD dwStyle = GetStyle();
  310. if (IsRight(dwStyle))
  311. {
  312. rc.left -= 2;
  313. }
  314. else if (IsLeft(dwStyle))
  315. {
  316. rc.right += 2;
  317. }
  318. else if (IsBottom(dwStyle))
  319. {
  320. rc.top -= 2;
  321. }
  322. else
  323. {
  324. rc.bottom += 2;
  325. }
  326. CXTPBufferDC dcMem(*pDC, rc);
  327. FillClient(&dcMem, CXTPClientRect(this));
  328. if (m_bActiveX)
  329. {
  330. m_bPaint = TRUE;
  331. CXTPBufferDC dcMem2(*pDC, rc);
  332. DefWindowProc(WM_PAINT, (WPARAM)dcMem2.GetSafeHdc(), 0);
  333. dcMem2.Discard();
  334. m_bPaint = FALSE;
  335. }
  336. CTabCtrl* pTabCtrl = (CTabCtrl*)this;
  337. CXTPFontDC font(&dcMem, GetFont());
  338. dcMem.SetBkMode(TRANSPARENT);
  339. for (int iItem = 0; iItem < pTabCtrl->GetItemCount(); ++iItem)
  340. {
  341. DrawTab(&dcMem, iItem);
  342. }
  343. DrawTab(&dcMem, pTabCtrl->GetCurSel());
  344. }
  345. void CXTPSkinObjectTab::OnMouseLeave()
  346. {
  347. OnMouseMove(0,CPoint(-1, -1));
  348. }
  349. void CXTPSkinObjectTab::OnMouseMove(UINT /*nFlags*/, CPoint point)
  350. {
  351. int nHotItem = -1;
  352. CTabCtrl* pTabCtrl = (CTabCtrl*)this;
  353. for (int iItem = 0; iItem < pTabCtrl->GetItemCount(); ++iItem)
  354. {
  355. CRect rcItem;
  356. pTabCtrl->GetItemRect(iItem, &rcItem);
  357. if (rcItem.PtInRect(point))
  358. {
  359. nHotItem = iItem;
  360. break;
  361. }
  362. }
  363. if (nHotItem != m_nHotItem)
  364. {
  365. m_nHotItem = nHotItem;
  366. InvalidateRect(GetHeaderRect(), FALSE);
  367. if (m_nHotItem != -1)
  368. {
  369. TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, HOVER_DEFAULT};
  370. _TrackMouseEvent(&tme);
  371. }
  372. }
  373. }
  374. //////////////////////////////////////////////////////////////////////////
  375. // CXTPSkinObjectTabClient
  376. ////////////////////////////////////////////////////////////////////
  377. HBRUSH CXTPSkinObjectFrame::GetClientBrush(HDC hDC, HWND hWnd, UINT nCtlColor)
  378. {
  379. if (m_dwDialogTexture != ETDT_ENABLETAB)
  380. {
  381. GrayCtlColor(hDC, hWnd, nCtlColor, GetMetrics()->m_brushDialog, GetColor(COLOR_BTNTEXT));
  382. return GetMetrics()->m_brushDialog;
  383. }
  384. if (GetMetrics()->m_brushTabControl == NULL)
  385. {
  386. CWindowDC dcWindow(this);
  387. CXTPSkinManagerClass* pClass = GetSkinManager()->GetSkinClass(_T("TAB"));
  388. CString strImageFile = pClass->GetThemeString(TABP_BODY, 0, TMT_STOCKIMAGEFILE);
  389. if (strImageFile.IsEmpty())
  390. {
  391. return GetMetrics()->m_brushDialog;
  392. }
  393. CXTPSkinImage* pImage = pClass->GetImages()->LoadFile(m_pManager->GetResourceFile(), strImageFile);
  394. if (!pImage)
  395. {
  396. return GetMetrics()->m_brushDialog;
  397. }
  398. CRect rc(0, 0, pImage->GetWidth(), pImage->GetHeight());
  399. CBitmap bmp;
  400. bmp.CreateCompatibleBitmap(&dcWindow, rc.Width(), rc.Height());
  401. CXTPCompatibleDC dc(&dcWindow, bmp);
  402. pImage->DrawImage(&dc, rc, rc, CRect(0, 0, 0, 0), COLORREF_NULL, ST_TRUESIZE, FALSE);
  403. GetMetrics()->m_brushTabControl = ::CreatePatternBrush(bmp);
  404. }
  405. if (hWnd != m_hWnd)
  406. {
  407. CXTPWindowRect rcPaint(hWnd);
  408. CXTPWindowRect rcBrush(m_hWnd);
  409. ::SetBrushOrgEx(hDC, rcBrush.left - rcPaint.left, rcBrush.top - rcPaint.top, NULL);
  410. ::SetBkMode(hDC, TRANSPARENT);
  411. ::SetTextColor(hDC, GetColor(COLOR_BTNTEXT));
  412. }
  413. return GetMetrics()->m_brushTabControl;
  414. }