一般游戏的Launcher窗口或者Splash窗口都有比较玄的半透明效果。
普通的通过镂空窗口形成的异形窗口无法支持半透明效果,
下面介绍一种通过绘制半透明PNG的方式来实现这种效果的方法。
如果窗口不需要拖动,简单点,用GDI+ 在 OnEraseBkgnd 或者 OnPaint 绘制PNG就可以实现。
如果窗口需要拖动,则需要动点手脚。我们可以用LAYERED的特性解决拖动时背景来源的问题。
关键代码如下:
BOOL CSPWndDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//LAYERED 窗口
ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW|WS_EX_LAYERED);
//用GDI+ 加载PNG图片
m_pImg = ImageFromResource(AfxGetApp()->m_hInstance, IDR_PNG_LOGO, _T("PNG"));
int screenCX = GetSystemMetrics(SM_CXSCREEN);
int screenCY = GetSystemMetrics(SM_CYSCREEN);
int cx = m_pImg->GetWidth() * 2;
int cy = m_pImg->GetHeight() * 2;
int x = (screenCX - cx) / 2;
int y = (screenCY - cy) / 2;
SetLayeredWindowAttributes(0, 255, LWA_ALPHA);
MoveWindow(x, y, cx, cy);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
BOOL CSPWndDlg::OnEraseBkgnd(CDC* pDC)
{
HDC hDesktopDC = ::GetDC(NULL);
CRect rc;
GetClientRect(&rc);
CPoint po = rc.TopLeft();
ClientToScreen(&po);
//从桌面把背景图先拷贝过来
BitBlt(pDC->GetSafeHdc(), 0, 0, rc.Width(), rc.Height(), hDesktopDC, po.x, po.y, SRCCOPY);
Gdiplus::Graphics gra(pDC->GetSafeHdc());
gra.DrawImage(m_pImg, 0, 0);
::ReleaseDC(NULL, hDesktopDC);
return TRUE;
}
LRESULT CSPWndDlg::OnNcHitTest(CPoint point)
{
//全客户区可拖动
return HTCAPTION;
}
//拖动的时候刷新窗口
void CSPWndDlg::OnMove(int x, int y)
{
CDialog::OnMove(x, y);
if (m_pImg != NULL)
{
//OnPaint绘图 参数为 False, OnEraseBkgnd 参数为True
//Invalidate();
//如果是 在 OnEraseBkgnd 还可以这么来
CClientDC dc(this);
OnEraseBkgnd(&dc);
}
}
这样之后,窗口就是半透明的并且可以拖动的。
但窗口不是异形的,如果需要把透明部分镂空需要其他操作。
示例代码: