目录
在渲染进程(UI界面)中使用shell模块
//在文件管理器中打开
const { ..., shell } = require('electron');
const showFile = () => {
if (!filePath) { return alert('This file has not been saved to the file system.'); }
shell.showItemInFolder(filePath);
};
//使用默认程序打开
const openInDefaultApplication = () => {
if (!filePath) { return alert('This file has not been saved to the file system.'); }
//electron-9.x 已经不存在了
shell.openItem(fullPath)
};
在应用菜单中使用 shell 模块
- applicationMenu.js
{ type: 'separator' },
{
label: 'Show File',
enabled: hasFilePath,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
'Cannot Show File\'s Location',
'There is currently no active document show.'
);
}
focusedWindow.webContents.send('show-file');
},
},
{
label: 'Open in Default Application',
enabled: hasFilePath,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
'Cannot Open File in Default Application',
'There is currently no active document to open.'
);
}
focusedWindow.webContents.send('open-in-default');
},
},
- renderer.js
ipcRenderer.on('show-file', showFile);
ipcRenderer.on('open-in-default', openInDefaultApplication);
在上下文菜单中使用 shell 模块
- renderer.js
//上下文菜单
const markdownContextMenu = Menu.buildFromTemplate([
...
{
label: 'Show File in Folder',
click: showFile,
enabled: !!filePath
},
{
label: 'Open in Default',
click: openInDefaultApplication,
enabled: !!filePath
},
{ type: 'separator' },
...
]);
markdownView.addEventListener('contextmenu', (event) => {
event.preventDefault();
markdownContextMenu.popup();
});
禁用菜单项
!!
!! 常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算,在js中新手常常会写这样臃肿的代码:
判断变量a为非空,未定义或者非空串才能执行方法体的内容
var a;
if(a!=null&&typeof(a)!=undefined&&a!=''){
//a有内容才执行的代码
}
实际上我们只需要写一个判断表达:
if(!!a){
//a有内容才执行的代码...
}
就能和上面达到同样的效果。a是有实际含义的变量才执行方法,否则变量null,undefined和''空串都不会执行以下代码。
可以总结出来;
“!”是逻辑与运算,并且可以与任何变量进行逻辑与将其转化为布尔值,“!!”则是逻辑与的取反运算,尤其后者在判断类型时代码简洁高效,省去了多次判断null、undefined和空字符串的冗余代码。
动态生成菜单
禁用菜单:enabled: !!filePath
动态启动菜单:createContextMenu().popup();
const createContextMenu = () => {
return Menu.buildFromTemplate([
{ label: 'Open File', click() { mainProcess.getFileFromUser(); } },
{
label: 'Show File in Folder',
click: showFile,
enabled: !!filePath
},
{
label: 'Open in Default',
click: openInDefaultApplication,
enabled: !!filePath
},
{ type: 'separator' },
{ label: 'Cut', role: 'cut' },
{ label: 'Copy', role: 'copy' },
{ label: 'Paste', role: 'paste' },
{ label: 'Select All', role: 'selectall' },
]);
};
markdownView.addEventListener('contextmenu', (event) => {
event.preventDefault();
createContextMenu().popup();
});
应用菜单
应用菜单不同于上下文菜单的特殊点:
- 与上下文菜单不同,应用菜单只用一个,所有窗口共享
- 在macOS系统中,甚至应用没有打开窗口的情形。
- 应用菜单存在于主进程中,访问不到渲染进程的变量(这个变量跟菜单项禁用相关)
创建应用菜单(动态处理启用和禁用状态)
要点:
const hasOneOrMoreWindows = !!BrowserWindow.getAllWindows().length; //是否有窗口打开
const focusedWindow = BrowserWindow.getFocusedWindow(); //获取当前焦点窗口,无返回null
const hasFilePath = !!(focusedWindow && focusedWindow.getRepresentedFilename()); //focusedWindow.getRepresentedFilename() 返回窗口打开的文件
focusedWindow.getRepresentedFilename()只适用于darwin平台
- applicationMenu.js
const { app, BrowserWindow, dialog, Menu } = require('electron');
const mainProcess = require('./main');
const createApplicationMenu = () => {
const hasOneOrMoreWindows = !!BrowserWindow.getAllWindows().length; //是否有窗口打开
const focusedWindow = BrowserWindow.getFocusedWindow(); //获取当前焦点窗口,无返回null
const hasFilePath = !!(focusedWindow && focusedWindow.getRepresentedFilename()); //focusedWindow.getRepresentedFilename() 返回窗口打开的文件
const template = [
{
label: 'File',
submenu: [
...
{
label: 'Save File',
accelerator: 'CommandOrControl+S',
enabled: hasOneOrMoreWindows,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
'Cannot Save or Export',
'There is currently no active document to save or export.'
);
}
focusedWindow.webContents.send('save-markdown');
},
},
{
label: 'Export HTML',
accelerator: 'Shift+CommandOrControl+S',
enabled: hasOneOrMoreWindows,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
'Cannot Save or Export',
'There is currently no active document to save or export.'
);
}
focusedWindow.webContents.send('save-html');
},
},
{ type: 'separator' },
{
label: 'Show File',
enabled: hasFilePath,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
'Cannot Show File\'s Location',
'There is currently no active document show.'
);
}
focusedWindow.webContents.send('show-file');
},
},
{
label: 'Open in Default Application',
enabled: hasFilePath,
click(item, focusedWindow) {
if (!focusedWindow) {
return dialog.showErrorBox(
'Cannot Open File in Default Application',
'There is currently no active document to open.'
);
}
focusedWindow.webContents.send('open-in-default');
},
},
],
},
...
];
...
return Menu.setApplicationMenu(Menu.buildFromTemplate(template));
};
module.exports = createApplicationMenu;
- main.js
程序启动时
app.on('ready', () => {
//Menu.setApplicationMenu(applicationMenu); //设置应用菜单
createApplicationMenu();//设置应用菜单
mainWindow = createwindow();
});
打开和关闭新窗口时
newWindow.on('focus', () => {
createApplicationMenu(); //窗口获取焦点时,创建新的应用菜单
});
newWindow.on('closed', () => {
...
createApplicationMenu();//关闭一个窗口时,创建新的应用菜单
})
打开新文件时
const openFile = exports.openFile = (targetWindow, file) => {
...
createApplicationMenu(); //打开新文件时,创建新应用菜单
};
来源:oschina
链接:https://my.oschina.net/u/4254929/blog/4321982