您的位置:首页 > 其它

总结了两种绘画透明窗体的方法,都有些缺陷,能适用一般情况

2015-10-22 17:57 246 查看
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);  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: