1、这是一个实现自绘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.#e
2、ndif // _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.
3、 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
4、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,
5、 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()
6、 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 OnNcMouse
7、Move(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
8、 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./////////////////////
9、//////////////////////////////////////////////////////// 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.// Bu
10、ttonST.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.//////////////////////////////////////
11、/////////////////////////////////////// 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::~CBu
12、ttonST() 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() 4
13、3. 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::
14、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 TextCol
15、or) 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.
16、 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
17、 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 specifi
18、ed 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 (byGr
19、een + 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; 12
20、0. 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
21、 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
22、 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
23、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_
24、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->Fill
25、Rect(&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.
26、 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.
27、 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. GetWindowTe
28、xt(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
29、 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; 21
30、1. 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,re
31、ct.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->Cr
32、eateCompatibleDC(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,SRCCO
33、PY); 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,S
34、RCAND); 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);
35、 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->FillRe
36、ct(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(sT
37、itle, 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::
38、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)
39、 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 co
40、de 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, poin
41、t); 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->Invalidat
42、e(); 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
43、 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 3
44、35.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.
45、 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 a
46、nd/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博客,转载请标明出处:






