Win32視窗設定為透明

2023-03-09 12:00:42

可以使用以下方法將Win32視窗設定為透明:

  1. 定義視窗類時,在WNDCLASSEX結構體中設定hbrBackground成員為NULL。

  2. 在視窗建立時,使用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(完全不透明)。

  1. 在視窗的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;