关于cstatic控件的自绘,网上也有很多的代码及文章,更有其界面画得很漂亮的、多种多样的功能。近来我自行封装实现了一个真彩色静态框类,目标初衷是从颜色、字体、光标入手,改变原始标准cstatic的色彩风格,使界面初步美化,具有好看的效果。同时作为一个基础简单的类来维护,为后续的功能增强及美化提供参考扩展,这个CColorStatic类的特点及功能如下:
(1)文本、文本背景、控件背景的颜色,支持3种状态(正常时、鼠标在上、鼠标按下)下不同颜色的设定,具体实现使用了掩码机制,形如SetXXXColor名称的函数接口,每种函数对不同状态下颜色的设定是很灵活的。
(2)字体设定,提供粗体、斜体、下划线基本属性,能调整字体名称和大小。
(3)光标设定,支持自定义光标(资源ID或名称)、系统光标。具体实现使用带LR_SHARED标志的LoadImage来装载光标,因此对于共享光标不能调用DestroyCursor销毁,也不必在这里销毁。
(4)透明设定,支持文本背景和控件背景的透明。
(5)只是绘制文本(凡和文本有关的样式都考虑进该类中实现),不考虑边框、形状及图形图像的绘制。
(6)绘制工作在WM_PAINT而非WM_CTLCOLOR消息中实现。
实现效果如下截图,从左到右依次是正常、鼠标在上、鼠标按下、文本背景透明、控件背景透明5种情况。
下面来看看该类的接口代码,如下所示
1class CColorStatic : public CStatic
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}; 类的方法接口,就不多讲了,因为很简单。最后列出它的实现代码,如下所示
1IMPLEMENT_DYNAMIC(CColorStatic, CStatic)
2
3CColorStatic::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
19CColorStatic::~CColorStatic()
20{
21 if (m_dcBk.m_hDC && m_pbmpOldBk)
22 m_dcBk.SelectObject(m_pbmpOldBk);
23}
24
25BEGIN_MESSAGE_MAP(CColorStatic, CStatic)
26 ON_CONTROL_REFLECT_EX(STN_CLICKED,OnStnClicked)
27 ON_WM_MOUSEMOVE()
28 ON_WM_PAINT()
29 ON_WM_SETCURSOR()
30END_MESSAGE_MAP()
31
32void 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
42void 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
52void 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
62void 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
72void 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
82void 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
92BOOL 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
102BOOL 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
112BOOL 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
122BOOL 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
130BOOL 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
139BOOL 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
152void CColorStatic::SetTextBkTransparent(BOOL bTransparent)
153{
154 m_bTextBkTransparent = bTransparent;
155 RedrawWindow();
156}
157
158void CColorStatic::SetBkTransparent(BOOL bTransparent)
159{
160 m_bBkTransparent = bTransparent;
161 RedrawWindow();
162}
163
164BOOL CColorStatic::SetCursor(UINT uID)
165{
166 return SetCursor(MAKEINTRESOURCE(uID));
167}
168
169BOOL 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/**///////////////////////////////////////////////////////////////////////////177void 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/**///////////////////////////////////////////////////////////////////////////199BOOL CColorStatic::OnStnClicked()
200{
201 m_bPressed = TRUE;
202 RedrawWindow();
203 return FALSE;
204}
205
206void 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
229BOOL 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
239void 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
258void 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
269void 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
281void 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
298void 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
328void 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}
posted on 2011-12-18 00:54
春秋十二月 阅读(3717)
评论(1) 编辑 收藏 引用 所属分类:
C/C++