electron窗口锁定、解锁、解决阴影问题

复制代码
transparent:true,//设置透明
  hasShadow:false,//去除阴影
  alwaysOnTop:true,//置顶

<template>
  <div @mousedown="mousedown" style="margin-bottom: 30px;width: 100%;height: 100%;" class="list" :style="{ '--hover-color': hoverColor }">
    <el-button @click="clone" :class="isSUO == true ? 'no' : ''">关闭当前窗口</el-button>
    <el-button @click="min">最小化</el-button>
    <el-button @click="max">最大化</el-button>
    <el-button @click="jia">加锁/解锁</el-button>
    <div>
      123
      {{count}}
      <button @click="T">跳转回去Home页面</button>
    </div> 
  </div>
</template>
<script setup lang="ts">
  name:'List';
 import { ref } from 'vue'
  import {useCountStore} from '@renderer/store/Count'
  import {storeToRefs} from 'pinia'
  import {useRouter} from 'vue-router'
  
  const CountStore =useCountStore()
  const {count} = storeToRefs(CountStore)
  const router = useRouter()
  const T = () =>{
    router.push('/')
  }
//定义透明度的变量样式
  const hoverColor  = ref('rgba(0,0,0,.5)')
 
  // 定义是否隐藏关闭按钮
  let isSUO = ref(false)
let isKeyDown = ref(false)
//x轴的位置
let dinatesX = ref(0)
//y轴的位置
let dinatesY = ref(0)
// 判断是否加锁
let isjia = ref(false)
//鼠标移动时触发事件
const mousedown = (e) => {
  isKeyDown.value = true
  // 获取鼠标移入到窗口时的x坐标
  dinatesX.value = e.x
   // 获取鼠标移入到窗口时的y坐标
  dinatesY.value = e.y

  document.onmousemove = (ev) => {
    // ev就是获取鼠标移入到窗口时相对于屏幕的x坐标y坐标
    if (isKeyDown.value) {
      const x = ev.screenX - dinatesX.value
      const y = ev.screenY - dinatesY.value
      //给主进程传入坐标
      let data = {
        appX: x,
        appY: y
      }
      //给主进程传值,使能够拖动
      electron.ipcRenderer.invoke('list-adsorption', data)
    }
  }
  document.onmouseup = (ev) => {
    isKeyDown.value = false
  }
}
//放大
const max = () =>{
electron.ipcRenderer.invoke('lmax')
}
//缩小
const min = async() =>{
 const res =await electron.ipcRenderer.invoke('lmin')
  console.log(res,'res最小化返回数据')
}
//关闭当前窗口
const clone = () =>{
  electron.ipcRenderer.invoke('lclone')
}
//退出这个程序
const emit = () =>{
  electron.ipcRenderer.invoke('lemit')
}
// 加锁
const jia = () =>{
  isjia.value= !isjia.value
  // 假如点击了上锁按钮
  if(isjia.value == true){
    // 通知主进程,禁止拖动
    electron.ipcRenderer.invoke('jia',isjia.value)
    // 就把透明度清除
    hoverColor.value = ''
    // 把关闭按钮隐藏掉
    isSUO.value  = true
  }else{
        electron.ipcRenderer.invoke('jia',isjia.value)
    hoverColor.value = 'rgba(0,0,0,.5)'
    isSUO.value  = false
  }
}
</script>
<style>
//鼠标移入进来才显示透明度的样式
  .list:hover { background-color: var(--hover-color); }
//定义上锁后隐藏关闭的按钮样式,并且位置保持占用
  .no{
    visibility: hidden;
    background-color: red;
}
</style>

主进程

复制代码
import { app, shell, BrowserWindow, ipcMain, screen } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'

function createWindow(): void {
  // Create the browser window.
  // 创建一个浏览器的窗口
  const mainWindow = new BrowserWindow({
    width: 900,
    height: 670,
    // 最小高度
    minHeight: 500,
    minWidth: 500,
    show: false,
    // alwaysOnTop: true, //是否置顶窗口
    // 窗口大小是否可调整,false就是不可以调整
    // resizable: false,
    // 窗口位置
    // x: 100,
    // 窗口位置
    // y: 100,
    // autoHideMenuBar: false,
    // 去除顶部标题以及菜单栏
    // frame: false,
    fullscreen: false, //一进页面是否全屏
    // 隐藏标题,会导致窗口无法移动
    titleBarStyle: 'hidden',
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
      // nodeIntegration: true, // 不加,渲染进程会报错
      // contextIsolation: false // 为了安全性
      // // enableRemoteModule: true // 不加,渲染进程会报错
    }
  })
  // interface List {
  //   [key: string]: string | number
  // }
//定义一个判断是否上锁的变量
  let isJia = false
  const context = {
    // 是否退出应用
    allowQuitting: false,
    isShow: false,
    listWindow: null
  }
  ipcMain.handle('chuangjian', () => {
    // 判断是否已经创建了子窗口,如果没有创建的话再创建
    if (context.listWindow === null) {
      Chuangjian()
    } else {
      if (context.isShow) {
        console.log('真')
        hideWindow()
      } else {
        console.log('假')
        showWindow()
      }
    }
  })
  // 隐藏的事件
  const hideWindow = () => {
    if (context.listWindow && !context.listWindow.isDestroyed()) {
      context.isShow = false
      context.listWindow.hide()
    }
  }
  // 显示的事件
  const showWindow = () => {
    console.log('外面')
    if (context.listWindow && !context.listWindow.isDestroyed()) {
      console.log('显示事件')
      context.isShow = true
      context.listWindow.show()
    }
  }

  // 创建一个子窗口
  const Chuangjian = () => {
    context.listWindow = new BrowserWindow({
      width: 500,
      height: 200,
      // 最小高度
      show: false,
      hasShadow: false, //去除阴影
      // 窗口大小是否可调整,false就是不可以调整
      resizable: false,
      // 窗口位置
      x: 100,
      // 窗口位置
      y: 100,
      transparent: true, //窗口透明
      alwaysOnTop: true, //置顶
      // autoHideMenuBar: false,
      // 去除顶部标题以及菜单栏
      frame: false,
      // 隐藏标题,会导致窗口无法移动
      titleBarStyle: 'hidden',
      ...(process.platform === 'linux' ? { icon } : {}),
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false
        // nodeIntegration: true, // 不加,渲染进程会报错
        // contextIsolation: false // 为了安全性
        // // enableRemoteModule: true // 不加,渲染进程会报错
      }
    })
    // 显示窗口
    context.listWindow.on('ready-to-show', () => {
      context.listWindow.show()
      context.isShow = true
    })
    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
      context.listWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '/#/list')
    } else {
      context.listWindow.loadFile(join(__dirname, '../renderer/index.html'))
    }
    context.listWindow.on('close', (event) => {
      console.log('走没走12')
      console.log(event, 'event')
      // if(context.allowQuitting == false){

      // }
    })
  }
  ipcMain.handle('jia', (_, res) => {
    console.log(res, 'res')
    isJia = res
  })
//拖动窗口事件
  ipcMain.handle('list-adsorption', (_, res) => {
//先判断是否上锁了,上锁就不能拖动
    if (!isJia) {
      context.listWindow.setPosition(res.appX, res.appY)
    }
  })
  // 获取屏幕的高度等
  console.log(screen.getPrimaryDisplay().bounds.height)
  // 显示窗口
  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
  })
  ipcMain.handle('custom-adsorption', (_, res) => {
    mainWindow.setPosition(res.appX, res.appY)
  })
  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  ipcMain.handle('clone', () => {
    mainWindow.close()
  })
  ipcMain.handle('min', () => {
    mainWindow.minimize()
    mainWindow.webContents.send('data-from-main', app.getAppPath())
    // return 132
  })
  ipcMain.handle('max', () => {
    if (mainWindow.isMaximized()) {
      //判断窗口是否最大化
      mainWindow.restore() //将窗口恢复为之前的状态
    } else {
      mainWindow.maximize() //将窗口全屏
    }
  })
  ipcMain.handle('emit', () => {
    app.quit()
  })

  ipcMain.handle('lclone', () => {
    context.listWindow.close()
    context.listWindow = null
    context.isShow = false
  })
  ipcMain.handle('lmin', () => {
    context.listWindow.minimize()
    // context.listWindow.webContents.send('data-from-main', app.getAppPath())
    // return 132
  })
  ipcMain.handle('lmax', () => {
    if (context.listWindow.isMaximized()) {
      //判断窗口是否最大化
      context.listWindow.restore() //将窗口恢复为之前的状态
    } else {
      context.listWindow.maximize() //将窗口全屏
    }
  })
  ipcMain.handle('lemit', () => {
    app.quit()
  })
  // 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'))
  }
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.

app.whenReady().then(() => {
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron')

  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // IPC test
  ipcMain.on('ping', () => console.log('pong'))

  createWindow()
  // macOS 专用,用户点击 dock 图标时重新打开窗口。
  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})
// ipcMain.send('tese', app.getAppPath())
console.log(app.getAppPath(), '根目录')
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
// 监听所有窗口关闭,通常用于在非 macOS 系统中退出应用。
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.
相关推荐
剑亦未配妥19 分钟前
移动端触摸事件与鼠标事件的触发机制详解
前端·javascript
人工智能训练师6 小时前
Ubuntu22.04如何安装新版本的Node.js和npm
linux·运维·前端·人工智能·ubuntu·npm·node.js
Seveny076 小时前
pnpm相对于npm,yarn的优势
前端·npm·node.js
yddddddy7 小时前
css的基本知识
前端·css
昔人'7 小时前
css `lh`单位
前端·css
前端君8 小时前
实现最大异步并发执行队列
javascript
Nan_Shu_6149 小时前
Web前端面试题(2)
前端
知识分享小能手9 小时前
React学习教程,从入门到精通,React 组件核心语法知识点详解(类组件体系)(19)
前端·javascript·vue.js·学习·react.js·react·anti-design-vue
蚂蚁RichLab前端团队10 小时前
🚀🚀🚀 RichLab - 花呗前端团队招贤纳士 - 【转岗/内推/社招】
前端·javascript·人工智能
孩子 你要相信光10 小时前
css之一个元素可以同时应用多个动画效果
前端·css