1.使用屏蔽绘画函数方法
窗口属性修改ModifyStyleEx(0, WS_EX_LAYERED);//去除Onpaint函数响应;
刷新窗口采用UpdateLayeredWindow;
缺点:控件因为窗口不能刷新,使得windows自带控件不能使用,需重写应用控件,在不需要控件或则不需要复杂控件时使用。
void DrawUI()
{
HDC hDC=::GetDC(m_hWnd);
HDC hMemDC=::CreateCompatibleDC(hDC);
BITMAPINFO bitmapinfo;
bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapinfo.bmiHeader.biBitCount = 32;
bitmapinfo.bmiHeader.biHeight =/*GetSystemMetrics(SM_CXSCREEN)*/1000;
bitmapinfo.bmiHeader.biWidth = /*GetSystemMetrics(SM_CYSCREEN)*/1000;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biCompression=BI_RGB;
bitmapinfo.bmiHeader.biXPelsPerMeter=0;
bitmapinfo.bmiHeader.biYPelsPerMeter=0;
bitmapinfo.bmiHeader.biClrUsed=0;
bitmapinfo.bmiHeader.biClrImportant=0;
bitmapinfo.bmiHeader.biSizeImage = bitmapinfo.bmiHeader.biWidth * bitmapinfo.bmiHeader.biHeight * bitmapinfo.bmiHeader.biBitCount / 8;
HBITMAP hBitmap=::CreateDIBSection (hMemDC,&bitmapinfo, 0,NULL, 0, 0);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject (hMemDC,hBitmap);
//画出各个界面元素----------------------
m_image.Draw( hMemDC,0,0 );
//设置透明窗口-------------------------------------------------
CPoint DestPt(0,0);
CSize psize(1000, 1000);
BLENDFUNCTION blendFunc32bpp;
blendFunc32bpp.AlphaFormat = AC_SRC_ALPHA;
blendFunc32bpp.BlendFlags = 0;
blendFunc32bpp.BlendOp = AC_SRC_OVER;
blendFunc32bpp.SourceConstantAlpha = 255;
::UpdateLayeredWindow(m_hWnd,hDC,NULL,&psize,hMemDC,&DestPt,0,&blendFunc32bpp,ULW_ALPHA);
//释放资源-------------------------------------------------
::SelectObject (hMemDC,hOldBitmap);
::DeleteObject(hBitmap);
::DeleteDC(hMemDC);
::ReleaseDC(m_hWnd,hDC);
}
2.使用设置窗口区域的方法
使用PS通过移动添加背景的方法,重做一张双色图片比如实际图片区域为RGB(255,0,255),实际图片区域以外区域为RGB(0, 0, 0);
采用一下方法去除RGB(0, 0, 0)颜色,并通过调用系统函数重新设置窗口区域
缺点:效果不是很理想,描边PNG图片绘画时,效果很不理想,不是很好替换背景图片。
void SetRegion(CDC* pDC, UINT BackBitmapID, COLORREF TransColor)
{
CDC dcMem;
if(!dcMem.CreateCompatibleDC(pDC))
{
MessageBox(_T("创建兼容DC失败!"));
}
CBitmap bitmap;
if(!bitmap.LoadBitmap(BackBitmapID))
{
MessageBox(_T("加载位图失败!"));
}
if(!dcMem.SelectObject(&bitmap))
{
MessageBox(_T("选进设备描述表失败!"));
}
BITMAP bitmapinfo;
bitmap.GetBitmap(&bitmapinfo);
//把窗口设为图片的大小,去掉这个的话,那么程序分割会不正确
MoveWindow(0,0,bitmapinfo.bmWidth,bitmapinfo.bmHeight,true);
//整体区域
CRgn rgn;
CRgn tmpRgn;
rgn.CreateRectRgn(0,0,bitmapinfo.bmWidth,bitmapinfo.bmHeight);
//从整体区域中剔除所有黑色像素区域
for(int i=0;i<bitmapinfo.bmWidth;i++)
{
for(int j=0;j<bitmapinfo.bmHeight;j++)
{
COLORREF cl=dcMem.GetPixel(i,j);
if(cl== TransColor)
{
tmpRgn.CreateRectRgn(i,j,i+1,j+1);
rgn.CombineRgn(&rgn,&tmpRgn,RGN_XOR);
tmpRgn.DeleteObject();
}
}
}
//设置窗口显示区域
SetWindowRgn(rgn,true);
}