⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 translucentwnd.cpp

📁 Under CE4.2 view bitmap with shrink and magnify
💻 CPP
字号:
// TranslucentWnd.cpp : implementation file
//

#include "stdafx.h"
#include "TranslucentWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//////////////////////////////////////////////////////////////////////////
//Global Variable
//static const UINT SELFREFRESH_TIMER = 1000;
//static const UINT AUTOREFRESH_TIMER = 1001;
//static const UINT ElapseTime = 50;


//BOOL CTranslucentWnd::m_sbRefresh = FALSE;

/////////////////////////////////////////////////////////////////////////////
// CTranslucentWnd

CTranslucentWnd::CTranslucentWnd()
{
	m_pParentWnd = NULL;
	m_nMode      = 0;
	m_nUpIcon    = 0;
	m_nDownIcon  = 0;
	m_nCurIcon   = 0;
	m_nID        = 0;
	m_bMSGFlag   = FALSE;

//	m_bActive    = FALSE;
}

CTranslucentWnd::~CTranslucentWnd()
{
}


BEGIN_MESSAGE_MAP(CTranslucentWnd, CWnd)
	//{{AFX_MSG_MAP(CTranslucentWnd)
	ON_WM_ERASEBKGND()
	ON_WM_CREATE()
	ON_WM_PAINT()
//	ON_WM_LBUTTONDOWN()
//	ON_WM_LBUTTONUP()
//	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CTranslucentWnd message handlers

BOOL CTranslucentWnd::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	
	//return CWnd::OnEraseBkgnd(pDC);

	return TRUE;
}

int CTranslucentWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here

	//
	//Timer to auto refresh the translucent window if background changes
	//
//	SetTimer(AUTOREFRESH_TIMER, ElapseTime, NULL);
	return 0;
}

void CTranslucentWnd::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	CRect rc;
	GetClientRect(&rc);

	dc.BitBlt(0,0,rc.Width(),rc.Height(),CDC::FromHandle(m_memIcon.m_hDC),0,0,SRCCOPY);
}

void CTranslucentWnd::Create(CWnd *pParentWnd, const RECT &rect, UINT nID)
{
	m_pParentWnd = pParentWnd;
	m_nID        = nID;
	CWnd::Create(NULL, NULL, /*WS_VISIBLE|*/WS_CHILD, rect, pParentWnd, nID, NULL);

	//Init memory dc
	CDC *pDC = GetDC();

	InitMem(pDC);

	ReleaseDC(pDC);

}

//only when OnPaint do not run
void CTranslucentWnd::RefreshBG(CMemDC *pMemDC)
{
	CRect rc;
	GetClientRect(rc);
	ClientToScreen(rc);
	m_pParentWnd->ScreenToClient(rc);
	BitBlt(m_memIcon.m_hDC, 0, 0, rc.Width(), rc.Height(), pMemDC->m_hDC, rc.left, rc.top, SRCCOPY);
}

void CTranslucentWnd::InitMem(CDC *pDC)
{
	CRect rc;
	GetClientRect(&rc);

	HBITMAP hBmp;

	// Prepare foreground menu image to blend with background image.
	m_memIcon.m_hDC = CreateCompatibleDC(pDC->GetSafeHdc());
	hBmp = pecCreateDIBBitmap(pDC->GetSafeHdc(), (VOID**)&m_pMenuBits, rc.Width(), rc.Height());
	ASSERT(hBmp);
	m_memIcon.m_hOldBmp = (HBITMAP)SelectObject(m_memIcon.m_hDC, hBmp);
}

void CTranslucentWnd::Popup()
{	
	CRect rc;
	GetClientRect(&rc);
	RefreshBG(m_pMemBG);
	FillRect(CDC::FromHandle(m_memIcon.m_hDC),&rc,RGB(83,83,83),80);//80);
	WriteBackBG(m_pMemBG);
}

void CTranslucentWnd::FillRect(CDC* pDC, LPRECT lpRect, COLORREF crColor /*= FORMBACKCOLOR*/, int nAlpha /*= 80*/)
{
	ASSERT(pDC);
	ASSERT(lpRect);

	HDC hDC = CreateCompatibleDC(pDC->GetSafeHdc());
	CRect rc(lpRect);
	LPBYTE pBits;
	HBITMAP hBmp = pecCreateDIBBitmap(pDC->GetSafeHdc(), (void**)&pBits, rc.Width(), rc.Height());
	ASSERT(hBmp);
	HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp);

	CPoint pt(0,0);

	if(m_nMode==0) ::BitBlt(hDC, 0, 0, rc.Width(), rc.Height(), m_memIcon.m_hDC, rc.left, rc.top, SRCCOPY);
	else CDC::FromHandle(hDC)->FillSolidRect(&rc,crColor);
	
	//pecAlphaBlend(pBits, crColor, nAlpha, rc.Width(), rc.Height());
	if(m_nCurIcon) DrawIcon(CDC::FromHandle(hDC),pt,m_nCurIcon);
	
	pecAlphaBlend(pBits,m_pMenuBits,nAlpha,rc.Width(),rc.Height());

	pDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), CDC::FromHandle(hDC), 0, 0, SRCCOPY);

	SelectObject(hDC, hOldBmp);
	DeleteObject(hBmp);
	DeleteDC(hDC);
}

void CTranslucentWnd::SetBkMem(CMemDC *pMemDC)
{
	m_pMemBG = pMemDC;
}

void CTranslucentWnd::SetIcon(UINT nUpIcon, UINT nDownIcon)
{
	m_nUpIcon   = nUpIcon;
	m_nDownIcon = nDownIcon;
	m_nCurIcon  = m_nUpIcon;
}

void CTranslucentWnd::DrawIcon(CDC *pDC, CPoint pt, UINT nIcon)
{
	HICON hIcon = AfxGetApp()->LoadIcon(nIcon);
	ASSERT(hIcon);
	pDC->DrawIcon(pt, hIcon);
	DestroyIcon(hIcon);
}

void CTranslucentWnd::WriteBackBG(CMemDC *pMemDC)
{
	CRect rc;
	GetClientRect(rc);
	ClientToScreen(rc);
	m_pParentWnd->ScreenToClient(rc);
	BitBlt(pMemDC->m_hDC, rc.left, rc.top, rc.Width(), rc.Height(), m_memIcon.m_hDC, 0, 0, SRCCOPY);
}

void CTranslucentWnd::SetFillMode(int nMode)
{
	m_nMode = nMode;
}
/*
void CTranslucentWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
	//Open auto refresh window for all instances
//	CTranslucentWnd::m_sbRefresh = TRUE;
//	m_pParentWnd->PostMessage(WM_TRANSLUCENTBTN, m_nID);
 //   m_bMSGFlag	= TRUE;
//    m_nCurIcon  = m_nDownIcon;
//	m_bActive   = TRUE;
//	SetTimer(SELFREFRESH_TIMER, ElapseTime, NULL);
//	Popup();
//	Invalidate();
//	if(m_nCurIcon != m_nDownIcon)
//	{
//       m_nCurIcon  = m_nDownIcon;
//	    Popup();
//	}
	CWnd::OnLButtonDown(nFlags, point);
}

void CTranslucentWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
//	m_nCurIcon = m_nUpIcon;
//	SetTimer(SELFREFRESH_TIMER, ElapseTime, NULL);
//	m_bActive = FALSE;
//	Popup();
//	Invalidate();

	CWnd::OnLButtonUp(nFlags, point);
}

void CTranslucentWnd::OnTimer(UINT nIDEvent)
{
	switch(nIDEvent)
	{
	case SELFREFRESH_TIMER:
		{
		    KillTimer(SELFREFRESH_TIMER);
	        Popup();
	        Invalidate();

		    //Open auto refresh window for all instance
		    CTranslucentWnd::m_sbRefresh = TRUE;
		}
		break;
	case AUTOREFRESH_TIMER:        
		if(CTranslucentWnd::m_sbRefresh && !m_bActive)
		{
			Popup();
			Invalidate();

			//Close auto refresh window for all instance
			CTranslucentWnd::m_sbRefresh = FALSE;
		}
		break;
	default:
		break;

	}
	
	CWnd::OnTimer(nIDEvent);
}
*/
//////////////////////////////////////////////////////////////////////////
//Functions for Translucent effect
HBITMAP pecCreateDIBBitmap(HDC hDC, void** ppvBits, int nWidth, int nHeight)
{
	// Create memory bmp 
	BITMAPINFOHEADER bmiHeader = {0};
	bmiHeader.biSize	= sizeof(BITMAPINFOHEADER);
	bmiHeader.biWidth	= nWidth;
	bmiHeader.biHeight	= -nHeight;
	bmiHeader.biPlanes	= 1;
	bmiHeader.biBitCount	= 24;
	bmiHeader.biCompression = BI_RGB;
	// Create bmp handle
	return ( 
		CreateDIBSection(
		hDC,
		(BITMAPINFO*)&bmiHeader,
		0, ppvBits, NULL, 0));
}

#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)

void pecAlphaBlend(const PBYTE pDestBits, const PBYTE pBits, int nAlpha, int nWidth, int nHeight)
{
	__try {
		BYTE* pDest = pDestBits;
		BYTE* pSrc 	= pBits;
		for (int y = 0; y < nHeight; y++)
		{
			pDest = pDestBits + y * WIDTHBYTES(nWidth * 24);
			pSrc  = pBits + y * WIDTHBYTES(nWidth * 24);
			for (int x = 0 ; x < nWidth; x++, pDest += 3, pSrc += 3)
			{
				pDest[0] = max(0, min(0xFF, (pSrc[0] - pDest[0]) * nAlpha / 0xFF + pDest[0]));
				pDest[1] = max(0, min(0xFF, (pSrc[1] - pDest[1]) * nAlpha / 0xFF + pDest[1]));
				pDest[2] = max(0, min(0xFF, (pSrc[2] - pDest[2]) * nAlpha / 0xFF + pDest[2]));
			}
		}
	}

	__except (EXCEPTION_EXECUTE_HANDLER) {
		ASSERT(FALSE);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -