随笔-156  评论-223  文章-30  trackbacks-0
   关于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(00, 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++

评论:
# re: 真彩色静态框CColorStatic类的设计实现 2012-05-31 22:06 | zhan zhan zhan
我也写了个类似的,没那么多功能呵呵  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理