首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Windows 分層視窗 API 實現視窗透明效果:SetLayeredWindowAttributes 動態載入技巧

     編輯:關於VC++

Windows 2000 引入分層視窗,透過 SetLayeredWindowAttributes() 可輕鬆實現視窗整體透明、淡入淡出、色鍵透明等效果。但舊版 SDK(VC6 預設)缺少此 API 宣告。本文展示如何以動態載入 User32.dll 取得函數指標的方式繞過 SDK 限制,在 VC6 環境下實現視窗透明效果。

API 簽章與常數


BOOL SetLayeredWindowAttributes(
    HWND hwnd,        // 分層視窗控制代碼
    COLORREF crKey,   // 色鍵(LWA_COLORKEY 時使用)
    BYTE bAlpha,      // Alpha 值 0-255(LWA_ALPHA 時使用)
    DWORD dwFlags     // LWA_ALPHA(0x2) | LWA_COLORKEY(0x1)
);

WS_EX_LAYERED = 0x80000;  // 擴充視窗風格

需求:Windows 2000/XP/2003/Vista/7/8/10/11 支援;Windows 95/98/Me 不支援。

動態載入實作


// 在 OnInitDialog() 或 OnCreate() 中
// 1. 加入 WS_EX_LAYERED 擴充風格
SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE,
    GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE) ^ WS_EX_LAYERED);

// 2. 動態載入 User32.dll 並取得函數指標
HINSTANCE hInst = LoadLibrary(_T("User32.DLL"));
if (hInst) {
    typedef BOOL (WINAPI *PFN_SETLAYEREDWINDOWATTRS)(HWND, COLORREF, BYTE, DWORD);
    PFN_SETLAYEREDWINDOWATTRS pfn = (PFN_SETLAYEREDWINDOWATTRS)
        GetProcAddress(hInst, "SetLayeredWindowAttributes");

    if (pfn) {
        // 設定 50% 透明度 (Alpha = 128)
        pfn(GetSafeHwnd(), 0, 128, LWA_ALPHA);
    }
    FreeLibrary(hInst);
}

參數說明與效果

dwFlagsbAlpha / crKey效果
LWA_ALPHA (0x2)bAlpha = 0-255整體透明度:0 完全透明,255 不透明
LWA_COLORKEY (0x1)crKey = RGB 值指定顏色變透明(如綠幕抠圖)
LWA_ALPHA | LWA_COLORKEY兩者皆用混合效果

注意:bAlpha 勿設太小(如 < 50),視窗幾乎不可見將難以操作關閉。

進階應用:淡入淡出動畫


// 淡入:0 → 255
for (BYTE alpha = 0; alpha <= 255; alpha += 10) {
    pfn(hWnd, 0, alpha, LWA_ALPHA);
    Sleep(10);
}

// 淡出:255 → 0
for (BYTE alpha = 255; alpha >= 0; alpha -= 10) {
    pfn(hWnd, 0, alpha, LWA_ALPHA);
    Sleep(10);
}

現代開發環境建議

  • Visual Studio 2008+ (Windows SDK 6.0+) 已內建 SetLayeredWindowAttributes 宣告,可直接呼叫
  • WPF/UWP 使用 Window.Opacity / UIElement.Opacity 更簡單
  • 若需逐像素 Alpha 混合(如不規則視窗),改用 UpdateLayeredWindow() 配合 32 位元 DIB

常見問題

  • 視窗變透明但子控制項不透明 → 子控制項繼承父視窗分層屬性,正常情況下會一起透明
  • GDI 繪製內容透明度異常 → 確保視窗類別註冊時不帶 CS_OWNDC,或使用 UpdateLayeredWindow
  • 效能問題 → 分層視窗由 DWM/系統合成器處理,現代 GPU 無壓力;舊機器大面積透明可能佔用較多資源
視窗透明效果示意

結語

動態載入 SetLayeredWindowAttributes 是在舊版開發環境(VC6 + 老舊 SDK)實現視窗透明的經典技巧。雖現代 SDK 已內建此 API,但動態載入技術對於相容舊系統、插件式架構、運行時功能檢測仍具參考價值。配合 WS_EX_LAYERED 即可用幾行代碼賦予應用程式現代化的視覺效果。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved