c++下实现异形窗口(上方只显示文字其他区域穿透,下方半透明)

        功能有俩个,一个透明背景,一个是上方文字处镂空(文字显示,其他空白处不显示,见下图)

c++下实现异形窗口(上方只显示文字其他区域穿透,下方半透明)_第1张图片

 

        //上方文字处理

void OperationHollowOutCharacters()
{
	//
	CRect	rectCharacters(0, 0, Dialog_Width, HollowOutCharachers_Height);

	//
	if (!m_hDCMem && !m_hBitmap && !m_hOldBitmap)
	{
		//创建相关资源
		HDC		hDC = ::GetDC(NULL);
		m_hDCMem = CreateCompatibleDC(hDC);
		m_hBitmap = CreateCompatibleBitmap(hDC, rectCharacters.Width(), rectCharacters.Height());
		m_hOldBitmap = (HBITMAP)::SelectObject(m_hDCMem, m_hBitmap);
		::SetStretchBltMode(m_hDCMem, COLORONCOLOR);

		//hBmp资源由img释放
		{
			DWORD	dwID = m_bUnknownSourceChecked ? IDB_PNG_InstallMarket_UnknownChecked : IDB_PNG_InstallMarket_UnknownUnchecked;
			HBITMAP	hBmp = AtlLoadGdiplusImage((_U_STRINGorID)dwID, _T("png")); //该处可由CImage.LoadFromResource实现
			CImage	img;
			img.Attach(hBmp);
			img.StretchBlt(m_hDCMem, rectCharacters, CRect(0, 0, img.GetWidth(), img.GetHeight()), SRCCOPY);
		}

		//整个客户区域显示,下面将不显示的进行RGN_XOR
		if (!m_hRgnWnd)
			m_hRgnWnd = ::CreateRectRgn(0, 0, Dialog_Width, Dialog_Height);

		//双层循环检查图像颜色,白色的过滤或只有黑色的才能显示
		COLORREF	color;
		COLORREF	colorCmp = RGB(255, 255, 255);	//RGB(0, 0, 0)
		HRGN		hRgnTemp;
		for (int i = 0; i < rectCharacters.Width(); ++i)
		{
			for (int j = 0; j < rectCharacters.Height(); ++j)
			{
				color = ::GetPixel(m_hDCMem, i, j);
				//条件二选一:颜色不是黑色或颜色是白色
				if (color == colorCmp)
				{
					hRgnTemp = ::CreateRectRgn(i, j, i + 1, j + 1);
					::CombineRgn(m_hRgnWnd, m_hRgnWnd, hRgnTemp, RGN_XOR);
					::DeleteObject(hRgnTemp);
				}
			}
		}

		//释放gdi资源
		::ReleaseDC(NULL, hDC);
	}
}

其中

const int Dialog_Width = 810;
const int Dialog_Height = 590;
const int HollowOutCharachers_Height = 75;
const int HollowOutCharachers_Border = 15;


        在窗口初始化时添加下面的代码即可

//为使得窗口拥有透明属性,需要窗口拥有WS_EX_LAYERED属性
long	lStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
::SetWindowLong(m_hWnd, GWL_EXSTYLE, lStyle | WS_EX_LAYERED);
::SetLayeredWindowAttributes(m_hWnd, 0, 220, LWA_ALPHA);

//设置镂空布局
if (m_hRgnWnd)
	::SetWindowRgn(m_hWnd, m_hRgnWnd, TRUE);


        注意窗口关闭时的资源释放

void ReleaseResource()
{
	if (m_hDCMem && m_hBitmap && m_hOldBitmap)
	{
		::SelectObject(m_hDCMem, m_hOldBitmap);
		::DeleteObject(m_hBitmap);
		::DeleteDC(m_hDCMem);
	}
	m_hDCMem = NULL;
	m_hBitmap = NULL;
	m_hOldBitmap = NULL;

	if (m_hRgnWnd)
	{
		::DeleteObject(m_hRgnWnd);
		m_hRgnWnd = NULL;
	}
}

 

你可能感兴趣的:(VC/MFC类,C/C++用法类,API,/,SDK)