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

WinAPI窗口模糊实现失败,寻求有效解决方法

正确实现Windows窗口模糊效果(适配MinGW环境)

解决MinGW中SetWindowCompositionAttribute未定义问题

MinGW默认头文件未包含该函数定义,需手动声明结构体与函数指针:

typedef enum _WINDOWCOMPOSITIONATTRIB {
    WCA_ACCENT_POLICY = 19
} WINDOWCOMPOSITIONATTRIB;

typedef struct _ACCENT_POLICY {
    int AccentState;
    int AccentFlags;
    int GradientColor;
    int AnimationId;
} ACCENT_POLICY;

typedef struct _WINDOWCOMPOSITIONATTRIBDATA {
    WINDOWCOMPOSITIONATTRIB Attrib;
    PVOID pvData;
    SIZE_T cbData;
} WINDOWCOMPOSITIONATTRIBDATA;

typedef BOOL(WINAPI* pSetWindowCompositionAttribute)(HWND, WINDOWCOMPOSITIONATTRIBDATA*);

从系统动态库加载函数:

pSetWindowCompositionAttribute SetWindowCompositionAttribute = 
    (pSetWindowCompositionAttribute)GetProcAddress(LoadLibraryA("user32.dll"), "SetWindowCompositionAttribute");

修正窗口样式与背景,避免客户区变白

  • 创建窗口时添加WS_EX_LAYERED扩展样式,并设置白色为透明色:
    SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
    SetLayeredWindowAttributes(hwnd, RGB(255,255,255), 0, LWA_COLORKEY);
    
  • 或在窗口过程中拦截WM_ERASEBKGND消息,阻止系统绘制默认白色背景:
    case WM_ERASEBKGND:
        return TRUE;
    

正确调用模糊函数流程

方案1:使用SetWindowCompositionAttribute实现强模糊/亚克力效果

这是目前效果最稳定的方式,优先推荐:

if (SetWindowCompositionAttribute) {
    ACCENT_POLICY policy = {0};
    // 普通模糊
    policy.AccentState = 3; // ACCENT_ENABLE_BLURBEHIND
    // 亚克力模糊(效果更强,需设置渐变颜色)
    // policy.AccentState = 4; // ACCENT_ENABLE_ACRYLICBLURBEHIND
    // policy.GradientColor = 0x80000000; // 高8位为透明度,0x80表示半透明
    policy.AccentFlags = 0;
    policy.AnimationId = 0;

    WINDOWCOMPOSITIONATTRIBDATA data = {0};
    data.Attrib = WCA_ACCENT_POLICY;
    data.pvData = &policy;
    data.cbData = sizeof(policy);

    SetWindowCompositionAttribute(hwnd, &data);
}

方案2:修复DWM系列函数调用

若坚持使用DwmEnableBlurBehindWindow等函数,需确保参数设置正确:

// 启用DWM客户区渲染
BOOL enable = TRUE;
DwmSetWindowAttribute(hwnd, DWMWA_ALLOW_NCPAINT, &enable, sizeof(enable));

// 设置全窗口模糊
DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = TRUE;
bb.hRgnBlur = NULL; // NULL表示整个客户区应用模糊
DwmEnableBlurBehindWindow(hwnd, &bb);

// 扩展框架到客户区(可选,配合模糊使用)
MARGINS margins = {-1};
DwmExtendFrameIntoClientArea(hwnd, &margins);

常见问题排查

  • 客户区变白:核心原因是系统默认绘制了不透明背景,必须通过WM_ERASEBKGND返回TRUE或分层窗口透明色规避。
  • 模糊效果弱:切换到亚克力模糊模式(AccentState=4),并调整GradientColor的透明度值(高8位范围0x00-0xFF)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:50:32