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

下面来看看该类的接口代码,如下所示
class
CColorStatic :
public
CStatic2
{3
DECLARE_DYNAMIC(CColorStatic)4

5
enum 6
{7
COLOR_NORMAL=0,8
COLOR_HOVER,9
COLOR_PRESSED,10
COLOR_MAX_NUM11
};12
enum 13
{14
BOLD_MASK=1,15
ITALIC_MASK=2,16
UNDERLINE_MASK=417
};18

19
public:20
enum 21
{22
stateNormal=1,23
stateHover=2,24
statePressed=4,25
stateAll=726
};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() const49
{ return m_mask&BOLD_MASK; }50

51
BOOL IsItalic() const52
{ return m_mask&ITALIC_MASK; }53

54
BOOL IsUnderline() const55
{ return m_mask&UNDERLINE_MASK; }56

57
CFont* GetFont()58
{ return &m_font; }59

60
const CFont* GetFont() const61
{ 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() const69
{ 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
}
;
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
else266
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
else277
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
else290
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
else335
DrawBkColor(&dc);336

337
DrawText(&dc);338
}
引自:http://www.cppblog.com/qinqing1984/archive/2011/12/18/162318.html
本文介绍了一个自定义的静态文本控件类,通过设置颜色、字体、光标等功能,实现了界面美化并提供了基础扩展功能。
8554

被折叠的 条评论
为什么被折叠?



