I’m going to describe the way to make a transparent picture box control in MFC (Smart Device application). It worked well on Windows CE, and it should be fine on Win32 application.
The key function is TransparentImage. Using it, you will see that the job is pretty simple…
I called my class CPictureEx, which derived from CStatic.
#pragma once
// CPictureEx
class CPictureEx : public CStatic
{
DECLARE_DYNAMIC(CPictureEx)
INT m_iPicStyle;
COLORREF m_colorTransparent;
COLORREF m_colorBkgrnd;
public:
enum PIC_STYLE
{
PICSTYLE_NORMAL = 0,
PICSTYLE_CENTER = 1,
PICSTYLE_STRETCH = 2
};
CPictureEx();
virtual ~CPictureEx();
protected:
DECLARE_MESSAGE_MAP()
public:
void SetTransparentColor(COLORREF color);
COLORREF GetTransparentColor();
void SetBkColor(COLORREF color);
COLORREF GetBkColor();
void SetPictureStyle(INT style);
INT GetPictureStyle();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaint();
};
And this is in PictureEx.cpp:
// PictureEx.cpp : implementation file
//
#include "stdafx.h"
#include "PictureEx.h"
// CPictureEx
IMPLEMENT_DYNAMIC(CPictureEx, CStatic)
CPictureEx::CPictureEx()
{
m_iPicStyle = PICSTYLE_CENTER;
m_colorBkgrnd = m_colorTransparent = RGB(0, 0, 0);
}
CPictureEx::~CPictureEx()
{
}
BEGIN_MESSAGE_MAP(CPictureEx, CStatic)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
END_MESSAGE_MAP()
void CPictureEx::SetTransparentColor(COLORREF color)
{
m_colorTransparent = color;
Invalidate();
}
COLORREF CPictureEx::GetTransparentColor()
{
return m_colorTransparent;
}
void CPictureEx::SetBkColor(COLORREF color)
{
m_colorBkgrnd = color;
Invalidate();
}
COLORREF CPictureEx::GetBkColor()
{
return m_colorBkgrnd;
}
void CPictureEx::SetPictureStyle(INT style)
{
m_iPicStyle = style;
Invalidate();
}
INT CPictureEx::GetPictureStyle()
{
return m_iPicStyle;
}
// CPictureEx message handlers
BOOL CPictureEx::OnEraseBkgnd(CDC* pDC)
{
if(GetBitmap())
{
return TRUE;
}
return CStatic::OnEraseBkgnd(pDC);
}
void CPictureEx::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rClient;
this->GetClientRect(&rClient);
// background
CBrush* br = new CBrush(m_colorBkgrnd);
dc.FillRect(rClient, br);
delete br;
// image
HBITMAP hBmp = this->GetBitmap();
BITMAP bmpObj;
if(hBmp && GetObject(hBmp, sizeof(BITMAP), &bmpObj))
{
INT x, y, w, h;
switch(m_iPicStyle)
{
case PICSTYLE_NORMAL:
x = y = 0;
w = bmpObj.bmWidth;
h = bmpObj.bmHeight;
break;
case PICSTYLE_CENTER:
w = bmpObj.bmWidth;
h = bmpObj.bmHeight;
x = rClient.Width() / 2 - w/2;
y = rClient.Height() / 2 - h/2;
break;
case PICSTYLE_STRETCH:
x = y = 0;
w = rClient.Width();
h = rClient.Height();
break;
}
::TransparentImage(dc, x, y, w, h, hBmp, 0, 0, bmpObj.bmWidth, bmpObj.bmHeight, m_colorTransparent);
}
}