使用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