首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >电子如何与其棱角的前端通信?

电子如何与其棱角的前端通信?
EN

Stack Overflow用户
提问于 2022-01-29 10:57:34
回答 1查看 352关注 0票数 2

我在一个无框电子窗口内运行一个有角度的前端。因为窗口是无框架的,所以我需要自己实现minimizing/maximizing/unmaximizing/closing-behaviour。我有一个按钮的最大化和非最大化,并希望隐藏其中一个在任何时候,取决于窗口状态。

我的节点整合设置为假,我想知道如何从电子到我的角度前端。然后,我只需要找到一种方法来获取我的应用程序窗口并发出一个事件,每当它被最大化/未最大化时,然后相应地更改我的UI。

我从角度到电子的交流是这样的:

在角度上,我有一个“electronService”,它被注入到我的元件中,并调用电子函数。

在我的preload.js中,我将main.js中的一个函数公开给呈现程序进程,如下所示:

代码语言:javascript
复制
const { ipcRenderer, contextBridge } = require('electron');

contextBridge.exposeInMainWorld('electron', {
    maximizeWindow: () => {
        return ipcRenderer.invoke('electron::maximize-window');
    }
});

在我的main.js中,我处理来电,如下所示:

代码语言:javascript
复制
app.whenReady().then(() => {
    ipcMain.handle('electron::maximize-window', maximizeWindow);
});

function maximizeWindow(_) {
    ...
}

有办法在相反的方向做这件事吗?

EN

回答 1

Stack Overflow用户

发布于 2022-05-08 06:33:24

虽然我没有使用Angular,但是一旦正确地布局、理解和实现了最大化/还原功能,实现就非常简单了。IPC的使用以及窗口状态的检测和通信将是其功能的核心。

期望的功能:

  • 当窗口最大化时,显示恢复按钮。
  • 当窗口没有最大化(恢复)时,显示最大化按钮。

执行情况:

我们的呈现将显示所有四个按钮:最小化、还原、最大化和关闭。在呈现按钮click上的

  • ,向主进程发送一条IPC消息,在主进程中实现窗口状态下的窗口(更改),向呈现过程发送一条消息以显示/隐藏各自的按钮。
  1. 在窗口创建时,在标题栏被双击以切换显示按钮和还原按钮时,向呈现过程发送一条消息以显示/隐藏相应的。

你可能想知道为什么需要第3点?它存在于第4点和第5点。第4点用于创建窗口。无论使用什么设置来创建窗口(手动或从.json文件中提取),新创建的窗口都将动态显示正确的按钮。第5点是当你双击标题栏的最大值/恢复。

在您的preload.js脚本中,我们需要两个函数。一个用于指示哪个呈现按钮是单击(点2),另一个用于接收窗口的状态(点3)。

preload.js (主进程)

代码语言:javascript
复制
const { ipcRenderer, contextBridge } = require('electron');

contextBridge.exposeInMainWorld('electron', {
    buttonClicked: (button) => {
        ipcRenderer.send('buttonClicked', button);
    },
    windowState: (state) => {
        ipcRenderer.on('windowState', state);
    }
});

在您的main.js脚本中,我们添加了一些功能来告诉呈现过程,窗口在创建时处于什么状态(第4点)。

在这里,我们还接收来自呈现过程的按钮click消息(第2点),并相应地实现功能。

最后,聆听标题栏的双击(第5点).

main.js (主进程)

代码语言:javascript
复制
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronIpcMain = require('electron').ipcMain;

const nodePath = require('path');

let window;

function initialiseButtons() {
    if (window.isMaximized()) {
        window.webContents.send('windowState','maximised')
    } else {
        window.webContents.send('windowState','restored')
    }
}

function createWindow() {
    const window = new electronBrowserWindow({
        x: 0,
        y: 0,
        width: 800,
        height: 600,
        frame: false,
        show: false,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            preload: nodePath.join(__dirname, 'preload.js')
        }
    });

    window.loadFile('index.html')
        // .then(() => { window.maximize(); }) // Testing
        .then(() => { initialiseButtons(); })
        .then(() => { window.show(); });

    // Double-click of title bar from restore to maximise
    window.on('maximize', () => {
        initialiseButtons();
    })

    // Double-click of title bar from maximise to restore
    window.on('unmaximize', () => {
        initialiseButtons();
    })

    return window;
}

electronApp.on('ready', () => {
    window = createWindow();
});

electronApp.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        electronApp.quit();
    }
});

electronApp.on('activate', () => {
    if (electronBrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});

// ---

electronIpcMain.on('buttonClicked', (event, buttonClicked) => {
    if (buttonClicked === 'minimise') {
        window.minimize();
        return;
    }

    if (buttonClicked === 'restore') {
        window.restore();
        window.webContents.send('windowState','restored');
        return;
    }

    if (buttonClicked === 'maximise') {
        window.maximize();
        window.webContents.send('windowState','maximised');
        return;
    }

    if (buttonClicked === 'close') {
        window.close();
    }
})

最后,我们将按钮click事件发送到主进程(第1点),并在创建窗口时侦听窗口状态(第4点)。

为了简单起见,我忽略了内联样式和交互按钮的使用。

index.html (渲染过程)

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Electron Test</title>
        <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
    </head>

    <body style="margin: 0; padding: 0;">

        <div style="display: flex; flex-flow: row nowrap; padding: 5px; background-color: #ccc;">
            <div style="flex: 1 0 auto">Title</div>
            <div style="flex: 0 1 auto">
                <input type="button" id="minimise" value="_">
                <input type="button" id="restore" value="&#10064;">
                <input type="button" id="maximise" value="&#9744;">
                <input type="button" id="close" value="&#9747;">
            </div>
        </div>
    </body>

    <script>
        let restoreButton = document.getElementById('restore');
        let maximiseButton = document.getElementById('maximise');

        document.getElementById('minimise').addEventListener('click', () => {
            window.electron.buttonClicked('minimise');
        });

        document.getElementById('close').addEventListener('click', () => {
            window.electron.buttonClicked('close');
        });

        restoreButton.addEventListener('click', () => {
            window.electron.buttonClicked('restore');
        });

        maximiseButton.addEventListener('click', () => {
            window.electron.buttonClicked('maximise');
        });

        window.electron.windowState((event, state) => {
            if (state === 'maximised') {
                restoreButton.style.display = 'inline-block';
                maximiseButton.style.display = 'none';
            } else {
                restoreButton.style.display = 'none';
                maximiseButton.style.display = 'inline-block';
            }
        })
    </script>
</html>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70904619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档