资源描述
这是一个实现自绘CButton的类,期望对大家有点帮助,我提供这个类,只是为大家提供一个自绘控件的思路,你可以在此基础上,随意地修改代码,直到它能完成你所需要的功能.其它控件的自绘,原理了和这个差不多.
1.#if !defined(AFX_BUTTONST_H__1271FF9C_E28C_4D3B_B429_AFE65924A5D0__INCLUDED_) 2.#define AFX_BUTTONST_H__1271FF9C_E28C_4D3B_B429_AFE65924A5D0__INCLUDED_ 3.4.#if _MSC_VER > 1000 5.#pragma once 6.#endif // _MSC_VER > 1000 7.// ButtonST.h : header file 8.// 9.10.///////////////////////////////////////////////////////////////////////////// 11.// CButtonST window 12.13.class CButtonST : public CButton
14.{
15.// Construction 16.public:
17. CButtonST();
18.19.// Attributes 20.public:
21.
22.// Operations 23.public:
24. //设置背景颜色 25. void SetBkColor(COLORREF BkColor);
26. //设置鼠标在按钮上的偏移颜色 27. void SetShOffset(int nShOffset);
28. //设置字体颜色 29. void SetTextColor(COLORREF TextColor);
30. //设置网页链接 31. void SetURL(CString strURL);
32. //设置背景图片 33. void SetBkPicture(CBitmap *pBitMap);
34.35.// Overrides 36. // ClassWizard generated virtual function overrides 37. //{{AFX_VIRTUAL(CButtonST) 38. public:
39. virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
40. virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
41. protected:
42. virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
43. virtual void PreSubclassWindow();
44. //}}AFX_VIRTUAL 45.46.// Implementation 47.public:
48. virtual ~CButtonST();
49.
50. void DrawItem1(LPDRAWITEMSTRUCT lpDrawItemStruct);
51.52. // Generated message map functions 53.protected:
54. //{{AFX_MSG(CButtonST) 55. afx_msg void OnMouseMove(UINT nFlags, CPoint point);
56. afx_msg BOOL OnNcActivate(BOOL bActive);
57. afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point);
58. afx_msg void OnKillFocus(CWnd* pNewWnd);
59. afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
60. //}}AFX_MSG 61.protected:
62. //鼠标是否在按钮上面 63. BOOL m_IsPressed;
64. COLORREF m_BkColor;
65. int m_nShOffset;
66. COLORREF m_TextColor;
67. CString m_strURL;
68. CBitmap *m_pBitMapBK;
69.protected:
70. //背景颜色偏移 71. COLORREF OffsetColor(COLORREF color,int nOffset);
72. //鼠标离开 73. LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
74. DECLARE_MESSAGE_MAP()
75.};
76.77.///////////////////////////////////////////////////////////////////////////// 78.79.//{{AFX_INSERT_LOCATION}} 80.// Microsoft Visual C++ will insert additional declarations immediately before the previous line. 81.82.#endif // !defined(AFX_BUTTONST_H__1271FF9C_E28C_4D3B_B429_AFE65924A5D0__INCLUDED_) 83.
1.// ButtonST.cpp : implementation file 2.// 3.4.#include "stdafx.h" 5.#include "ContrlST.h" 6.#include "ButtonST.h" 7.8.#ifdef _DEBUG 9.#define new DEBUG_NEW 10.#undef THIS_FILE 11.static char THIS_FILE[] = __FILE__; 12.#endif 13.#define BS_TYPEMASK SS_TYPEMASK 14.15.///////////////////////////////////////////////////////////////////////////// 16.// CButtonST 17.18.CButtonST::CButtonST()
19.{
20. m_IsPressed = FALSE;
21. m_BkColor = RGB(216,233,216);
22. m_nShOffset = 30;
23. m_TextColor = RGB(0,0,0);
24. m_strURL = "";
25. m_pBitMapBK = NULL;
26.}
27.28.CButtonST::~CButtonST()
29.{
30. if(m_pBitMapBK!=NULL)
31. {
32. delete m_pBitMapBK;
33. m_pBitMapBK = NULL;
34. }
35.}
36.37.38.BEGIN_MESSAGE_MAP(CButtonST, CButton)
39. //{{AFX_MSG_MAP(CButtonST) 40. ON_WM_MOUSEMOVE()
41. ON_WM_NCACTIVATE()
42. ON_WM_NCMOUSEMOVE()
43. ON_WM_KILLFOCUS()
44. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
45. ON_WM_LBUTTONDOWN()
46. //}}AFX_MSG_MAP 47.END_MESSAGE_MAP()
48.49.///////////////////////////////////////////////////////////////////////////// 50.// CButtonST message handlers 51.52.53.//设置背景颜色 54.void CButtonST::SetBkColor(COLORREF BkColor)
55.{
56. m_BkColor = BkColor;
57. this->Invalidate();
58.}
59.//设置鼠标在按钮上的偏移颜色
60.void CButtonST::SetShOffset(int nShOffset)
61.{
62. m_nShOffset = nShOffset;
63. this->Invalidate();
64.}
65.//设置字体颜色 66.void CButtonST::SetTextColor(COLORREF TextColor)
67.{
68. m_TextColor = TextColor;
69. this->Invalidate();
70.}
71.//设置网页链接 72.void CButtonST::SetURL(CString strURL)
73.{
74. m_strURL = strURL;
75.}
76.77.//设置背景图片 78.void CButtonST::SetBkPicture(CBitmap *pBitMap)
79.{
80. if(m_pBitMapBK==pBitMap)
81. return;
82. if(m_pBitMapBK!=NULL)
83. {
84. delete m_pBitMapBK;
85. m_pBitMapBK = pBitMap;
86. }
87. m_pBitMapBK = pBitMap;
88. this->Invalidate();
89.}
90.//背景颜色偏移 91.COLORREF CButtonST::OffsetColor(COLORREF color,int nOffset)
92.{
93. BYTE byRed = 0;
94. BYTE byGreen = 0;
95. BYTE byBlue = 0;
96. short shOffsetR = nOffset;
97. short shOffsetG = nOffset;
98. short shOffsetB = nOffset;
99. if (nOffset < -255 || nOffset > 255)
100. {
101. nOffset = 30;
102. }
103.
104. // Get RGB components of specified color 105. byRed = GetRValue(color);
106. byGreen = GetGValue(color);
107. byBlue = GetBValue(color);
108.
109. // Calculate max. allowed real offset 110. if (nOffset > 0)
111. {
112. if (byRed + nOffset > 255) shOffsetR = 255 - byRed;
113. if (byGreen + nOffset > 255) shOffsetG = 255 - byGreen;
114. if (byBlue + nOffset > 255) shOffsetB = 255 - byBlue;
115. nOffset = min(min(shOffsetR, shOffsetG), shOffsetB);
116. }
117. else118. {
119. if (byRed + nOffset < 0) shOffsetR = -byRed;
120. if (byGreen + nOffset < 0) shOffsetG = -byGreen;
121. if (byBlue + nOffset < 0) shOffsetB = -byBlue;
122.
123. nOffset = max(max(shOffsetR, shOffsetG), shOffsetB);
124. }
125. int r,g,b;
126. r = byRed + nOffset;
127. g =byGreen + nOffset;
128. b =byBlue + nOffset;
129. return RGB(r,g,b);
130.}
131.132.void CButtonST::DrawItem1(LPDRAWITEMSTRUCT lpDrawItemStruct)
133.{
134. // TODO: Add your code to draw the specified item 135.
136.
137. CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
138. CRect rect = lpDrawItemStruct->rcItem;
139. CRect offRect = rect;
140. int ndist = 2;
141. offRect.left+= ndist;
142. offRect.right -=ndist;
143. offRect.top += ndist;
144. offRect.bottom -=ndist;
145.
146.
147. pDC->SetBkMode(TRANSPARENT);
148. pDC->SetTextColor(m_TextColor);
149.
150. //绘制背景 151. if(m_pBitMapBK!=NULL)
152. {
153. CDC* pNewDC = new CDC;
154. pNewDC->CreateCompatibleDC(pDC);
155. pNewDC->SelectObject(m_pBitMapBK);
156. BITMAP bmp;
157. m_pBitMapBK->GetBitmap(&bmp);
158. if(m_IsPressed)
159. {
160. pDC->StretchBlt(0,0,rect.Width(),rect.Height(),pNewDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
161. }
162. else163. {
164. CBrush brush(RGB(220,220,220));//RGB(m_nShOffset,m_nShOffset,m_nShOffset)); 165. pDC->FillRect(&rect,&brush);
166. pDC->StretchBlt(0,0,rect.Width(),rect.Height(),pNewDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCAND);
167. }
168.
169. delete pNewDC;
170. pNewDC = NULL;
171. }
172. else173. {
174. if(m_IsPressed)
175. {
176. CBrush brush(OffsetColor(m_BkColor,m_nShOffset));
177. pDC->FillRect(rect,&brush);
178. CBrush brush1(RGB(128,128,128));
179. pDC->FrameRect(rect,&brush1);
180. pDC->FrameRect(offRect,&brush1);
181. }
182. else183. {
184. CBrush brush(m_BkColor);
185. pDC->FillRect(rect,&brush);
186. CBrush brush1(RGB(128,128,128));
187. pDC->FrameRect(offRect,&brush1);
188. }
189. }
190.
191.
192. CString sTitle;
193. GetWindowText(sTitle);
194. offRect.OffsetRect(0,rect.Height()/2-8);
195. // pDC->DrawText(sTitle, sTitle.GetLength(),offRect, DT_WORDBREAK | DT_CENTER); 196. pDC->DrawText(sTitle, sTitle.GetLength(),offRect, DT_WORDBREAK|DT_CENTER);
197.198.199.}
200.201.void CButtonST::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
202.{
203. // TODO: Add your code to draw the specified item
204. DrawItem1(lpDrawItemStruct);
205. return;
206.207.
208. CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
209. CRect rect = lpDrawItemStruct->rcItem;
210. CRect offRect = rect;
211. int ndist = 2;
212. offRect.left+= ndist;
213. offRect.right -=ndist;
214. offRect.top += ndist;
215. offRect.bottom -=ndist;
216.217. CDC* pResetDC=new CDC();
218. pResetDC->CreateCompatibleDC(pDC);
219. CBitmap bitmap;
220. bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
221. pResetDC->SelectObject(&bitmap);
222.223.
224. pResetDC->SetBkMode(TRANSPARENT);
225. pResetDC->SetTextColor(m_TextColor);
226.
227. //绘制背景
228. if(m_pBitMapBK!=NULL)
229. {
230. CDC* pNewDC = new CDC;
231. pNewDC->CreateCompatibleDC(pResetDC);
232. pNewDC->SelectObject(m_pBitMapBK);
233. BITMAP bmp;
234. m_pBitMapBK->GetBitmap(&bmp);
235. if(m_IsPressed)
236. {
237. pResetDC->StretchBlt(0,0,rect.Width(),rect.Height(),pNewDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
238. }
239. else240. {
241. CBrush brush(RGB(220,220,220));//RGB(m_nShOffset,m_nShOffset,m_nShOffset)); 242. pResetDC->FillRect(&rect,&brush);
243. pResetDC->StretchBlt(0,0,rect.Width(),rect.Height(),pNewDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCAND);
244. }
245.
246. delete pNewDC;
247. pNewDC = NULL;
248. }
249. else250. {
251. if(m_IsPressed)
252. {
253. CBrush brush(OffsetColor(m_BkColor,m_nShOffset));
254. pResetDC->FillRect(rect,&brush);
255. CBrush brush1(RGB(128,128,128));
256. pResetDC->FrameRect(rect,&brush1);
257. pResetDC->FrameRect(offRect,&brush1);
258.
259. }
260. else261. {
262. CBrush brush(m_BkColor);
263. pResetDC->FillRect(rect,&brush);
264. CBrush brush1(RGB(128,128,128));
265. pResetDC->FrameRect(offRect,&brush1);
266. }
267. }
268.
269.
270. CString sTitle;
271. GetWindowText(sTitle);
272. offRect.OffsetRect(0,rect.Height()/2-8);
273.// pDC->DrawText(sTitle, sTitle.GetLength(),offRect, DT_WORDBREAK | DT_CENTER); 274. pResetDC->DrawText(sTitle, sTitle.GetLength(),offRect, DT_CENTER);
275. pDC->StretchBlt(0,0,rect.Width(),rect.Height(),pResetDC,0,0,rect.Width(),rect.Height(),SRCCOPY);
276. delete pResetDC;
277.}
278.279.void CButtonST::OnMouseMove(UINT nFlags, CPoint point)
280.{
281. // TODO: Add your message handler code here and/or call default 282. TRACKMOUSEEVENT csTME;
283. csTME.cbSize = sizeof(csTME);
284. csTME.dwFlags = TME_LEAVE;
285. csTME.hwndTrack = m_hWnd;
286. ::_TrackMouseEvent(&csTME);
287.288. if(m_IsPressed==FALSE)
289. {
290. m_IsPressed = TRUE;
291. this->Invalidate();
292. }
293.
294. CButton::OnMouseMove(nFlags, point);
295.}
296.297.BOOL CButtonST::OnNcActivate(BOOL bActive)
298.{
299. // TODO: Add your message handler code here and/or call default 300.301. return CButton::OnNcActivate(bActive);
302.}
303.304.void CButtonST::OnNcMouseMove(UINT nHitTest, CPoint point)
305.{
306. // TODO: Add your message handler code here and/or call default 307.
308.
309. CButton::OnNcMouseMove(nHitTest, point);
310.}
311.312.void CButtonST::OnKillFocus(CWnd* pNewWnd)
313.{
314. CButton::OnKillFocus(pNewWnd);
315. // TODO: Add your message handler code here 316.}
317.LRESULT CButtonST::OnMouseLeave(WPARAM wParam, LPARAM lParam)
318.{
319. m_IsPressed = FALSE;
320. this->Invalidate();
321. return 0;
322.} // End of OnMouseLeave 323.324.325.BOOL CButtonST::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
326.{
327. // TODO: Add your specialized code here and/or call the base class 328. dwStyle |= BS_OWNERDRAW;
329. return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
330.}
331.332.void CButtonST::OnLButtonDown(UINT nFlags, CPoint point)
333.{
334. // TODO: Add your message handler code here and/or call default 335.336. if(m_strURL.IsEmpty()==FALSE)
337. {
338. SHELLEXECUTEINFO csSEI;
339.
340. memset(&csSEI, 0, sizeof(csSEI));
341. csSEI.cbSize = sizeof(SHELLEXECUTEINFO);
342. csSEI.fMask = SEE_MASK_FLAG_NO_UI;
343. csSEI.lpVerb = _T("open");
344. csSEI.lpFile = m_strURL;
345. csSEI.nShow = SW_SHOWMAXIMIZED;
346. ::ShellExecuteEx(&csSEI);
347. }
348. CButton::OnLButtonDown(nFlags, point);
349.}
350.351.BOOL CButtonST::PreCreateWindow(CREATESTRUCT& cs)
352.{
353. // TODO: Add your specialized code here and/or call the base class 354.
355. return CButton::PreCreateWindow(cs);
356.}
357.358.void CButtonST::PreSubclassWindow()
359.{
360. // TODO: Add your specialized code here and/or call the base class 361. ModifyStyle(BS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED);
362. CButton::PreSubclassWindow();
363.}
本文来自CSDN博客,转载请标明出处:
展开阅读全文