|
本帖最后由 Metest 于 2025-7-30 22:07 编辑
抽空借助Ai助手编写了这个小工具,看看是否适合,编写环境为AutoIt v3脚本代码。末尾附上成品及源码,需要可自行修改。
界面截图
功能特点:
- 全屏界面:覆盖整个屏幕,无法最小化
- 禁用系统快捷键:屏蔽Win键、Alt+Tab、Alt+F4、Esc等快捷键
- 开机自启:程序会自动添加至开机启动项
- 随机题目:每次随机显示题库中的问题
- 时间显示:屏幕底部显示当前时间和日期
- 答题控制:
支持上一题/下一题切换
输入答案后按回车或点击"提交答案"按钮
回答正确后程序自动退出
首次使用:
- 将程序文件(StudyTool.exe)和题库文件(questions.ini)放在同一目录
- 若没有questions.ini文件,程序会自动创建示例题库
运行方式:
- 直接运行(双击StudyTool.exe)
- 程序会修改注册表实现开机自启(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)
退出条件:
题库配置:
[分类名称]
问题编号=问题内容
A编号=答案内容
题库示例:
[古诗]
1=床前明月光的下一句是什么?
A1=疑是地上霜
2=举头望明月的下一句是什么?
A2=低头思故乡
[数学]
1=25 × 4 ÷ 2 = ?
A1=50
配置规则:
- 每个分类用[分类名]开头
- 问题编号使用纯数字(如1=,2=)
- 答案编号使用A+问题编号(如A1=,A2=)
- 支持多分类,问题数量不限
脚本源码:带注释【已和成品一起打包】AutoIt
- #NoTrayIcon ; 不显示系统托盘图标
- #include <MsgBoxConstants.au3> ; 消息框支持
- #include <WinAPISys.au3> ; Windows API 系统函数
- #include <WinAPIProc.au3> ; Windows API 进程函数
- #include <WindowsConstants.au3> ; Windows 常量
- #include <GUIConstantsEx.au3> ; GUI 控件常量
- #include <EditConstants.au3> ; 编辑框控件常量
- #include <ButtonConstants.au3> ; 按钮控件常量
- #include <StaticConstants.au3> ; 静态文本控件常量
- #include <File.au3> ; 文件操作函数
- #include <Date.au3> ; 日期时间函数
- ; ==== 全局变量声明 ====
- Global $sCurrentAnswer = "" ; 当前问题的正确答案
- Global $aQuestions[0][2] ; 存储所有问题和答案的二维数组 [问题, 答案]
- Global $iCurrentQuestion = -1 ; 当前显示的问题索引
- Global $hGUI, $hLabel, $hInput, $hButtonSubmit, $hButtonPrev, $hButtonNext, $hStatusLabel ; GUI 控件句柄
- Global $hKeyboardHook, $hCallback ; 键盘钩子相关变量
- Global $hTimeLabel, $hDateLabel ; 时间和日期标签句柄
- ; 键盘钩子常量
- Global Const $WH_KEYBOARD_LL = 13
- ; ==== 主程序入口 ====
- _Main()
- Func _Main()
- ; 设置开机自动启动
- _SetAutoStart()
- ; 确保资源管理器运行(防止系统功能异常)
- If Not ProcessExists("explorer.exe") Then
- Run("explorer.exe")
- EndIf
- ; 从INI文件加载题目
- $aQuestions = _LoadQuestionsFromINI()
- ; 检查题目加载情况
- If UBound($aQuestions) = 0 Then
- MsgBox(16, "错误", "未加载到任何题目,请检查questions.ini文件")
- Exit
- EndIf
- ; 创建全屏窗口
- $hGUI = GUICreate("学习工具", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, _
- BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) ; 置顶且不显示在任务栏
- GUISetBkColor(0x1F1F1F) ; 设置背景色为深灰色
- ; ==== 创建界面控件 ====
- ; 1. 时间日期显示
- $hTimeLabel = GUICtrlCreateLabel("", 0, @DesktopHeight - 100, @DesktopWidth, 40, $SS_CENTER)
- GUICtrlSetFont($hTimeLabel, 24, 800) ; 加粗字体
- GUICtrlSetColor($hTimeLabel, 0xFFFFFF) ; 白色文字
- $hDateLabel = GUICtrlCreateLabel("", 0, @DesktopHeight - 60, @DesktopWidth, 30, $SS_CENTER)
- GUICtrlSetFont($hDateLabel, 16)
- GUICtrlSetColor($hDateLabel, 0xFFFFFF) ; 白色文字
- ; 2. 问题显示区域
- $hLabel = GUICtrlCreateLabel("请等待题目加载...", 100, 150, @DesktopWidth - 200, 100, $SS_CENTER)
- GUICtrlSetFont($hLabel, 28, 800) ; 大号加粗字体
- GUICtrlSetColor($hLabel, 0xFFFFFF) ; 白色文字
- ; 3. 状态标签(显示回答正确/错误信息)
- $hStatusLabel = GUICtrlCreateLabel("", 0, 280, @DesktopWidth, 40, $SS_CENTER)
- GUICtrlSetFont($hStatusLabel, 16, 800)
- ; 4. 答案输入框
- $hInput = GUICtrlCreateInput("", (@DesktopWidth - 600)/2, 330, 600, 40, $ES_CENTER) ; 居中文本
- GUICtrlSetFont($hInput, 24)
- GUICtrlSetBkColor($hInput, 0x333333) ; 深灰色背景
- GUICtrlSetColor($hInput, 0xFFFFFF) ; 白色文字
- ; 5. 按钮区域
- $hButtonPrev = GUICtrlCreateButton("上一题", (@DesktopWidth - 600)/2, 400, 150, 50)
- GUICtrlSetFont($hButtonPrev, 14)
- $hButtonSubmit = GUICtrlCreateButton("提交答案", (@DesktopWidth - 200)/2, 400, 200, 50, $BS_DEFPUSHBUTTON) ; 设置为默认按钮
- GUICtrlSetFont($hButtonSubmit, 14)
- GUICtrlSetBkColor($hButtonSubmit, 0x2C8DFF) ; 蓝色背景
- GUICtrlSetColor($hButtonSubmit, 0xFFFFFF) ; 白色文字
- $hButtonNext = GUICtrlCreateButton("下一题", (@DesktopWidth - 600)/2 + 450, 400, 150, 50)
- GUICtrlSetFont($hButtonNext, 14)
- ; 禁用系统快捷键(防止用户退出)
- _DisableSystemShortcuts()
- ; 设置键盘钩子(拦截系统快捷键)
- $hCallback = DllCallbackRegister("_KeyboardProc", "long", "int;wparam;lparam")
- $hKeyboardHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hCallback), _WinAPI_GetModuleHandle(0), 0)
- ; 显示随机题目
- _ShowRandomQuestion()
- ; 显示窗口
- GUISetState(@SW_SHOW, $hGUI)
- ; 注册定时器更新日期时间(每秒更新一次)
- AdlibRegister("_UpdateDateTime", 1000)
- _UpdateDateTime() ; 立即更新一次
- ; ==== 主消息循环 ====
- While 1
- $nMsg = GUIGetMsg()
- Switch $nMsg
- Case $GUI_EVENT_CLOSE
- ; 已禁用关闭按钮(不做任何操作)
- Case $hButtonSubmit
- ; 检查答案
- If _CheckAnswer() Then
- GUICtrlSetData($hStatusLabel, "恭喜您回答正确!程序将退出。")
- GUICtrlSetColor($hStatusLabel, 0x00FF00) ; 绿色文字
- Sleep(2000)
- ExitLoop ; 退出循环
- Else
- GUICtrlSetData($hStatusLabel, "答案不正确,请重新回答!")
- GUICtrlSetColor($hStatusLabel, 0xFF0000) ; 红色文字
- GUICtrlSetData($hInput, "") ; 清空输入框
- GUICtrlSetState($hInput, $GUI_FOCUS) ; 聚焦输入框
- EndIf
- Case $hButtonPrev
- ; 显示上一题
- _ShowPreviousQuestion()
- Case $hButtonNext
- ; 显示下一题
- _ShowNextQuestion()
- EndSwitch
- WEnd
- ; ==== 退出前清理 ====
- _CleanUpResources()
- Exit
- EndFunc
- ; ==== 功能函数 ====
- ; 更新日期时间显示(避免闪烁)
- Func _UpdateDateTime()
- Static $sLastTime = "", $sLastDate = "" ; 静态变量保存上次值(优化性能)
- ; 更新时间显示 (格式: 时:分:秒)
- Local $sTime = StringFormat("%02d:%02d:%02d", @HOUR, @MIN, @SEC)
- ; 更新日期和星期显示
- Local $sWeek = _GetWeekday(@WDAY)
- Local $sDate = @YEAR & "年" & @MON & "月" & @MDAY & "日 " & $sWeek
- ; 仅当时间变化时更新
- If $sTime <> $sLastTime Then
- GUICtrlSetData($hTimeLabel, $sTime)
- $sLastTime = $sTime
- EndIf
- ; 仅当日期变化时更新
- If $sDate <> $sLastDate Then
- GUICtrlSetData($hDateLabel, $sDate)
- $sLastDate = $sDate
- EndIf
- EndFunc
- ; 获取星期名称(根据数字1-7)
- Func _GetWeekday($iWday)
- Switch $iWday
- Case 1
- Return "星期日"
- Case 2
- Return "星期一"
- Case 3
- Return "星期二"
- Case 4
- Return "星期三"
- Case 5
- Return "星期四"
- Case 6
- Return "星期五"
- Case 7
- Return "星期六"
- EndSwitch
- EndFunc
- ; 键盘钩子处理函数(拦截系统快捷键)
- Func _KeyboardProc($nCode, $wParam, $lParam)
- ; 必须调用下一个钩子
- If $nCode < 0 Then
- Return _WinAPI_CallNextHookEx($hKeyboardHook, $nCode, $wParam, $lParam)
- EndIf
- ; 解析键盘事件结构
- Local $tKEYHOOKS = DllStructCreate("dword vkCode;dword scanCode;dword flags;dword time;ulong_ptr dwExtraInfo", $lParam)
- Local $vkCode = DllStructGetData($tKEYHOOKS, "vkCode")
- ; 拦截特定按键
- Switch $vkCode
- Case 0x5B, 0x5C ; Win键
- Return 1 ; 阻止按键传递
- Case 0x09 ; Tab键
- ; 检查Alt键是否按下(Alt+Tab组合)
- If _WinAPI_GetKeyState(0x12) < 0 Then
- Return 1
- EndIf
- Case 0x1B ; Esc键
- Return 1
- Case 0x73 ; F4键
- ; 检查Alt键是否按下(Alt+F4组合)
- If _WinAPI_GetKeyState(0x12) < 0 Then
- Return 1
- EndIf
- Case 0x0D ; 回车键
- ; 当焦点在输入框时,点击提交按钮
- If ControlGetFocus($hGUI) = "Edit1" Then
- GUICtrlSendMsg($hButtonSubmit, $BM_CLICK, 0, 0)
- Return 1 ; 阻止默认回车行为
- EndIf
- EndSwitch
- ; 传递其他按键
- Return _WinAPI_CallNextHookEx($hKeyboardHook, $nCode, $wParam, $lParam)
- EndFunc
- ; 清理资源(退出时调用)
- Func _CleanUpResources()
- ; 取消定时器
- AdlibUnRegister("_UpdateDateTime")
- ; 卸载键盘钩子
- If $hKeyboardHook Then
- _WinAPI_UnhookWindowsHookEx($hKeyboardHook)
- EndIf
- ; 释放回调函数
- If $hCallback Then
- DllCallbackFree($hCallback)
- EndIf
- ; 恢复系统快捷键
- HotKeySet("{ESC}")
- HotKeySet("!{F4}")
- HotKeySet("!{TAB}")
- ; 删除GUI
- GUIDelete($hGUI)
- EndFunc
- ; 禁用系统快捷键
- Func _DisableSystemShortcuts()
- HotKeySet("{ESC}", "_DoNothing")
- HotKeySet("!{F4}", "_DoNothing") ; Alt+F4
- HotKeySet("!{TAB}", "_DoNothing") ; Alt+Tab
- EndFunc
- ; 空函数(用于禁用快捷键)
- Func _DoNothing()
- ; 不执行任何操作
- EndFunc
- ; 设置开机自启动(写入注册表)
- Func _SetAutoStart()
- ; 检查是否已存在注册表项
- If Not RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "StudyTool") Then
- ; 写入当前程序路径
- RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "StudyTool", "REG_SZ", @ScriptFullPath)
- EndIf
- EndFunc
- ; 从INI文件加载题目
- Func _LoadQuestionsFromINI()
- Local $aResult[0][2] ; 初始化结果数组 [问题, 答案]
- Local $sIniFile = @ScriptDir & "\questions.ini" ; INI文件路径
- ; 如果文件不存在,创建示例文件
- If Not FileExists($sIniFile) Then
- _CreateSampleIni($sIniFile)
- EndIf
- ; 读取文件内容
- Local $sContent = FileRead($sIniFile)
- If @error Then Return $aResult ; 读取失败返回空数组
- ; 按行分割内容
- Local $aLines = StringSplit($sContent, @CRLF, $STR_ENTIRESPLIT + $STR_NOCOUNT)
- Local $sCurrentSection = "" ; 当前INI节名
- Local $sLastQuestion = "" ; 临时存储问题
- ; 逐行解析INI文件
- For $i = 0 To UBound($aLines) - 1
- ; 跳过空行
- If StringStripWS($aLines[$i], $STR_STRIPALL) = "" Then ContinueLoop
- ; 检查是否是节头(例如 [古诗])
- If StringLeft($aLines[$i], 1) = "[" And StringRight($aLines[$i], 1) = "]" Then
- $sCurrentSection = StringMid($aLines[$i], 2, StringLen($aLines[$i]) - 2)
- ContinueLoop
- EndIf
- ; 解析键值对
- Local $iPos = StringInStr($aLines[$i], "=")
- If $iPos > 1 Then
- Local $sKey = StringStripWS(StringLeft($aLines[$i], $iPos - 1), $STR_STRIPTRAILING + $STR_STRIPLEADING)
- Local $sValue = StringStripWS(StringMid($aLines[$i], $iPos + 1), $STR_STRIPTRAILING + $STR_STRIPLEADING)
- ; 处理问题行(纯数字键)
- If StringIsDigit($sKey) Then
- $sLastQuestion = $sValue
- ; 处理答案行(A+数字键)
- ElseIf StringLeft($sKey, 1) = "A" And StringIsDigit(StringMid($sKey, 2)) And $sLastQuestion <> "" Then
- ; 添加到结果数组
- ReDim $aResult[UBound($aResult) + 1][2]
- $aResult[UBound($aResult) - 1][0] = $sLastQuestion
- $aResult[UBound($aResult) - 1][1] = $sValue
- $sLastQuestion = "" ; 重置问题
- EndIf
- EndIf
- Next
- Return $aResult
- EndFunc
- ; 创建示例INI文件(当questions.ini不存在时)
- Func _CreateSampleIni($sFilePath)
- Local $hFile = FileOpen($sFilePath, $FO_OVERWRITE + $FO_UTF8)
- If $hFile = -1 Then Return
- ; 写入示例内容
- FileWrite($hFile, "[古诗]" & @CRLF)
- FileWrite($hFile, "1=床前明月光的下一句是什么?" & @CRLF)
- FileWrite($hFile, "A1=疑是地上霜" & @CRLF)
- FileWrite($hFile, "2=举头望明月的下一句是什么?" & @CRLF)
- FileWrite($hFile, "A2=低头思故乡" & @CRLF)
- FileWrite($hFile, "3=春眠不觉晓的下一句是什么?" & @CRLF)
- FileWrite($hFile, "A3=处处闻啼鸟" & @CRLF & @CRLF)
- FileWrite($hFile, "[数学]" & @CRLF)
- FileWrite($hFile, "1=25 × 4 ÷ 2 = ?" & @CRLF)
- FileWrite($hFile, "A1=50" & @CRLF)
- FileWrite($hFile, "2=(18 + 7) × 3 = ?" & @CRLF)
- FileWrite($hFile, "A2=75" & @CRLF)
- FileWrite($hFile, "3=144 的平方根是多少?" & @CRLF)
- FileWrite($hFile, "A3=12" & @CRLF & @CRLF)
- FileWrite($hFile, "[常识]" & @CRLF)
- FileWrite($hFile, "1=中国的首都是哪个城市?" & @CRLF)
- FileWrite($hFile, "A1=北京" & @CRLF)
- FileWrite($hFile, "2=太阳系中最大的行星是?" & @CRLF)
- FileWrite($hFile, "A2=木星" & @CRLF)
- FileClose($hFile)
- EndFunc
- ; 显示随机题目
- Func _ShowRandomQuestion()
- $iCurrentQuestion = Random(0, UBound($aQuestions) - 1, 1)
- _ShowQuestion($iCurrentQuestion)
- EndFunc
- ; 显示上一题
- Func _ShowPreviousQuestion()
- If $iCurrentQuestion > 0 Then
- $iCurrentQuestion -= 1
- Else
- ; 循环到最后一条
- $iCurrentQuestion = UBound($aQuestions) - 1
- EndIf
- _ShowQuestion($iCurrentQuestion)
- EndFunc
- ; 显示下一题
- Func _ShowNextQuestion()
- If $iCurrentQuestion < UBound($aQuestions) - 1 Then
- $iCurrentQuestion += 1
- Else
- ; 循环到第一条
- $iCurrentQuestion = 0
- EndIf
- _ShowQuestion($iCurrentQuestion)
- EndFunc
- ; 显示指定索引的题目
- Func _ShowQuestion($iIndex)
- ; 更新问题标签
- GUICtrlSetData($hLabel, $aQuestions[$iIndex][0])
- ; 保存正确答案
- $sCurrentAnswer = $aQuestions[$iIndex][1]
- ; 清空输入框和状态标签
- GUICtrlSetData($hInput, "")
- GUICtrlSetData($hStatusLabel, "")
- ; 聚焦输入框
- GUICtrlSetState($hInput, $GUI_FOCUS)
- ; 更新窗口标题显示进度
- WinSetTitle($hGUI, "", "学习工具 - 题目 " & ($iIndex + 1) & "/" & UBound($aQuestions))
- EndFunc
- ; 检查答案是否正确
- Func _CheckAnswer()
- ; 获取并清理用户答案(去除空格)
- Local $sUserAnswer = StringStripWS(GUICtrlRead($hInput), $STR_STRIPALL)
- ; 与正确答案比较
- Return ($sUserAnswer == $sCurrentAnswer)
- EndFunc
复制代码
下载链接:
主链接:https://www.123912.com/s/iINuVv-YRUBd 提取码:tdoi
备链接:https://www.123865.com/s/iINuVv-YRUBd 提取码:tdoi
|
|