透明/半透明視窗是打造現代 UI 的關鍵技術。Windows 2000 引入 WS_EX_LAYERED 與 GDI+ 原生支援,而 Win9x/NT 4.0 需手工實現。本文系統整理兩種時代的技術方案,並提供核心程式碼片段。
void __fastcall TForm1::FormCreate(TObject *Sender) {
LONG lExStyle = GetWindowLong(Handle, GWL_EXSTYLE);
lExStyle |= WS_EX_LAYERED;
SetWindowLong(Handle, GWL_EXSTYLE, lExStyle);
// 200/255 ≈ 78% 不透明度,clBlue 為透明色鍵 (此處用 LWA_ALPHA 忽略色鍵)
SetLayeredWindowAttributes(Handle, clBlue, 200, LWA_ALPHA);
}
LWA_ALPHA 使用 bAlpha (0-255) 控制整體透明度;LWA_COLORKEY 則指定單一透明色。
SetLayeredWindowAttributes(HWND, COLORREF, BYTE, DWORD):設定透明度/色鍵。UpdateLayeredWindow:高效更新分層視窗內容 (支援 Alpha Blending 位圖)。AnimateWindow:視窗動畫 (摺疊、滑入、淡入淡出)。核心流程:
BitBlt 回螢幕。| 問題 | 解決方案 | |
|---|---|---|
| 如何繪製隱藏視窗到位圖? | 使用 WM_PRINT 訊息 (而非 WM_PAINT),可捕獲被遮蓋區域。需先將視窗置頂 (SetWindowPos HWND_TOP)、顯示 (ShowWindow SW_SHOW)、發送 WM_PRINT、再隱藏/恢復 Z-order。 | |
| WM_PRINT 不支援的控制項 (如 Static) | 手工在記憶體位圖上繪製該控制項外觀。 | |
| 如何取得視窗下方其他應用程式畫面? | 極其困難。真正的桌面合成需 DWM (Vista+) 或鏡像驅動。本法僅適用於 Splash 視窗、工具提示等靜態/半靜態透明視窗。 |
| 時代 | 技術 | 適用場景 |
|---|---|---|
| Win9x/NT4 | 手工離屏合成 + WM_PRINT | Splash 畫面、工具提示、簡單透明視窗 |
| Win2000/XP | WS_EX_LAYERED + SetLayeredWindowAttributes | 恆定半透明視窗、簡單淡入淡出 |
| Vista/7/8/10/11 | DWM (Desktop Window Manager) + DwmExtendFrameIntoClientArea | 玻璃效果、全視窗 Aero Glass、高效硬體加速合成 |
| 現代跨平台 | DirectComposition / WinUI 3 / Skia / Flutter | 高性能 GPU 加速 UI、複雜動畫、向量圖形 |
WS_EX_LAYERED + SetLayeredWindowAttributes / UpdateLayeredWindow。理解透明視窗技術演進脈絡,能幫助開發者根據目標平台選擇最適合的方案,在相容性與視覺效果間取得最佳平衡。