电子,如何使我的自定义标题按钮工作

2024-01-14

我正在尝试制作自定义标题按钮,但似乎发生了一些错误。我尝试了以下方法this one https://stackoverflow.com/questions/70566475/how-to-close-minimize-and-maximize-window-in-javascript/但无法处理错误消息。

main.js:

const { app, BrowserWindow } = require('electron');
const path = require('path');
const electronIpcMain = require('electron').ipcMain;

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
// eslint-disable-next-line global-require
if (require('electron-squirrel-startup')) {
  app.quit();
}

const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 1370,
    height: 755,
    resizable: false,
    autoHideMenuBar: true,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false,
    },
    icon: path.join(__dirname, 'res/applogo.png'),
    frame: false,
    movable: false,
  });
  // and load the index.html of the app.
  mainWindow.loadFile(path.join(__dirname, 'index.html'));
  
  // Open the DevTools.
  mainWindow.webContents.openDevTools();
};


// 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.on('ready', createWindow);

// 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.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // On OS X 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();
  }
});

//set applogo.png to every window
app.on("browser-window-created", (event, window) => {
  window.setIcon(path.join(__dirname, 'res/applogo.png'))
});

//win btns
electronIpcMain.on('window:minimize', () => {
  window.minimize();
})

electronIpcMain.on('window:maximize', () => {
  window.maximize();
})

electronIpcMain.on('window:restore', () => {
  window.restore();
})

electronIpcMain.on('window:close', () => {
  window.close();
})

预加载.js:

// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// White-listed channels.
const ipc = {
    'render': {
        // From render to main.
        'send': [
            'window:minimize', // Channel names
            'window:maximize',
            'window:restore',
            'window:close'
        ],
        // From main to render.
        'receive': [],
        // From render to main and back again.
        'sendReceive': []
    }
};

// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods.
    'ipcRender', {
        // From render to main.
        send: (channel, args) => {
            let validChannels = ipc.render.send;
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, args);
            }
        },
        // From main to render.
        receive: (channel, listener) => {
            let validChannels = ipc.render.receive;
            if (validChannels.includes(channel)) {
                // Deliberately strip event as it includes `sender`.
                ipcRenderer.on(channel, (event, ...args) => listener(...args));
            }
        },
        // From render to main and back again.
        invoke: (channel, args) => {
            let validChannels = ipc.render.sendReceive;
            if (validChannels.includes(channel)) {
                return ipcRenderer.invoke(channel, args);
            }
        }
    }
);

索引.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>my app</title>
    <link rel="stylesheet" href="index.css" />
  </head>
  <body>
    <div class="title-container">
      <img src="res/applogo.png" style="width: 22px; height: 22px;">
      <div style="width: 5px; height: 22px;"></div>
      <p class="title-text">Phigros Fanmade - Editor - Chart Name</p>
      <div class="title-button" id="min-btn">
        <img src="res/icons/titleButton/minimize_button.png" style="width: 20px; height: 20px; margin: 1px;">
      </div>
      <div class="title-button" id="res-btn">
        <img src="res/icons/titleButton/restore_button.png" style="width: 20px; height: 20px; margin: 1px;">
      </div>
      <div class="title-button" id="max-btn">
        <img src="res/icons/titleButton/maximize_button.png" style="width: 20px; height: 20px; margin: 1px;">
      </div>
      <div class="title-button" id="clo-btn">
        <img src="res/icons/titleButton/close_button.png" style="width: 20px; height: 20px; margin: 1px;">
      </div>
    </div>
    <div class="application-container">
      <!-- ... -->
    </div>

    <script>
      //developer tool open command
      document.querySelector("div[data-title='Developer Tool']").addEventListener('click', () => {
        window.open('devTool.html', "_blank", "width=1200,height=714,resizable=false,autoHideMenuBar=true,frame=false");
      })
      
    </script>
    <script src="index.js"></script>
  </body>

  <script>
    //title buttons call commands
    document.getElementById('min-btn').addEventListener('click', () => {
      window.ipcRender.send('window:minimize');
    });

    document.getElementById('max-btn').addEventListener('click', () => {
      window.ipcRender.send('window:maximize');
    });

    document.getElementById('res-btn').addEventListener('click', () => {
      window.ipcRender.send('window:restore');
    });

    document.getElementById('clo-btn').addEventListener('click', () => {
      window.ipcRender.send('window:close');
    });
  </script>
</html>

index.js 是空的,index.css 只是基本样式。

错误信息:

主进程中发生 JavaScript 错误未捕获的异常: ReferenceError:窗口未定义 在 IpcMainImpl 处。 (C:\Users...\src\main.js:64:3) 在 IpcMainImpl.emit (节点:事件:527:28) 在事件发射器处。 (节点:电子/js2c/browser_init:161:11014) 在EventEmiiter.emit(节点:事件:527:28)

感谢您到目前为止的阅读,如果可以的话请帮助我。如果您需要我提供更多信息,我看到后会尽快更新。谢谢。


首要问题是范围window在你的main.js file.

变量window在您的内部使用electronIpcMain.on()函数,但没有事先声明。结果,您收到window is not defined at错误信息。

要纠正此问题,您需要添加let window;之前createWindow() const.

此外,我只想声明createWindow对象作为函数而不是const。这将使事情变得简单。另外,这createWindow()函数应该返回 Electronwindow对象,允许您在需要时进一步操作它,例如当您最小化、最大化、恢复和关闭时。其他操纵可能是x, y, width, height, etc.


我已经简化了下面的内容main.js文件仅包含上述更改和最小工作示例所需的代码。

main.js(主要流程)

const { app, BrowserWindow } = require('electron');
const path = require('path');
const electronIpcMain = require('electron').ipcMain;

// Declare window in the (file) scope, so it can be accessed by other functions in this file
let window;

function createWindow() {
    // This window const is function scoped, therefore not accessible outside this function
    const window = new BrowserWindow({
        width: 1370,
        height: 755,
        resizable: false,
        autoHideMenuBar: true,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            contextIsolation: true,
            nodeIntegration: false,
        },
        frame: false,
        movable: false,
    });

    window.loadFile(path.join(__dirname, 'index.html'))
        // The loadFile() function returns a promise, so let's use it correctly below
        .then(() => {window.webContents.openDevTools();})

    // Return this function scoped window const
    return window;
}

app.on('ready', () => {
    // Assign the returned value of the createWindow() function to this (file) scoped variable.
    window = createWindow();
});

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

app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
        // Assign the returned value of the createWindow() function to this (file) scoped variable.
        window = createWindow();
    }
});

app.on('browser-window-created', (event, window) => {
    window.setIcon(path.join(__dirname, 'res/applogo.png'));
});

electronIpcMain.on('window:minimize', () => {
    // Now we can access the window variable
    window.minimize();
})

electronIpcMain.on('window:maximize', () => {
    // Now we can access the window variable
    window.maximize();
})

electronIpcMain.on('window:restore', () => {
    // Now we can access the window variable
    window.restore();
})

electronIpcMain.on('window:close', () => {
    // Now we can access the window variable
    window.close();
})

Your preload.js脚本保持不变。

preload.js(主要流程)

// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// White-listed channels.
const ipc = {
    'render': {
        // From render to main.
        'send': [
            'window:minimize',
            'window:maximize',
            'window:restore',
            'window:close'
        ],
        // From main to render.
        'receive': [],
        // From render to main and back again.
        'sendReceive': []
    }
};

// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods.
    'ipcRender', {
        // From render to main.
        send: (channel, args) => {
            let validChannels = ipc.render.send;
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, args);
            }
        },
        // From main to render.
        receive: (channel, listener) => {
            let validChannels = ipc.render.receive;
            if (validChannels.includes(channel)) {
                // Deliberately strip event as it includes `sender`.
                ipcRenderer.on(channel, (event, ...args) => listener(...args));
            }
        },
        // From render to main and back again.
        invoke: (channel, args) => {
            let validChannels = ipc.render.sendReceive;
            if (validChannels.includes(channel)) {
                return ipcRenderer.invoke(channel, args);
            }
        }
    }
);

最后,我简化了index.html文件以获得最小的可重现示例。

index.html(渲染过程)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>my app</title>
        <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
    </head>
    <body>
        <div>
            <div class="title-button" id="min-btn"> Minimize </div>
            <div class="title-button" id="res-btn"> Restore </div>
            <div class="title-button" id="max-btn"> Maximize </div>
            <div class="title-button" id="clo-btn"> Close </div>
        </div>
    </body>

    <script>
        document.getElementById('min-btn').addEventListener('click', () => {
            window.ipcRender.send('window:minimize');
        });

        document.getElementById('res-btn').addEventListener('click', () => {
            window.ipcRender.send('window:restore');
        });

        document.getElementById('max-btn').addEventListener('click', () => {
            window.ipcRender.send('window:maximize');
        });

        document.getElementById('clo-btn').addEventListener('click', () => {
            window.ipcRender.send('window:close');
        });
    </script>
</html>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

电子,如何使我的自定义标题按钮工作 的相关文章

随机推荐

  • MySQL存储过程,处理多个游标和查询结果

    如何在同一个例程中使用两个游标 如果我删除第二个游标声明并获取循环 则一切正常 该例程用于在我的网络应用程序中添加朋友 它获取当前用户的 id 和我们要添加为好友的好友的电子邮件 然后检查该电子邮件是否具有相应的用户 id 如果不存在好友关
  • 使用 python nmap 模块扫描先前扫描生成的主机

    我一直在直接从 python 命令行使用该模块 尝试弄清楚它是如何工作的 并开始拼凑出我想要编写的脚本将如何工作 我想做的是首先进行简单的主机发现扫描 例如 n sP PE 然后使用 all hosts 函数生成实际端口扫描的主机列表 所以
  • 设置“log4j.properties”文件的绝对路径

    我的网络应用程序使用 apache commons log4j 通常 log4j 需要类路径中的配置文件 但我需要将日志记录配置委托给外部文件 我需要在环境中部署 war 但日志配置 最大大小 位置等 取决于第二个团队 我的类路径中有一个
  • 如何在 WebApi OwinHost 启动中使用 Ninject 引导程序?

    我正在从 IIS WebAPI 迁移到 OwinHost 利用 nuget 软件包的最新预发布版本 我成功地使用了此处的说明 https github com ninject Ninject Web Common wiki Setting
  • 上个月名称的 VBA 代码

    我已在电子邮件中添加了如下文本 请提供 MMMM 月末的数字 其中 MMMM 是上个月的名称 今天是四月 MMMM 将显示三月 我有以下代码 Dim newDate newDate DateAdd M 1 Now 但结果是 27 03 20
  • hadoop 中的 -libjars 问题

    我正在尝试在 Hadoop 上运行 MapReduce 作业 但遇到错误 并且不确定出了什么问题 我必须传递我的映射器所需的库罐子 我正在终端上执行以下命令 hadoop ubuntu usr local hadoop bin hadoop
  • 是否可以使用认知用户池身份调用 Lambda 函数?

    我想使用 Javascript API 调用 Lambda 函数 我希望使用在浏览器上进行身份验证的用户的认知用户池凭据来调用它 目标是 Lambda 函数将具有与 cognito 用户池中的用户相同级别的 S3 访问权限 我怎样才能做到这
  • C11aligned_alloc分配的内存realloc是否保持对齐?

    考虑以下 C11 代码 void ptr aligned alloc 4096 4096 do something with ptr ptr realloc ptr 6000 自从有记忆以来ptr指向有 4096 字节对齐aligned a
  • 使用flask-ask 和 ngrok 进行 Alexa 技能开发

    我正在尝试使用 python 中的flask ask 和 ngrok 开始开发 Alexa 的技能 以下是我的代码 from flask import Flask from flask ask import Ask statement qu
  • 在应用程序内购买正在进行时显示 UIAlertView

    我添加了一个 UIAlertView 其中 UIActivityIndi catior 作为我的应用程序的子视图 此警报视图仅在购买正在进行时显示 我在 StoreObserver 中以这种方式放置了警报视图 void paymentQue
  • pandas 使用 .isin() 检查 nan 不工作

    我有以下 pandas DataframeNaN in it import pandas as pd df pd DataFrame 1 2 3 float nan columns A df A 0 1 1 2 2 3 3 NaN 我也有清
  • 如何通过 facebook iOS SDK 和 Graph API 邀请朋友加入我的应用程序

    我正在编写一个 iPhone 应用程序 我想让用户可以选择邀请朋友通过 Facebook 开始使用我的应用程序 更具体地说 我想呈现一个对话框 让用户选择要邀请的特定朋友 我怎样才能做到这一点 Thanks 很简单 您只需编写以下代码即可实
  • 使用 read(...) 时在换行符处停止

    我需要从通过 UART 连接的 GPS 读取 NMEA 语句 操作系统是Debian 语言必须是C 为此 我使用以下命令打开文件open 并读取一个字符串read 但是 这样我必须指定字符串长度 这会分解句子 相反 我想读到 NMEA 句子
  • 开源词典库[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找尽可能多的口语 英语 法语 德语 的免费词典 基本上我需要检查字典中是否存在字符串 我正在考虑 firefox 或 openof
  • 带角度的可点击引导行

    我有一张桌子 用引导程序设计 该表的内容是使用 Angular js 填充的 如何使一行可点击 以便它将调用范围内的函数 以下代码对我不起作用 ng click 部分 Table table class table table hover
  • ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature Rails 5 中的错误

    在迁移到 Rails 5 之前 它工作得很好 但是当我迁移到 Rails 5 1 1 时 它给了我这样的错误 ActiveSupport MessageVerifier InvalidSignature ActiveSupport Mess
  • ListBoxFor 不绑定我的视图模型

    我知道这个问题已经被很多人问过 here https stackoverflow com questions 3194143 challenges with selecting values in listboxfor and here h
  • 在 javascript 中跨域访问 css 文件中的 CSS 类

    我们通过标准 HTML STYLE 标签包含 CSS 文件 然后我们需要 JavaScript 代码来访问 CSS 类和属性 在 IE 和 Chrome 中一切正常 但在 Firefox 中它会抛出此异常 未捕获的异常 安全错误 NS ER
  • 一个 cookie 具有多个值,还是多个 cookie 具有一个值?

    如果我想在 cookie 中存储许多设置 我应该创建多个 cookie 每个 cookie 包含一个选项 还是创建一个大 cookie 在序列化数组或其他内容中包含多个选项 这两种方法都有优点 缺点吗 大多数人做什么 嗯 大多数情况下我们都
  • 电子,如何使我的自定义标题按钮工作

    我正在尝试制作自定义标题按钮 但似乎发生了一些错误 我尝试了以下方法this one https stackoverflow com questions 70566475 how to close minimize and maximize