如何移除已知HWND的Windows11窗口标题栏并保留窗口动画?
移除Windows 11窗口默认标题栏并保留动画效果
直接修改窗口核心样式(GWL_STYLE)会破坏Windows 11 DWM(桌面窗口管理器)的动画关联逻辑,因为系统默认标题栏的部分样式是动画触发的依赖项。以下是两种可行的替代方案:
方案一:使用DWM API隐藏标题栏(推荐)
通过DwmSetWindowAttribute仅隐藏标题栏渲染,不修改窗口核心样式,能完整保留系统动画:
#include <dwmapi.h> BOOL HideTitleBar(HWND hwnd) { // 禁用非客户端区域渲染,隐藏系统标题栏 DWMNCRENDERINGPOLICY policy = DWMNCRP_DISABLED; HRESULT hr = DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof(policy)); if (SUCCEEDED(hr)) { // 可选:添加WS_EX_TOOLWINDOW隐藏任务栏上的窗口标题(不需要可跳过) LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); exStyle |= WS_EX_TOOLWINDOW; SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle); // 调整窗口尺寸,让客户端区域覆盖原标题栏位置 RECT winRect; GetWindowRect(hwnd, &winRect); AdjustWindowRectEx(&winRect, GetWindowLongPtr(hwnd, GWL_STYLE), FALSE, exStyle); SetWindowPos(hwnd, NULL, winRect.left, winRect.top, winRect.right - winRect.left, winRect.bottom - winRect.top, SWP_NOZORDER | SWP_FRAMECHANGED); return TRUE; } return FALSE; }
核心逻辑:保留WS_CAPTION、WS_MAXIMIZEBOX、WS_MINIMIZEBOX等关键样式,仅通过DWM关闭非客户端区域的渲染,系统仍会识别窗口的标准属性,从而保留最小化、最大化及隐藏动画。
方案二:保留核心样式,仅移除标题栏绘制
若必须修改窗口样式,需保留动画依赖的关键样式,仅移除标题栏的显示逻辑:
// 获取当前窗口样式 LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE); // 保留最大化、最小化、边框样式,移除系统菜单和标题栏 style &= ~(WS_SYSMENU | WS_CAPTION); style |= WS_BORDER; SetWindowLongPtr(hwnd, GWL_STYLE, style); // 调整窗口尺寸,弥补移除WS_CAPTION后的布局偏移 RECT clientRect; GetClientRect(hwnd, &clientRect); AdjustWindowRectEx(&clientRect, style, FALSE, GetWindowLongPtr(hwnd, GWL_EXSTYLE)); SetWindowPos(hwnd, NULL, 0, 0, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); // 需自行处理窗口拖动:在WM_NCHITTEST消息中返回HTCAPTION
注意事项:
- 绝对不能移除
WS_MAXIMIZEBOX和WS_MINIMIZEBOX,这两个是系统触发动画的必要条件。 - 修改样式后必须调用
SetWindowPos并传入SWP_FRAMECHANGED,强制系统重新绘制窗口框架。 - 若要保留Windows 11的窗口圆角,不要禁用DWM非客户端渲染,而是通过
DwmSetWindowAttribute设置DWMWA_WINDOW_CORNER_PREFERENCE为DWMWCP_ROUND后再隐藏标题栏。
内容的提问来源于stack exchange,提问作者old.
相关产品推荐
相关产品推荐

