效果1.窗體整體透明,支持子控件,支持OnPaint()
//為窗體添加WS_EX_LAYERED屬性,該屬性使窗體支持透明
ModifyStyleEx(0, WS_EX_LAYERED);
效果1.1 窗體整體透明,子控件也透明
//設置Alpha值為150
BYTE byteAlpha=150;
SetLayeredWindowAttributes(0,byteAlpha,LWA_ALPHA);
效果1.2 窗體整體透明,子控件不透明
//在OnCtlColor中將窗體背景刷為某種單色,比如RGB(255,0,0)
//在OnPaint中當然也可以
if(nCtlColor=IDD)
return m_brush; //m_brush.CreateSolidBrush(RGB(255,0,255));
//設置窗體中所有單色區域都透明
SetLayeredWindowAttributes(RGB(255,0,255),0,LWA_COLORKEY);
效果2.窗體部分透明,但該窗體不支持子控件,不支持OnPaint()
USES_CONVERSION;
Image* _pImage=
Image::FromFile(A2W("F:\\Desktop\\TestTransparentWnd\\test.png"));
//透明度由PNG圖片的Alpha通道決定
//如果加上WS_EX_TRANSPARENT屬性,則鼠標會(huì )穿透此窗體
ModifyStyleEx(0, WS_EX_LAYERED/*|WS_EX_TRANSPARENT*/);
CDC *pDCDst=this->GetDC();
CDC dcSrc;
dcSrc.CreateCompatibleDC(pDCDst);
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDCDst,300,300);
dcSrc.SelectObject(&bmp);
//用GDI+顯示PNG圖片
Graphics _Graphics(dcSrc.m_hDC);
_Graphics.DrawImage(_pImage,0,0,300,300);
BLENDFUNCTION _Blend;
_Blend.BlendOp=0;
_Blend.BlendFlags=0;
_Blend.AlphaFormat=1;
_Blend.SourceConstantAlpha=255;
//此時(shí),鼠標會(huì )穿透窗體中Alpha值為0的區域
UpdateLayeredWindow(pDCDst,&CPoint(0,0),&CSize(300,300),
&dcSrc,&CPoint(0,0),
0,&_Blend,ULW_ALPHA);
bmp.DeleteObject();
dcSrc.DeleteDC();
_Graphics.ReleaseHDC(dcSrc.m_hDC);
this->ReleaseDC(pDCDst);
3.既要窗體部分透明(鼠標能穿透窗體中Alpha值為0的區域),還要能顯示控件
解決方案:
創(chuàng )建兩個(gè)窗體,窗體A使用效果2的方法,作為背景窗體;窗體B使用效果1.2的方法,作為前景窗體,控件都放在窗體B上。在窗體A的OnMove中,同步移動(dòng)窗體B。
備注:
1.以上代碼只需在窗體初始化的時(shí)候(如OnInitDialog)執行一次即可
2.WS_EX_LAYERED要求宏_WIN32_WINNT >= 0x0500
3.以上程序需要GDI+支持
參考資料: