VC(MFC)在工具栏中使用PNG图片

--------------------------------------------------------------------------------------------------------

本文转自http://hi.baidu.com/adoblog/item/a9961905d031f6f0a1103472

--------------------------------------------------------------------------------------------------------

 

MFC的CToolBar类中对图标的处理仅提供了三个函数:SetImageList()、 SetHotImageList()和SetDisabledImageList()。对于图像的透明,也仅支持镂空效果,即要么图标显示前景,要么显示背景。而PNG图像中的半透明效果、边缘羽化后的效果均无法表现。CToolBar没有提供图标自画功能,如何实现更漂亮的ToolBar呢?
     答案就是:自已画!
     虽然CToolBar没有提供自画方法,但使用它提供的三个函数,我们仍可以把自己画的内容应用到CToolBar上。
     我们先按ToolBar上图标的大小创建一个位图,然后用系统的颜色画上背景,再使用GDI+的函数把PNG画到到位图中,最后使用生成的位图生成CImgList,再使用CToolBar的三个函数把新的CImgList传给CToolBar,这样,一个使用带有半透明效果的ToolBar就出现了。
     CImageToolBar从CToolBar继承,源代码如下
ImageToolBar.h
class CImageToolBar : public CToolBar
{
DECLARE_DYNAMIC(CImageToolBar)
public:
ULONG_PTR            gdiplusToken;
CImageToolBar();
virtual ~CImageToolBar();
enum SET_ERR { SUCCESS = 0, RESOURCE_ERR, TOOBAR_ERR, SIZE_ERR, ERR };
int SetImage(const char * imgPath);
int SetImage(int sourceId);
int SetImage(HBITMAP h_bmp);
int RefreshImg();
protected:
Image * m_pImage;
void ColorReplace(CBitmap & bmpImg, COLORREF from, COLORREF to);
int GetButtonCount();
void GetButtonImgSize(CSize & size);
void GetToolImgRect(CRect & imgRect);
virtual void DrawBarImg(CBitmap & bmpImg);
virtual void RendHotImg(CBitmap & bmpImg);
virtual void RendDisableImg(CBitmap & bmpImg);
protected:
DECLARE_MESSAGE_MAP()
public:
};
ImageToolBar.cpp
IMPLEMENT_DYNAMIC(CImageToolBar, CToolBar)
CImageToolBar::CImageToolBar()
{
m_pImage = NULL;
    GdiplusStartupInput gdiplusStartupInput;
   
    // Initialize GDI+.
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}
CImageToolBar::~CImageToolBar()
{
if (m_pImage!=NULL)
   delete m_pImage;
GdiplusShutdown(gdiplusToken);
}

BEGIN_MESSAGE_MAP(CImageToolBar, CToolBar)
END_MESSAGE_MAP()

// CImageToolBar 消息处理程序
int CImageToolBar::SetImage(const char * imgPath)
{
if (m_pImage!=NULL)
   delete m_pImage;
m_pImage = Image::FromFile(CStringW(imgPath));
if (m_pImage == NULL)
   return RESOURCE_ERR;
return RefreshImg();
}
int CImageToolBar::SetImage(int sourceId)
{
CBitmap   bitmap;
if (bitmap.LoadBitmap(sourceId))
   return SetImage(bitmap);
return RESOURCE_ERR;
}
int CImageToolBar::SetImage(HBITMAP h_bmp )
{
if (m_pImage!=NULL)
   delete m_pImage;
m_pImage = Bitmap::FromHBITMAP(h_bmp,NULL);
if (m_pImage == NULL)
   return RESOURCE_ERR;
return RefreshImg();
}
int CImageToolBar::RefreshImg()
{
if (m_hWnd == NULL)
   return TOOBAR_ERR;
CToolBarCtrl& ToolBarCtrl = GetToolBarCtrl();
CSize ButtonSize;
GetButtonImgSize(ButtonSize);
CBitmap BmpBack;
CRect BKRect;
GetToolImgRect(BKRect);
CDC * pWndDC = GetWindowDC();
BmpBack.CreateCompatibleBitmap(pWndDC, BKRect.Width(), BKRect.Height());
ReleaseDC(pWndDC);
CImageList ImgList;

{ // normal
   DrawBarImg(BmpBack);
  
   ImgList.Create(ButtonSize.cx, ButtonSize.cy, ILC_COLORDDB ¦ ILC_MASK, 1, 1);
   ImgList.Add(&BmpBack, RGB(0,0,0) );
  
   ToolBarCtrl.SetImageList(&ImgList);
   ImgList.Detach();
}
{ // hot
   DrawBarImg(BmpBack);
   RendHotImg(BmpBack);
   ImgList.Create(ButtonSize.cx, ButtonSize.cy, ILC_COLORDDB ¦ ILC_MASK, 1, 1);
   ImgList.Add(&BmpBack, RGB(0,0,0) );

   ToolBarCtrl.SetHotImageList(&ImgList);
   ImgList.Detach();
}
{
   // disable
   DrawBarImg(BmpBack);
   RendDisableImg(BmpBack);
   ImgList.Create(ButtonSize.cx, ButtonSize.cy, ILC_COLORDDB ¦ ILC_MASK, 1, 1);
   ImgList.Add(&BmpBack, RGB(0,0,0) );
   ToolBarCtrl.SetDisabledImageList(&ImgList);
   ImgList.Detach();
}
ReleaseDC(pWndDC);
return SUCCESS;
}
void CImageToolBar::ColorReplace(CBitmap & bmpImg, COLORREF from, COLORREF to)
{
CImage   img;

img.Attach(bmpImg);
COLORREF BKold = img.GetPixel(0,0);
COLORREF BKnew = GetSysColor(COLOR_BTNFACE);
int w = img.GetWidth(),
   h = img.GetHeight();
int x,y;
for (x=0; x < w; ++x)
{
   for (y=0; y < h; ++y)
   {
    if (img.GetPixel(x,y) == from)
     img.SetPixel(x,y, to);
   }
}
img.Detach();
}
void CImageToolBar::GetButtonImgSize(CSize & size)
{
size = GetToolBarCtrl().GetButtonSize();
size.cx -= 7;
size.cy -= 6;
}
int CImageToolBar::GetButtonCount()
{
int count = GetToolBarCtrl().GetButtonCount();
for (int i=count-1; i>=0; --i)
{
   if (TBBS_BUTTON != GetButtonStyle(i))
    --count;
}
return count;
}
void CImageToolBar::GetToolImgRect(CRect & imgRect)
{
CSize size;
GetButtonImgSize(size);
imgRect.left = 0;
imgRect.top = 0;
imgRect.bottom = size.cy;
imgRect.right = size.cx * GetButtonCount();
}
void CImageToolBar::DrawBarImg(CBitmap & bmpImg)
{
if (m_pImage==NULL)
   return;
CRect BKRect;
GetToolImgRect(BKRect);
CDC   DrawDC,
   *pWndDC = GetWindowDC();
DrawDC.CreateCompatibleDC(pWndDC);
DrawDC.SelectObject(&bmpImg);
ReleaseDC(pWndDC);
DrawDC.FillRect(&BKRect, &CBrush(GetSysColor(COLOR_BTNFACE) ) );
Graphics graphics(DrawDC);

graphics.DrawImage(m_pImage, 0.0, 0.0, BKRect.Width(), BKRect.Height());

if (m_pImage->GetType() < ImageTypeMetafile)
{
   COLORREF bk = DrawDC.GetPixel(0,0);
   DrawDC.DeleteDC();
   ColorReplace(bmpImg, bk, GetSysColor(COLOR_BTNFACE));
}
}
void CImageToolBar::RendHotImg(CBitmap & bmpImg)
{
CRect BKRect;
GetToolImgRect(BKRect);
CDC   DrawDC,
   *pWndDC = GetWindowDC();
DrawDC.CreateCompatibleDC(pWndDC);
DrawDC.SelectObject(&bmpImg);
ReleaseDC(pWndDC);
unsigned char r,g,b;
COLORREF color;
for (int x = 0; x <BKRect.Width(); ++x)
   for (int y=0; y <BKRect.Height(); ++y)
   {
    color = DrawDC.GetPixel(x,y);
    r = (color>>0)&0x0ff;
    g = (color>> 8)&0x0ff;
    b = (color>>16)&0x0ff;
    r += min(255-r, r*0.15);
    g += min(255-g, g*0.15);
    b += min(255-b, b*0.15);
    DrawDC.SetPixel(x,y,RGB(r,g,b));
   }

}
void CImageToolBar::RendDisableImg(CBitmap & bmpImg)
{
try{
   CRect BKRect;
   GetToolImgRect(BKRect);
   CDC   DrawDC,
    *pWndDC = GetWindowDC();
   DrawDC.CreateCompatibleDC(pWndDC);
   DrawDC.SelectObject(&bmpImg);
   ReleaseDC(pWndDC);
   CImage Img;
   if (!Img.Create(BKRect.Width(), BKRect.Height(), 32))
    return;
   CDC ImgDC;
   ImgDC.Attach(Img.GetDC());
   ImgDC.FillRect(&BKRect, &CBrush(GetSysColor(COLOR_BTNFACE)) );  
   ImgDC.Detach();
   Img.AlphaBlend(DrawDC, BKRect, BKRect, 180);
   Img.ReleaseDC();
}catch(...)
{
}
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值