11 changed files with 601 additions and 71 deletions
@ -0,0 +1,63 @@ |
|||||
|
import Shared from "./share" |
||||
|
import { Menu, Tray, ipcMain, BrowserWindow, App } from "electron" |
||||
|
const path = require("path") |
||||
|
|
||||
|
// 隐藏主窗口,并创建托盘,绑定关闭事件
|
||||
|
export default function setTray(app: App, mainWindow: BrowserWindow) { |
||||
|
if (Shared.data.miniWindow) { |
||||
|
mainWindow.hide() |
||||
|
return |
||||
|
} |
||||
|
// 用一个 Tray 来表示一个图标,这个图标处于正在运行的系统的通知区
|
||||
|
// 通常被添加到一个 context menu 上.
|
||||
|
// 系统托盘右键菜单
|
||||
|
const trayMenuTemplate = [ |
||||
|
{ |
||||
|
// 系统托盘图标目录
|
||||
|
label: "打开主窗口", |
||||
|
click: () => { |
||||
|
mainWindow.show() |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
// 系统托盘图标目录
|
||||
|
label: "打开悬浮窗", |
||||
|
click: () => { |
||||
|
ipcMain.emit("showSuspensionWindow") |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
// 系统托盘图标目录
|
||||
|
label: "退出", |
||||
|
click: () => { |
||||
|
Shared.data.forceClose = true |
||||
|
app.quit() |
||||
|
}, |
||||
|
}, |
||||
|
] |
||||
|
// 设置系统托盘图标
|
||||
|
const iconPath = path.join(__static, "/icon.png") |
||||
|
|
||||
|
Shared.data.miniWindow = new Tray(iconPath) |
||||
|
|
||||
|
// 图标的上下文菜单
|
||||
|
const contextMenu = Menu.buildFromTemplate(trayMenuTemplate) |
||||
|
|
||||
|
// 展示主窗口,隐藏主窗口 mainWindow.hide()
|
||||
|
mainWindow.hide() |
||||
|
|
||||
|
// 设置托盘悬浮提示
|
||||
|
Shared.data.miniWindow.setToolTip("never forget") |
||||
|
|
||||
|
// 设置托盘菜单
|
||||
|
Shared.data.miniWindow.setContextMenu(contextMenu) |
||||
|
|
||||
|
// 单击托盘小图标显示应用
|
||||
|
Shared.data.miniWindow.on("double-click", () => { |
||||
|
// 显示主程序
|
||||
|
mainWindow.show() |
||||
|
// 关闭托盘显示
|
||||
|
// Shared.data.miniWindow.destroy();
|
||||
|
}) |
||||
|
return Shared.data.miniWindow |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
import { ipcMain, dialog } from "electron" |
||||
|
|
||||
|
/** |
||||
|
* 格式:@类型:扩展:函数 |
||||
|
*/ |
||||
|
|
||||
|
// 保存数据
|
||||
|
ipcMain.on("@func:buildin:close", data => { |
||||
|
// dialog.showMessageBox(
|
||||
|
// {
|
||||
|
// type: "info",
|
||||
|
// title: "Information",
|
||||
|
// defaultId: 0,
|
||||
|
// cancelId: 0,
|
||||
|
// message: "确定要关闭吗?" + data,
|
||||
|
// buttons: ["没事", "最小化到托盘", "直接退出"],
|
||||
|
// },
|
||||
|
// index => {}
|
||||
|
// )
|
||||
|
}) |
@ -0,0 +1,121 @@ |
|||||
|
import Shared from "./share" |
||||
|
import { BrowserWindow, ipcMain, screen, Menu, shell, webContents } from "electron" |
||||
|
// webContents
|
||||
|
console.log(webContents.getAllWebContents()) |
||||
|
|
||||
|
const window: any = null //BrowserWindow.fromWebContents(webContents.getFocusedWebContents())
|
||||
|
const winURL = |
||||
|
process.env.NODE_ENV === "development" ? `http://localhost:${process.env.PORT}/#/float` : `file://${__dirname}/index.html#/float` |
||||
|
|
||||
|
ipcMain.on("@float:setPosition", (event, x, y) => { |
||||
|
Shared.data.floatWindow?.setPosition(x, y) |
||||
|
}) |
||||
|
|
||||
|
ipcMain.on("showSuspensionWindow", () => { |
||||
|
console.log(24324) |
||||
|
|
||||
|
if (Shared.data.floatWindow) { |
||||
|
if (Shared.data.floatWindow.isVisible()) { |
||||
|
createSuspensionWindow() |
||||
|
} else { |
||||
|
Shared.data.floatWindow.showInactive() |
||||
|
} |
||||
|
} else { |
||||
|
createSuspensionWindow() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
ipcMain.on("createSuspensionMenu", e => { |
||||
|
const rightM = Menu.buildFromTemplate([ |
||||
|
{ label: "开始全部任务", enabled: false }, |
||||
|
{ label: "暂停全部任务", enabled: false }, |
||||
|
{ |
||||
|
label: "本次传输完自动关机", |
||||
|
click: () => { |
||||
|
ipcMain.emit("@func:buildin:saveData", 32232) |
||||
|
}, |
||||
|
}, |
||||
|
{ type: "separator" }, |
||||
|
{ |
||||
|
label: "隐藏悬浮窗", |
||||
|
click: () => { |
||||
|
if (window) { |
||||
|
window.webContents.send("hideSuspension", false) |
||||
|
} |
||||
|
Shared.data.floatWindow.hide() |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: "打开主窗口", |
||||
|
click: () => { |
||||
|
// && !Shared.data.mainWindow.isVisible()
|
||||
|
if (Shared.data.mainWindow) { |
||||
|
Shared.data.mainWindow.show() |
||||
|
} |
||||
|
// window.webContents.send('hideSuspension', false)
|
||||
|
}, |
||||
|
}, |
||||
|
{ type: "separator" }, |
||||
|
{ |
||||
|
label: "加入qq群", |
||||
|
click: () => { |
||||
|
shell.openExternal( |
||||
|
"tencent://groupwpa/?subcmd=all¶m=7B2267726F757055696E223A3831343237303636392C2274696D655374616D70223A313533393531303138387D0A" |
||||
|
) |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: "GitHub地址", |
||||
|
click: () => { |
||||
|
shell.openExternal("https://github.com/lihaotian0607/auth") |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: "退出软件", |
||||
|
click: () => { |
||||
|
Shared.data.mainWindow.close() |
||||
|
}, |
||||
|
}, |
||||
|
]) |
||||
|
rightM.popup({}) |
||||
|
}) |
||||
|
|
||||
|
function createSuspensionWindow() { |
||||
|
Shared.data.floatWindow = new BrowserWindow({ |
||||
|
width: 102, // 悬浮窗口的宽度 比实际DIV的宽度要多2px 因为有1px的边框
|
||||
|
height: 27, // 悬浮窗口的高度 比实际DIV的高度要多2px 因为有1px的边框
|
||||
|
type: "toolbar", // 创建的窗口类型为工具栏窗口
|
||||
|
frame: false, // 要创建无边框窗口
|
||||
|
resizable: false, // 禁止窗口大小缩放
|
||||
|
show: false, // 先不让窗口显示
|
||||
|
webPreferences: { |
||||
|
devTools: false, // 关闭调试工具
|
||||
|
nodeIntegration: true, |
||||
|
contextIsolation: false, |
||||
|
}, |
||||
|
transparent: true, // 设置透明
|
||||
|
alwaysOnTop: true, // 窗口是否总是显示在其他窗口之前
|
||||
|
}) |
||||
|
const size = screen.getPrimaryDisplay().workAreaSize // 获取显示器的宽高
|
||||
|
const winSize = Shared.data.floatWindow.getSize() // 获取窗口宽高
|
||||
|
// 设置窗口的位置 注意x轴要桌面的宽度 - 窗口的宽度
|
||||
|
Shared.data.floatWindow.setPosition(size.width - winSize[0], 100) |
||||
|
Shared.data.floatWindow.setPosition(size.width / 2, size.height / 2) |
||||
|
Shared.data.floatWindow.loadURL(winURL) |
||||
|
|
||||
|
Shared.data.floatWindow.once("ready-to-show", () => { |
||||
|
Shared.data.floatWindow.show() |
||||
|
}) |
||||
|
Shared.data.floatWindow.on("double-click", () => { |
||||
|
alert(123) |
||||
|
}) |
||||
|
Shared.data.floatWindow.on("close", () => { |
||||
|
Shared.data.floatWindow = null |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
ipcMain.on("hideSuspensionWindow", () => { |
||||
|
if (Shared.data.floatWindow) { |
||||
|
Shared.data.floatWindow.hide() |
||||
|
} |
||||
|
}) |
@ -0,0 +1,66 @@ |
|||||
|
import electron from "electron" |
||||
|
|
||||
|
const BrowserWindow = electron.BrowserWindow |
||||
|
const Menu = electron.Menu |
||||
|
const app = electron.app |
||||
|
const dialog = electron.dialog |
||||
|
const ipcMain = electron.ipcMain |
||||
|
|
||||
|
let newwin:electron.BrowserWindow|null = null |
||||
|
|
||||
|
let template = [ |
||||
|
{ |
||||
|
label: "关于", |
||||
|
click: function (item:any, focusedWindow:any) { |
||||
|
// https://www.electronjs.org/docs/api/browser-window#winsetmenubarvisibilityvisible-windows-linux
|
||||
|
if (focusedWindow && !newwin) { |
||||
|
newwin = new BrowserWindow({ |
||||
|
width: 600, |
||||
|
height: 200, |
||||
|
// modal: true,
|
||||
|
show: false, |
||||
|
resizable: true, |
||||
|
parent: focusedWindow, // win是主窗口
|
||||
|
//
|
||||
|
webPreferences: { |
||||
|
// 下面两个必须这么用,看a.md的文档
|
||||
|
nodeIntegration: true, |
||||
|
contextIsolation: false, |
||||
|
// 预加载动画
|
||||
|
// preload: join(__dirname, "../../src/preload/index.js"),
|
||||
|
}, |
||||
|
}) |
||||
|
// 隐藏菜单
|
||||
|
newwin.setMenuBarVisibility(false) |
||||
|
newwin.loadURL(process.env.NODE_ENV === "development" ? `http://localhost:${process.env.PORT}/#/about` : `file://${__dirname}/index.html#/about`); |
||||
|
newwin.on("ready-to-show", () => { |
||||
|
newwin?.show() |
||||
|
}) |
||||
|
newwin.on("closed", () => { |
||||
|
newwin = null |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
// if (process.platform === 'darwin') {
|
||||
|
//
|
||||
|
// }
|
||||
|
//
|
||||
|
// if (process.platform === 'win32') {
|
||||
|
//
|
||||
|
// }
|
||||
|
app.on("ready", function () { |
||||
|
const menu = Menu.buildFromTemplate(template) |
||||
|
Menu.setApplicationMenu(menu) |
||||
|
}) |
||||
|
app.on("browser-window-created", function () { |
||||
|
// let reopenMenuItem = findReopenMenuItem()
|
||||
|
// if (reopenMenuItem) reopenMenuItem.enabled = false
|
||||
|
}) |
||||
|
app.on("window-all-closed", function () { |
||||
|
app.exit() |
||||
|
// let reopenMenuItem = findReopenMenuItem()
|
||||
|
// if (reopenMenuItem) reopenMenuItem.enabled = true
|
||||
|
}) |
@ -0,0 +1,10 @@ |
|||||
|
.view-float { |
||||
|
width: 100px; |
||||
|
height: 25px; |
||||
|
line-height: 25px; |
||||
|
background-color: #fff; |
||||
|
position: fixed; |
||||
|
overflow: auto; |
||||
|
user-select: none; |
||||
|
border: 1px solid red; |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
import React, { MouseEventHandler, useEffect } from "react" |
||||
|
import electron from "@/plugins/electron" |
||||
|
import style from "./index.module.scss" |
||||
|
import { useLocation, Route, Switch, useHistory } from "react-router-dom" |
||||
|
|
||||
|
export default function Float(props: any) { |
||||
|
useEffect(() => { |
||||
|
// let win = electron.remote.getCurrentWindow()
|
||||
|
let biasX = 0 |
||||
|
let biasY = 0 |
||||
|
document.addEventListener("mousedown", function (e) { |
||||
|
switch (e.button) { |
||||
|
case 0: |
||||
|
biasX = e.x |
||||
|
biasY = e.y |
||||
|
document.addEventListener("mousemove", moveEvent) |
||||
|
break |
||||
|
case 2: |
||||
|
electron.ipcRenderer.send("createSuspensionMenu") |
||||
|
break |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
document.addEventListener("mouseup", function () { |
||||
|
biasX = 0 |
||||
|
biasY = 0 |
||||
|
document.removeEventListener("mousemove", moveEvent) |
||||
|
}) |
||||
|
|
||||
|
function moveEvent(e: any) { |
||||
|
electron.ipcRenderer.send('@float:setPosition', e.screenX - biasX, e.screenY - biasY) |
||||
|
// win.setPosition(e.screenX - biasX, e.screenY - biasY)
|
||||
|
} |
||||
|
}, []) |
||||
|
function dblclick(e: MouseEventHandler<HTMLDivElement>) { |
||||
|
alert("asd") |
||||
|
} |
||||
|
return ( |
||||
|
<div className={style["view-float"]} onDoubleClick={(e: any) => dblclick(e)}> |
||||
|
悬浮窗 |
||||
|
</div> |
||||
|
) |
||||
|
} |
Loading…
Reference in new issue