1. 在对话框初始化中
m_hModule = LoadLibrary("User32.DLL");
m_pUpdateLayeredWindow = (functionpointer)GetProcAddress(m_hModule, "UpdateLayeredWindow");
const DWORD WS_EX_LAYERED = 0x00080000;
DWORD dwExStyle = GetWindowLong(GetSafeHwnd(),GWL_EXSTYLE|WS_EX_TRANSPARENT);
SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,dwExStyle|WS_EX_LAYERED);
UpdateView();
2. 实现 UpdateView方法
void UpdateView()
{
CRect rc;
GetWindowRect(rc);
POINT ptDest ={rc.left,rc.top};
SIZE sizeDest = {rc.Width(),rc.Height()};
HDC hDC = ::GetDC(GetSafeHwnd());
HDC hMemDc = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpinfo;
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biWidth = rc.Width();
bmpinfo.bmiHeader.biHeight = rc.Height();
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biBitCount = 32;//32bpp
bmpinfo.bmiHeader.biCompression = BI_RGB;
void* pBits = NULL;
HBITMAP hBitmap = CreateDIBSection(hDC,&bmpinfo,DIB_RGB_COLORS,&pBits,NULL,0);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDc,hBitmap);
DrawSurface(hMemDc);
BLENDFUNCTION blf;
blf.BlendOp = AC_SRC_OVER;
blf.BlendFlags = 0;
blf.SourceConstantAlpha = 255;
blf.AlphaFormat = 1;//AC_SRC_ALPHA;
POINT ptSrc = {0,0};
m_pUpdateLayeredWindow(GetSafeHwnd(),hDC,&ptDest,&sizeDest,hMemDc,&ptSrc,0,&blf,2/*ULW_ALPHA*/);
::SelectObject(hMemDc,hOldBitmap);
::DeleteObject(hBitmap);
DeleteDC(hMemDc);
::ReleaseDC(GetSafeHwnd(),hDC);
}
3 在 DrawSurface 方法中实现所有的绘制逻辑。
CRect rcClient;
GetClientRect(rcClient);
SolidBrush br(Color(25,255,0,0));
Graphics g(hDC);
g.FillRectangle(&br,rcClient.left,rcClient.top,rcClient.Width(),rcClient.Height());
4 每当想要更新的时候 ,调用 UpdateView 方法.
注意: 1. GDI 不支持 alpha通道,所以所有的颜色的alpha通道值都是0(代表全透明),所以要使用GDIPlus绘制,或自己写DiBsection设置Alpha通道的值。
2. 窗口全透明的位置默认鼠标穿透。
3. 如果非全透明的位置想实现鼠标穿透,相应WM_NCHITTEST消息 ,返回 HTTRANSPARENT