200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Electron无边框窗口(最小化 最大化 关闭 拖动)以及动态改变窗口大小

Electron无边框窗口(最小化 最大化 关闭 拖动)以及动态改变窗口大小

时间:2021-11-22 01:30:44

相关推荐

Electron无边框窗口(最小化 最大化 关闭 拖动)以及动态改变窗口大小

文章目录

一、目标原型1. 目标2. 原型设计3. 原型初步实现二、无边框窗口1. 要点2. 改造三、可拖拽区1. 要点2. 改造四、最小化、最大化、关闭1. 要点2. 改造五、动态改变窗口大小1. 要点2. 改造六、扩展扩展1:在内嵌的独立项目中怎么实现拖拽、最大化、最小化、关闭?扩展2:在``标签内嵌的页面中怎么实现拖拽、最大化、最小化、关闭?扩展3:如何在Electron关闭时执行cmd命令扩展4:系统托盘tray七、源码下载

一、目标原型

1. 目标

实现一个无边框窗口,包括最小化、最大化、关闭、拖动等功能动态改变窗口大小,即在页面跳转的时候根据需要改变窗口大小

2. 原型设计

(1) 登录窗口(500×300)

点击登录跳转到首页

(2) 首页(全屏)

跳转到首页,自动全屏包括最小化、最大化、关闭,以及灰色区域可拖动整个窗口功能

3. 原型初步实现

创建login.html和index.html页面,实现原型页面基本效果,下文逐步改造,实现Electron无边框窗口。

二、无边框窗口

1. 要点

要创建无边框窗口,只需在BrowserWindow的options中将frame设置为 false:

const {BrowserWindow } = require('electron')let win = new BrowserWindow({width: 800, height: 600, frame: false })win.show()

通过将 transparent 选项设置为 true, 还可以使无框窗口透明:

let win = new BrowserWindow({ transparent: true, frame: false })

参考地址:/docs/api/frameless-window#%E9%80%8F%E6%98%8E%E7%AA%97%E5%8F%A3

2. 改造

main.js文件中添加frame:false

mainWindow = new BrowserWindow({width: 800,height: 600,frame:false,webPreferences: {/*preload: path.join(__dirname, 'preload.js')*/nodeIntegration: true}})

注意:webPreferences的值,如果写preload无nodeIntegration,会影响后面最大最小化功能不起作用,暂不明白原因。

三、可拖拽区

1. 要点

应用程序需要在 CSS 中指定-webkit-app-region: drag来告诉 Electron 哪些区域是可拖拽的在可拖拽区域内部使用-webkit-app-region: no-drag则可以将其中部分区域排除拖动行为可能与选择文本冲突。 例如, 当您拖动标题栏时, 您可能会意外地选择标题栏上的文本。 为防止此操作, 您需要在可区域中禁用文本选择

.titlebar {-webkit-app-region: drag;-webkit-user-select: none;}

在某些平台上,可拖拽区域不被视为窗口的实际内容,而是作为窗口边框处理,因此在右键单击时会弹出系统菜单。 要使上下文菜单在所有平台上都正确运行, 您永远也不要在可拖拽区域上使用自定义上下文菜单。备注:如果你在某些页面设置了可拖拽区,跳转到一个新的页面,而这个新的页面没有设置可拖拽区,则会沿用上一页面的可拖拽区,感觉很奇怪,也没有相应的dom支持,就像取用的上一页面固定的像素区域一样(测试发现是这样,不准确之处请指正,谢谢)。如果拖拽区域不同,这种情况下,在新的页面中设置上拖拽区域即可。

2. 改造

修改index.html页面中的样式,添加相应drag和no-drag特性

<div class="topbar" style="-webkit-app-region: drag;-webkit-user-select: none;"><div class="logo fl"><img src="images/logo.png" alt=""><span>这里写软件名称</span></div><ul class="menu fl" style="-webkit-app-region: no-drag;"><li>菜单1</li><li>菜单2</li><li>菜单3</li><li>菜单4</li></ul><div class="min_max_close fr" style="-webkit-app-region: no-drag;"><img src="images/min.png" id="min" alt=""><img src="images/max.png" id="max" alt=""><img src="images/close.png" id="close" alt=""></div></div>

四、最小化、最大化、关闭

1. 要点

render 进程通过 ipcRenderer 与 ipcMain 进行通讯,以通知 main 进程操作窗体。

2. 改造

(1) 在renderer.js中添加click事件,发送操作命令给主进程

let ipcRenderer = require('electron').ipcRenderer;var max = document.getElementById('max');if (max) {max.addEventListener('click', () => {//发送最大化命令ipcRenderer.send('window-max');//最大化图形切换if (max.getAttribute('src') == 'images/max.png') {max.setAttribute('src', 'images/maxed.png');} else {max.setAttribute('src', 'images/max.png');}})}var min = document.getElementById('min');if (min) {min.addEventListener('click', () => {//发送最小化命令ipcRenderer.send('window-min');})}var close = document.getElementById('close');if (close) {close.addEventListener('click', () => {//发送关闭命令ipcRenderer.send('window-close');})}

(2) 在main.js中接收操作命令,做出相应处理

let ipcMain = require('electron').ipcMain;//接收最小化命令ipcMain.on('window-min', function() {mainWindow.minimize();})//接收最大化命令ipcMain.on('window-max', function() {if (mainWindow.isMaximized()) {mainWindow.restore();} else {mainWindow.maximize();}})//接收关闭命令ipcMain.on('window-close', function() {mainWindow.close();})

补充:这里最大化和取消最大化时,修改图标的方法不合适,因为通过双击drag-area或者拉动窗口到屏幕边缘等操作,也可能修改窗口的状态。

因此,应该在主进程中监听窗口的最大化操作,然后发送命令给渲染进程:

mainWindow.on('maximize', function () {mainWindow.webContents.send('main-window-max');})mainWindow.on('unmaximize', function () {mainWindow.webContents.send('main-window-unmax');})

在渲染进程中接收到相应命令,再进行处理:

ipcRenderer.on('main-window-max', (event) => {max.classList.remove('icon-max');max.classList.add('icon-maxed');});ipcRenderer.on('main-window-unmax', (event) => {max.classList.remove('icon-maxed');max.classList.add('icon-max');});

五、动态改变窗口大小

1. 要点

思路同最小化、最大化、关闭,仅添加了页面调转。

2. 改造

(1) 在main.js中设置启动初始页面为login.html

mainWindow.loadFile('login.html')

(2) 在renderer.js中添加login按钮的click事件,发送最大化给主进程

var loginbtn = document.getElementById('login');if (loginbtn) {loginbtn.addEventListener('click', () => {ipcRenderer.send('window-max');location.href = "index.html";})}

六、扩展

扩展1:在内嵌的独立项目中怎么实现拖拽、最大化、最小化、关闭?

如果你只是用Electron打个包,用它的浏览器功能,里面还是一个完整的其它项目,比如一个普通的java web项目,相当于只是穿层衣服。怎么在里边实现以上最小化、最大化、关闭、拖动等功能呢?

首先创建一个完全独立的nodejs项目,创建一个index页面,其中有最小化、最大化、关闭按钮和拖拽区

在Electron项目index.html中直接跳转到独立项目页面

<script type="text/javascript">window.location='http://localhost:8888/index.html';</script>

实现可拖拽区

同上加上样式即可:style="-webkit-app-region: drag;-webkit-user-select: none;"实现最小化、最大化、关闭

关键的有两步:

(1)在main.js中new BrowserWindow加上nodeIntegration: true

mainWindow = new BrowserWindow({width: 500,height: 300,frame: false,webPreferences: {nodeIntegration: true}})

(2)在独立项目中加上之前的renderer.js文件,在页面中引入renderer.js

<script type="text/javascript" src="renderer.js"></script>

其实不应该这样做,应该可以直接写require('./renderer.js')的,但是这样要求在electron项目中把renderer.js export出来,由于我语法不熟,就直接拷过去了,先不研究了。

扩展2:在<webview>标签内嵌的页面中怎么实现拖拽、最大化、最小化、关闭?

在webview标签上加上nodeintegration属性:

<webview src="/" nodeintegration></webview>

当有此属性时, webview 中的访客页(guest page)将具有Node集成, 并且可以使用像 require 和 process 这样的node APIs 去访问低层系统资源。

扩展3:如何在Electron关闭时执行cmd命令

两种实现方式:/article/170628.htm

我的需求比较简单,简单实现如下:

//接收关闭命令ipcMain.on('window-close', function() {let closeProcess = child_process.exec('taskkill /f /im XXXXX.exe');closeProcess.on('close', function (code) {mainWindow.close();})})

扩展4:系统托盘tray

在任务栏右下角添加图标和右键菜单。查看Electron tray文档即可。

七、源码下载

Electron无边框窗口(最小化、最大化、关闭、拖动)以及动态改变窗口大小

在Electron内嵌的独立项目中怎么实现拖拽、最大化、最小化、关闭

references

[1] 无边框窗口 | Electron

[2] Electron 无边框窗口最大化最小化关闭功能

[3] electron 改变窗体大小

[4] BrowserWindow配置说明文档

[5] webview标签说明文档

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。