Rust实现Windows平台Tauri窗口隐藏标题栏并保留装饰
问题
Windows 11下,想要移除Tauri窗口的标题栏,但保留边框、阴影和圆角等装饰效果。使用winapi和windows库编写代码后,标题栏消失但出现异常:窗口弹出时顶部有奇怪的栏,点击该栏和调整窗口大小都会出现异常显示。尝试过window-shadows库,虽能实现圆角和无标题栏,但窗口调整困难且丢失启动动画。
原代码:
use tauri::Manager; use windows::{ Win32::Foundation::HWND, Win32::UI::WindowsAndMessaging::{ GetWindowLongW, SetWindowLongW, GWL_STYLE, }, }; use winapi::um::winuser::{WS_CAPTION}; fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![greet]) .setup(|app| { let window = app.get_window("main").unwrap(); let hwnd = HWND(window.hwnd().unwrap().0); unsafe { let styles = GetWindowLongW(hwnd, GWL_STYLE); SetWindowLongW(hwnd, GWL_STYLE, styles & !(WS_CAPTION as i32)); } Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
解决方案
直接移除WS_CAPTION会破坏Windows 11窗口的标准装饰逻辑,导致布局和交互异常。正确的做法是保留必要的窗口样式,仅隐藏标题栏,同时处理窗口拖动和大小调整逻辑,确保系统阴影、圆角等装饰效果正常。
改进后的代码:
use tauri::{Manager, WindowEvent}; use windows::{ Win32::Foundation::HWND, Win32::UI::WindowsAndMessaging::{ GetWindowLongW, SetWindowLongW, SetWindowPos, GWL_STYLE, SWP_FRAMECHANGED, SWP_NOMOVE, SWP_NOSIZE, WS_CAPTION, WS_THICKFRAME, WS_SYSMENU, WS_MINIMIZEBOX, WS_MAXIMIZEBOX }, }; fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![greet]) .setup(|app| { let window = app.get_window("main").unwrap(); let hwnd = HWND(window.hwnd().unwrap().0); unsafe { // 获取当前窗口样式 let mut styles = GetWindowLongW(hwnd, GWL_STYLE); // 移除标题栏,保留必要的交互和装饰样式 styles &= !(WS_CAPTION as i32); styles |= (WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) as i32; SetWindowLongW(hwnd, GWL_STYLE, styles); // 强制窗口框架更新,避免样式切换异常 SetWindowPos(hwnd, None, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); } // 实现自定义窗口拖动:指定顶部区域为可拖动范围 window.on_window_event(|event| { if let WindowEvent::MouseDown { position, .. } = event { // 可根据UI布局调整拖动区域的高度 if position.y <= 20.0 { let _ = window.start_drag(); } } }); Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
核心改进说明
- 保留关键样式:移除
WS_CAPTION的同时,保留WS_THICKFRAME(支持窗口大小调整)、WS_SYSMENU(右键菜单功能)、WS_MINIMIZEBOX/WS_MAXIMIZEBOX(最小化/最大化按钮),确保基础交互正常。 - 强制样式刷新:调用
SetWindowPos并传入SWP_FRAMECHANGED,触发系统重新绘制窗口框架,解决样式切换后的异常显示问题。 - 自定义拖动逻辑:通过监听鼠标按下事件,指定窗口顶部区域为可拖动区域,替代原生标题栏的拖动功能,解决无标题栏后无法拖动窗口的问题。
- 兼容Windows 11装饰:该方式不会破坏系统对窗口圆角、阴影的原生渲染,保留系统默认的视觉效果,也不会丢失启动动画。
如果不需要最小化/最大化按钮,可以移除对应的WS_MINIMIZEBOX/WS_MAXIMIZEBOX样式,但需保留WS_THICKFRAME以支持窗口大小调整。
内容的提问来源于stack exchange,提问作者ItsBursty
相关产品推荐
相关产品推荐

