自定义彩色static text控件类,如何设置控件背景透明

自定义彩色static text控件类,怎么设置控件背景透明
不是设置文字的背景透明,请看代码

.h文件
C/C++ code

#pragma once

// CColorStatic
class CColorStatic : public CStatic
{
    DECLARE_DYNAMIC(CColorStatic)

public:
    CColorStatic();
    virtual ~CColorStatic();
    afx_msg HBRUSH CtlColor( CDC* pDC, UINT nCtlColor );

    void SetTextColor( COLORREF crText );
    void SetTransparent( bool bTran );
    void SetBackColor( COLORREF crBackColor );

protected:
    DECLARE_MESSAGE_MAP()

    COLORREF    m_crTextColor;
    COLORREF    m_crBackColor;
    HBRUSH        m_hBrush;            
    bool        m_bTran;
};




cpp文件
C/C++ code

#include "stdafx.h"
#include "test.h"
#include "ColorStatic.h"


// CColorStatic

IMPLEMENT_DYNAMIC(CColorStatic, CStatic)

CColorStatic::CColorStatic()
    : m_bTran(0)
    , m_crTextColor( RGB( 0, 0, 0 ) )
    , m_crBackColor( RGB( 240, 240, 240 ) )
{

}

CColorStatic::~CColorStatic()
{
}


BEGIN_MESSAGE_MAP( CColorStatic, CStatic )
    ON_WM_CTLCOLOR_REFLECT()
END_MESSAGE_MAP()

// CColorStatic message handlers


HBRUSH CColorStatic::CtlColor( CDC* pDC, UINT nCtlColor )  
{
    if (CTLCOLOR_STATIC == nCtlColor)      
    {        
        pDC->SetTextColor( m_crTextColor ); 
        pDC->SetBkColor( m_crBackColor );
        if (m_bTran == true)             
            pDC->SetBkMode(TRANSPARENT); 
    }      
    return m_hBrush;
}

void CColorStatic::SetTextColor( COLORREF crText )  
{      
    m_crTextColor = crText;
    RedrawWindow();  
}  

void CColorStatic::SetTransparent( bool bTran )  
{      
    m_bTran = bTran;
    RedrawWindow();  
}  

void CColorStatic::SetBackColor( COLORREF crBackColor )  
{      
    m_crBackColor = crBackColor;      
    RedrawWindow();  
}  


SetBackColor,还有SetTransparent,都只能改变文字的背景,不能改变控件的背景。

SetTransparent 之后,只是文字的背景透明了,但是控件的背景一直是白色不透明的,如果控件拖很大的话会有很大一片白色。
在属性里面设置Transparent也是不行的。

怎么让控件背景透明?


------解决方案--------------------
C/C++ code

#include "stdafx.h"
#include "TStatic.h"
#include ".\tstatic.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// TStatic

TStatic::TStatic()
{
    m_crText = GetSysColor(COLOR_WINDOWTEXT);
    m_hBackBrush = NULL;
    ::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(m_lf),&m_lf);
    m_font.CreateFontIndirect(&m_lf);
    m_bTimer =            FALSE;
    m_bState =            FALSE;
    m_bTransparent =    FALSE;
    m_bLink =            TRUE;
    m_hCursor =            NULL;
    m_Type =            None;
    m_bFont3d =            FALSE;
    m_bNotifyParent =    FALSE;
    m_bToolTips =        FALSE;
    m_bRotation =        FALSE;
    m_bHover    =        FALSE;
    m_isLinkWord =        FALSE;
    m_bHotTrack =        FALSE;
    m_cr3DHiliteColor =    RGB(255,255,255);    
    m_hwndBrush = ::CreateSolidBrush(RGB(255,255,255));

}

TStatic::~TStatic()
{
    m_font.DeleteObject();
    ::DeleteObject(m_hwndBrush);
    ::DeleteObject(m_hBackBrush);    
    ::DeleteObject(m_hCursor);
    OutputDebugString("Clear Static text:");
    CString strText;
    GetWindowText(strText);
    OutputDebugString(strText);
    OutputDebugString("\n");
}


BEGIN_MESSAGE_MAP(TStatic, CStatic)
    //{{AFX_MSG_MAP(TStatic)
    ON_WM_MOUSEMOVE()
    ON_WM_SETCURSOR()
    ON_WM_SYSCOLORCHANGE()
    //}}AFX_MSG_MAP
    ON_MESSAGE(WM_MOUSEHOVER,OnMouseHover)
    ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
    ON_WM_PAINT()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// TStatic message handlers


void TStatic::ReconstructFont()
{
    m_font.DeleteObject();
    BOOL bCreated = m_font.CreateFontIndirect(&m_lf);

    ASSERT(bCreated);
}

void TStatic::OnMouseMove(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    //SetWindowText("鼠标进入");
    TRACKMOUSEEVENT tme; 
    tme.cbSize = sizeof(tme); 
    tme.hwndTrack = m_hWnd; 
    tme.dwFlags = TME_LEAVE | TME_HOVER; 
    tme.dwHoverTime = 1; 
    _TrackMouseEvent(&tme); 
    if (m_bHover) // Cursor is currently over control    
    {         
        CRect rect;        
        GetClientRect(rect);        
        if (!rect.PtInRect(point))        
        {             
            m_bHover = FALSE;            
            this->Invalidate();            
            ::ReleaseCapture();         
        }     
    }    
    else   // Cursor has just moved over control    
    {         
        m_bHover = TRUE;        
        this->Invalidate();        
        this->SetCapture();        
        if (m_bHotTrack)            
            ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(32649)));
    }
    CStatic::OnMouseMove(nFlags, point);
}

HRESULT TStatic::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
    if (m_isLinkWord)
    {
        //绘制字体颜色
        m_crText = RGB(0,0,0);
        Invalidate();
    }
    return S_OK;
}
HRESULT TStatic::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
    if (m_isLinkWord)
    {
        //绘制字体颜色
        m_crText = RGB(0,0,255);
        Invalidate();
    }
    return S_OK;
}

void TStatic::SetLinkWord(BOOL isLinkWord)
{
    m_isLinkWord = isLinkWord;
    if (m_isLinkWord)
    {
        m_crText = RGB(0,0,255);
        Invalidate();
    }
}
void TStatic::OnPaint()
{
    CPaintDC dc(this); // device context for painting

    DWORD dwFlags = 0;

    CRect rc;
    GetClientRect(rc);
    CString strText;
    GetWindowText(strText);
    CBitmap bmp;

    // Set up for double buffering...
    CDC* pDCMem;

    if (!m_bTransparent)
    {
        pDCMem = new CDC;
        pDCMem->CreateCompatibleDC(&dc);
        bmp.CreateCompatibleBitmap(&dc,rc.Width(),rc.Height());
        pDCMem->SelectObject(&bmp);
    }
    else
    {
        pDCMem = GetDC();
    }

    UINT nMode = pDCMem->SetBkMode(TRANSPARENT);

    COLORREF crText = pDCMem->SetTextColor(m_crText);
    CFont *pOldFont = pDCMem->SelectObject(&m_font);

    // Fill in backgound if not transparent
    if (!m_bTransparent)
    {
        CBrush br;

        if (m_bState && m_Type == Background)
        {
            if (m_hBackBrush != NULL)
                br.Attach(m_hBackBrush);
            else
                br.Attach(m_hwndBrush);
        }
        else
        {
            if (m_hBackBrush != NULL)
                br.Attach(m_hBackBrush);
            else
                br.Attach(m_hwndBrush);
        }

        pDCMem->FillRect(rc,&br);
        br.Detach();
        br.DeleteObject();
    }

    // If the text is flashing turn the text color on
    // then to the color of the window background.

    LOGBRUSH lb;
    ZeroMemory(&lb,sizeof(lb));
    ::GetObject(m_hBackBrush,sizeof(lb),&lb);

    // Something to do with flashing
    if (!m_bState && m_Type == Text)
        pDCMem->SetTextColor(lb.lbColor);

    if (!(GetStyle() & SS_LEFTNOWORDWRAP))
        dwFlags |= DT_WORDBREAK;

    if (GetStyle() & SS_LEFT)
        dwFlags = DT_LEFT;

    if (GetStyle() & SS_RIGHT)
        dwFlags = DT_RIGHT;

    if (GetStyle() & SS_CENTER)
        dwFlags = DT_CENTER;

    // If the text centered make an assumtion that
    // the will want to center verticly as well
    if (GetStyle() & SS_CENTERIMAGE)
    {
        dwFlags = DT_CENTER;

        // Apply 
        if (strText.Find("\r\n") == -1)
        {
            dwFlags |= DT_VCENTER;
            // And because DT_VCENTER only works with single lines
            dwFlags |= DT_SINGLELINE; 
        }
    }

    // 3D旋转效果
    if (m_bRotation)
    {
        int nAlign = pDCMem->SetTextAlign (TA_BASELINE);

        CPoint pt;
        GetViewportOrgEx (pDCMem->m_hDC,&pt) ;
        SetViewportOrgEx (pDCMem->m_hDC,rc.Width() / 2, rc.Height() / 2, NULL) ;
        pDCMem->TextOut (0, 0, strText) ;
        SetViewportOrgEx (pDCMem->m_hDC,pt.x / 2, pt.y / 2, NULL) ;
        pDCMem->SetTextAlign (nAlign);
    }
    else
    {
        pDCMem->DrawText(strText,rc,dwFlags);
        if (m_bFont3d)
        {
            pDCMem->SetTextColor(m_cr3DHiliteColor);

            if (m_3dType == Raised)
                rc.OffsetRect(-1,-1);
            else
                rc.OffsetRect(1,1);

            pDCMem->DrawText(strText,rc,dwFlags);
        }
    }

    // Restore DC's State
    pDCMem->SetBkMode(nMode);
    pDCMem->SelectObject(pOldFont);
    pDCMem->SetTextColor(crText);



    if (!m_bTransparent)
    {
        dc.BitBlt(0,0,rc.Width(),rc.Height(),pDCMem,0,0,SRCCOPY);
        pDCMem->DeleteDC();
        delete pDCMem;
        bmp.DeleteObject();
        return;
    }
    bmp.DeleteObject();
    ReleaseDC(pDCMem);
}

BOOL TStatic::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
    if (m_hCursor)
    {
        ::SetCursor(m_hCursor);
        return TRUE;
    }
    return CStatic::OnSetCursor(pWnd, nHitTest, message);
}


TStatic& TStatic::SetText(const CString& strText)
{
    SetWindowText(strText);
    Invalidate(FALSE);

    return *this;
}


TStatic& TStatic::SetTextColor(COLORREF crText)
{
    m_crText = crText;
    RedrawWindow();
    return *this;
}


TStatic& TStatic::SetFontBold(BOOL bBold)
{
    m_lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
    ReconstructFont();
    RedrawWindow();
    return *this;
}


TStatic& TStatic::SetFontUnderline(BOOL bSet)
{    
    m_lf.lfUnderline = bSet;
    ReconstructFont();
    RedrawWindow();
    return *this;
}


TStatic& TStatic::SetFontItalic(BOOL bSet)
{
    m_lf.lfItalic = bSet;
    ReconstructFont();
    RedrawWindow();
    return *this;    
}


TStatic& TStatic::SetSunken(BOOL bSet)
{
    if (!bSet)
        ModifyStyleEx(WS_EX_STATICEDGE,0,SWP_DRAWFRAME);
    else
        ModifyStyleEx(0,WS_EX_STATICEDGE,SWP_DRAWFRAME);        
    return *this;    
}

TStatic& TStatic::SetBorder(BOOL bSet)
{
    if (!bSet)
        ModifyStyle(WS_BORDER,0,SWP_DRAWFRAME);
    else
        ModifyStyle(0,WS_BORDER,SWP_DRAWFRAME);        
    return *this;    
}

TStatic& TStatic::SetFontSize(int nSize)
{
    CFont cf;
    LOGFONT lf;

    cf.CreatePointFont(nSize * 10, m_lf.lfFaceName);
    cf.GetLogFont(&lf);
    m_lf.lfHeight = lf.lfHeight;
    m_lf.lfWidth  = lf.lfWidth;
    ReconstructFont();
    RedrawWindow();
    return *this;
}

TStatic& TStatic::SetBkColor(COLORREF crBkgnd)
{
    if (m_hBackBrush)
        ::DeleteObject(m_hBackBrush);    
    m_hBackBrush = ::CreateSolidBrush(crBkgnd);
    Invalidate(FALSE);
    return *this;
}

TStatic& TStatic::SetFontName(const CString& strFont)
{    
    strcpy(m_lf.lfFaceName,strFont);
    ReconstructFont();
    RedrawWindow();
    return *this;
}

TStatic& TStatic::FlashText(BOOL bActivate)
{
    if (m_bTimer)
        KillTimer(1);

    if (bActivate)
    {
        m_bState = FALSE;        
        m_bTimer = TRUE;        
        SetTimer(1,500,NULL);
        m_Type = Text;
    }
    else
        m_Type = None;
    return *this;
}

TStatic& TStatic::FlashBackground(BOOL bActivate)
{
    if (m_bTimer)
        KillTimer(1);

    if (bActivate)
    {
        m_bState = FALSE;
        m_bTimer = TRUE;
        SetTimer(1,500,NULL);
        m_Type = Background;
    }
    return *this;
}

TStatic& TStatic::SetLink(BOOL bLink,BOOL bNotifyParent)
{

    m_bLink = bLink;
    m_bNotifyParent = bNotifyParent;

    if (bLink)
        ModifyStyle(0,SS_NOTIFY);
    else
        ModifyStyle(SS_NOTIFY,0);

    return *this;
}

TStatic& TStatic::SetLinkCursor(HCURSOR hCursor)
{

    m_hCursor = hCursor;
    return *this;
}

TStatic& TStatic::SetTransparent(BOOL bSet)
{

    m_bTransparent = bSet;
    ModifyStyleEx(0,WS_EX_TRANSPARENT);
    InvalidateRect(NULL,TRUE);
    UpdateWindow();
    return *this;
}

TStatic& TStatic::SetFont3D(BOOL bSet,Type3D type)
{
    m_bFont3d = bSet;
    m_3dType = type;
    RedrawWindow();
    return *this;
}

void TStatic::OnSysColorChange() 
{
    if (m_hwndBrush)
        ::DeleteObject(m_hwndBrush);
    m_hwndBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DFACE));    
    RedrawWindow();        
}

TStatic& TStatic::SetRotationAngle(UINT nAngle,BOOL bRotation)
{
    m_lf.lfEscapement = m_lf.lfOrientation = (nAngle * 10);
    m_bRotation = bRotation;    
    ReconstructFont();    
    RedrawWindow();
    return *this;
}

TStatic& TStatic::SetText3DHiliteColor(COLORREF cr3DHiliteColor)
{
    m_cr3DHiliteColor = cr3DHiliteColor;
    RedrawWindow();
    return *this;
}
void TStatic::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_crText = RGB(255,0,0);
    Invalidate(TRUE);
    CStatic::OnLButtonDown(nFlags, point);
}

void TStatic::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_crText = RGB(0,0,255);
    Invalidate(TRUE);
    CStatic::OnLButtonUp(nFlags, point);
}