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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:11:21