electron 自定义标题栏(React 二)

文章介绍了如何在Electron应用中利用ipcMain和ipcRenderer模块进行进程间通信,通过定义通道实现主进程和渲染进程的交互。示例代码展示了创建窗口、监听事件以及通过预加载脚本exposeInMainWorld暴露IPC方法。此外,还展示了使用React创建自定义菜单组件来控制窗口的最小化、最大化和关闭操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 Electron 中,进程使用 ipcMainipcRenderer 模块,通过开发人员定义的“通道”传递消息来进行通信。 这些通道是 任意 (您可以随意命名它们)和 双向 (您可以在两个模块中使用相同的通道名称)的。

1、修改electron.js

const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    titleBarStyle: 'hidden',
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  });
  // and load the index.html of the app.
  // win.loadFile("index.html");
  mainWindow.loadURL(
    isDev
      ? "http://localhost:3000"
      : `file://${path.join(__dirname, "../build/index.html")}`
  );

  // Open the DevTools.
  if (isDev) {
    mainWindow.webContents.openDevTools({ mode: "detach" });
  }
    //不通过按钮最大化还原时需改变自定义图标
  mainWindow.on('maximize', (event) => {
    mainWindow.webContents.send('max-handle', true)
  }); 
  mainWindow.on('unmaximize', (event) => {
    mainWindow.webContents.send('max-handle', false)
  }); 
};
app.whenReady().then(() => {
  // 关闭窗体
  ipcMain.on('close-app', (event) => {
    const webContents = event.sender
    const win = BrowserWindow.fromWebContents(webContents)
    if (win) {
      win.close()
    }
  })
  // 最大化窗体
  ipcMain.on('max-app', (event) => {
    const webContents = event.sender
    const win = BrowserWindow.fromWebContents(webContents)
    win.maximize()
  })
  // 还原窗体
  ipcMain.on('unmax-app', (event) => {
    const webContents = event.sender
    const win = BrowserWindow.fromWebContents(webContents)
    win.unmaximize()
  })
  // 最小化窗体
  ipcMain.on('min-app', (event) => {
    const webContents = event.sender
    const win = BrowserWindow.fromWebContents(webContents)
    win.minimize()
  })
  createWindow()
});

2、通过预加载脚本暴露 ipcRenderer.send ,在preload.js添加

const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
    closeApp: () => ipcRenderer.send('close-app'),
    maxApp: () => ipcRenderer.send('max-app'),
    unmaxApp: () => ipcRenderer.send('unmax-app'),
    minApp: () => ipcRenderer.send('min-app'),
    maxHandle: (ismax) => ipcRenderer.on('max-handle', ismax)
})

3、添加菜单组件,这里使用的是React

import "./CustomizeMenus.css"
import { Button } from 'antd';
import { useState } from 'react';
import {
    MinusOutlined,
    CloseOutlined,
    ExpandOutlined,
    CompressOutlined
} from '@ant-design/icons';
const CustomizeMenus = ({ title}) => {
    const [isMax, setIsMax] = useState(false);
    //接收到主程序的消息
    window.electronAPI.maxHandle((event, value) => {
        if (value) {
            setIsMax(true)
        } else {
            setIsMax(false)
        }
    })
    const min = () => {
        window.electronAPI.minApp()
    };
    const max = () => {
        if (isMax) {
            window.electronAPI.unmaxApp()
            setIsMax(false)
        }else{
            window.electronAPI.maxApp()
            setIsMax(true)
        }
    };
    const closed = () => {
        window.electronAPI.closeApp()
    };
    return (
        <>
            <div id="custom-menu">
                <div className="menu-div menu-text"> <span>{title}</span></div>
                <div className="menu-div" id="menu-btn">
                    <Button type="text" icon={<MinusOutlined />} onClick={() => min()} />
                    <Button type="text" icon={isMax?<CompressOutlined />:<ExpandOutlined />} onClick={() => max()} />
                    <Button type="text" id="closed-btn" icon={<CloseOutlined />} onClick={() => closed()} />
                </div>

            </div>
        </>
    );
};
export default CustomizeMenus;

4、设置拖动区域

#custom-menu {
    width: 100%;
    height: 32px;
    background-color: rgb(178, 123, 209);
    -webkit-app-region: drag;/* 设置自定义可拖动区域 */
    -webkit-user-select: none;/* 禁用文本选择 */
}

.menu-div {
    display: inline-block;
    height: 32px;
    line-height: 30px;
}
.menu-text{
    color: rgb(255, 255, 255);
    margin-left: 16px;
}
#closed-btn:hover {
    color: rgba(0, 0, 0, 0.88);
    background-color: red !important;
}

#closed-btn:active {
    color: rgba(0, 0, 0, 0.88);
    background-color: rgb(155, 5, 5) !important;
}
#custom-menu .ant-btn{
    border-radius: 0px;
}
#menu-btn {
    position: absolute;
    right: 0px;
    -webkit-app-region: no-drag;/* 按钮标记为不可拖拽 */
}

项目案例下载icon-default.png?t=O83Ahttps://download.youkuaiyun.com/download/qq_34533703/87994664

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值