diff --git a/WordDictationStudentApp/.DS_Store b/WordDictationStudentApp/.DS_Store index c5d45d8..6d4bf5b 100644 Binary files a/WordDictationStudentApp/.DS_Store and b/WordDictationStudentApp/.DS_Store differ diff --git a/WordDictationStudentApp/dist/.DS_Store b/WordDictationStudentApp/dist/.DS_Store index 384098d..659d889 100644 Binary files a/WordDictationStudentApp/dist/.DS_Store and b/WordDictationStudentApp/dist/.DS_Store differ diff --git a/WordDictationStudentApp/main.js b/WordDictationStudentApp/main.js index c3aaae5..867edb4 100644 --- a/WordDictationStudentApp/main.js +++ b/WordDictationStudentApp/main.js @@ -1,92 +1,94 @@ // main.js -const { app, BrowserWindow, dialog, ipcMain } = require('electron'); // 1. 导入 ipcMain +const { app, BrowserWindow, globalShortcut, screen, ipcMain } = require('electron'); // 添加 ipcMain const path = require('path'); -// const cv = require('opencv4nodejs'); // 已移除视觉作弊相关 let mainWindow; -let switchCount = 0; // 在主进程中也维护一个计数器 -const switchLimit = 3; -const warningLimit = 2; - -// --- 已移除视觉作弊相关变量 --- function createWindow () { + // 获取主显示器尺寸 + const primaryDisplay = screen.getPrimaryDisplay(); + const { width, height } = primaryDisplay.size; + mainWindow = new BrowserWindow({ // --- 关键修改:设置为全屏无框 --- + width: width, + height: height, fullscreen: true, - frame: false, + kiosk: true, // 关键:kiosk 模式,隐藏菜单栏、Dock + alwaysOnTop: true, resizable: false, + movable: false, + fullscreenable: false, + titleBarStyle: 'hidden', webPreferences: { nodeIntegration: false, - contextIsolation: true, // 2. 必须开启 + contextIsolation: true, enableRemoteModule: false, - preload: path.join(__dirname, 'preload.js') // 3. 关键:加载 preload 脚本 - }, - // --- 可选:设置图标 --- - // icon: path.join(__dirname, 'icon.png') + preload: path.join(__dirname, 'preload.js') + } }); mainWindow.loadFile('student_app_fullscreen.html'); - // --- 关键修改:监听窗口失去焦点事件 --- - mainWindow.on('blur', () => { - switchCount++; - console.log(`窗口失去焦点,切屏次数: ${switchCount}`); // 控制台输出日志 - - if (switchCount <= warningLimit - 1 ) { - // 显示警告对话框 - dialog.showMessageBox(mainWindow, { - type: 'warning', - title: '切屏警告', - message: `您进行了切屏操作,此行为已被记录,如您再次进行两次切屏,则会重置考试`, - buttons: ['确定'] - }).then(() => { - // 警告后,将焦点重新移回主窗口 - mainWindow.focus(); - }); - } else if (switchCount < switchLimit) { - // 第三次切屏,重置警告 - dialog.showMessageBox(mainWindow, { - type: 'warning', - title: '切屏警告', - message: `您再次进行了切屏操作,此行为已被记录,如您再次进行一次切屏,则会重置考试`, - buttons: ['确定'] - }).then(() => { - mainWindow.focus(); - }); - } else { - // 超过限制次数 - dialog.showMessageBox(mainWindow, { - type: 'error', - title: '切屏过多', - message: `您因切屏超过误触缓冲次数,重置考试`, - buttons: ['确定'] - }).then(() => { - // 重置考试:重新加载页面,重置计数器 - switchCount = 0; - mainWindow.reload(); - }); - } + // --- 移除窗口关闭拦截,允许通过按钮退出 --- + + // 启动时就注册全局快捷键拦截 + registerGlobalShortcuts(); + + // 添加退出应用的IPC处理程序 + ipcMain.handle('exit-app', async () => { + app.quit(); }); - // --- 结束监听 --- - - // 监听窗口关闭事件 - mainWindow.on('closed', () => { - mainWindow = null; - }); - - // --- 已移除视觉作弊检测启动 --- } -// --- 已移除视觉作弊检测相关函数 --- +// 注册全局快捷键拦截 +function registerGlobalShortcuts() { + // 移除 Esc 退出功能 + + // 尝试注册其他快捷键(在无辅助功能权限时可能无效,但无害) + const shortcuts = [ + 'CommandOrControl+Tab', + 'CommandOrControl+Shift+Tab', + 'Command+Q', + 'Command+W', + 'Command+R', + 'F5', + 'F11', + 'F12', + 'Alt+Tab', + 'Alt+F4', + 'Control+Escape', + 'CommandOrControl+W', + 'CommandOrControl+R', + 'Control+R', + 'Alt+Space', // Windows打开菜单 + 'Command+Space', // Mac打开Spotlight + 'Command+M', // Mac最小化 + 'Command+H', // Mac隐藏 + 'Command+Option+H', // Mac隐藏其他 + 'Command+Option+M', // Mac最小化所有 + 'Command+Option+Escape', // Mac强制退出 + 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', // 功能键 + 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', + 'Fn' // 禁用 Fn 键 + ]; -// --- IPC 处理程序 --- -// 处理来自渲染进程的获取切屏次数请求 -ipcMain.handle('get-switch-count', async () => { - return switchCount; // 返回当前计数 -}); + shortcuts.forEach(key => { + try { + globalShortcut.register(key, () => { + // 吃掉事件,什么都不做 + console.log(`⚠️ 阻止了快捷键:`, key); + }); + } catch (e) { + console.warn('Failed to register:', key); + } + }); +} -// --- 已移除未认真答题次数相关 IPC --- +// 注销全局快捷键拦截 +function unregisterGlobalShortcuts() { + globalShortcut.unregisterAll(); +} app.whenReady().then(() => { createWindow(); @@ -97,16 +99,7 @@ app.whenReady().then(() => { }); app.on('window-all-closed', function () { - // --- 已移除应用退出时停止色码检测 --- + // 注销所有快捷键 + unregisterGlobalShortcuts(); if (process.platform !== 'darwin') app.quit(); -}); - -// --- 注释掉或移除旧的 IPC 代码 --- -// const { ipcMain } = require('electron'); -// ipcMain.on('get-switch-count', (event) => { -// event.reply('switch-count-reply', switchCount); -// }); -// ipcMain.on('reset-switch-count', () => { -// switchCount = 0; -// }); -// --- 结束注释 --- \ No newline at end of file +}); \ No newline at end of file diff --git a/WordDictationStudentApp/preload.js b/WordDictationStudentApp/preload.js index 545da2f..77d3aac 100644 --- a/WordDictationStudentApp/preload.js +++ b/WordDictationStudentApp/preload.js @@ -1,12 +1,8 @@ // preload.js const { contextBridge, ipcRenderer } = require('electron'); -// 安全地暴露 API 到渲染进程 +// 安全地暴露退出应用的 API 到渲染进程 contextBridge.exposeInMainWorld('electronAPI', { - // 向主进程请求获取切屏次数 - getSwitchCount: () => ipcRenderer.invoke('get-switch-count'), - // 已移除未认真答题次数相关 API - // 如果需要,也可以暴露重置计数的 API - // resetSwitchCount: () => ipcRenderer.invoke('reset-switch-count'), - // resetOffTaskCount: () => ipcRenderer.invoke('reset-off-task-count'), + // 退出应用 + exitApp: () => ipcRenderer.invoke('exit-app') }); \ No newline at end of file diff --git a/WordDictationStudentApp/student_app_fullscreen.html b/WordDictationStudentApp/student_app_fullscreen.html index f673d8a..7848931 100644 --- a/WordDictationStudentApp/student_app_fullscreen.html +++ b/WordDictationStudentApp/student_app_fullscreen.html @@ -965,9 +965,40 @@ margin-bottom: 10px; } } + + /* 添加全局退出按钮样式 */ + #exitButton { + position: fixed; + top: 20px; + right: 20px; + z-index: 10000; + background: linear-gradient(45deg, #FF3B30, #ff6b6b); + color: white; + border: none; + border-radius: 50%; + width: 50px; + height: 50px; + font-size: 20px; + cursor: pointer; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; + } + + #exitButton:hover { + transform: scale(1.1); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4); + } + + +
@@ -1155,17 +1186,6 @@
0
总计
- -
-
0
-
切屏次数
-
- -
-
0
-
未认真答题次数
-
-

错误详情

@@ -1181,50 +1201,17 @@