用C++实现半透明按钮控件(PNG,GDI+)
使用MFC实现上面的按钮半透明效果能看到父窗口中的内容,上面是效果图(一个是带背景图片的、另一个是不带的)。
控件继承自CWnd类(彩色的部分是窗口的背景图片、按钮是PNG图片,第二个图标是鼠标指向时的效果)。
图标的绘制使用GDI+绘制PNG图片,在此不多说了(处理WM_PAINT消息):
[cpp]
1. void PNGButton::OnPaint()
2. {
3. CPaintDC dc(this);
4. Graphics g(dc.m_hDC);
5. if(DrawBorder){
6. g.DrawImage(hoverBg,0,0);//画鼠标指向时的亮色背景
7. }
8. g.DrawImage(this->bg,0,0);//画按钮图标
9. g.ReleaseHDC(dc.m_hDC);
10. }
透明的关键:注意后面调用此方法的代码
关键在于InvalidateRect函数:通知父窗口重新绘制特定区域,执行此函数后按钮所在区域就被父窗口绘制的内容覆盖.在父窗口绘制完成后,
按钮也会收到WM_PAINT消息,执行上面的一段OnPaint代码.
[cpp]
1. void PNGButton::PaintParent()
2. {
3. CRect rect;
4. GetWindowRect(&rect);
5. GetParent()-> ScreenToClient(&rect);
6. GetParent()-> InvalidateRect(&rect);
7. }
捕获鼠标指向或移出事件(处理WM_MOUSEMOVE,WM_MOUSEOVER,WM_MOUSELEAVE消息):
[cpp]
1. void PNGButton::OnMouseHover(UINT nFlags, CPoint point)
2. {
3. DrawBorder=true;
4. PaintParent();//通知父窗口重绘特定区域,会引发控件自身的重绘
5. }
6.
7.
8. void PNGButton::OnMouseLeave()
9. {
10. m_is_mouse_over = false;
11. m_is_tracked = false;
12. DrawBorder=false;
13. PaintParent(); //通知父窗口重绘特定区域,会引发控件自身的重绘
14. CWnd::OnMouseLeave();
15. }
16.
17.
18. void PNGButton::OnMouseMove(UINT nFlags, CPoint point)
19. {
20. m_is_mouse_over = true;
21. if(!m_is_tracked)
22. {
23. TRACKMOUSEEVENT tme;
24. tme.cbSize = sizeof(TRACKMOUSEEVENT);
25. tme.dwFlags = TME_LEAVE|TME_HOVER;
26. tme.hwndTrack = GetSafeHwnd();
27. tme.dwHoverTime = 80;
28. _TrackMouseEvent(&tme);
29. m_is_tracked = true;
30. }
31. CWnd::OnMouseMove(nFlags, point);
32. }
附:
从资源加载PNG图片
附:
从资源加载PNG图片
[cpp]
1. View Code
2. #pragma once
3. #include "stdafx.h"
4. using namespace Gdiplus;
5.
6. static bool ImageFromIDResource(UINT nID, LPCTSTR sTR,Image * &pImg)
7. {
8. HINSTANCE hInst = AfxGetResourceHandle();
9. HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
10. if (!hRsrc)
11. return FALSE;
12. // load resource into memory
13. DWORD len = SizeofResource(hInst, hRsrc);
14. BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
15. if (!lpRsrc)
16. return FALSE;
17. // Allocate global memory on which to create stream
18. HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
19. BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
20. memcpy(pmem,lpRsrc,len);
21. IStream* pstm;
22. CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
23. // load from stream
24. pImg=Gdiplus::Image::FromStream(pstm);
25. // free/release stuff
26. GlobalUnlock(m_hMem);
27. pstm->Release();
28. FreeResource(lpRsrc);
29. return TRUE;
30. }
平铺图片的代码
[cpp]
1. CPaintDC dc(this);
2. CRect rect;
3. GetClientRect(rect);
4. CBrush bs(RGB(240,240,240));//窗口背景色
5. dc.FillRect(&rect,&bs); //窗口着色
6. //填充背景图片:平铺
7. Graphics g(dc.m_hDC);
8. if(has_bg) g.DrawImage(this->bg,0,0);
9. Gdiplus::TextureBrush bbs(this->img);
10. g.FillRectangle(&bbs,0,0,rect.Width(),this->img->GetHeight());
11. g.ReleaseHDC(dc.m_hDC);
12. //TRACE(L"CMainFrame::OnPaint\r\n");
作者:eit520
补充:软件开发 , C++ ,