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

对话框与窗口

开发平台:

Visual C++

  1. // XTPSkinObjectTrackBar.cpp: implementation of the CXTPSkinObjectTrackBar 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/XTPDrawHelpers.h"
  22. #include "XTPSkinObjectTrackBar.h"
  23. #include "XTPSkinManager.h"
  24. #ifdef _DEBUG
  25. #undef THIS_FILE
  26. static char THIS_FILE[]=__FILE__;
  27. #define new DEBUG_NEW
  28. #endif
  29. inline void swap(long& _X, long& _Y)
  30. {
  31. long _Tmp = _X;
  32. _X = _Y;
  33. _Y = _Tmp;
  34. }
  35. //////////////////////////////////////////////////////////////////////
  36. // Construction/Destruction
  37. //////////////////////////////////////////////////////////////////////
  38. IMPLEMENT_DYNCREATE(CXTPSkinObjectTrackBar, CXTPSkinObjectFrame)
  39. CXTPSkinObjectTrackBar::CXTPSkinObjectTrackBar()
  40. {
  41. m_strClassName = _T("TRACKBAR");
  42. m_nTickFreq = 1;
  43. m_bHotThumb = FALSE;
  44. ZeroMemory(&m_drawRect, sizeof(m_drawRect));
  45. }
  46. CXTPSkinObjectTrackBar::~CXTPSkinObjectTrackBar()
  47. {
  48. }
  49. BEGIN_MESSAGE_MAP(CXTPSkinObjectTrackBar, CXTPSkinObjectFrame)
  50. //{{AFX_MSG_MAP(CXTPSkinObjectTrackBar)
  51. ON_WM_ERASEBKGND()
  52. ON_WM_PAINT()
  53. ON_MESSAGE(TBM_SETTICFREQ, OnSetTicFreq)
  54. ON_WM_LBUTTONDOWN()
  55. ON_WM_LBUTTONUP()
  56. ON_WM_MOUSEMOVE()
  57. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  58. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  59. //}}AFX_MSG_MAP
  60. END_MESSAGE_MAP()
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CXTPSkinObjectTrackBar message handlers
  63. BOOL CXTPSkinObjectTrackBar::OnEraseBkgnd(CDC* /*pDC*/)
  64. {
  65. return TRUE;
  66. }
  67. #define TICKHEIGHT 3
  68. #define BORDERSIZE 2
  69. #define MIN_THUMB_HEIGHT (2 * GetSystemMetrics(SM_CXEDGE))
  70. void PatRect(CDC* pDC,int x,int y,int dx,int dy, BOOL bVert, COLORREF clr)
  71. {
  72. if (bVert)
  73. {
  74. pDC->FillSolidRect(y, x, dy, dx, clr);
  75. }
  76. else
  77. {
  78. pDC->FillSolidRect(x, y, dx, dy, clr);
  79. }
  80. }
  81. void CXTPSkinObjectTrackBar::DrawTic(CDC* pDC, int x, int y, int dir, COLORREF clr)
  82. {
  83. if (dir == -1) y -= TICKHEIGHT;
  84. PatRect(pDC,x,y,1,TICKHEIGHT, GetStyle() & TBS_VERT, clr);
  85. }
  86. int CXTPSkinObjectTrackBar::LogToPhys(DWORD dwPos)
  87. {
  88. const RECT& rc = m_drawRect.rc;
  89. int lLogMin = (int)SendMessage(TBM_GETRANGEMIN);
  90. int lLogMax = (int)SendMessage(TBM_GETRANGEMAX);
  91. int iSizePhys = max(1, rc.right - rc.left);
  92. int x;
  93. x = rc.left;
  94. if (lLogMax == lLogMin)
  95. return x;
  96. return (int)MulDiv(dwPos - lLogMin, iSizePhys - 1, lLogMax - lLogMin) + x;
  97. }
  98. void ValidateThumbHeight(DWORD dwStyle, int& iThumbHeight, int& iThumbWidth)
  99. {
  100. if (iThumbHeight < MIN_THUMB_HEIGHT)
  101. iThumbHeight = MIN_THUMB_HEIGHT;
  102. iThumbWidth = iThumbHeight / 2;
  103. iThumbWidth |= 0x01;
  104. if (dwStyle & TBS_ENABLESELRANGE)
  105. {
  106. if (dwStyle & TBS_FIXEDLENGTH)
  107. {
  108. iThumbWidth = (iThumbHeight * 9) / 20;
  109. iThumbWidth |= 0x01;
  110. }
  111. else
  112. {
  113. iThumbHeight += (iThumbWidth * 2) / 9;
  114. }
  115. }
  116. }
  117. void CXTPSkinObjectTrackBar::FillDrawRect()
  118. {
  119. CXTPClientRect rc(this);
  120. DWORD dwStyle = GetStyle();
  121. if (dwStyle & TBS_VERT)
  122. {
  123. swap(rc.left, rc.top);
  124. swap(rc.right, rc.bottom);
  125. }
  126. int iThumbHeight = 0, iThumbWidth = 0;
  127. if (dwStyle & TBS_FIXEDLENGTH)
  128. {
  129. iThumbHeight = (int)SendMessage(TBM_GETTHUMBLENGTH);
  130. ValidateThumbHeight(dwStyle, iThumbHeight, iThumbWidth);
  131. }
  132. else
  133. {
  134. iThumbHeight = (GetSystemMetrics(SM_CYHSCROLL) * 4) / 3;
  135. if ((iThumbHeight > MIN_THUMB_HEIGHT) && (rc.bottom < (int)iThumbHeight))
  136. {
  137. iThumbHeight = rc.bottom - 3 * GetSystemMetrics(SM_CYEDGE); // top, bottom, and tic
  138. if (dwStyle & TBS_ENABLESELRANGE)
  139. iThumbHeight = iThumbHeight * 3 / 4;
  140. ValidateThumbHeight(dwStyle, iThumbHeight, iThumbWidth);
  141. }
  142. ValidateThumbHeight(dwStyle, iThumbHeight, iThumbWidth);
  143. }
  144. if (dwStyle & (TBS_BOTH | TBS_TOP) && !(GetStyle() & TBS_NOTICKS))
  145. rc.top += TICKHEIGHT + BORDERSIZE + 3;
  146. rc.top   += BORDERSIZE;
  147. rc.bottom  = rc.top + iThumbHeight;
  148. rc.left   += (iThumbWidth + BORDERSIZE);
  149. rc.right  -= (iThumbWidth + BORDERSIZE);
  150. m_drawRect.rc = rc;
  151. m_drawRect.iThumbHeight = iThumbHeight;
  152. m_drawRect.iThumbWidth = iThumbWidth;
  153. m_drawRect.iSizePhys = max(1, rc.right - rc.left);
  154. m_drawRect.dwStyle = dwStyle;
  155. }
  156. // dir = direction multiplier (drawing up or down)
  157. // yTic = where (vertically) to draw the line of tics
  158. void CXTPSkinObjectTrackBar::DrawTicsOneLine(CDC* pDC, int dir, int yTic)
  159. {
  160. const RECT& rc = m_drawRect.rc;
  161. BOOL bVert = GetStyle() & TBS_VERT;
  162. CXTPSkinManagerClass* pClass = GetSkinClass();
  163. COLORREF clrTick = pClass->GetThemeColor(bVert ? TKP_TICSVERT : TKP_TICS, 1,  TMT_COLOR, GetColor(COLOR_BTNTEXT));
  164. DrawTic(pDC, rc.left, yTic, dir, clrTick);
  165. DrawTic(pDC, rc.left, yTic + (dir * 1), dir, clrTick);
  166. DrawTic(pDC, rc.right-1, yTic, dir, clrTick);
  167. DrawTic(pDC, rc.right-1, yTic+ (dir * 1), dir, clrTick);
  168. PDWORD pTics = (PDWORD)SendMessage(TBM_GETPTICS);
  169. int    iPos;
  170. int    i;
  171. int nTics = pTics ? (int)LocalSize((HANDLE)pTics) / sizeof(DWORD) : 0;
  172. // those inbetween
  173. if (m_nTickFreq && pTics)
  174. {
  175. for (i = 0; i < nTics; ++i)
  176. {
  177. if (((i + 1) % m_nTickFreq) == 0)
  178. {
  179. iPos = LogToPhys(pTics[i]);
  180. DrawTic(pDC, iPos, yTic, dir, clrTick);
  181. }
  182. }
  183. }
  184. int lSelStart = (int)SendMessage(TBM_GETSELSTART);
  185. int lSelEnd = (int)SendMessage(TBM_GETSELEND);
  186. int lLogMin = (int)SendMessage(TBM_GETRANGEMIN);
  187. // draw the selection range (triangles)
  188. if ((GetStyle() & TBS_ENABLESELRANGE) &&
  189. (lSelStart < lSelEnd) && (lSelEnd >= lLogMin))
  190. {
  191. pDC->SetBkColor(clrTick);
  192. iPos = LogToPhys(lSelStart);
  193. for (i = 0; i < TICKHEIGHT; i++)
  194. PatRect(pDC,iPos-i,yTic+(dir==1 ? i : -TICKHEIGHT),
  195. 1,TICKHEIGHT-i, GetStyle() & TBS_VERT, GetColor(COLOR_BTNTEXT));
  196. iPos = LogToPhys(lSelEnd);
  197. for (i = 0; i < TICKHEIGHT; i++)
  198. PatRect(pDC,iPos+i,yTic+(dir==1 ? i : -TICKHEIGHT),
  199. 1,TICKHEIGHT-i, GetStyle() & TBS_VERT, GetColor(COLOR_BTNTEXT));
  200. }
  201. }
  202. void CXTPSkinObjectTrackBar::DrawTics(CDC* pDC)
  203. {
  204. const RECT& rc = m_drawRect.rc;
  205. DWORD dwStyle = GetStyle();
  206. if (dwStyle & TBS_NOTICKS)
  207. return;
  208. if ((dwStyle & TBS_BOTH) || !(dwStyle & TBS_TOP))
  209. {
  210. DrawTicsOneLine(pDC, 1, rc.bottom + 1);
  211. }
  212. if ((dwStyle & (TBS_BOTH | TBS_TOP)))
  213. {
  214. DrawTicsOneLine(pDC, -1, rc.top - 1);
  215. }
  216. }
  217. void CXTPSkinObjectTrackBar::DrawChannel(CDC* pDC)
  218. {
  219. RECT rcChannel;
  220. ::SendMessage(m_hWnd, TBM_GETCHANNELRECT, 0, (LPARAM)&rcChannel);
  221. BOOL bVert = m_drawRect.dwStyle & TBS_VERT;
  222. if (bVert)
  223. {
  224. swap(rcChannel.left, rcChannel.top);
  225. swap(rcChannel.right, rcChannel.bottom);
  226. }
  227. CXTPSkinManagerClass* pClass = GetSkinClass();
  228. pClass->DrawThemeBackground(pDC, bVert ? TKP_TRACKVERT: TKP_TRACK, 1, &rcChannel);
  229. }
  230. void CXTPSkinObjectTrackBar::DrawThumb(CDC* pDC)
  231. {
  232. DWORD dwStyle =  m_drawRect.dwStyle;
  233. if (dwStyle & TBS_NOTHUMB)
  234. return;
  235. BOOL bVert = dwStyle & TBS_VERT;
  236. CXTPSkinManagerClass* pClass = GetSkinClass();
  237. RECT rcThumb;
  238. ::SendMessage(m_hWnd, TBM_GETTHUMBRECT, 0, (LPARAM)&rcThumb);
  239. int nPartId = bVert ? TKP_THUMBVERT: TKP_THUMB;
  240. if (!(dwStyle & TBS_BOTH))
  241. {
  242. if (!bVert)
  243. nPartId = dwStyle & TBS_TOP ? TKP_THUMBTOP : TKP_THUMBBOTTOM;
  244. else
  245. nPartId = dwStyle & TBS_TOP ? TKP_THUMBLEFT : TKP_THUMBRIGHT;
  246. }
  247. int nStateId = TUS_NORMAL;
  248. if (m_bHotThumb)
  249. nStateId = TUS_HOT;
  250. if (::GetCapture() == m_hWnd)
  251. nStateId = TUS_PRESSED;
  252. else if (::GetFocus() == m_hWnd && ((SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) == 0))
  253. nStateId = TUS_FOCUSED;
  254. if (!IsWindowEnabled())
  255. nStateId = TUS_DISABLED;
  256. pClass->DrawThemeBackground(pDC, nPartId , nStateId, &rcThumb);
  257. }
  258. LRESULT CXTPSkinObjectTrackBar::OnPrintClient(WPARAM wParam, LPARAM lParam)
  259. {
  260. if ((lParam & PRF_CLIENT) == 0)
  261. return Default();
  262. CDC* pDC = CDC::FromHandle((HDC)wParam);
  263. if (pDC) OnDraw(pDC);
  264. return 1;
  265. }
  266. void CXTPSkinObjectTrackBar::OnPaint()
  267. {
  268. CXTPSkinObjectPaintDC dc(this);
  269. OnDraw(&dc);
  270. }
  271. void CXTPSkinObjectTrackBar::OnDraw(CDC* pDC)
  272. {
  273. CXTPClientRect rc(this);
  274. CXTPBufferDC dcMem(*pDC, rc);
  275. NMCUSTOMDRAW nm;
  276. ZeroMemory(&nm, sizeof(NMCUSTOMDRAW));
  277. nm.hdc = dcMem.GetSafeHdc();
  278. nm.dwDrawStage = CDDS_PREPAINT;
  279. nm.hdr.code = NM_CUSTOMDRAW;
  280. nm.hdr.hwndFrom = GetSafeHwnd();
  281. nm.hdr.idFrom = GetDlgCtrlID();
  282. LRESULT lrCdrf = GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nm);
  283. FillBackground(&dcMem, rc);
  284. if (::GetFocus() == m_hWnd && ((SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) == 0))
  285. {
  286. dcMem.SetBkColor(GetColor(COLOR_BTNHIGHLIGHT));
  287. DrawFocusRect(dcMem, &rc);
  288. }
  289. FillDrawRect();
  290. if (lrCdrf & CDRF_NOTIFYITEMDRAW)
  291. {
  292. ZeroMemory(&nm, sizeof(NMCUSTOMDRAW));
  293. nm.hdc = dcMem.GetSafeHdc();
  294. nm.dwDrawStage = CDDS_ITEMPREPAINT;
  295. nm.dwItemSpec = TBCD_TICS;
  296. nm.hdr.code = NM_CUSTOMDRAW;
  297. nm.hdr.hwndFrom = GetSafeHwnd();
  298. nm.hdr.idFrom = GetDlgCtrlID();
  299. GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nm);
  300. }
  301. DrawTics(&dcMem);
  302. if (lrCdrf & CDRF_NOTIFYITEMDRAW)
  303. {
  304. ZeroMemory(&nm, sizeof(NMCUSTOMDRAW));
  305. nm.hdc = dcMem.GetSafeHdc();
  306. nm.dwDrawStage = CDDS_ITEMPOSTPAINT;
  307. nm.dwItemSpec = TBCD_TICS;
  308. nm.hdr.code = NM_CUSTOMDRAW;
  309. nm.hdr.hwndFrom = GetSafeHwnd();
  310. nm.hdr.idFrom = GetDlgCtrlID();
  311. GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nm);
  312. ZeroMemory(&nm, sizeof(NMCUSTOMDRAW));
  313. nm.hdc = dcMem.GetSafeHdc();
  314. nm.dwDrawStage = CDDS_ITEMPREPAINT;
  315. nm.dwItemSpec = TBCD_CHANNEL;
  316. nm.hdr.code = NM_CUSTOMDRAW;
  317. nm.hdr.hwndFrom = GetSafeHwnd();
  318. nm.hdr.idFrom = GetDlgCtrlID();
  319. GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nm);
  320. }
  321. DrawChannel(&dcMem);
  322. if (lrCdrf & CDRF_NOTIFYITEMDRAW)
  323. {
  324. ZeroMemory(&nm, sizeof(NMCUSTOMDRAW));
  325. nm.hdc = dcMem.GetSafeHdc();
  326. nm.dwDrawStage = CDDS_ITEMPOSTPAINT;
  327. nm.dwItemSpec = TBCD_CHANNEL;
  328. nm.hdr.code = NM_CUSTOMDRAW;
  329. nm.hdr.hwndFrom = GetSafeHwnd();
  330. nm.hdr.idFrom = GetDlgCtrlID();
  331. GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nm);
  332. ZeroMemory(&nm, sizeof(NMCUSTOMDRAW));
  333. nm.hdc = dcMem.GetSafeHdc();
  334. nm.dwDrawStage = CDDS_ITEMPREPAINT;
  335. nm.dwItemSpec = TBCD_THUMB;
  336. nm.hdr.code = NM_CUSTOMDRAW;
  337. nm.hdr.hwndFrom = GetSafeHwnd();
  338. nm.hdr.idFrom = GetDlgCtrlID();
  339. GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nm);
  340. }
  341. DrawThumb(&dcMem);
  342. if (lrCdrf & CDRF_NOTIFYITEMDRAW)
  343. {
  344. ZeroMemory(&nm, sizeof(NMCUSTOMDRAW));
  345. nm.hdc = dcMem.GetSafeHdc();
  346. nm.dwDrawStage = CDDS_ITEMPOSTPAINT;
  347. nm.dwItemSpec = TBCD_THUMB;
  348. nm.hdr.code = NM_CUSTOMDRAW;
  349. nm.hdr.hwndFrom = GetSafeHwnd();
  350. nm.hdr.idFrom = GetDlgCtrlID();
  351. GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nm);
  352. }
  353. if (lrCdrf & CDRF_NOTIFYPOSTPAINT)
  354. {
  355. ZeroMemory(&nm, sizeof(NMCUSTOMDRAW));
  356. nm.hdc = dcMem.GetSafeHdc();
  357. nm.dwDrawStage = CDDS_POSTPAINT;
  358. nm.hdr.code = NM_CUSTOMDRAW;
  359. nm.hdr.hwndFrom = GetSafeHwnd();
  360. nm.hdr.idFrom = GetDlgCtrlID();
  361. GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nm);
  362. }
  363. }
  364. LRESULT CXTPSkinObjectTrackBar::OnSetTicFreq(WPARAM wParam, LPARAM)
  365. {
  366. m_nTickFreq = (int)wParam;
  367. return Default();
  368. }
  369. void CXTPSkinObjectTrackBar::OnMouseMove(UINT nFlags, CPoint point)
  370. {
  371. RECT rcThumb;
  372. ::SendMessage(m_hWnd, TBM_GETTHUMBRECT, 0, (LPARAM)&rcThumb);
  373. BOOL bHotThumb = ::PtInRect(&rcThumb, point);
  374. if (bHotThumb != m_bHotThumb)
  375. {
  376. m_bHotThumb = bHotThumb;
  377. Invalidate(FALSE);
  378. if (m_bHotThumb)
  379. {
  380. TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, HOVER_DEFAULT};
  381. _TrackMouseEvent(&tme);
  382. }
  383. }
  384. CXTPSkinObjectFrame::OnMouseMove(nFlags, point);
  385. }
  386. void CXTPSkinObjectTrackBar::OnMouseLeave()
  387. {
  388. OnMouseMove(0, CPoint(-1, -1));
  389. }
  390. void CXTPSkinObjectTrackBar::OnLButtonDown(UINT nFlags, CPoint point)
  391. {
  392. CXTPSkinObjectFrame::OnLButtonDown(nFlags, point);
  393. }
  394. void CXTPSkinObjectTrackBar::OnLButtonUp(UINT nFlags, CPoint point)
  395. {
  396. CXTPSkinObjectFrame::OnLButtonUp(nFlags, point);
  397. }