返回

Tauri 自定义窗口样式:隐藏标题栏并保留装饰效果

windows

在 Windows 应用程序开发中,隐藏窗口标题栏并实现自定义窗口样式是一个常见的需求。Tauri 作为一个跨平台的桌面应用程序框架,为我们提供了便捷的窗口管理功能。本文将介绍如何使用 Rust 和 WinAPI,在 Tauri 应用程序中隐藏窗口标题栏,同时保留边框、阴影和圆角等装饰效果,并探讨几种不同的实现方案。

隐藏标题栏带来的问题

直接使用 WS_CAPTION 样式移除标题栏,看似简单直接,实际上会带来一些副作用。你可能会发现窗口顶部出现一个奇怪的空白区域,点击这个区域会导致窗口发生一些异常变化,例如最大化或最小化。调整窗口大小时,这个空白区域的大小也会随之改变,显得非常不协调。这些问题的根源在于我们仅仅移除了标题栏,而没有对窗口的其他样式进行相应的调整,导致窗口的行为变得不可预测。

解决方案:精细控制窗口样式

为了彻底解决这些问题,我们需要更精细地控制窗口样式。除了移除 WS_CAPTION 样式之外,还需要添加 WS_THICKFRAMEWS_SYSMENU 样式。

  • WS_THICKFRAME 样式允许用户通过拖动窗口边缘来调整窗口大小。这弥补了移除 WS_CAPTION 样式后失去的窗口调整功能。
  • WS_SYSMENU 样式会在窗口标题栏上添加一个系统菜单,即使标题栏被隐藏,用户仍然可以通过 Alt+Space 快捷键或右键单击窗口边框来访问系统菜单,例如关闭、最小化、最大化等操作。

下面是使用 Rust 和 WinAPI 实现隐藏标题栏并保留窗口功能的代码示例:

use tauri::Manager;
use windows::{
    Win32::Foundation::HWND,
    Win32::UI::WindowsAndMessaging::{
        GetWindowLongW, SetWindowLongW, GWL_STYLE,
    },
};

use winapi::um::winuser::{WS_CAPTION, WS_THICKFRAME, WS_SYSMENU};

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)) | WS_THICKFRAME as i32 | WS_SYSMENU as i32,
                );
            }

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

这段代码首先获取窗口的当前样式,然后通过位运算移除 WS_CAPTION 样式,并添加 WS_THICKFRAMEWS_SYSMENU 样式。这样,我们就能在隐藏标题栏的同时,保留窗口的调整大小功能和系统菜单。

其他方案:第三方库

除了使用 WinAPI 直接操作窗口样式,还可以考虑使用第三方库,例如 window-shadows。这个库提供了更高级的窗口装饰功能,包括圆角、阴影和无标题栏窗口。使用第三方库可以简化开发过程,并提供更丰富的自定义选项。

例如,window-shadows 库可以轻松地为窗口添加阴影效果,并支持自定义阴影颜色、模糊半径等参数。它还提供了创建无标题栏窗口的便捷方法,可以帮助我们快速实现自定义窗口样式。

但是,使用第三方库也可能会引入一些问题。首先,它会增加项目的依赖项,使得项目管理变得更加复杂。其次,第三方库的性能可能不如直接使用 WinAPI,尤其是在窗口调整大小等操作方面。因此,在选择使用第三方库时,需要权衡其优缺点,并根据项目的具体需求做出决策。

总结与选择

通过合理地组合窗口样式或者使用第三方库,我们可以在 Tauri 应用程序中隐藏窗口标题栏,并保留其他装饰效果,例如边框、阴影和圆角等。选择哪种方案取决于项目的具体需求和开发者的偏好。

如果项目对性能要求较高,或者希望对窗口样式有更精细的控制,那么建议直接使用 WinAPI 操作窗口样式。如果项目对开发效率要求较高,或者需要更丰富的窗口装饰功能,那么可以考虑使用第三方库,例如 window-shadows

需要注意的是,直接操作窗口样式或者使用第三方库都可能会影响窗口的行为和外观,因此在开发过程中需要仔细测试和调整,以确保应用程序的稳定性和用户体验。

常见问题

1. 如何在隐藏标题栏后仍然能够拖动窗口?

可以通过添加 WS_THICKFRAME 样式来实现。这个样式允许用户通过拖动窗口边缘来调整窗口大小,即使标题栏被隐藏。

2. 如何在隐藏标题栏后仍然能够访问系统菜单?

可以通过添加 WS_SYSMENU 样式来实现。这个样式会在窗口标题栏上添加一个系统菜单,即使标题栏被隐藏,用户仍然可以通过 Alt+Space 快捷键或右键单击窗口边框来访问系统菜单。

3. 如何为窗口添加阴影效果?

可以使用第三方库,例如 window-shadows,来为窗口添加阴影效果。这个库提供了便捷的方法来创建和自定义窗口阴影。

4. 如何创建圆角窗口?

可以使用第三方库,例如 window-shadows,来创建圆角窗口。这个库提供了便捷的方法来设置窗口的圆角半径。

5. 如何在隐藏标题栏后自定义窗口的拖动区域?

可以使用 WinAPI 的 SetCaptureReleaseCapture 函数来捕获和释放鼠标事件,从而自定义窗口的拖动区域。例如,可以将窗口的客户区设置为拖动区域,即使标题栏被隐藏,用户仍然可以通过拖动窗口的任何位置来移动窗口。

希望本文能帮助你解决在 Tauri 应用程序中隐藏窗口标题栏的问题,并为你提供一些自定义窗口样式的思路。祝你开发顺利!