使用MFC實現上面的按鈕半透明效果能看到父窗口中的內容,上面是效果圖(一個是帶背景圖片的、另外一個是不帶的)。函數
控件繼承自CWnd類(彩色的部分是窗口的背景圖片、按鈕是PNG圖片,第二個圖標是鼠標指向時的效果)。this
圖標的繪製使用GDI+繪製PNG圖片,在此很少說了(處理WM_PAINT消息):spa
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 }3d
透明的關鍵:注意後面調用此方法的代碼blog
關鍵在於InvalidateRect函數:通知父窗口從新繪製特定區域,執行此函數後按鈕所在區域就被父窗口繪製的內容覆蓋.在父窗口繪製完成後,
按鈕也會收到WM_PAINT消息,執行上面的一段OnPaint代碼.繼承
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消息):圖片
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 }ip
附:資源
從資源加載PNG圖片
1 #pragma once
2 #include "stdafx.h"
3 using namespace Gdiplus;
4
5 static bool ImageFromIDResource(UINT nID, LPCTSTR sTR,Image * &pImg)
6 {
7 HINSTANCE hInst = AfxGetResourceHandle();
8 HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
9 if (!hRsrc)
10 return FALSE;
11 // load resource into memory
12 DWORD len = SizeofResource(hInst, hRsrc);
13 BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
14 if (!lpRsrc)
15 return FALSE;
16 // Allocate global memory on which to create stream
17 HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
18 BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
19 memcpy(pmem,lpRsrc,len);
20 IStream* pstm;
21 CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
22 // load from stream
23 pImg=Gdiplus::Image::FromStream(pstm);
24 // free/release stuff
25 GlobalUnlock(m_hMem);
26 pstm->Release();
27 FreeResource(lpRsrc);
28 return TRUE;
29 }
平鋪圖片的代碼
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");