文章目录
一、渲染进程与主进程通信
// 渲染进程向主进程发送信息
window.electron.ipcRenderer.invoke('dialog:openFileWindow', {
name: 'list'
})
二、主进程获取渲染进程发送的信息
import { app, shell, BrowserWindow, ipcMain } from 'electron'
function createWindow(): void {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 900,
height: 670,
show: false,
autoHideMenuBar: true,
...(process.platform === 'linux' ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false
}
})
// 使用ipcMain处理渲染进程发送给主进程的消息
ipcMain.handle('dialog:openFileWindow', async (_event, args) => {
const listWindow = new BrowserWindow({
width: 500,
height: 300,
show: false,
autoHideMenuBar: true,
...(process.platform === 'linux' ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false
}
})
listWindow.on('ready-to-show', () => {
listWindow.show()
})
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
listWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '/list')
} else {
listWindow.loadFile(join(__dirname, '../renderer/index.html'))
}
})
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
})
// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
}
}
三、创建窗口的一些参数选项
const windowOptions = {
// 基本窗口尺寸和位置
width: 800, // 窗口宽度,默认为 800px
height: 600, // 窗口高度,默认为 600px
x: 0, // 窗口相对于屏幕的左上角 x 坐标
y: 0, // 窗口相对于屏幕的左上角 y 坐标
useContentSize: false, // 是否使用内容尺寸(不包括边框)来设置窗口大小
// 窗口外观和行为
center: false, // 是否在屏幕中心显示窗口
minWidth: 0, // 窗口最小宽度
minHeight: 0, // 窗口最小高度
maxWidth: 0, // 窗口最大宽度
maxHeight: 0, // 窗口最大高度
resizable: true, // 窗口是否可以调整大小
movable: true, // 窗口是否可以移动
minimizable: true, // 窗口是否可以最小化
maximizable: true, // 窗口是否可以最大化
closable: true, // 窗口是否可以关闭
focusable: true, // 窗口是否可以获取焦点
alwaysOnTop: false, // 窗口是否总是在最前面
fullscreen: false, // 窗口是否全屏
fullscreenable: true, // 窗口是否可以进入全屏模式
simpleFullscreen: false, // 在 macOS 上使用简单全屏模式
skipTaskbar: false, // 是否在任务栏中隐藏窗口
kiosk: false, // 是否启用 kiosk 模式
// 窗口标题和图标
title: '', // 窗口标题
icon: null, // 窗口图标路径
// Web 页面相关
webPreferences: {
nodeIntegration: false, // 是否启用 Node.js 集成
contextIsolation: true, // 是否启用上下文隔离
webSecurity: true, // 是否启用 web 安全特性
allowRunningInsecureContent: false, // 是否允许在 HTTPS 页面中运行 HTTP 内容
preload: '', // 预加载脚本路径
zoomFactor: 1.0, // 页面默认缩放因子
devTools: true, // 是否启用开发者工具
sandbox: false, // 是否启用沙箱模式
enableRemoteModule: false, // 是否启用 remote 模块(Electron 12+ 默认禁用)
autoplayPolicy: 'no-user-gesture-required', // 自动播放策略
spellcheck: true, // 是否启用拼写检查
nativeWindowOpen: false, // 是否使用原生 window.open()
webviewTag: false, // 是否启用 <webview> 标签
plugins: false, // 是否启用插件
experimentalFeatures: false, // 是否启用实验性功能
scrollBounce: false, // 是否启用滚动弹性效果(macOS)
enableWebSQL: true, // 是否启用 WebSQL
defaultFontFamily: {}, // 默认字体族
defaultFontSize: 16, // 默认字体大小
defaultMonospaceFontSize: 13, // 等宽字体默认大小
minimumFontSize: 0, // 最小字体大小
defaultEncoding: 'ISO-8859-1', // 默认编码
offscreen: false, // 是否启用离屏渲染
additionalArguments: [], // 传递给渲染进程的额外参数
},
// 窗口样式和框架
frame: true, // 是否显示窗口边框和标题栏
parent: null, // 父窗口
modal: false, // 是否为模态窗口
acceptFirstMouse: false, // 是否接受第一次鼠标事件
disableAutoHideCursor: false, // 是否在输入时自动隐藏光标
autoHideMenuBar: false, // 是否自动隐藏菜单栏
enableLargerThanScreen: false, // 是否允许窗口大于屏幕
backgroundColor: '#FFF', // 窗口背景颜色
hasShadow: true, // 窗口是否有阴影
opacity: 1.0, // 窗口透明度 (0.0-1.0)
darkTheme: false, // 是否使用深色主题
transparent: false, // 窗口是否透明
type: 'desktop', // 窗口类型(平台特定)
titleBarStyle: 'default', // 标题栏样式 ('default', 'hidden', 'hiddenInset')
trafficLightPosition: null, // 交通灯按钮位置(macOS)
roundedCorners: true, // 窗口是否有圆角
thickFrame: true, // 是否使用厚边框(Windows)
vibrancy: null, // 毛玻璃效果(macOS)
visualEffectState: 'followWindow', // 视觉效果状态(macOS)
// 显示相关
show: true, // 窗口创建后是否立即显示
paintWhenInitiallyHidden: true, // 是否在初始隐藏状态下绘制内容
// 平台特定选项
tabbingIdentifier: '', // 标签页标识符(macOS)
webContents: null, // 使用现有的 webContents 而不是创建新的
timeout: 30, // 等待页面加载的超时时间(秒)
}
四、窗口拖拽
当设置titleBarStyle: 'hidden’时,窗口无法移动
1、使用-webkit-app-region: drag
在需要移动窗口的元素上,添加这个样式,就可以移动窗口了,但是会导致其中的元素事件失效,需要在不需要移动窗口的元素上加上-webkit-app-region: no-drag;才可以使事件生效
2、与主线程通信修改窗口大小
- 1、渲染线程添加mousedown事件
<template>
<div class="main-container" @mousedown="onMouseDown">
<router-view></router-view>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const isKeyDown = ref(false)
const distanceX = ref(0)
const distanceY = ref(0)
const onMouseDown = (event): void => {
isKeyDown.value = true
distanceX.value = event.x
distanceY.value = event.y
window.electron.ipcRenderer.invoke('window:mouseDown')
document.onmousemove = (ev): void => {
if (isKeyDown.value) {
const x = ev.screenX - distanceX.value
const y = ev.screenY - distanceY.value
// 给主进程传入坐标
let data = {
appX: x,
appY: y
}
window.electron.ipcRenderer.invoke('window:custom-adsorption', data)
}
}
document.onmouseup = (): void => {
isKeyDown.value = false
// 清理事件监听器
document.onmousemove = null
document.onmouseup = null
}
}
</script>
<style scoped>
.main-container {
background-color: red;
width: 100vw;
height: 100vh;
overflow: hidden;
}
</style>
- 2、主线程处理
// 这是因为window中,调用setPosition会修改窗口尺寸,所以我们这里每次获取一次窗口尺寸,在下面进行调用
ipcMain.handle('window:mouseDown', () => {
currentWindowSize = mainWindow.getSize()
})
ipcMain.handle('window:custom-adsorption', async (_event, args) => {
const x = args.appX
const y = args.appY
// 因为window下设置窗口位置会导致窗口大小变化,所以如下处理
const newBounds = {
x,
y,
width: currentWindowSize[0],
height: currentWindowSize[1]
}
mainWindow.setBounds(newBounds)
})
五、自定义实现关闭、最大化、最小化功能
ipcMain.handle('window:closeApp', () => {
// 退出程序
app.quit()
// 关闭窗口
// mainWindow.close()
})
// 最小化
ipcMain.handle('window:minWindow', () => {
mainWindow.minimize()
})
// 最大化切换
ipcMain.handle('window:maxWindow', () => {
// 获取屏幕大小
const screenSize = screen.getPrimaryDisplay().size
// 设置为全屏
if (!isFullscreen) {
isFullscreen = true
// 获取当前窗口位置大小信息
currentWindowBounds = mainWindow.getBounds()
mainWindow.setBounds(
{
x: 0,
y: 0,
width: screenSize.width,
height: screenSize.height
},
true
)
} else {
isFullscreen = false
mainWindow.setBounds(currentWindowBounds, true)
}
})