在 Electron + Vue3 + TypeScript 应用中实现双击窗口放大功能,需要在主进程中监听窗口的双击事件,并控制窗口的最大化状态。下面是完整实现方案:
### 一、基础实现步骤
#### 1. 在主进程中创建窗口并监听双击事件
```typescript:src/main/index.ts
import { app, BrowserWindow, ipcMain } from 'electron';
import path from 'path';
let mainWindow: BrowserWindow | null = null;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
contextIsolation: false,
devTools: true
},
// 对于无边框窗口,需要额外处理
// frame: false
});
// 加载应用
mainWindow.loadURL('http://localhost:3000');
// 监听窗口双击事件
mainWindow.on('dblclick', () => {
toggleMaximize();
});
// 可选:监听标题栏双击事件(如果有自定义标题栏)
ipcMain.on('title-bar-dblclick', () => {
toggleMaximize();
});
}
// 切换窗口最大化状态
function toggleMaximize() {
if (mainWindow) {
if (mainWindow.isMaximized()) {
mainWindow.unmaximize();
} else {
mainWindow.maximize();
}
}
}
app.whenReady().then(createWindow);
// 其他代码省略
```
#### 2. 处理自定义标题栏的情况
如果你的应用使用了无边框窗口和自定义标题栏,需要在渲染进程中监听标题栏的双击事件并通知主进程:
```vue:src/renderer/components/CustomTitleBar.vue
<template>
<div class="custom-title-bar" @dblclick="handleDoubleClick">
<div class="window-title">{{ title }}</div>
<div class="window-controls">
<!– 最小化、最大化、关闭按钮 –>
</div>
</div>
</template>
<script setup lang="ts">
import { defineProps } from 'vue';
import { ipcRenderer } from 'electron';
export interface TitleBarProps {
title: string;
}
const props = defineProps<TitleBarProps>();
const handleDoubleClick = () => {
// 通知主进程标题栏被双击
ipcRenderer.send('title-bar-dblclick');
};
</script>
<style scoped>
.custom-title-bar {
height: 32px;
background-color: #f5f5f5;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
-webkit-app-region: drag; /* 允许拖动 */
}
.window-title {
font-size: 14px;
}
.window-controls {
-webkit-app-region: no-drag; /* 控制按钮区域不允许拖动 */
}
</style>
```
### 二、Windows 系统特定问题解决
Windows 系统下可能会遇到以下问题及解决方案:
#### 1. 窗口边框双击问题
在 Windows 上,双击窗口边框默认会调整窗口大小。如果想禁用此行为,可以在创建窗口时设置:
```typescript
mainWindow = new BrowserWindow({
// 其他配置
resizable: true,
enableLargerThanScreen: true,
// 添加以下配置
frame: true, // 确保使用系统边框
autoHideMenuBar: true
});
```
#### 2. 无边框窗口的双击最大化
对于无边框窗口,Windows 系统没有默认的双击最大化行为,需要完全自己实现:
```typescript
// 在创建无边框窗口时
mainWindow = new BrowserWindow({
width: 800,
height: 600,
frame: false, // 无边框
webPreferences: {
// 其他配置
}
});
// 监听整个窗口的双击事件
mainWindow.on('dblclick', () => {
toggleMaximize();
});
// 或者只监听标题栏区域的双击(通过IPC)
ipcMain.on('title-bar-dblclick', () => {
toggleMaximize();
});
```
#### 3. 最大化时避免覆盖任务栏
在 Windows 上,有时窗口最大化会覆盖任务栏,可以通过以下方式解决:
```typescript
function toggleMaximize() {
if (mainWindow) {
if (mainWindow.isMaximized()) {
mainWindow.unmaximize();
} else {
// 获取系统工作区大小(不包括任务栏)
const { workArea } = require('electron').screen.getPrimaryDisplay();
mainWindow.setBounds({
x: workArea.x,
y: workArea.y,
width: workArea.width,
height: workArea.height
});
}
}
}
```
### 三、完整的主进程代码示例
```typescript:src/main/index.ts
import { app, BrowserWindow, ipcMain, screen } from 'electron';
import path from 'path';
let mainWindow: BrowserWindow | null = null;
function createWindow() {
// 获取系统工作区大小
const { workArea } = screen.getPrimaryDisplay();
mainWindow = new BrowserWindow({
width: 800,
height: 600,
x: (workArea.width – 800) / 2,
y: (workArea.height – 600) / 2,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
contextIsolation: false
},
autoHideMenuBar: true
});
mainWindow.loadURL('http://localhost:3000');
// 监听窗口双击事件
mainWindow.on('dblclick', () => {
toggleMaximize();
});
// 监听来自渲染进程的标题栏双击事件
ipcMain.on('title-bar-dblclick', () => {
toggleMaximize();
});
}
// 切换窗口最大化状态
function toggleMaximize() {
if (mainWindow) {
if (mainWindow.isMaximized()) {
mainWindow.unmaximize();
} else {
// 确保最大化时不会覆盖任务栏
const { workArea } = screen.getPrimaryDisplay();
mainWindow.setBounds({
x: workArea.x,
y: workArea.y,
width: workArea.width,
height: workArea.height
});
}
}
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
```
### 四、总结
实现 Electron + Vue3 + TypeScript 应用的双击窗口放大功能需要:
1. 在主进程中监听窗口的 `dblclick` 事件
2. 实现 `toggleMaximize` 函数来切换窗口的最大化状态
3. 对于自定义标题栏,需要在渲染进程中监听双击事件并通过 IPC 通知主进程
4. 在 Windows 系统上,需要特别注意处理无边框窗口和避免覆盖任务栏的问题
通过以上实现,你可以在各种情况下实现双击窗口放大/还原功能,提升用户体验。
评论前必须登录!
注册