1、 新建一个MFC AppWizard项目,选择选基于文档或者对话框都可以。
2、 添加两个图片,如下,第二张图片把第一张图片的中间部分镂空,也即删除该部分区域,让背景透明
3、 添加位图资源,导入上面的那两张图片。
4、 新建一个基类为CWnd的类TransparentWnd,代码如下:
头文件:
- //TransparentWnd.H
- #if !defined(AFX_TRANSPARENTWND_H__INCLUDED_)
- #define AFX_TRANSPARENTWND_H__INCLUDED_
- #if _MSC_VER > 1000
- #pragma once
- #endif
- class CTransparentWnd : public CWnd
- {
- public:
- CTransparentWnd();
- void CreateTransparent(LPCTSTR pTitle, RECT &rect, unsigned short MaskID, unsigned short BitmapID);
- void SetupRegion(CDC *pDC, unsigned short MaskID);
- public:
- // Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CTransparentWnd)
- //}}AFX_VIRTUAL
- // Implementation
- public:
- virtual ~CTransparentWnd();
- protected:
- unsigned short m_BitmapID;
- // Generated message map functions
- protected:
- //{{AFX_MSG(CTransparentWnd)
- afx_msg void OnPaint();
- afx_msg BOOL OnEraseBkgnd(CDC* pDC);
- afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
- //{{AFX_INSERT_LOCATION}}
- // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
- #endif
实现文件:
- //TransparentWnd.CPP
- #include "stdafx.h"
- #include "TransparentWnd.h"
- #include <assert.h>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- //********************************************************************************
- //* Constructor
- //********************************************************************************
- CTransparentWnd::CTransparentWnd()
- {
- }
- //********************************************************************************
- //* Destructor
- //********************************************************************************
- CTransparentWnd::~CTransparentWnd()
- {
- }
- BEGIN_MESSAGE_MAP(CTransparentWnd, CWnd)
- //{{AFX_MSG_MAP(CTransparentWnd)
- ON_WM_PAINT()
- ON_WM_ERASEBKGND()
- ON_WM_LBUTTONDOWN()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- //**************************************************************************
- //*创建一个背景透明的窗体
- //**************************************************************************
- void CTransparentWnd::CreateTransparent(LPCTSTR pTitle, RECT &rect, unsigned short MaskID, unsigned short BitmapID)
- {
- CreateEx( 0,
- AfxRegisterWndClass(0),
- pTitle,
- WS_POPUP | WS_SYSMENU,
- rect,
- NULL,
- NULL,
- NULL );
- SetupRegion(GetWindowDC(), MaskID);
- m_BitmapID = BitmapID;
- }
- //********************************************************************************
- //*创建一个背景透明的窗体
- //********************************************************************************
- void CTransparentWnd::SetupRegion(CDC *pDC, unsigned short MaskID)
- {
- CDC memDC;
- CBitmap cBitmap;
- CBitmap* pOldMemBmp = NULL;
- COLORREF col;
- CRect cRect;
- int x, y;
- CRgn wndRgn, rgnTemp;
- GetWindowRect(&cRect);
- cBitmap.LoadBitmap(MaskID);
- memDC.CreateCompatibleDC(pDC);
- pOldMemBmp = memDC.SelectObject(&cBitmap);
- wndRgn.CreateRectRgn(0, 0, cRect.Width(), cRect.Height());
- for(x=0; x<=cRect.Width(); x++)
- {
- for(y=0; y<=cRect.Height(); y++)
- {
- col = memDC.GetPixel(x, y);
- if(col == 0)
- {
- rgnTemp.CreateRectRgn(x, y, x+1, y+1);
- wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);
- rgnTemp.DeleteObject();
- }
- }
- }
- if (pOldMemBmp) memDC.SelectObject(pOldMemBmp);
- SetWindowRgn((HRGN)wndRgn, TRUE);
- }
- //**************************************************************************
- //*响应鼠标左键点击,让窗口可移动
- //**************************************************************************
- void CTransparentWnd::OnLButtonDown(UINT nFlags, CPoint point)
- {
- CWnd::OnLButtonDown(nFlags, point);
- PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y));
- }
- //**************************************************************************
- //*加载图片1作为背景
- //**************************************************************************
- BOOL CTransparentWnd::OnEraseBkgnd(CDC* pDC)
- {
- CRect rect;
- GetWindowRect(&rect);
- CDC memDC;
- CBitmap cBitmap;
- CBitmap* pOldMemBmp = NULL;
- cBitmap.LoadBitmap(m_BitmapID);
- memDC.CreateCompatibleDC(pDC);
- pOldMemBmp = memDC.SelectObject(&cBitmap);
- pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
- if (pOldMemBmp) memDC.SelectObject( pOldMemBmp );
- return TRUE;
- }
- void CTransparentWnd::OnPaint()
- {
- CPaintDC dc(this);
- // Add your drawing code here!
- }
5、 修改项目中的×××App.cpp文件的InitInstance()函数,如下:
- BOOL ×××App::InitInstance()
- {
- SetRegistryKey(_T("Local AppWizard-Generated Applications"));
- CTransparentWnd* pFrame = new CTransparentWnd;
- m_pMainWnd = pFrame;
- CRect rect(0, 0, 200, 250);
- pFrame->CreateTransparent("Transparent Test", rect, IDB_BITMAP2, IDB_BITMAP1);
- pFrame->ShowWindow(SW_SHOW);
- pFrame->UpdateWindow();
- return TRUE;
- }
6、 运行看结果:
7、 Try it yourself!
8、 扩展:
我们可以制作一组连续的图片构成动画,然后按照上面的方法动态更改窗口背景图片,可以作出更加好看的动画窗口,试试。