真彩色静态框CColorStatic类的设计实现
关于cstatic控件的自绘,网上也有很多的代码及文章,更有其界面画得很漂亮的、多种多样的功能。近来我自行封装实现了一个真彩色静态框类,目标初衷是从颜色、字体、光标入手,改变原始标准cstatic的色彩风格,使界面初步美化,具有好看的效果。同时作为一个基础简单的类来维护,为后续的功能增强及美化提供参考扩展,这个CColorStatic类的特点及功能如下:
(1)文本、文本背景、控件背景的颜色,支持3种状态(正常时、鼠标在上、鼠标按下)下不同颜色的设定,具体实现使用了掩码机制,形如SetXXXColor名称的函数接口,每种函数对不同状态下颜色的设定是很灵活的。
(2)字体设定,提供粗体、斜体、下划线基本属性,能调整字体名称和大小。
(3)光标设定,支持自定义光标(资源ID或名称)、系统光标。具体实现使用带LR_SHARED标志的LoadImage来装载光标,因此对于共享光标不能调用DestroyCursor销毁,也不必在这里销毁。
(4)透明设定,支持文本背景和控件背景的透明。
(5)只是绘制文本(凡和文本有关的样式都考虑进该类中实现),不考虑边框、形状及图形图像的绘制。
(6)绘制工作在WM_PAINT而非WM_CTLCOLOR消息中实现。
实现效果如下截图,从左到右依次是正常、鼠标在上、鼠标按下、文本背景透明、控件背景透明5种情况。





下面来看看该类的接口代码,如下所示
1
class
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
19
public:
20
enum
21
{
22
stateNormal=1,
23
stateHover=2,
24
statePressed=4,
25
stateAll=7
26
};
27
28
public:
29
CColorStatic();
30
virtual ~CColorStatic();
31
32
public:
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
74
protected:
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
81
protected:
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
89
protected:
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

4

5

6



7

8

9

10

11

12

13



14

15

16

17

18

19

20

21



22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49



50

51

52



53

54

55



56

57

58



59

60

61



62

63

64

65

66



67

68

69



70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

1
IMPLEMENT_DYNAMIC(CColorStatic, CStatic)
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
}

2

3

4

5

6

7

8

9

10



11

12



13

14

15

16

17

18

19

20



21

22

23

24

25

26

27

28

29

30

31

32

33



34

35

36

37

38

39

40

41

42

43



44

45

46

47

48

49

50

51

52

53



54

55

56

57

58

59

60

61

62

63



64

65

66

67

68

69

70

71

72

73



74

75

76

77

78

79

80

81

82

83



84

85

86

87

88

89

90

91

92

93



94

95

96

97

98

99

100

101

102

103



104

105

106

107

108

109

110

111

112

113



114

115

116

117

118

119

120

121

122

123



124

125

126

127

128

129

130

131



132

133

134

135

136

137

138

139

140



141

142

143

144

145



146

147

148

149

150

151

152

153



154

155

156

157

158

159



160

161

162

163

164

165



166

167

168

169

170



171

172

173

174

175

176


177

178



179

180

181



182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198


199

200



201

202

203

204

205

206

207



208

209

210

211



212

213

214

215



216

217

218

219

220

221

222



223

224

225

226

227

228

229

230



231

232



233

234

235

236

237

238

239

240



241

242

243

244

245

246

247

248

249



250

251

252

253

254

255

256

257

258

259



260

261

262

263

264

265

266

267

268

269

270



271

272

273

274

275

276

277

278

279

280

281

282



283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299



300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329



330

331

332

333

334

335

336

337

338
