如果你经常打开固定的一批文件夹、脚本、文档,最直接的方法当然是放桌面快捷方式。但桌面图标一多,很快又会乱。AHK 的 Menu 命令很适合做一个轻量入口:热键一按,常用文件夹和文件直接从菜单里打开。
Jack 博客里有几篇文章围绕 QuickLinks 和文件夹菜单展开,我觉得最值得保留的是这个思路:不要把菜单写死在脚本里,而是让脚本从某个文件夹读取内容,自动生成菜单。以后要增加入口,只需要往文件夹里放快捷方式或文件。
先做一个固定菜单
先看最简单版本。这个版本适合入口很少的情况。
#Requires AutoHotkey v1.1 Menu, QuickLinks, Add, 我的文档, OpenDocs Menu, QuickLinks, Add, 下载目录, OpenDownloads Menu, QuickLinks, Add, 脚本目录, OpenScripts F1:: Menu, QuickLinks, Show return OpenDocs: Run, %A_MyDocuments% return OpenDownloads: Run, %A_UserProfile%\Downloads return OpenScripts: Run, %A_ScriptDir% return
这个写法很稳,但缺点也明显:每增加一个入口,都要改代码。入口多了以后,脚本和数据混在一起,维护起来不舒服。
从文件夹生成菜单
更适合长期使用的办法,是准备一个 QuickLinks 文件夹。里面放文件、快捷方式、子文件夹,脚本启动时扫描这个文件夹,把内容变成菜单项。
QuickDir := A_ScriptDir "\QuickLinks"
FileCreateDir, %QuickDir%
F1::
Menu, QuickLinks, UseErrorLevel
Menu, QuickLinks, DeleteAll
Loop, Files, %QuickDir%\*.*, F
Menu, QuickLinks, Add, %A_LoopFileName%, OpenQuickItem
Menu, QuickLinks, Show
return
OpenQuickItem:
Run, % QuickDir "\" A_ThisMenuItem
return
这段代码每次按热键时都会重新生成菜单,所以你往 QuickLinks 里新增文件后,不需要重启脚本。这里用到的 Menu, DeleteAll 很关键,它会先清空旧菜单,避免重复添加。前面加一行 Menu, QuickLinks, UseErrorLevel,是为了避免菜单第一次还不存在时直接报错。
选择一个顶层文件夹
如果你不想把目录写死,可以用 FileSelectFolder 让用户选择一个顶层文件夹。这个命令比 FileSelectFile 更适合此场景,因为它明确要求选择文件夹,不会误选文件。
F1::
FileSelectFolder, TopDir, *%A_ScriptDir%, 3, 选择要生成菜单的文件夹
if ErrorLevel
return
Menu, FolderMenu, UseErrorLevel
Menu, FolderMenu, DeleteAll
Loop, Files, %TopDir%\*.*, F
Menu, FolderMenu, Add, %A_LoopFileName%, OpenFolderItem
Menu, FolderMenu, Show
return
OpenFolderItem:
Run, % TopDir "\" A_ThisMenuItem
return
这个版本适合临时查看某个目录里的文件。如果是每天都用的快捷入口,我更建议固定一个 QuickLinks 目录,这样心智负担更低。
子文件夹怎么办
如果目录里有子文件夹,可以把子文件夹做成子菜单。下面这个例子只处理一层子目录,逻辑更容易读;如果要无限层级递归,代码会复杂不少。
QuickDir := A_ScriptDir "\QuickLinks"
F1::
Menu, MainQuick, UseErrorLevel
Menu, MainQuick, DeleteAll
Loop, Files, %QuickDir%\*.*, D
{
subMenu := "Sub_" A_Index
Menu, %subMenu%, UseErrorLevel
Menu, %subMenu%, DeleteAll
Loop, Files, %A_LoopFileFullPath%\*.*, F
Menu, %subMenu%, Add, %A_LoopFileName%, OpenSubItem
Menu, MainQuick, Add, %A_LoopFileName%, :%subMenu%
}
Loop, Files, %QuickDir%\*.*, F
Menu, MainQuick, Add, %A_LoopFileName%, OpenMainItem
Menu, MainQuick, Show
return
OpenMainItem:
Run, % QuickDir "\" A_ThisMenuItem
return
OpenSubItem:
; 简化示例:实际项目里建议用对象保存菜单项和完整路径的对应关系。
MsgBox, 子菜单项目:%A_ThisMenuItem%
return
子菜单一多,最麻烦的不是显示,而是“点了某个菜单项后,怎么知道它对应哪个完整路径”。严谨一点的写法,可以用对象保存 菜单名 + 菜单项 到完整路径的映射。这样即使不同文件夹里有同名文件,也不会混淆。
用对象保存路径映射
下面是更实用的核心写法:菜单项显示文件名,真正运行时从对象里取完整路径。
QuickDir := A_ScriptDir "\QuickLinks"
ItemPath := {}
F1::
Menu, QuickLinks, UseErrorLevel
Menu, QuickLinks, DeleteAll
ItemPath := {}
Loop, Files, %QuickDir%\*.*, F
{
key := A_LoopFileName
ItemPath[key] := A_LoopFileFullPath
Menu, QuickLinks, Add, %key%, OpenMappedItem
}
Menu, QuickLinks, Show
return
OpenMappedItem:
Run, % ItemPath[A_ThisMenuItem]
return
这个结构清楚很多:菜单只是入口,路径数据放在对象里。后面如果要加图标、排序、过滤扩展名,也更容易扩展。
适合做成什么工具
我觉得这个思路很适合做三个方向:
- 常用文件夹菜单:快速打开项目、资料、下载、截图目录。
- 脚本启动菜单:把常用 AHK 脚本放到一个目录里,菜单点击运行。
- 资料入口菜单:把教程、模板、表格、文档用快捷方式集中管理。
如果菜单项超过几十个,就不要继续硬堆菜单了。可以考虑搜索框、ListView 或模糊搜索。菜单适合“常用入口”,不适合当完整文件管理器。

评论(0)