You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Win32无标题栏可调整大小窗口的DWM边框异常问题及Win10/Win11兼容解决方案咨询

Win32无标题栏可调整大小窗口的DWM边框异常问题及Win10/Win11兼容解决方案咨询

我目前正在开发一款基于C++的Win32桌面应用,核心是用WebView2控件填满整个窗口客户区。我想要实现的窗口样式需求如下:

  • 没有默认标题栏和系统按钮(最小化/最大化/关闭)
  • 保留原生DWM的边框拖拽调整大小功能
  • 窗口四周有1px左右的可见细边框
  • 保留正常的最小化/最大化/还原动画(和普通重叠窗口一致)
  • 同时兼容Windows 10和Windows 11系统

当前实现方案及问题

我现在用了一个比较粗糙的凑数方案,在Windows 11上基本能工作,但存在两个小问题:顶部边框的拖拽调整区域只有1px宽;而且在Windows 10上完全失效——会显示默认的顶部系统按钮,窗口左侧还有奇怪的1px留白。

窗口创建代码

window_ = CreateWindowExW(WS_EX_APPWINDOW, WINDOW_CLASS_NAME, 
                          L"WinRAT Server Control Panel", WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT, 1280, 800, 
                          nullptr, nullptr, GetModuleHandle(nullptr), this);
if (!window_) {
    return false;
}
SetWindowPos(window_, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
ShowWindow(window_, SW_SHOWNORMAL);
UpdateWindow(window_);

WM_NCCALCSIZE 处理代码

case WM_NCCALCSIZE: {
    if (wparam == TRUE) {
        NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(lparam);
        RECT original = params->rgrc[0];
        LRESULT result = DefWindowProc(hwnd, msg, wparam, lparam);
        params->rgrc[0] = original;
        int pad = GetSystemMetrics(SM_CXPADDEDBORDER);
        int frame = GetSystemMetrics(SM_CXSIZEFRAME);
        
        if (IsZoomed(hwnd)) {
            int total = frame + pad;
            params->rgrc[0].top += total;
            params->rgrc[0].bottom -= total;
            params->rgrc[0].left += total;
            params->rgrc[0].right -= total;
        } else {
            params->rgrc[0].top += 1;
            params->rgrc[0].bottom -= pad;
            params->rgrc[0].left += pad;
            params->rgrc[0].right -= pad;
        }
        return result;
    }
    break;
}

求助需求

这个方案明显是依赖Win11特定行为凑出来的“歪招”,完全不兼容Win10。想请教一下有没有官方推荐或者更可靠的实现方式,能同时满足我的所有窗口样式需求,并且在Win10和Win11上都能稳定工作?

火山引擎 最新活动