关于cstatic控件的自绘,网上也有很多的代码及文章,更有其界面画得很漂亮的、多种多样的功能。近来我自行封装实现了一个真彩色静态框类,目标初衷是从颜色、字体、光标入手,改变原始标准cstatic的色彩风格,使界面初步美化,具有好看的效果。同时作为一个基础简单的类来维护,为后续的功能增强及美化提供参考扩展,这个CColorStatic类的特点及功能如下:
(1)文本、文本背景、控件背景的颜色,支持3种状态(正常时、鼠标在上、鼠标按下)下不同颜色的设定,具体实现使用了掩码机制,形如SetXXXColor名称的函数接口,每种函数对不同状态下颜色的设定是很灵活的。
(2)字体设定,提供粗体、斜体、下划线基本属性,能调整字体名称和大小。
(3)光标设定,支持自定义光标(资源ID或名称)、系统光标。具体实现使用带LR_SHARED标志的LoadImage来装载光标,因此对于共享光标不能调用DestroyCursor销毁,也不必在这里销毁。
(4)透明设定,支持文本背景和控件背景的透明。
(5)只是绘制文本(凡和文本有关的样式都考虑进该类中实现),不考虑边框、形状及图形图像的绘制。
(6)绘制工作在WM_PAINT而非WM_CTLCOLOR消息中实现。
实现效果如下截图,从左到右依次是正常、鼠标在上、鼠标按下、文本背景透明、控件背景透明5种情况。
下面来看看该类的接口代码,如下所示
2 {
3 DECLARE_DYNAMIC(CColorStatic)
4
5 enum
6 {
7 COLOR_NORMAL=0,
8 COLOR_HOVER,
9 COLOR_PRESSED,
10 COLOR_MAX_NUM
11 };
12 enum
13 {
14 BOLD_MASK=1,
15 ITALIC_MASK=2,
16 UNDERLINE_MASK=4
17 };
18
19public:
20 enum
21 {
22 stateNormal=1,
23 stateHover=2,
24 statePressed=4,
25 stateAll=7
26 };
27
28public:
29 CColorStatic();
30 virtual ~CColorStatic();
31
32public:
33 void SetTextColor(COLORREF color,UINT uStateFlag=stateAll);
34 void SetTextBkColor(COLORREF color,UINT uStateFlag=stateAll);
35 void SetBkColor(COLORREF color,UINT uStateFlag=stateAll);
36
37 void GetTextColor(COLORREF* color,UINT uStateFlag=stateAll);
38 void GetTextBkColor(COLORREF* color,UINT uStateFlag=stateAll);
39 void GetBkColor(COLORREF* color,UINT uStateFlag=stateAll);
40
41 BOOL SetBold(BOOL bBold,BOOL bRedraw=TRUE);
42 BOOL SetItalic(BOOL bItalic,BOOL bRedraw=TRUE);
43 BOOL SetUnderline(BOOL bUnderline,BOOL bRedraw=TRUE);
44 BOOL SetFont(LOGFONT& logFont,BOOL bRedraw=TRUE);
45 BOOL SetFont(CFont& font,BOOL bRedraw=TRUE);
46 BOOL SetFont(LPCTSTR lpFaceName,int nPointSize,BOOL bRedraw=TRUE);
47
48 BOOL IsBold() const
49 { return m_mask&BOLD_MASK; }
50
51 BOOL IsItalic() const
52 { return m_mask&ITALIC_MASK; }
53
54 BOOL IsUnderline() const
55 { return m_mask&UNDERLINE_MASK; }
56
57 CFont* GetFont()
58 { return &m_font; }
59
60 const CFont* GetFont() const
61 { return &m_font; }
62
63 BOOL SetCursor(LPCTSTR lpName);
64 BOOL SetCursor(UINT uID);
65 void SetCursor(HCURSOR hCursor)
66 { m_hCursor = hCursor; }
67
68 HCURSOR GetCursor() const
69 { return m_hCursor; }
70
71 void SetTextBkTransparent(BOOL bTransparent);
72 void SetBkTransparent(BOOL bTransparent);
73
74protected:
75 DECLARE_MESSAGE_MAP()
76 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
77 afx_msg void OnPaint();
78 afx_msg BOOL OnStnClicked();
79 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
80
81protected:
82 virtual void PreSubclassWindow();
83 virtual void PaintBk(CDC* pDC);
84 virtual void DrawText(CDC* pDC);
85 virtual void DrawTextColor(CDC* pDC);
86 virtual void DrawTextBkColor(CDC* pDC);
87 virtual void DrawBkColor(CDC* pDC);
88
89protected:
90 COLORREF m_crText[COLOR_MAX_NUM];
91 COLORREF m_crTextBk[COLOR_MAX_NUM];
92 COLORREF m_crBk[COLOR_MAX_NUM];
93
94 CFont m_font;
95 HCURSOR m_hCursor;
96 UINT m_mask;
97 BOOL m_bHover;
98 BOOL m_bPressed;
99 BOOL m_bTextBkTransparent;
100 BOOL m_bBkTransparent;
101
102 CDC m_dcBk;
103 CBitmap m_bmpBk;
104 CBitmap* m_pbmpOldBk;
105} ;
2
3 CColorStatic::CColorStatic()
4 :m_mask( 0 )
5 ,m_bHover(FALSE)
6 ,m_bPressed(FALSE)
7 ,m_bTextBkTransparent(FALSE)
8 ,m_bBkTransparent(FALSE)
9 ,m_hCursor(NULL)
10 {
11 for(int i=0;i<COLOR_MAX_NUM;++i)
12 {
13 m_crText[i]=GetSysColor(COLOR_BTNTEXT);
14 m_crTextBk[i]=GetSysColor(COLOR_BTNFACE);
15 m_crBk[i]=GetSysColor(COLOR_BTNFACE);
16 }
17}
18
19 CColorStatic:: ~ CColorStatic()
20 {
21 if (m_dcBk.m_hDC && m_pbmpOldBk)
22 m_dcBk.SelectObject(m_pbmpOldBk);
23}
24
25 BEGIN_MESSAGE_MAP(CColorStatic, CStatic)
26 ON_CONTROL_REFLECT_EX(STN_CLICKED,OnStnClicked)
27 ON_WM_MOUSEMOVE()
28 ON_WM_PAINT()
29 ON_WM_SETCURSOR()
30 END_MESSAGE_MAP()
31
32 void CColorStatic::SetTextColor(COLORREF color,UINT uStatusFlag)
33 {
34 if (uStatusFlag&stateNormal)
35 m_crText[COLOR_NORMAL] = color;
36 if (uStatusFlag&stateHover)
37 m_crText[COLOR_HOVER] = color;
38 if (uStatusFlag&statePressed)
39 m_crText[COLOR_PRESSED] = color;
40}
41
42 void CColorStatic::SetTextBkColor(COLORREF color,UINT uStatusFlag)
43 {
44 if (uStatusFlag&stateNormal)
45 m_crTextBk[COLOR_NORMAL] = color;
46 if (uStatusFlag&stateHover)
47 m_crTextBk[COLOR_HOVER] = color;
48 if (uStatusFlag&statePressed)
49 m_crTextBk[COLOR_PRESSED] = color;
50}
51
52 void CColorStatic::SetBkColor(COLORREF color,UINT uStatusFlag)
53 {
54 if (uStatusFlag&stateNormal)
55 m_crBk[COLOR_NORMAL] = color;
56 if (uStatusFlag&stateHover)
57 m_crBk[COLOR_HOVER] = color;
58 if (uStatusFlag&statePressed)
59 m_crBk[COLOR_PRESSED] = color;
60}
61
62 void CColorStatic::GetTextColor(COLORREF * color,UINT uStateFlag)
63 {
64 if (uStateFlag&stateNormal)
65 *color++ = m_crText[COLOR_NORMAL];
66 if (uStateFlag&stateHover)
67 *color++ = m_crText[COLOR_HOVER];
68 if (uStateFlag&statePressed)
69 *color = m_crText[COLOR_PRESSED];
70}
71
72 void CColorStatic::GetTextBkColor(COLORREF * color,UINT uStateFlag)
73 {
74 if (uStateFlag&stateNormal)
75 *color++ = m_crTextBk[COLOR_NORMAL];
76 if (uStateFlag&stateHover)
77 *color++ = m_crTextBk[COLOR_HOVER];
78 if (uStateFlag&statePressed)
79 *color = m_crTextBk[COLOR_PRESSED];
80}
81
82 void CColorStatic::GetBkColor(COLORREF * color,UINT uStateFlag)
83 {
84 if (uStateFlag&stateNormal)
85 *color++ = m_crBk[COLOR_NORMAL];
86 if (uStateFlag&stateHover)
87 *color++ = m_crBk[COLOR_HOVER];
88 if (uStateFlag&statePressed)
89 *color = m_crBk[COLOR_PRESSED];
90}
91
92 BOOL CColorStatic::SetBold(BOOL bBold,BOOL bRedraw)
93 {
94 ASSERT((HFONT)m_font);
95 bBold ? (m_mask|=BOLD_MASK):(m_mask&=~BOLD_MASK);
96 LOGFONT lf;
97 m_font.GetLogFont(&lf);
98 lf.lfWeight = (m_mask&BOLD_MASK)?FW_BOLD:FW_NORMAL;
99 return SetFont(lf,bRedraw);
100}
101
102 BOOL CColorStatic::SetItalic(BOOL bItalic,BOOL bRedraw)
103 {
104 ASSERT((HFONT)m_font);
105 bItalic ? (m_mask|=ITALIC_MASK):(m_mask&=~ITALIC_MASK);
106 LOGFONT lf;
107 m_font.GetLogFont(&lf);
108 lf.lfItalic = (m_mask&ITALIC_MASK)?TRUE:FALSE;
109 return SetFont(lf,bRedraw);
110}
111
112 BOOL CColorStatic::SetUnderline(BOOL bUnderline,BOOL bRedraw)
113 {
114 ASSERT((HFONT)m_font);
115 bUnderline ? (m_mask|=UNDERLINE_MASK):(m_mask&=~UNDERLINE_MASK);
116 LOGFONT lf;
117 m_font.GetLogFont(&lf);
118 lf.lfUnderline = (m_mask&UNDERLINE_MASK)?TRUE:FALSE;
119 return SetFont(lf,bRedraw);
120}
121
122 BOOL CColorStatic::SetFont(CFont & font,BOOL bRedraw)
123 {
124 ASSERT((HFONT)font);
125 LOGFONT lf;
126 font.GetLogFont(&lf);
127 return SetFont(lf,bRedraw);
128}
129
130 BOOL CColorStatic::SetFont(LOGFONT & logFont,BOOL bRedraw)
131 {
132 m_font.DeleteObject();
133 if (!m_font.CreateFontIndirect(&logFont))
134 return FALSE;
135 if (bRedraw) RedrawWindow();
136 return TRUE;
137}
138
139 BOOL CColorStatic::SetFont(LPCTSTR lpFaceName, int nPointSize,BOOL bRedraw)
140 {
141 ASSERT((HFONT)m_font);
142 LOGFONT lf;
143 m_font.GetLogFont(&lf);
144 if (lpFaceName)
145 {
146 _tcsncpy(lf.lfFaceName, lpFaceName, sizeof(lf.lfFaceName)/sizeof(TCHAR)-1);
147 }
148 lf.lfHeight = GetFontHeight(nPointSize);
149 return SetFont(lf, bRedraw);
150}
151
152 void CColorStatic::SetTextBkTransparent(BOOL bTransparent)
153 {
154 m_bTextBkTransparent = bTransparent;
155 RedrawWindow();
156}
157
158 void CColorStatic::SetBkTransparent(BOOL bTransparent)
159 {
160 m_bBkTransparent = bTransparent;
161 RedrawWindow();
162}
163
164 BOOL CColorStatic::SetCursor(UINT uID)
165 {
166 return SetCursor(MAKEINTRESOURCE(uID));
167}
168
169 BOOL CColorStatic::SetCursor(LPCTSTR lpName)
170 {
171 m_hCursor = (HCURSOR)::LoadImage(AfxFindResourceHandle(lpName, RT_GROUP_CURSOR),
172 lpName,IMAGE_CURSOR,0,0,LR_SHARED);
173 return NULL!=m_hCursor;
174}
175
176 //
177 void CColorStatic::PreSubclassWindow()
178 {
179 CFont* pFont = GetFont();
180 if (NULL==pFont||NULL==pFont->GetSafeHandle())
181 {
182 HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
183 if (NULL==hFont)
184 hFont = (HFONT) GetStockObject(ANSI_VAR_FONT);
185 if (hFont)
186 pFont = CFont::FromHandle(hFont);
187 }
188 ASSERT(pFont->GetSafeHandle());
189
190 LOGFONT lf;
191 pFont->GetLogFont(&lf);
192 m_font.CreateFontIndirect(&lf);
193 ModifyStyle(0,SS_NOTIFY);
194
195 CStatic::PreSubclassWindow();
196}
197
198 //
199 BOOL CColorStatic::OnStnClicked()
200 {
201 m_bPressed = TRUE;
202 RedrawWindow();
203 return FALSE;
204}
205
206 void CColorStatic::OnMouseMove(UINT nFlags, CPoint point)
207 {
208 CStatic::OnMouseMove(nFlags, point);
209
210 if (m_bHover)
211 {
212 CRect rect;
213 GetClientRect(rect);
214 if (!rect.PtInRect(point))
215 {
216 m_bPressed = m_bHover = FALSE;
217 ReleaseCapture();
218 RedrawWindow();
219 }
220 }
221 else
222 {
223 m_bHover = TRUE;
224 RedrawWindow();
225 SetCapture();
226 }
227}
228
229 BOOL CColorStatic::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message)
230 {
231 if (NULL!=m_hCursor)
232 {
233 ::SetCursor(m_hCursor);
234 return TRUE;
235 }
236 return CStatic::OnSetCursor(pWnd, nHitTest, message);
237}
238
239 void CColorStatic::PaintBk(CDC * pDC)
240 {
241 CClientDC clDC(GetParent());
242 CRect rect;
243
244 GetClientRect(rect);
245 ClientToScreen(&rect);
246 GetParent()->ScreenToClient(&rect);
247
248 if (m_dcBk.m_hDC == NULL)
249 {
250 m_dcBk.CreateCompatibleDC(&clDC);
251 m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
252 m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
253 m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect.left, rect.top, SRCCOPY);
254 }
255 pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcBk,0,0,SRCCOPY);
256}
257
258 void CColorStatic::DrawTextColor(CDC * pDC)
259 {
260 ASSERT(pDC);
261 if (m_bPressed)
262 pDC->SetTextColor(m_crText[COLOR_PRESSED]);
263 else if (m_bHover)
264 pDC->SetTextColor(m_crText[COLOR_HOVER]);
265 else
266 pDC->SetTextColor(m_crText[COLOR_NORMAL]);
267}
268
269 void CColorStatic::DrawTextBkColor(CDC * pDC)
270 {
271 ASSERT(pDC);
272 if (m_bPressed)
273 pDC->SetBkColor(m_crTextBk[COLOR_PRESSED]);
274 else if (m_bHover)
275 pDC->SetBkColor(m_crTextBk[COLOR_HOVER]);
276 else
277 pDC->SetBkColor(m_crTextBk[COLOR_NORMAL]);
278 pDC->SetBkMode(m_bTextBkTransparent?TRANSPARENT:OPAQUE);
279}
280
281 void CColorStatic::DrawBkColor(CDC * pDC)
282 {
283 ASSERT(pDC);
284 COLORREF color;
285 if (m_bPressed)
286 color = m_crBk[COLOR_PRESSED];
287 else if (m_bHover)
288 color = m_crBk[COLOR_HOVER];
289 else
290 color = m_crBk[COLOR_NORMAL];
291
292 CRect cr;
293 GetClientRect(cr);
294 CBrush brush(color);
295 pDC->FillRect(&cr, &brush);
296}
297
298 void CColorStatic::DrawText(CDC * pDC)
299 {
300 ASSERT(pDC);
301 DrawTextColor(pDC);
302 DrawTextBkColor(pDC);
303
304 CRect rect;
305 GetClientRect(rect);
306
307 CFont* pOldFont = pDC->SelectObject(&m_font);
308 CString strText;
309 GetWindowText(strText);
310
311 UINT nFormat = 0;
312 DWORD dwStyle = GetStyle();
313
314 if (dwStyle & SS_CENTER)
315 nFormat |= DT_CENTER;
316 else if (dwStyle & SS_LEFT)
317 nFormat |= DT_LEFT;
318 else if (dwStyle & SS_RIGHT)
319 nFormat |= DT_RIGHT;
320
321 if (dwStyle & SS_CENTERIMAGE)
322 nFormat |= DT_VCENTER | DT_SINGLELINE;
323
324 pDC->DrawText(strText, rect, nFormat);
325 pDC->SelectObject(pOldFont);
326}
327
328 void CColorStatic::OnPaint()
329 {
330 CPaintDC dc(this);
331
332 if (m_bBkTransparent)
333 PaintBk(&dc);
334 else
335 DrawBkColor(&dc);
336
337 DrawText(&dc);
338}
引自:http://www.cppblog.com/qinqing1984/archive/2011/12/18/162318.html