electron+vue3全家桶+vite项目搭建【29】封装窗口工具类【3】控制窗口定向移动

文章目录

    • 引入
    • 实现效果
    • 思路
    • 声明通用的定位对象
    • 主进程模块
    • 渲染进程
    • 测试效果

引入

demo项目地址
窗口工具类系列文章:
封装窗口工具类【1】雏形
封装窗口工具类【2】窗口组,维护窗口关系
封装窗口工具类【3】控制窗口定向移动

很多时候,我们想直接让某个窗口移动到边角,例如居中、左上、右下等位置,electron没有提供直接的api来实现这种操作,我们不妨基于electron的位置移动api进行封装,实现窗口灵活的定向移动

实现效果

  • 输入key可以操作指定窗口,不输入则操作本窗口
  • 可以直接根据position参数快速控制窗口定向移动
  • 输入偏移量微调窗口
    electron+vue3控制窗口定向移动柜

思路

electron位置相关api

electron获取某个窗口所在屏幕的显示对象

首先electron的窗口位置也是有(x,y)坐标,对应横轴和纵轴,我们可以使用窗口移动api设置x和y,左上角就是[0,0],然后我们可以通过screen.getDisplayMatching(rect)来获取窗口所在屏幕的展示对象,从中可获取屏幕的长宽和x,y等信息,接着咱们直接用这两个数据做差即可:

假如屏幕用s表示,窗口用w表示,窗口居中计算如下:

x = s.x + (s.width - w.width) / 2
y = s.y + (s.height - w.height) / 2

声明通用的定位对象

  • types\global.d.ts
/** 一些全局的对象补充声明 */
export {};
declare global {....../*** ================= 窗口定位相关参数 ================*//** 自定义定位类型 */type MyPosition =| "center" // 居中| "bottom-left" // 左下| "bottom-right" // 右下| "top-right" // 右上| "top-left"; // 左上/*** 注意,这里指的屏幕是当前窗口所在的屏幕【存在多个屏幕的情况下】*/interface IWindowPosition {windowKey?:string; // 窗口的key,不传就是修改本窗口的位置x?: number; // 屏幕左上角开始x轴位置y?: number; // 屏幕左上角开始y轴位置relativeWindowId?: number; // 相对于某个窗口的位置/默认相对于屏幕position?: MyPosition; // 相对于屏幕或窗口的位置offsetX?: number; // X轴偏移量offsetY?: number; // Y轴偏移量}
}

主进程模块

1.我们在窗口工具类中补充一个修改窗口位置的方法

  • electron\main\windowUtils.ts
  • 这里还补充了一个横纵轴的偏移量offsetX,offsetY,用于需要微调定位的情况
  • 这里我们把window作为参数传入,而不是在方法内部直接通过key去获取,是为了方便后续其他在工具类中的位置修改操作方便调用
import {screen} from "electron";export class WindowUtils {...
/*** 修改窗口的位置* @param window 窗口对象* @param windowPosition 位置参数对象*/changeWindowPostion(window: BrowserWindow, windowPosition: IWindowPosition) {// xy轴值let x = windowPosition.x;let y = windowPosition.y;if (x != null && y != null) {// 偏移量const offsetX = windowPosition.offsetX || 0;const offsetY = windowPosition.offsetY || 0;x = windowPosition.x + offsetX;y = windowPosition.y + offsetY;// 如果是相对于某个窗口的话,加上相对窗口的x、y坐标if (windowPosition.relativeWindowId) {const relativeWin = BrowserWindow.fromId(windowPosition.relativeWindowId);if (relativeWin) {x += relativeWin.getPosition()[0];y += relativeWin.getPosition()[1];}}window.setPosition(x, y);}// 如果有定位if (windowPosition.position) {// 偏移量const offsetX = windowPosition.offsetX || 0;const offsetY = windowPosition.offsetY || 0;const winBounds = window.getBounds();let relativeBounds = screen.getDisplayMatching(winBounds).bounds;if (windowPosition.relativeWindowId) {const relativeWin = BrowserWindow.fromId(windowPosition.relativeWindowId);if (relativeWin) {relativeBounds = relativeWin.getBounds();}}// 计算坐标switch (windowPosition.position) {case "center":window.setPosition(relativeBounds.x +(relativeBounds.width - winBounds.width) / 2 +offsetX,relativeBounds.y +(relativeBounds.height - winBounds.height) / 2 +offsetY);break;case "bottom-left":window.setPosition(relativeBounds.x + offsetX,relativeBounds.y +relativeBounds.height -winBounds.height +offsetY);break;case "bottom-right":window.setPosition(relativeBounds.x + relativeBounds.width - winBounds.width + offsetX,relativeBounds.y +relativeBounds.height -winBounds.height +offsetY);break;case "top-left":window.setPosition(relativeBounds.x + offsetX,relativeBounds.y + offsetY);break;case "top-right":window.setPosition(relativeBounds.x + relativeBounds.width - winBounds.width + offsetX,relativeBounds.y + offsetY);break;}}}
}

2.接着我们补充两个获取窗口的方法

  • electron\main\windowUtils.ts
export class WindowUtils {.../*** 通过窗口事件获取发送者的窗口* @param event ipc发送窗口事件*/getWindowByEvent(event: Electron.IpcMainInvokeEvent): BrowserWindow {const webContentsId = event.sender.id;for (const currentWin of BrowserWindow.getAllWindows()) {if (currentWin.webContents.id === webContentsId) {return currentWin;}}return null;}/*** 通过传入的key获取指定的窗口* @param key 窗口唯一key*/getWindowByKey(key: string): BrowserWindow {return BrowserWindow.fromId(this.group.get(key).windowId);}   
}

3.接着我们在listen方法中补充handle监听,来处理渲染进程的事件

  • electron\main\windowUtils.ts
export class WindowUtils {...listen() {...// 窗口位置修改监听ipcMain.handle(CustomChannel.window_position_change,(_, windowPosition: IWindowPosition) => {// 假如传了窗口的key,则获取对应窗口,假如没传,则用发送事件的窗口const windowKey = windowPosition.windowKey;const cureentWin =windowKey && windowKey.length > 0? this.getWindowByKey(windowKey): this.getWindowByEvent(_);this.changeWindowPostion(cureentWin, windowPosition);});}
}

渲染进程

1.工具类中补充窗口位置修改方法调用

  • src\utils\electronUtils.ts
/*** 修改当前窗口的位置* @param windowPosition 窗口位置修改参数*/
export function changeWindowPosition(windowPosition: IWindowPosition) {ipcRenderer.invoke(CustomChannel.window_position_change, windowPosition);
}

2.写一个功能展示的demo

  • src\components\demo\WindowPositionDemo.vue
<template><div class="mockDemo"><GoBack></GoBack><ul><li><el-input v-model="windowKey"></el-input></li><li><el-form inline><el-form-item label="距离左边距离"><el-input v-model="x"></el-input></el-form-item><el-form-item label="距离上边距离"><el-input v-model="y"></el-input></el-form-item><el-form-item label="距离左边偏移量"><el-input v-model="offsetX"></el-input></el-form-item><el-form-item label="距离上边偏移量"><el-input v-model="offsetY"></el-input></el-form-item><el-form-item><el-button@click="changeWindowPosition({x: Number.parseFloat(x),y: Number.parseFloat(y),offsetX: Number.parseFloat(offsetX),offsetY: Number.parseFloat(offsetY),windowKey,})">移动位置</el-button></el-form-item></el-form></li><li><el-button@click="changeWindowPosition({position: 'top-left',offsetX: Number.parseFloat(offsetX),offsetY: Number.parseFloat(offsetY),windowKey,})">左上</el-button><el-button@click="changeWindowPosition({position: 'top-right',offsetX: Number.parseFloat(offsetX),offsetY: Number.parseFloat(offsetY),windowKey,})">右上</el-button></li><li><el-button@click="changeWindowPosition({position: 'center',offsetX: Number.parseFloat(offsetX),offsetY: Number.parseFloat(offsetY),windowKey,})">居中</el-button></li><li><el-button@click="changeWindowPosition({position: 'bottom-left',offsetX: Number.parseFloat(offsetX),offsetY: Number.parseFloat(offsetY),windowKey,})">左下</el-button><el-button@click="changeWindowPosition({position: 'bottom-right',offsetX: Number.parseFloat(offsetX),offsetY: Number.parseFloat(offsetY),windowKey,})">右下</el-button></li></ul></div>
</template><script setup lang="ts">
import { changeWindowPosition } from "@/utils/electronUtils";
import { ref } from "vue";
const x = ref("0");
const y = ref("0");
const offsetX = ref("0");
const offsetY = ref("0");
const windowKey = ref("");
</script><style scoped>
ul {list-style: none;
}
</style>

测试效果

可以随心所欲的控制任何窗口到处定向移动了,是不是很酷 _三└(┐卍 ˘ω˘)卍

  • 输入key可以操作指定窗口,不输入则操作本窗口
  • 可以直接根据position参数快速控制窗口定向移动
  • 输入偏移量微调窗口
    electron+vue3控制窗口定向移动柜

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/269135.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言--- qsort函数

目录 一.qsort函数 1.qsort函数的功能 2.四个参数讲解 (1)base (2)num (3)size (4)compare 3.使用qsort函数对一个整形数组进行排序 4.qsort函数排序结构体数据 第一种&#xff1a;按照年龄进行比较 第二种&#xff1a;按照名字进行排序 二.利用冒泡排序模仿qsort函…

嵌入式驱动学习第二周——Linux内核打印

前言 这篇博客来聊一聊Linux内核打印。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关注本博主并订阅本专栏&#xff0c;一起讨论一起学习。现在关注就是老粉啦&#xff01; 目录 前言1. dmesg指令…

#QT(串口助手-实现)

1.IDE&#xff1a;QTCreator 2.实验 3.记录 &#xff08;1&#xff09;在widget.h中加入必要文件&#xff0c;并且定义一个类指针 &#xff08;2&#xff09;如果有类的成员不知道怎么写&#xff0c;可以通过以下途径搜索 &#xff08;2&#xff09;设置串口数据 void Widget…

Java架构之路-架构应全面了解的技术栈和工作域

有时候我在想这么简单简单的东西&#xff0c;怎么那么难以贯通。比如作为一个架构师可能涉及的不单单是技术架构&#xff0c;还包含了项目管理&#xff0c;一套完整的技术架构也就那么几个技术栈&#xff0c;只要花点心思&#xff0c;不断的往里面憨实&#xff0c;总会学的会&a…

JavaScript基础2之运算符、函数

JavaScript基础 运算符一元操作符递增/递减一元加和减 布尔操作符逻辑非逻辑与逻辑或 乘性操作符乘法操作符除法操作符取模操作符 加性操作符加法操作符减法操作符 比较操作符相等操作符关系操作符 函数函数声明函数表达式箭头函数函数的实参和形参arguments 默认参数参数的拓展…

tomcat优化、nginx +tomcat 部署 (三)

在目前流行的互联网架构中&#xff0c;Tomcat在目前的网络编程中是举足轻重的&#xff0c;由于Tomcat的运行依赖于JVM&#xff0c;从虚拟机的角度把Tomcat的调整分为外部环境调优 JVM 和 Tomcat 自身调优两部分 Tomcat 是一个流行的开源 Java 服务器&#xff0c;用于托管 Java …

第十二届“中关村青联杯”全国研究生数学建模竞赛-A题:水面舰艇编队防空和信息化战争评估模型(续)

目录 5.5 问题五模型的建立与求解 5.5.1 战略级信息化战争评估模型 5.5.2 战略级信息化战争评估模型的验证 6. 模型的评价 6.1 模型的优点 6.2 模型的缺点 参考文献 代码实现 附件1 &#xff08;1&#xff09;No_1_result.m 源代码 &#xff08;2&#xff09;No_1_figure.m 源代…

汽车零部件制造中的信息抽取技术:提升效率与质量的关键

一、引言 在汽车制造业中&#xff0c;零部件的生产是整个制造流程的关键一环。这些零部件&#xff0c;包括但不限于制动系统、转向系统和传动系统&#xff0c;是确保汽车安全、可靠运行的基础。为了满足现代汽车工业对效率和质量的严格要求&#xff0c;制造商们纷纷投入到高度…

HarmonyOS—HAP唯一性校验逻辑

HAP是应用安装的基本单位&#xff0c;在DevEco Studio工程目录中&#xff0c;一个HAP对应一个Module。应用打包时&#xff0c;每个Module生成一个.hap文件。 应用如果包含多个Module&#xff0c;在应用市场上架时&#xff0c;会将多个.hap文件打包成一个.app文件&#xff08;称…

P-States/C-States/S-States/G-States/D-States

P-States是指处理器的性能状态&#xff0c;可以根据需要调整处理器的工作频率和电压来平衡性能和能效。 S-States是指系统的睡眠状态&#xff0c;可以让系统在空闲时进入低功耗状态以节省能量。 G-States是系统的全局状态&#xff0c;通常用于描述整个系统的运行状态。 C-St…

文件上传之图片马

图片马介绍 图片马&#xff1a;就是在正常图片中插入木马。 图片马的制作 1.我们先创建php木马文件1.php&#xff0c;内容有以下两种方式&#xff1a; <?php eval($_POST[a]); ?> /* 常规一句话木马 */ <?php $aPD9waHAgQGV2YWwoJF9QT1NUWydhJ10pOz8; $myfile…

使用Pytorch导出自定义ONNX算子

在实际部署模型时有时可能会遇到想用的算子无法导出onnx&#xff0c;但实际部署的框架是支持该算子的。此时可以通过自定义onnx算子的方式导出onnx模型&#xff08;注&#xff1a;自定义onnx算子导出onnx模型后是无法使用onnxruntime推理的&#xff09;。下面给出个具体应用中的…

重构笔记系统:Docker Compose在微服务架构中的应用与优化

虽然我的笔记系统的开发是基于微服务的思想&#xff0c;但是在服务的配置和编排上感觉还是不太合理&#xff0c;具体来说&#xff0c;在开发上的配置和在生产上的配置差别太大。现在规模小&#xff0c;后面规模变大&#xff0c;估计这一块会成为系统生长的瓶颈。 因此&#xff…

推特API(Twitter API)对接说明,用户code To Token换取

前期准备 提前准备、说明&#xff1a;目前对接推特api开发门户分为3个版本&#xff0c;分别是免费的&#xff0c;100美金一个月的基础版以及5000美金一个月的企业版&#xff0c;免费的目前就两个接口可以调用&#xff0c;所以想要对接和使用推特最基本的也需要付100美元一个月…

ETAS工具链ISOLAR-AB重要概念,RTE配置,ECU抽取

RTE配置界面&#xff0c;包含ECU抽取关联 首次配置RTE&#xff0c;出现需要勾选的抽取EXTRACT 创建System System制作SWC到ECU的Mapping System制作System Data 的Mapping

LabVIEW眼结膜微血管采集管理系统

LabVIEW眼结膜微血管采集管理系统 开发一套基于LabVIEW的全自动眼结膜微血管采集管理系统&#xff0c;以提高眼结膜微血管临床研究的效率。系统集成了自动化图像采集、图像质量优化和规范化数据管理等功能&#xff0c;有效缩短了图像采集时间&#xff0c;提高了图像质量&#…

9.WEB渗透测试-Linux基础知识-Linux用户权限管理(上)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;8.WEB渗透测试-Linux基础知识-Linux基础操作&#xff08;二&#xff09;-CSDN博客 用户管…

Laravel框架: Call to a member function connect() on null 异常报错处理

Laravel框架&#xff1a; Call to a member function connect() on null 异常报错处理 Date: 2024.03.01 21:03:11 author: lijianzhan 原文链接: https://learnku.com/laravel/t/63721 问题&#xff1a; local.ERROR: Call to a member function connect() on null {"…

【办公类-21-08】三级育婴师 多个二级文件夹的docx合并成PDF

背景需求: 前期制作了单题文件夹 【办公类-21-07】新建文件夹 三级育婴师操作参考题目-CSDN博客文章浏览阅读439次&#xff0c;点赞7次&#xff0c;收藏10次。【办公类-21-07】新建文件夹 三级育婴师操作参考题目https://blog.csdn.net/reasonsummer/article/details/1363360…

Spring Boot项目中不使用@RequestMapping相关注解,如何动态发布自定义URL路径

一、前言 在Spring Boot项目开发过程中&#xff0c;对于接口API发布URL访问路径&#xff0c;一般都是在类上标识RestController或者Controller注解&#xff0c;然后在方法上标识RequestMapping相关注解&#xff0c;比如&#xff1a;PostMapping、GetMapping注解&#xff0c;通…