图一、叠加在Visual C++开发工具上的透明"精灵"窗体 |
///////////////////////////////////////////////////////////////////////////// // 获得窗体矩形 CRect rectWnd; this->GetWindowRect(rectWnd); // 读取"掩模"位图资源 CBitmap myBitmap,*pOldBitmap; myBitmap.LoadBitmap(nMaskId); // 创建"内存一致"设备 CDC memDC; memDC.CreateCompatibleDC(pDC); // 选择绘图设备 pOldBitmap = memDC.SelectObject(&myBitmap); // 创建窗体的初始区域 CRgn rgnWnd,rgnTemp; rgnWnd.CreateRectRgn(0,0,rectWnd.Width(),rectWnd.Height()); int nWidth,nHeight; COLORREF color; //下面的两层循环为检查背景位图象素颜色,进行透明区域处理; //当象素颜色为指定的透明值时,即将该点从区域中剪裁掉。 for (nWidth = 0;nWidth <= rectWnd.Width()-1;nWidth++) { for (nHeight = 0;nHeight <= rectWnd.Height();nHeight++) { color = memDC.GetPixel(nWidth,nHeight); // 当象素是白色时,去掉该点 if (color == RGB(255,255,255)) { //象素颜色为指定的透明色,创建透明"微区域" rgnTemp.CreateRectRgn(nWidth,nHeight,nWidth+1,nHeight+1); //"扣像",从完整的区域中"扣除"透明的"微区域" rgnWnd.CombineRgn(&rgnWnd,&rgnTemp,RGN_XOR); //删除刚创建的透明"微区域",释放系统资源 rgnTemp.DeleteObject(); } } } memDC.SelectObject(pOldBitmap); SetWindowRgn((HRGN)rgnWnd,TRUE); //用最终设定窗口的显示区域为指定区域 |
//////////////////////////////////////////////////////////////// MyWnd.h : header file #if !defined(AFX_MYWND_H__A761190E_CDF2_4A56_8848_AEE5AC7AD160__INCLUDED_) #define AFX_MYWND_H__A761190E_CDF2_4A56_8848_AEE5AC7AD160__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // CMyWnd window class CMyWnd : public CWnd { // Construction public: CMyWnd(); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyWnd) //}}AFX_VIRTUAL // Implementation public: void Initialize(LPCTSTR lpszName,CRect &rectWnd,UINT nMaskId,UINT nShowId); void Display(CDC *pDC,UINT nMaskId); virtual ~CMyWnd(); // Generated message map functions protected: //{{AFX_MSG(CMyWnd) afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg UINT OnNcHitTest(CPoint point); afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: UINT m_nBitmapId; }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_MYWND_H__A761190E_CDF2_4A56_8848_AEE5AC7AD160__INCLUDED_) ////////////////////////////////////////////////////////// MyWnd.cpp : implementation file #include "stdafx.h" #include "transparent.h" #include "MyWnd.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // CMyWnd CMyWnd::CMyWnd() {} CMyWnd::~CMyWnd() {} BEGIN_MESSAGE_MAP(CMyWnd, CWnd) //{{AFX_MSG_MAP(CMyWnd) ON_WM_ERASEBKGND() ON_WM_NCHITTEST() ON_WM_CHAR() //}}AFX_MSG_MAP END_MESSAGE_MAP() BOOL CMyWnd::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default CRect rectWnd; this->GetWindowRect(&rectWnd); CDC memDC; CBitmap myBitmap,*pOldBitmap; myBitmap.LoadBitmap(m_nBitmapId); memDC.CreateCompatibleDC(pDC); pOldBitmap = memDC.SelectObject(&myBitmap); pDC->BitBlt(0,0,rectWnd.Width(),rectWnd.Height(), &memDC,0,0,SRCCOPY); // 将设备还原 memDC.SelectObject(pOldBitmap ); return TRUE; } UINT CMyWnd::OnNcHitTest(CPoint point) { // TODO: Add your message handler code here and/or call default UINT nHitTest = CWnd :: OnNcHitTest(point) ; return (nHitTest == HTCLIENT) ? HTCAPTION : nHitTest ; } void CMyWnd::Display(CDC *pDC, UINT nMaskId) { // 获得窗体矩形 CRect rectWnd; this->GetWindowRect(rectWnd); // 读取位图资源 CBitmap myBitmap,*pOldBitmap; myBitmap.LoadBitmap(nMaskId); // 创建"内存一致"设备 CDC memDC; memDC.CreateCompatibleDC(pDC); //选择绘图设备 pOldBitmap = memDC.SelectObject(&myBitmap); // 创建窗体的初始区域 CRgn rgnWnd,rgnTemp; rgnWnd.CreateRectRgn(0,0,rectWnd.Width(),rectWnd.Height()); int nWidth,nHeight; COLORREF color; for (nWidth = 0;nWidth <= rectWnd.Width()-1;nWidth++) { for (nHeight = 0;nHeight <= rectWnd.Height();nHeight++) { color = memDC.GetPixel(nWidth,nHeight); // 当象素是白色时,去掉该点 if (color == RGB(255,255,255)) { rgnTemp.CreateRectRgn(nWidth,nHeight,nWidth+1,nHeight+1); rgnWnd.CombineRgn(&rgnWnd,&rgnTemp,RGN_XOR); rgnTemp.DeleteObject(); } } } memDC.SelectObject(pOldBitmap); SetWindowRgn((HRGN)rgnWnd,TRUE); } void CMyWnd::Initialize(LPCTSTR lpszName, CRect &rectWnd, UINT nMaskId, UINT nShowId) { this->CreateEx(0,AfxRegisterWndClass(0),lpszName,WS_POPUP | WS_SYSMENU,rectWnd,NULL,NULL,NULL); this->Display(GetWindowDC(),nMaskId); m_nBitmapId = nShowId; } void CMyWnd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if(nChar==VK_ESCAPE) { PostMessage(WM_QUIT); } CWnd::OnChar(nChar, nRepCnt, nFlags); } //////////////////////////////////////////////////////////// BOOL CTransparentApp::InitInstance() { #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif m_pMainWnd = &m_wndMain;// m_wndMain是CmyWnd类成员变量; CRect rectWnd(500, 300, 580, 380); m_wndMain.Initialize(_T("loveghost"),rectWnd,IDB_MASK,IDB_SHOW); m_wndMain.ShowWindow(SW_SHOW); // 窗体创建完毕,显示之; return TRUE; // 返回非零值表示要继续处理消息 } |