electron自定义窗口和右键菜单样式

news/2024/7/10 1:28:16 标签: electron, 前端框架, 前端, vue

前言

electron默认沿用系统UI,并没有提供很多接口供使用者定制样式,如果想要完全自定义的样式,目前我能想到的方案只能是通过前端自定义样式,然后通过进程通信来实现系统基础功能:最大/小化、关闭、拖动窗口等。

效果图:
在这里插入图片描述
在这里插入图片描述

一、窗口自定义

通过前面系列文章我们可以了解到,窗口是通过实例化BrowserWindow对象创建的,实例化时会传入一些窗口的参数。

要实现窗口自定义,就必须把窗口默认样式都屏蔽。几个关键的参数如下:

transparent: true,
backgroundColor:'rgba(0,0,0,0)',
frame:false,

参数含义很好理解,窗体透明无边框,参数详解请查询官网。

把系统自带的窗体样式去掉后,我们会得到一个只有主体的窗口,这个主体就是前端vue)渲染的窗口,我们可以通过控制它,来实现任何样式的窗口。

但是这会带来一个问题,那就是窗口对象提供的很多便捷功能无法使用了,所以如果需要做最大化、最小化、拖动窗口等功能,只能通过进程通信,前端发送指令,主进程接收指令后,完成相应功能。具体原理请参考本系列前面关于进程通信的文章。

这里简单列一个示例代码,以最大化为例:

//vue代码部分,在某个dom元素上监听事件
<img class="title-icon" src="@/assets/img/maxsize.png"  alt="最大化" @click="handleMaxSize()">

 function handleMaxSize(){
        renderApi.handleMaxSize()
    }
//preload.js中定义通信的api,下面是我项目中所有渲染进程到主进程的通信

const handleSendPageName= (pageName) => ipcRenderer.send('send-page-name', pageName) //渲染进程主动到主进程
const handleMinSize= () => ipcRenderer.send('send-min-size') //渲染进程主动到主进程
const handleMaxSize= () => ipcRenderer.send('send-max-size') //渲染进程主动到主进程
const handleRestore= () => ipcRenderer.send('send-restore') //渲染进程主动到主进程
const handleRelaunch= () => ipcRenderer.send('user-click-Dock-Icon') //渲染进程主动到主进程

const handleCloseWin=()=>{
    ipcRenderer.send('send-auto-close')
}

contextBridge.exposeInMainWorld('renderApi', {
    //监听渲染进程事件
    handleGetStoreFiles,
    handleSendPageName,
    handleMinSize,
    handleMaxSize,
    handleCloseWin,
    handleRestore,
    handleRelaunch
})
//主进程main.js中接收对应的通信
     ipcMain.on('send-max-size', () => {
            if(win.isMaximized()){
                win.unmaximize()
            }else{
                win.maximize()
            }
        })

至此,模拟窗口最大化功能的全部过程就打通了。

二、窗口拖拽功能

这里值得注意的是,拖拽窗口不止是要配置参数,还要给对应dom元素增加类。

比如说我想实现拖动类名为“c-drag”的元素时,拖动窗口移动,大致代码如下:

   <div class="c-drag">

 </div>
.c-drag{
  -webkit-app-region: drag;
}

-webkit-app-region: drag是electron提供的css样式,具体可查询官网。

这是一个比较小众的知识点,网上资料目前较少,这里记录一下。

三、不同窗口设置不同大小

这一部分逻辑略微复杂。

窗口大小的设置一定是在主进程中设置,如果仅仅依靠vue部分控制显示区域大小,不显示区域设置为透明,虽然视觉上可以实现不同的窗体大小,但是这是一种伪实现,因为透明部分只是人眼看不到而已,鼠标点击、拖拽等功能仍然存在,就会对软件用户造成困扰。

在主进程中设置窗口大小,最重要的就是进入不同页面时,要主动向主进程发送指令,并告诉主进程,我现在进入登录页了,我现在进入正常页了,我现在进入xx页……

主进程接收指令后,根据参数,控制窗口的大小即可。

在我的项目中,各页面有一个统一的路由跳转方法,所以我在跳转路由后,同时将活跃页面的name通handleSendPageName发送给主进程。代码如下:

function turnToPage_menu(name) {
  console.log(name)
  turnToPage(router, name)

  renderApi.handleSendPageName(activeName.value) //发送pageName到主进程,以此判断窗口大小

}

主进程接收到指令后,根据参数,决定窗口设置为多大,代码:

  ipcMain.on('send-page-name', (event, pageName) => {
            console.log('setWindowSize',pageName)
            const loginSize={
                width:500,
                height:580
            }
            const pageSize={
                width:1000,
                height: 950
            }
            if (pageName && pageName == 'normalLogin') {
                win.setSize(loginSize.width, loginSize.height)
                win.center()
                win.setMenuBarVisibility(false)

            } else {
                if(this.judgePageSet(win,pageSize,loginSize)){
                    win.setSize(pageSize.width, pageSize.height)
                    win.center()
                    win.setMenuBarVisibility(true)
                }

            }
        })

至此不同页面实现不同大小的窗口功能,就实现了。

其实在我们项目中,还有另一种需求场景,那就是当通过注册表把软件注册到系统右键后,上传文件时,右下角有一个简易窗口,窗口高度根据上传文件数量来计算。这就需要判断命令行参数、获取文件下载地址等操作,更加复杂,但是应用场景应该不多,有兴趣的同学可以私聊,此处不再赘述。

四、右键菜单自定义

我并没有在实际项目中真正实现过右键菜单的自定义,但是道理和窗口是相通的,如果electron提供的右键菜单样式无法满足要求,那就舍弃框架提供的便捷菜单,通过进程间通信,手动实现。

总结

  1. 舍弃系统窗口所有功能,利用通信机制,模拟实现需要的窗口功能。
  2. 判断页面发送的参数,为不同页面的窗口设置不同的样式。

http://www.niftyadmin.cn/n/5320819.html

相关文章

HCIP-2

Broadcast 类型查看 [R4]display ospf interface g0/0/0 OSPF Process 100 with Router ID 4.4.4.4 Interfaces Interface: 34.1.1.2 (GigabitEthernet0/0/0) Cost: 1 State: DROther Type: Broadcast MTU: 1500 Priority: 0 Designated Router: 34.1.1.1 Backup…

Spring Boot项目中校验器的使用与注意事项

Spring Boot项目中校验器的使用与注意事项 Spring Boot为开发者提供了强大而灵活的校验机制&#xff0c;通过使用校验器&#xff08;Validator&#xff09;&#xff0c;我们能够在应用程序中方便地进行数据验证和错误处理。本文将深入介绍Spring Boot中校验器的使用方法&#…

AVL树(Java)

目录 一、什么是AVL树 二、AVL树的实现 AVL树的节点 AVL树的插入 AVL树的旋转 右单旋 左单旋 左右双旋 右左双旋 AVL树的验证 三、AVL树的性能分析 一、什么是AVL树 在了解什么是AVL树之前&#xff0c;我们先回顾二叉搜索树的概念 二叉搜索树&#xff08;二叉排序…

Sip - Ubuntu 配置 miniSIPServer 服务器(测试用)

客户提供的账号过期了&#xff0c;简单搭建 SIP 服务器&#xff0c;以便测试使用。个人认为这个配置起来最为简单&#xff0c;且测试功能足够。 官网miniSIPServer - 基于 Windows 以及 Linux 平台的 VoIP (SIP) 服务器软件. miniSIPServer 可能是最容易使用的 VoIP(SIP) 服务器…

CCRC认证办理流程以及申报材料

CCRC认证办理流程 签订合同--咨询老师收集信息--申报资料处理--申报资料/项目过程文档提交--文审--整改--&#xff08;现场审核--整改&#xff09;证书批准--证书下发--公示--监督审核。 认证流程&#xff1a; 1.资料提供&#xff1a;企业提供符合要求的完工项目合同、验收报…

Java LeetCode刷题 单调栈

单调栈 单调栈概念 每日温度 单调栈 概念 单调栈&#xff08;Monotonic Stack&#xff09;是一个特殊的数据结构&#xff0c;它是一种栈&#xff0c;但具有单调性的特性。单调栈有两种类型&#xff1a;单调递增栈和单调递减栈。 在单调递增栈中&#xff0c;栈内的元素保持递…

数据结构排序——详细讲解归并排序(c语言实现递归及非递归)

上次是快排和冒泡&#xff1a;数据结构排序——详解快排及其优化和冒泡排序(c语言实现、附有图片与动图示意&#xff09; 今天为大家带来归并排序 文章目录 1.基本思想2.递归实现3.非递归实现 1.基本思想 归并排序是一种分治算法&#xff0c;它将序列分成两个子序列&#xff0…

【RV1126 学习】SDK/ U-Boot/kernel/rootfs 编译学习

文章目录 RV1126芯片介绍rv1126 模块代码目录相关说明 SDK 包下的脚本使用build.sh 脚本使用envsetup.sh 脚本使用mkfirmware.sh 脚本使用rkflash.sh 脚本使用 U-Boot 编译和配置uboot 的配置修改编译操作 kernel 的修改编译rootfs 编译和配置buildroot 配置busybox 配置 RV112…