electron+vue3,禁止快捷键 ctrl+shift+i 的使用

1. 在主进程文件中,创建主窗口时,加入以下代码:

win.webContents.on("before-input-event", (event, input) => {
    // console.log(input, 123);
    if (input.control && input.shift && input.key.toLowerCase() === "i") {
      // console.log("Pressed Control+I");
      event.preventDefault(); // 阻止默认行为
    }
  });

全部代码展示:

import {
  BrowserWindow,
  BrowserWindowConstructorOptions,
  ipcMain,
  screen,
} from "electron";
import {
  url,
  appTitle,
  preloadPath,
  iconPath,
  indexHtmlPath,
} from "./common/variables";
import { CustomChannel } from "../../globel/channelEvent";

interface IWindowsZi {
  isMainWin: boolean; // 是否主窗口(当为true时会替代当前主窗口)
}

/* ======================= 定义一些窗口工具类中会使用到的常量,以及窗口顶级父类 ========================= */

// 默认窗口参数
export const defaultWindowConfig: BrowserWindowConstructorOptions &
  IWindowConfig &
  IWindowsZi = {
  title: appTitle, //窗口标题
  icon: iconPath, //窗口图标
  width: 800, // 默认窗口宽度
  height: 600, // 默认窗口高度
  autoHideMenuBar: true, // false: 显示默认菜单栏   true:不显示默认菜单栏
  frame: false, // false: 去掉顶部导航,关闭按钮   true : 不去掉
  modal: true,
  show: false, // 启动后 显示不显示
  isMainWin: false, //是否主窗口(当为true时会替代当前主窗口)
  resizable: true, //是否支持调整窗口大小
  webPreferences: {
    devTools: true, // 是否打开调试模式
    webviewTag: true,
    preload: preloadPath,
    nodeIntegration: true, //启用Node集成(是否完整的支持 node)
    contextIsolation: false, //上下文隔离
  },
};

/**
 * 窗口管理顶级父类 定义一些属性,和公共方法
 */
export class WindowUtils {
  group: Map<string, WindowGroup>; // 窗口组 key就是传入的key值,如果没传,则取窗口的id作为key值
  main: BrowserWindow | any; // 主窗口的实例对象

  /**
   * 构造方法,初始化属性
   */
  constructor() {
    this.group = new Map();
  }

  // 显示 主窗口
  listShow() {
    this.main.show();
    this.main.setSkipTaskbar(false);

    // 单击通知区图标实现应用的显示或隐藏
    // this.main.isVisible() ? this.main.hide() : this.main.show();
    // this.main.isVisible() ? this.main.setSkipTaskbar(false) : this.main.setSkipTaskbar(true);
  }

  // 直接退出--前提条件
  listMain() {
    this.main = undefined;
  }

  // 事件监听处理
  listen() {
    // 窗口创建监听
    ipcMain.handle(
      CustomChannel.window_create,
      (_, opt: IWindowConfig & IWindowsZi) => {
        this.createWindows(opt);
      }
    );

    // 窗口位置修改监听
    ipcMain.handle(
      CustomChannel.window_position_change,
      (_, windowPosition: IWindowPosition) => {
        // 假如传了窗口的key,则获取对应窗口,假如没传,则用发送事件的窗口
        const windowKey = windowPosition.windowKey;
        const cureentWin =
          windowKey && windowKey.length > 0
            ? this.getWindowByKey(windowKey)
            : this.getWindowByEvent(_);
        this.changeWindowPostion(cureentWin, windowPosition);
      }
    );
  }

  /**
   * 创建窗口
   * @param windowConfig 窗口创建参数
   */
  createWindows(windowConfig: IWindowConfig & IWindowsZi): BrowserWindow {
    // 先通过key判断是否已窗口,有则聚焦
    let windowKey = windowConfig.key;

    let isMainWin = windowConfig.isMainWin; // 是否主窗口(当为true时会替代当前主窗口)

    if (windowKey && windowKey.length > 0) {
      /// 先从窗口组中取出记录
      const wg: WindowGroup = this.group.get(windowKey);
      if (wg) {
        /// 根据记录中的窗口id获取窗口,假如存在该窗口,则聚焦该窗口
        const oldWin = BrowserWindow.fromId(wg.windowId);
        if (oldWin) {
          oldWin.focus();
          return oldWin;
        }
      }
    }

    // 创建窗口对象
    const win: BrowserWindow = new BrowserWindow(
      Object.assign({}, defaultWindowConfig, windowConfig)
    );

    // 将窗口的关键信息与key关联,存入窗口组中
    windowKey = windowKey || win.id.toString();
    this.group.set(windowKey, {
      windowId: win.id,
      webContentsId: win.webContents.id,
    });

    // 是否主窗口
    if (isMainWin) {
      if (this.main) {
        // this.main.close();
        this.main.destroy();
      }
      this.main = win;
    }

    // 根据当前环境加载页面,并传递参数
    const param = windowConfig.param
      ? "?urlParamData=" + windowConfig.param
      : "";
    if (process.env.VITE_DEV_SERVER_URL) {
      // 如果是开发环境,则直接访问本地跑起的服务,拼接对应的路由
      win.loadURL(`${url}#${windowConfig.route}${param}`);
    } else {
      // 如果是线上环境,则加载html文件的路径,然后拼接路由
      win.loadFile(indexHtmlPath, { hash: windowConfig.route + param });
    }

    win.webContents.openDevTools(); // 打开 开发者工具

    // 绑定通用窗口事件
    this.bindWindowEvent(win, windowConfig);
    // console.log(this.group);

    return win;
  }

  /**
   * 绑定窗口事件
   * @param win 窗口对象
   * @param windowConfig 窗口创建参数
   */
  bindWindowEvent(win: BrowserWindow | any, windowConfig: IWindowConfig) {
    win.once("ready-to-show", () => {
      win.show();
    });

    // 禁止  ctrl+shift+i 快捷键 打开 开发者工具
    win.webContents.on("before-input-event", (event, input) => {
      // console.log(input, 123);
      if (input.control && input.shift && input.key.toLowerCase() === "i") {
        // console.log("Pressed Control+I");
        event.preventDefault(); // 阻止默认行为
      }
    });

    // 窗口关闭监听,此事件触发时,窗口即将关闭,可以拒绝关闭,此时窗口对象还未销毁
    win.on("close", (e: any) => {
      // let windowId = this.group.get(windowConfig.key).windowId;

      if (this.main == win) {
        win.webContents.send("mainSendToRender", { data: true });

        e.preventDefault();

        // win.destroy(); // 强制关闭窗口
      } else {
        // 设置窗口透明
        if (win != null) {
          win.setOpacity(0);
          const key = windowConfig.key || win.id.toString();
          this.group.delete(key);
        }
      }
    }); // 尝试关闭窗口

    // 此事件触发时,窗口已关闭,窗口对象已销毁
    win.on("closed", () => {
      // 在窗口对象被关闭时,取消订阅所有与该窗口相关的事件
      if (win != null) {
        win.removeAllListeners();
        // 引用置空
        win = null;
      }
    });
  }

  /**
   * 修改窗口的位置
   * @param window 窗口对象
   * @param windowPosition 位置参数对象
   */
  changeWindowPostion(window: BrowserWindow, windowPosition: IWindowPosition) {
    // xy轴值
    let x = windowPosition.x;
    let y = windowPosition.y;
    if (x != null && y != null) {
      // 偏移量
      const offsetX = windowPosition.offsetX || 0;
      const offsetY = windowPosition.offsetY || 0;
      x = windowPosition.x + offsetX;
      y = windowPosition.y + offsetY;
      // 如果是相对于某个窗口的话,加上相对窗口的x、y坐标
      if (windowPosition.relativeWindowId) {
        const relativeWin = BrowserWindow.fromId(
          windowPosition.relativeWindowId
        );
        if (relativeWin) {
          x += relativeWin.getPosition()[0];
          y += relativeWin.getPosition()[1];
        }
      }
      window.setPosition(x, y);
    }

    // 如果有定位
    if (windowPosition.position) {
      // 偏移量
      const offsetX = windowPosition.offsetX || 0;
      const offsetY = windowPosition.offsetY || 0;

      const winBounds = window.getBounds();
      let relativeBounds = screen.getDisplayMatching(winBounds).bounds;
      if (windowPosition.relativeWindowId) {
        const relativeWin = BrowserWindow.fromId(
          windowPosition.relativeWindowId
        );
        if (relativeWin) {
          relativeBounds = relativeWin.getBounds();
        }
      }

      // 计算坐标
      switch (windowPosition.position) {
        case "center":
          window.setPosition(
            relativeBounds.x +
              (relativeBounds.width - winBounds.width) / 2 +
              offsetX,
            relativeBounds.y +
              (relativeBounds.height - winBounds.height) / 2 +
              offsetY
          );
          break;
        case "bottom-left":
          window.setPosition(
            relativeBounds.x + offsetX,
            relativeBounds.y +
              relativeBounds.height -
              winBounds.height +
              offsetY
          );
          break;
        case "bottom-right":
          window.setPosition(
            relativeBounds.x + relativeBounds.width - winBounds.width + offsetX,
            relativeBounds.y +
              relativeBounds.height -
              winBounds.height +
              offsetY
          );
          break;
        case "top-left":
          window.setPosition(
            relativeBounds.x + offsetX,
            relativeBounds.y + offsetY
          );
          break;
        case "top-right":
          window.setPosition(
            relativeBounds.x + relativeBounds.width - winBounds.width + offsetX,
            relativeBounds.y + offsetY
          );
          break;
      }
    }
  }

  /**
   * 通过窗口事件获取发送者的窗口
   * @param event ipc发送窗口事件
   */
  getWindowByEvent(event: Electron.IpcMainInvokeEvent): BrowserWindow {
    const webContentsId = event.sender.id;
    for (const currentWin of BrowserWindow.getAllWindows()) {
      if (currentWin.webContents.id === webContentsId) {
        return currentWin;
      }
    }
    return null;
  }

  /**
   * 通过传入的key获取指定的窗口
   * @param key 窗口唯一key
   */
  getWindowByKey(key: string): BrowserWindow {
    return BrowserWindow.fromId(this.group.get(key).windowId);
  }
}

官方文档:键盘快捷键 | Electron 中文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值