📄 translucentwnd.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 + -