1. 程式人生 > >MFC UpdateLayeredWindow 以png作為視窗背景

MFC UpdateLayeredWindow 以png作為視窗背景

標頭檔案

主要宣告
DECLARE_MESSAGE_MAP()
VOID OnPaint();

cpp檔案


#include <gdiplus.h>

using namespace Gdiplus;

BEGIN_MESSAGE_MAP(animateWindow, CDialog)
	ON_WM_PAINT()
END_MESSAGE_MAP()

void transparentWindow::OnPaint()
{

	initTransparent();

	CDialog::OnPaint();
}

//OnPaint只會響應一遍,設定了UpdateLayeredWindow之後就不響應了,不過如果只是做一個背景的話,不用響應OnPaint,
void transparentWindow::initTransparent()
{
	if (0 == m_ImagePath.GetLength())
	{
		return;
	}

	DWORD dwExStyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
	if ((dwExStyle & WS_EX_LAYERED) != WS_EX_LAYERED)
	{
		SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, dwExStyle | WS_EX_LAYERED);
		//SetLayeredWindowAttributes(m_BkColor, 128, LWA_COLORKEY);
        //SetLayeredWindowAttributes和UpdateLayeredWindow互斥,只能一個有效
	}

	Bitmap *_pImage = Bitmap::FromFile(m_ImagePath);
    //Bitmap::FromFile返回的物件可以用DeleteObject釋放掉
	//透明度由PNG圖片的Alpha通道決定  

	if (NULL == dcSrc)
	{
		dcSrc = new CDC();
		//bmp = new CBitmap();
	}

	RECT rt;
	GetClientRect(&rt);

	CDC *pDCDst = GetDC();
	dcSrc->CreateCompatibleDC(pDCDst);
	//bmp->CreateCompatibleBitmap(pDCDst, rt.right, rt.bottom);
	//dcSrc->SelectObject(&bmp);

	Gdiplus::Color color;//預設black
	HBITMAP hBitmap;
	_pImage->GetHBITMAP(color, &hBitmap);
	dcSrc->SelectObject(hBitmap);

	BLENDFUNCTION _Blend;
	_Blend.BlendOp = 0;
	_Blend.BlendFlags = 0;
	_Blend.AlphaFormat = 1;
	_Blend.SourceConstantAlpha = 255;

	//此時,滑鼠會穿透窗體中Alpha值為0的區域  
	GetWindowRect(&rt);
	CPoint wndPoint;
	wndPoint.x = rt.left;
	wndPoint.y = rt.top;

	CPoint srcPoint;
	srcPoint.x = 0;
	srcPoint.y = 0;

	CSize clientSize;
	clientSize.cx = _pImage->GetWidth();
	clientSize.cy = _pImage->GetHeight();

	UpdateLayeredWindow(pDCDst, &wndPoint, &clientSize,
		dcSrc, &srcPoint,
		0, &_Blend, ULW_ALPHA);

	//bmp->DeleteObject();
	dcSrc->DeleteDC();
	ReleaseDC(pDCDst);
}

void transparentWindow::SetBkImage(CString filePath)
{
	m_ImagePath = filePath;
}

呼叫的時候需要提前呼叫SetBkImage一面OnPaint中找不到檔案

效果如下