我又不是很笨,专注地去做一件事,总有一天会成功!一个月不够、一年、一年不够十年、十年不够、一辈子、一辈子不够...无撼!因为有的人一辈子没做好过一件事!
查看文章 |
VC(MFC)在工具栏中使用PNG图片
2008-05-26 02:31
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(...) { } } |
最近读者: