You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI 3桌面覆盖层中SetLayeredWindowAttributes()为何失效?

WinUI 3中实现类似WinForms TransparencyKey的窗口透明效果

你遇到的问题根源在于WinUI 3的渲染机制和WinForms不同,单纯调用SetLayeredWindowAttributes指定LWA_COLORKEY不会生效——WinUI默认会绘制不透明的背景层,覆盖了分层窗口的颜色透明设置。以下是可行的解决方案:

关键步骤

  1. 设置窗口背景为透明:在XAML或代码中禁用WinUI的默认不透明背景。
  2. 正确配置分层窗口属性:确保窗口添加WS_EX_LAYERED扩展样式,并指定要透明的RGB颜色值。
  3. 强制窗口重绘:触发窗口属性更新,让透明设置生效。

完整实现代码

XAML部分

<Window
    x:Class="WinUI3TransparencyKey.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="TransparencyKeyDemo"
    Background="Transparent"> <!-- 核心:设置窗口背景透明 -->
    <Grid>
        <!-- 示例内容:红色矩形,测试黑色背景透明效果 -->
        <Rectangle Width="200" Height="200" Fill="Red" Margin="50"/>
    </Grid>
</Window>

C#代码部分

using Microsoft.UI.Xaml;
using System.Runtime.InteropServices;
using WinRT.Interop;

namespace WinUI3TransparencyKey
{
    public sealed partial class MainWindow : Window
    {
        private IntPtr _hWnd;

        // P/Invoke 函数声明
        [DllImport("user32.dll")]
        private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);

        [DllImport("user32.dll")]
        private static extern int GetWindowLong(IntPtr hwnd, int nIndex);

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll")]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        // 常量定义
        private const int GWL_EXSTYLE = -20;
        private const uint WS_EX_LAYERED = 0x80000;
        private const uint LWA_COLORKEY = 0x00000001;
        private const uint SWP_NOMOVE = 0x0002;
        private const uint SWP_NOSIZE = 0x0001;
        private const uint SWP_FRAMECHANGED = 0x0020;

        public MainWindow()
        {
            InitializeComponent();

            // 获取窗口句柄
            _hWnd = WindowNative.GetWindowHandle(this);

            // 添加分层窗口扩展样式
            int exStyle = GetWindowLong(_hWnd, GWL_EXSTYLE);
            exStyle |= (int)WS_EX_LAYERED;
            SetWindowLong(_hWnd, GWL_EXSTYLE, exStyle);

            // 设置黑色(RGB 0x000000)为透明色
            SetLayeredWindowAttributes(_hWnd, 0x000000, 0, LWA_COLORKEY);

            // 强制窗口重绘,应用透明设置
            SetWindowPos(_hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
        }
    }
}

注意事项

  • SetLayeredWindowAttributes的crKey参数需要传入RGB格式的颜色值(例如黑色是0x000000,红色是0xFF0000),不要使用ARGB值。
  • 如果窗口内的控件使用了和透明键相同的颜色,该部分也会被透明,这和WinForms的TransparencyKey行为一致。
  • 确保Windows App SDK版本(1.3)支持分层窗口的相关设置,该方案在WinUI 3桌面应用中稳定生效。

内容的提问来源于stack exchange,提问作者Et3rnos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:12:00