UpdateLayeredWindow 文字透明的解决办法

来源:https://www.cnblogs.com/xzy1210/archive/2014/03/25/3622818.html

增加 gdi+ 实现方法 ,主要代码如下:

HBITMAP CreateAlphaTextBitmap_Gdiplus(LPCTSTR inText, LPCTSTR strFont, Color crC)
{ 
	int TextLength = (int)_tcslen(inText); 
	if (TextLength <= 0) return NULL; 

	// Create DC and select font into it 
	HDC hTextDC = CreateCompatibleDC(NULL); 
	Gdiplus::Font font(strFont,26,FontStyleRegular,UnitPoint);

	RectF TextArea(0,0,400,40);

	HBITMAP hMyDIB = NULL; 
	if (TextArea.Width > 0 && TextArea.Height > 0)
	{ 
		BITMAPINFOHEADER BMIH; 
		memset(&BMIH, 0x0, sizeof(BITMAPINFOHEADER)); 
		void *pvBits = NULL; 

		// Specify DIB setup 
		BMIH.biSize = sizeof(BMIH); 
		BMIH.biWidth = (int)TextArea.Width + 1; 
		BMIH.biHeight = (int)TextArea.Height + 1; 
		BMIH.biPlanes = 1; 
		BMIH.biBitCount = 32; 
		BMIH.biCompression = BI_RGB; 

		// Create and select DIB into DC 
		hMyDIB = CreateDIBSection(hTextDC, (LPBITMAPINFO)&BMIH, 0, (LPVOID*)&pvBits, NULL, 0); 
		HBITMAP hOldBMP = (HBITMAP)SelectObject(hTextDC, hMyDIB); 
		if (hOldBMP != NULL)
		{ 
		// 把背景填黑 ,文字用白色
			Graphics grp(hTextDC);
			SolidBrush brText(Color(255,255,255,255));
			SolidBrush brBk(Color(255,0,0,0));
			grp.FillRectangle(&brBk,0,0,BMIH.biWidth,BMIH.biHeight);
			grp.DrawString(inText,TextLength,&font,PointF(0,0),StringFormat::GenericTypographic(),&brText);

			BLENDFUNCTION bf; 
			bf.BlendOp = AC_SRC_OVER; 
			bf.BlendFlags = 0; 
			bf.SourceConstantAlpha = 0xff; 
			bf.AlphaFormat = AC_SRC_ALPHA; 

			BYTE* DataPtr = (BYTE*)pvBits; 
			BYTE FillR = crC.GetR();
			BYTE FillG = crC.GetG();
			BYTE FillB = crC.GetB();
			BYTE ThisA; 
			for (int LoopY = 0; LoopY < BMIH.biHeight; LoopY++) { 
				for (int LoopX = 0; LoopX < BMIH.biWidth; LoopX++) { 
					ThisA = *DataPtr; // Move alpha and pre-multiply with RGB 
					if (ThisA > 0)
					{
						int ii = 0;
					}
					*DataPtr++ = (FillB * ThisA) >> 8; 
					*DataPtr++ = (FillG * ThisA) >> 8; 
					*DataPtr++ = (FillR * ThisA) >> 8; 
					*DataPtr++ = ThisA; // Set Alpha 
				} 
			} 

			// De-select bitmap 
			SelectObject(hTextDC, hOldBMP); 
		} 
	} 

	// De-select font and destroy temp DC 
	DeleteDC(hTextDC); 

	// Return DIBSection 
	return hMyDIB;
}

void CTestGdiplusDlg::AlphaShowWnd()
{
	HDC inDC = ::GetDC(m_hWnd);

	HDC hDCAlpha = CreateCompatibleDC(inDC);
	HBITMAP hBmpAlpha = NULL;
	CRect rcWnd;
	GetWindowRect(&rcWnd);

	BLENDFUNCTION bf; 
	bf.BlendOp = AC_SRC_OVER; 
	bf.BlendFlags = 0; 
	bf.SourceConstantAlpha = 0xff; 
	bf.AlphaFormat = AC_SRC_ALPHA; 
	{

		BITMAPINFOHEADER BMIH; 
		memset(&BMIH, 0x0, sizeof(BITMAPINFOHEADER)); 
		void *pvBits = NULL; 

		// Specify DIB setup 
		BMIH.biSize = sizeof(BMIH); 
		BMIH.biWidth = rcWnd.Width();
		BMIH.biHeight = rcWnd.Height();
		BMIH.biPlanes = 1; 
		BMIH.biBitCount = 32; 
		BMIH.biCompression = BI_RGB; 

		hBmpAlpha = CreateDIBSection(inDC, (LPBITMAPINFO)&BMIH, 0, (LPVOID*)&pvBits, NULL, 0);
		SelectObject(hDCAlpha,hBmpAlpha);

	}
	const TCHAR *DemoText = _T("测试代码"); 
	RECT TextArea = {0, 0, 0, 0}; 
	HFONT TempFont = CreateFont(50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _T("微软雅黑")); 
	HBITMAP MyBMP = CreateAlphaTextBitmap(DemoText, TempFont, 0); 
	if (MyBMP)
	{
		// Create temporary DC and select new Bitmap into it 
		HDC hTempDC = CreateCompatibleDC(inDC); 
		HBITMAP hOldBMP = (HBITMAP)SelectObject(hTempDC, MyBMP); 
		if (hOldBMP)
		{
			// Get Bitmap image size
			BITMAP BMInf;
			GetObject(MyBMP, sizeof(BITMAP), &BMInf); 

			// Fill blend function and blend new text to window 
			AlphaBlend(hDCAlpha, 100, 100, BMInf.bmWidth, BMInf.bmHeight, hTempDC, 0, 0, BMInf.bmWidth, BMInf.bmHeight, bf); 

			// Clean up 
			SelectObject(hTempDC, hOldBMP); 
			DeleteObject(MyBMP); 
			DeleteDC(hTempDC); 
		} 
	} 

	//  gdi+ 在 HDC 绘制
	const TCHAR *DemoText_Gdiplus = _T("Gdi+ 测试代码");
	MyBMP = CreateAlphaTextBitmap_Gdiplus(DemoText_Gdiplus,_T("微软雅黑"),Color(255,255,0,0));
	if (MyBMP)
	{
		HDC hTempDC = CreateCompatibleDC(inDC); 
		HBITMAP hOldBMP = (HBITMAP)SelectObject(hTempDC, MyBMP); 
		if (hOldBMP)
		{
			// Get Bitmap image size
			BITMAP BMInf;
			GetObject(MyBMP, sizeof(BITMAP), &BMInf); 

			// Fill blend function and blend new text to window 
			AlphaBlend(hDCAlpha, 100, 150, BMInf.bmWidth, BMInf.bmHeight, hTempDC, 0, 0, BMInf.bmWidth, BMInf.bmHeight, bf); 

			// Clean up 
			SelectObject(hTempDC, hOldBMP); 
			DeleteObject(MyBMP); 
			DeleteDC(hTempDC); 
		} 
	}


	SelectObject(inDC,TempFont);
	SetBkMode(inDC,TRANSPARENT);
	TextOut(inDC,100,200,DemoText,_tcslen(DemoText));

	DeleteObject(TempFont); 
	::ReleaseDC(m_hWnd,inDC);

	{
		POINT ptDst = rcWnd.TopLeft();
		POINT ptSrc = {0,0};
		SIZE siDst = rcWnd.Size();
		::UpdateLayeredWindow(m_hWnd,NULL,&ptDst,&siDst,hDCAlpha,&ptSrc,0,&bf,ULW_ALPHA);
	}
	DeleteObject(hBmpAlpha);
	DeleteObject(hDCAlpha);
}

缺点:文字边缘显示效果看起来不如非透明的舒服

以微软雅黑字体为例:

非透明,边缘有其它颜色:

透明的边缘是文字颜色变浅:

previous arrow
next arrow
Slider

你可能 也喜欢

发表评论

电子邮件地址不会被公开。 必填项已用*标注