• electron自定义标题栏,并监听双击以及右键改变窗口大小。


    1、前言

    当需要在标题栏添加一些额外的操作时候,比如添加 帮助 菜单,自带的标题栏开发起来比较困难(没了解不知道能不能实现),这时候,自己写一个标题栏就比较方便。

    2、实现

    首先是禁止掉原先的标题栏,就是创建无边框窗口 (官网描述,点此跳转)
    默认情况下, 无边框窗口是不可拖拽的。 应用程序需要在 CSS 中指定 -webkit-app-region: drag 来告诉 Electron 哪些区域是可拖拽的(如操作系统的标准标题栏)设置后点击事件是无效的。
    需要在可拖拽区域内部使用 -webkit-app-region: no-drag 则可以将其中部分区域排除。 请注意, 当前只支持矩形形状。(官网描述,点此跳转)

    async function createWindow() {
      win = new BrowserWindow({
        title: 'xxxx工具',
        width: 1280,
        height: 720,
        // 不显示顶部栏
        frame: false,
        //实际尺寸不包含边框
        useContentSize: true,
      })
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后使用 ipcMain 进行进程通信
    监听 最小化、关闭、最大化事件
    将代码写在createWindow当中

     // 监听放大缩小事件
      ipcMain.on('close', () => {
        win?.destroy()
      })
    
      ipcMain.on('max', () => {
        // true表示窗口已最大化.
        if (win?.isMaximized()) {
          win.restore() // 将窗口恢复为之前的状态
        } else {
          win?.maximize() // 窗口最大化
        }
      })
    
      ipcMain.on('min', () => {
        win?.minimize()
      })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在页面当中可以通过调用这些事件进行窗口的操作,来实现窗口状态的控制

    3、优化

    但是还可以通过双击标题栏来进行窗口的最大化还原操作

    这时候就需要监听到其余最大化窗口和最小化窗口的事件,来改变图标的变化。、

    窗口有很多实例事件,可以监听,
    这里我们只对最大化和还原进行监听

    然后通过webContents来发送监听到的值到渲染层

      // 对双击等其余操作导致的窗口变化监听
      // 事件: 最大化
      win.on('maximize', () => {
        win?.webContents.send('isMaxWindow', win?.isMaximized())
      })
    
      // 事件: 还原
      win.on('unmaximize', () => {
        // 在窗口从最大化状态还原时执行操作
        win?.webContents.send('isMaxWindow', win?.isMaximized())
      })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    页面中使用ipcRenderer来获取主进程发送过来的值,这样不论是自己点击图标,或者双击、右键改变窗口的状态都可以正确的显示图标。

    import {
      LineOutlined,
      BorderOutlined,
      BlockOutlined,
      CloseOutlined,
    } from '@ant-design/icons'
    import { useState, useMemo, FC, useEffect } from 'react'
    import styles from './style.module.scss'
    
    type ipcOperateType = 'close' | 'min' | 'max'
    type TopPageProps = {
      date: string
      userCode: string
    }
    
    const TopPage: FC<TopPageProps> = () => {
      const [isMax, setIsMax] = useState<boolean>(false)
      useEffect(() => {
            window.ipcRenderer.on('isMaxWindow', (_event, message) => {
                setIsMax(message);
            });
        }, []);
      //   窗口事件
      const operateWindow = (operate: ipcOperateType) => {
        switch (operate) {
          case 'close':
            window.ipcRenderer.send('close')
            break
          case 'min':
            window.ipcRenderer.send('min')
            break
          case 'max':
           // 监听双击事件以及其余事件导致的窗口全屏还原
            window.ipcRenderer.on('isMaxWindow', (_event, message) => {
              setIsMax(message)
            })
            window.ipcRenderer.send('max')
            break
        }
      }
    
    
      return (
        <div className={styles.top_page}>
          <div>我是标题xxxxx</div>
          <div className={styles.action_box}>
            <LineOutlined
              onClick={() => {
                operateWindow('min')
              }}
            />
            {!isMax && (
              <BorderOutlined
                onClick={() => {
                  operateWindow('max')
                }}
              />
            )}
            {isMax && (
              <BlockOutlined
                onClick={() => {
                  operateWindow('max')
                }}
              />
            )}
            <CloseOutlined
              onClick={() => {
                operateWindow('close')
              }}
            />
          </div>
        </div>
      )
    }
    export default TopPage
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    此时已经可以实现正常的最小化最大化操作

  • 相关阅读:
    依赖注入
    linux Make 工具 Makefile变量
    与传统IT开发相比,低代码平台有何优势?
    【无标题】
    uniapp 显示icon异常
    Prometheus 使用cadvisor采集docker容器监控数据
    BERT论文阅读
    Databend 开源周报 #66
    7-3 投票统计 武汉理工大学C语言
    MySQL GROUP BY和HAVING的使用 2022/09/09
  • 原文地址:https://blog.csdn.net/weixin_45892086/article/details/133688318