在VC中使用Picture Control来放置图片时想做成透明背景的,选择Bitmap类型时是图片原样显示出来的,想做成透明的Icon然后在Picture Control中选择Icon类型,可是控件缩成了一个图标。最后只能选择Bitmap类型,因为用这种模式可以把很多图片使用多个Picture Control组合起来。
在网上找了一些资料,经过自己多方的实验,终于可以搞定。
原理是重载Picture Control,在窗体初始化时给控件设置图片ID,并去掉控件的Bitmap类型,即设置成“无”类型,然后在OnPaint方法中重画图片。
处理步骤是:
1. Picture Control仍使用Bitmap类型,选择正确的图片并布局好。
2. 在窗体初始化时给控件设置具体的图片ID。
重载的类源码.h文件:
#pragma once
class CTransparentPic : public CStatic
{
DECLARE_DYNAMIC(CTransparentPic)
public:
CTransparentPic();
virtual ~CTransparentPic();
void SetBitmapIndex(UINT nBitmapIndex);
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaint();
private:
UINT m_nBitmapIndex; // Bitmap index of resource
};
.cpp文件:
#include "stdafx.h"
#include "TransparentPic.h"
IMPLEMENT_DYNAMIC(CTransparentPic, CStatic)
CTransparentPic::CTransparentPic()
: m_nBitmapIndex(0)
{
}
CTransparentPic::~CTransparentPic()
{
}
BEGIN_MESSAGE_MAP(CTransparentPic, CStatic)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
END_MESSAGE_MAP()
void CTransparentPic::SetBitmapIndex(UINT nBitmapIndex)
{
ModifyStyle(SS_BITMAP, 0); // Remove bitmap style, use owner paint
bool bForceRedraw = (m_nBitmapIndex != nBitmapIndex);
m_nBitmapIndex = nBitmapIndex;
// Force owner paint
if (::IsWindow(m_hWnd) && bForceRedraw)
{
Invalidate();
}
}
// CTransparentPic message handlers
BOOL CTransparentPic::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CTransparentPic::OnPaint()
{
CWnd::Default(); // Calls the default window procedure
CClientDC dc(this);
CBitmap bmp;
// Try to load bitmap
if (bmp.LoadBitmap(m_nBitmapIndex))
{
CDC memDC;
memDC.CreateCompatibleDC(NULL);
CBitmap* pOldBmp = memDC.SelectObject(&bmp);
BITMAP bitmap;
bmp.GetBitmap(&bitmap);
TransparentBlt(dc.m_hDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight,
memDC.m_hDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, RGB(236, 233, 216));
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
}
else
{
// Draw error information
dc.TextOut(1, 1, _T("ERROR!"));
}
}
说明一下:上面的RGB(236, 233, 216)指的是制作图片时以该颜色值作为背景色(要改一起改),TransparentBit方法在处理时自动把这些颜色值过滤掉,看起来就是透明的。
然后给Picture Control指定一个ID,在对话框的.h文件中定义CTransparentPic对象:
CTransparentPic m_ctrlPic1;
接着在对话框.cpp文件的DoDataExchange方法CDialog::DoDataExchange之后加一项完成关联:
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BITMAP1, m_ctrlPic1);
最后在对话框的OnInitDialog加一项设置图片ID项:
m_ctrlPic1.SetBitmapIndex(IDB_BITMAP1);