可以使用以下方法将Win32窗口设置为透明:
-
定义窗口类时,在WNDCLASSEX结构体中设置hbrBackground成员为NULL。
-
在窗口创建时,使用WS_EX_LAYERED风格和SetLayeredWindowAttributes函数将窗口设置为透明:
HWND hwnd = CreateWindowEx(WS_EX_LAYERED, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hInstance, NULL); SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA);
其中,第二个参数指定颜色偏移量,第三个参数指定透明度,范围从0(完全透明)到255(完全不透明)。
- 在窗口的WM_PAINT消息处理函数中,使用CreateCompatibleDC函数创建一个与窗口DC兼容的内存DC,并将要绘制的图形绘制到该内存DC上。然后使用UpdateLayeredWindow函数将内存DC中的内容复制到窗口DC中。
case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); // 创建与窗口DC兼容的内存DC HDC memDC = CreateCompatibleDC(hdc); // 创建一个与窗口大小相同的位图 HBITMAP memBmp = CreateCompatibleBitmap(hdc, 500, 100); // 将位图选入内存DC HBITMAP oldBmp = (HBITMAP)SelectObject(memDC, memBmp); // 在内存DC中绘制图形 // ... // 使用UpdateLayeredWindow函数将内存DC中的内容复制到窗口DC中 POINT ptSrc = { 0, 0 }; SIZE size = { 500, 100 }; BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; POINT ptDst = { 0, 0 }; UpdateLayeredWindow(hwnd, hdc, &ptDst, &size, memDC, &ptSrc, 0, &blend, ULW_ALPHA); // 恢复原来的位图 SelectObject(memDC, oldBmp); // 释放内存DC和位图 DeleteDC(memDC); DeleteObject(memBmp); EndPaint(hwnd, &ps); } break;
以上代码中,在内存DC中绘制图形的过程自行实现。另外,由于UpdateLayeredWindow函数需要使用内存DC和位图,因此需要在WM_DESTROY消息处理函数中释放这些资源:
case WM_DESTROY: { PostQuitMessage(0); DeleteObject(hBrush); DeleteObject(hPen); DeleteObject(hFont); DeleteObject(hImage); // 释放内存DC和位图 HDC memDC = GetDC(hwnd); ReleaseDC(hwnd, memDC); } break;