Click here to Skip to main content
15,888,579 members
Articles / Desktop Programming / MFC
Article

CEdit & CStatic Transparency Control

Rate me:
Please Sign up or sign in to vote.
4.58/5 (24 votes)
6 Oct 2001CPOL 202K   9K   67   30
This acticle explain how to apply transparency on CEdit and CStatic Controls

Sample Image - CtrlTrans.gif

Introduction

To apply transparency on CEdit control, create a new class derived from CEdit control and simply add these members.

In the new class .h file add.

// Attributes
private:
    COLORREF    m_TextColor;
    COLORREF    m_BackColor;
    CBrush        m_Brush;
    // Operations
public:
    void SetTextColor(COLORREF col) 
    { 
        m_TextColor = col;
        UpdateCtrl();             
    }
    void SetBackColor(COLORREF col) 
    { 
        m_BackColor = col;                                                   
        UpdateCtrl();            
    }
private:
    void UpdateCtrl();
    // Generated message map functions
protected:
    //{{AFX_MSG(CEditTrans)
    afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
    afx_msg void OnUpdate();
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnKillfocus();
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()

In the new class .cpp file add.

CEditTrans::CEditTrans()
{
    m_TextColor  = RGB(0, 0, 0);
    m_BackColor = TRANS_BACK;
}
BEGIN_MESSAGE_MAP(CEditTrans, CEdit)
    //{{AFX_MSG_MAP(CEditTrans)
    ON_WM_CTLCOLOR_REFLECT()
    ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
    ON_WM_LBUTTONDOWN()
    ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

HBRUSH CEditTrans::CtlColor(CDC* pDC, UINT nCtlColor) 
{
    m_Brush.DeleteObject();

    if (m_BackColor == TRANS_BACK) {
        m_Brush.CreateStockObject(HOLLOW_BRUSH);
        pDC->SetBkMode(TRANSPARENT);
    }
    else {
        m_Brush.CreateSolidBrush(m_BackColor);
        pDC->SetBkColor(m_BackColor);
    }

    pDC->SetTextColor(m_TextColor);

    return (HBRUSH)m_Brush;
}

void CEditTrans::OnUpdate() 
{
    UpdateCtrl();
}
void CEditTrans::UpdateCtrl()
{
    CWnd* pParent = GetParent();
    CRect   rect;

    GetWindowRect(rect);
    pParent->ScreenToClient(rect);
    rect.DeflateRect(2, 2);

    pParent->InvalidateRect(rect, FALSE); 
}

Implementation of the class

#include "EditTrans.h"

//Derived control from ClassWizard
CEditTrans m_edtTrans; 

//To make transparency
m_edtTrans.SetBackColor(TRANS_BACK); 

That all. Enjoy!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO
Canada Canada

Comments and Discussions

 
Generalthis doesn't work on Windows2000 Server Familiy Pin
anonymous119-Aug-02 23:40
anonymous119-Aug-02 23:40 
Generalthis doesn't work on WindowsXP Pin
alkee23-Jul-02 22:54
alkee23-Jul-02 22:54 
GeneralRe: this doesn't work on WindowsXP Pin
Anonymous25-Jul-02 11:23
Anonymous25-Jul-02 11:23 
GeneralRe: this doesn't work on WindowsXP Pin
Magetek21-Jan-03 5:39
Magetek21-Jan-03 5:39 
GeneralRe: this doesn't work on WindowsXP Pin
brdavid22-Jul-04 16:50
brdavid22-Jul-04 16:50 
GeneralRe: this doesn't work on WindowsXP Pin
wahahawb130-Aug-04 21:52
wahahawb130-Aug-04 21:52 
GeneralRe: this doesn't work on WindowsXP Pin
hsctim26-Sep-04 12:17
hsctim26-Sep-04 12:17 
GeneralVery very good. Pin
Jose Reyes22-Jul-02 9:35
Jose Reyes22-Jul-02 9:35 
This classes work very good. However, we found a small detail in the redrawing of the edit if we change the selected text using the keyboard (Shift with movement keys). In this case, the background remains blue without the redrawing. A posible solution could be capturing the OnKeyDown event and calling the UpdateCtrl method. Something like:

void CTransEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ( nChar == VK_PRIOR || nChar == VK_NEXT ||
nChar == VK_END || nChar == VK_HOME ||
nChar == VK_LEFT || nChar == VK_UP ||
nChar == VK_RIGHT || nChar == VK_DOWN )
{
UpdateCtrl();
}
CEdit::OnKeyUp( nChar, nRepCnt, nFlags );
}

Another different approach could be if we use a pattern brush with a bitmap which duplicate the drawing on the parent window. The code for the CtlColor message will look like:

HBRUSH CTransEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
m_Brush.DeleteObject();

if ( m_BackColor == TRANS_BACK )
{
m_Brush.CreatePatternBrush( &m_Background );
m_Brush.UnrealizeObject();

pDC->SelectObject( &m_Brush );

pDC->SetBrushOrg( 0, 0 );

pDC->SetBkMode(TRANSPARENT);
else
{
m_Brush.CreateSolidBrush( m_BackColor );
}

return m_Brush;
}

To create the background bitmap we can use a code like the above:
(The rectangle "pos" is the position of the editor inside the parent window. We assume here that we have the bitmap m_drawBmp in the parent window, with the whole window content in it).

void CTransEdit::PrepareBackground( CRect pos )
{
ASSERT_VALID( m_pView );

CClientDC thisDC( this );
CBitmap* pOldThisBmp;
CDC thisMem;

CClientDC viewDC( m_pView );
CBitmap* pOldViewBmp;
CDC viewMem;

m_Background.DeleteObject();
m_Background.CreateCompatibleBitmap( &thisDC, pos.Size().cx, pos.Size().cy );

thisMem.CreateCompatibleDC( &thisDC );
pOldThisBmp = thisMem.SelectObject( &m_Background );

viewMem.CreateCompatibleDC( &viewDC );
pOldViewBmp = viewMem.SelectObject( &m_pView->m_drawBmp );

thisMem.BitBlt( 0, 0, pos.Size().cx, pos.Size().cy, &viewMem, pos.left, pos.top, SRCCOPY );

thisMem.SelectObject( pOldThisBmp );
viewMem.SelectObject( pOldViewBmp );
}

Jose Reyes.
email: jreyes_97@yahoo.com
GeneralGreat!!! Pin
erehw7-Nov-01 1:33
erehw7-Nov-01 1:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.