Menu

创建, 删除, 修改和显示菜单和菜单项. 改变托盘图标和它的提示. 控制是否可以打开已编译脚本主窗口.

Menu, MenuName, SubCommand , Value1, Value2, Value3, Value4

MenuName 参数可以是 Tray 或任何自定义菜单的名称. 自定义菜单在第一次使用 Add 子命令时自动创建. 例如: Menu, MyMenu, Add, Item1. 创建后, 可以使用 Show 子命令显示自定义菜单. 它也可以通过 Add 子命令作为子菜单附加到一个或多个其他菜单上.

SubCommand, Value1, Value2, Value3Value4 参数相互依赖, 它们的用法如下所述.

目录

子命令

对于 SubCommand, 指定以下命令之一:

Add

添加一个菜单项, 用一个新的子菜单或标签更新一个菜单项, 或把普通菜单转换成子菜单(或相反).

Menu, MenuName, Add , MenuItemName, LabelOrSubmenu, Options

这是一个多用途子命令. MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName). 如果 MenuItemName 还不存在, 则把它添加到菜单. 否则, 将使用新指定的 LabelOrSubmenu 更新 MenuItemName.

要添加菜单分隔线, 请省略所有三个参数.

当用户选择菜单项时, 标签子程序作为新线程运行(类似于 Gosub热键子程序). 如果省略 LabelOrSubmenu, 那么将使用 MenuItemName 同时作为标签和菜单项的名称.

[v1.1.20+]: 如果不存在这个名称的标签, 那么 LabelOrSubmenu 可以是一个函数对象的名称, 或是引用某个函数对象的变量. 例如 , %funcObj%% funcObj. 有关特性完整的演示, 请参阅示例 #5. 目前暂不支持其他返回对象的表达式. 另外还可以定义函数可选参数, 例如:

FunctionName(ItemName, ItemPos, MenuName)

要让 MenuItemName 变成子菜单(在选择时打开新菜单的菜单项), 请在 LabelOrSubmenu 中指定冒号后面跟着现有自定义菜单的 MenuName. 例如:

Menu, MySubmenu, Add, Item1
Menu, Tray, Add, This menu item is a submenu, :MySubmenu

如果不省略, Options 必须是包含一个或多个下列选项并以空格或制表符分隔的列表:

选项 描述
Pn 指定 n 代表菜单项的线程优先级, 如 P1. 如果在添加菜单项时省略此选项, 其优先级将会是默认的 0 . 如果在更新菜单项时省略此选项, 其优先级不变. 用十进制数字(不是十六进制) 表示优先级.
+Radio [v1.1.23+]: 选中菜单项时显示的是一个空心圆而不是打勾标志.
+Right [v1.1.23+]: 让菜单栏中的菜单项右对齐. 此选项仅适用于菜单栏而不是弹出式菜单或子菜单.
+Break [v1.1.23+]: 让弹出式菜单中的菜单项以新的一列开始.
+BarBreak [v1.1.23+]: 作用同上, 不过该选项会在列之间加分隔线.

选项中的加号(+) 是可选的也可以用减号(-) 代替用以移除某个选项, 就像 -Radio . 选项不区分大小写.

为了不影响菜单项的标签或子菜单, 在改变一个已存在的菜单项的选项时直接忽略 LabelOrSubmenu 参数即可.

Insert [v1.1.23+]

在指定的菜单项前插入一个新的菜单项.

Menu, MenuName, Insert , MenuItemName, ItemToInsert, LabelOrSubmenu, Options

用法同上面的 Add 子命令, 除了 MenuItemName 始终是现有菜单项的名称或位置(详细信息请参阅 MenuItemName), ItemToInsert 是要在 MenuItemName 之前插入的新菜单项的名称. 菜单项也可以通过忽略 MenuItemName(连写两个逗号) 的方式追加. 与 Add 子命令不同, Insert 子命令创建一个新的菜单项, 即使 ItemToInsert 与现有菜单项的名称匹配.

Delete

从菜单中删除指定的菜单项.

Menu, MenuName, Delete , MenuItemName

MenuItemName 是菜单项的名称或位置(有关详情, 请参阅 MenuItemName). 标准菜单项例如 "Exit"(见下文) 不能被单独删除. 如果删除了 default 菜单项, 效果将类似于使用 NoDefault 子命令.

如果省略了 MenuItemName, 则会删除整个 MenuName 菜单以及其他菜单中名称为 MenuName 的子菜单项. 删除菜单还会导致当前 Win32 菜单及其每个子菜单被销毁, 稍后在需要时重新创建. 包含这些子菜单的其他菜单也可能受到影响. 这可以通过在删除菜单本身之前使用 DeleteAll 删除菜单中的项目来避免.

DeleteAll

从菜单中删除所有自定义菜单项.

Menu, MenuName, DeleteAll

任何现有的标准菜单项(见下文) 仍然不受影响. 与使用 Delete 子命令(见上文) 完全删除菜单不同, 空菜单仍然存在, 因此其他任何包含此菜单项作为子菜单的菜单仍保留这些子菜单.

Rename

重命名指定的菜单项到 NewName.

Menu, MenuName, Rename, MenuItemName , NewName

如果 NewName 为空, 指定的菜单项将被转换为分隔线. MenuItemName 是菜单项的名称或位置(有关详情, 请参阅 MenuItemName). 菜单项的当前目标标签或子菜单不会改变. [v1.1.23+]: 可通过指定分隔线的位置, 如 MenuItemName1& 和一个非空的 NewName 的方式将分隔线转换成正常的菜单项, 随后使用 Add 子命令为其指定一个标签或子菜单.

Check

在指定的菜单项前添加复选标记(如果还没有).

Menu, MenuName, Check, MenuItemName

MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName).

Uncheck

从指定的菜单项中删除复选标记(如果有).

Menu, MenuName, Uncheck, MenuItemName

MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName).

ToggleCheck

指定的菜单项如果没有复选标记则添加一个复选标记; 如果已经有了, 则删除它.

Menu, MenuName, ToggleCheck, MenuItemName

MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName).

Enable

允许用户再次选择指定的菜单项, 如果它先前是被禁用(灰色的).

Menu, MenuName, Enable, MenuItemName

MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName).

Disable

将指定的菜单项更改为灰色, 以指示用户无法选择它.

Menu, MenuName, Disable, MenuItemName

MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName).

ToggleEnable

如果指定的菜单项之前是启用的则禁用; 否则, 启用它.

Menu, MenuName, ToggleEnable, MenuItemName

MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName).

Default

将菜单的默认项更改为指定的菜单项, 并将其字体加粗.

Menu, MenuName, Default , MenuItemName

目前在 TRAY 以外的菜单中设置默认项只是改变外观而没有其他作用. MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName). 当用户双击托盘图标时, 会选择其默认菜单项. 如果没有默认项, 则双击没有效果. 如果省略了 MenuItemName, 则效果等同于使用了下面的 NoDefault 子命令.

NoDefault

反向设置用户定义的默认菜单项.

Menu, MenuName, NoDefault

对于托盘菜单: 让菜单恢复其默认菜单项, 对于未编译脚本为 "Open", 而对于已编译脚本则没有(除非 MainWindow 子命令生效). 如果因为之前使用了下面的 NoStandard 子命令使得 "Open" 菜单项不存在, 那么将没有默认菜单项, 因此双击托盘图标没有效果. 对于 TRAY 以外的其他菜单: 任何现有的默认项恢复为非加粗字体.

Standard

在菜单底部插入标准菜单项(如果还不存在).

Menu, MenuName, Standard

此子命令可用于托盘菜单或其他任何菜单.

NoStandard

从菜单移除所有标准(非自定义) 的菜单项(如果存在).

Menu, MenuName, NoStandard

此子命令可用于托盘菜单或其他任何菜单.

Icon

作用于托盘图标或在 [AHK_L 17+]菜单项的图标具体取决于下面语法的用法.

设置托盘图标

改变脚本的托盘图标FileName 中的某个图标.

Menu, Tray, Icon , FileName, IconNumber, Freeze

支持下列的文件类型: ICO, CUR, ANI, EXE, DLL, CPL, SCR 以及包含图标资源的其他类型. 要使用文件中除第一个之外的图标组, 请在 IconNumber 指定它的编号(如果省略, 则它默认为 1). 例如, 2 将加载第二个图标组中的默认图标. 如果 IconNumber 为负数, 则假定其绝对值表示可执行文件中图标的资源 ID. 在 FileName 指定星号(*) 来恢复脚本到其默认图标.

指定 Freeze 为 1 来冻结图标, 而 0 则解冻它(或留空来保持冻结/解冻状态不变). 当图标已经冻结时, PauseSuspend 不会改变它. 注: 要冻结或解冻 当前的 图标, 请使用 Freeze 参数, 例如: Menu, Tray, Icon,,, 1.

改变托盘图标同时也改变由 InputBox, Progress 和后续创建的 GUI 窗口显示的图标. 也会影响已编译脚本, 即使它在编译时指定了自定义的图标.

注意: 如果之前使用如 #NoTrayIcon 的方法隐藏了托盘图标, 则改变图标不会让它显示出来; 要让它显示, 请使用 Menu, Tray, Icon(不带参数).

从 .ICO 外的其他类型文件中加载托盘图标时可能产生轻微的变形. 尤其是对于 16x16 的图标. 要避免此问题, 请把要使用的托盘图标保存到 .ICO 文件.

操作系统的 DLL 和 CPL 文件包含的一些图标可能会有用. 例如: Menu, Tray, Icon, Shell32.dll, 174.

内置变量 A_IconNumberA_IconFile 分别包含了当前图标的编号和名称(带完整路径)(如果为默认图标则两者都为空).

[v1.1.23+]: 图标句柄可替代文件名. 例如, Menu Tray, Icon, HICON:*%handle%. 星号是必需的, 因为图标必须 "加载" 两次: 一次为小图标, 再次为大图标.

[v1.1.27+]: FileName 支持非图标图片文件和位图句柄. 例如, Menu Tray, Icon, HBITMAP:*%handle%.

为指定的菜单项设置一个图标.

Menu, MenuName, Icon, MenuItemName, FileName , IconNumber, IconWidth

MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName). FileName 可以为图标文件或 AutoHotkey 支持的格式的任何图像. 要使用文件中除第一个之外的图标组, 请在 IconNumber 指定它的编号(如果省略, 则它默认为 1). 如果 IconNumber 为负数, 则假定其绝对值表示可执行文件中图标的资源 ID. 在 IconWidth 中指定期望的图标宽度. 如果 IconNumber 表示的图标组包含多种大小的图标, 则使用最接近的匹配并将图标缩放到指定的大小. 请参阅示例 #4 的用法示例.

当前在 Windows Vista 和更高版本中如果需要被设置的图标保留透明度时, 则必须指定 "真实的大小". 例如 Menu, MyMenu, Icon, Item1, Filename.png,, 0.

已知限制: 在 Windows XP 和更早版本中, Gui 菜单栏中的图标无法放置到正确的位置.

[v1.1.23+]: 位图或图标句柄可替代文件名. 例如, HBITMAP:%handle%.

NoIcon

作用于托盘图标或在 [AHK_L 17+]菜单项的图标, 具体取决于下面的语法的用法.

移除托盘图标

如果存在托盘图标则移除它.

Menu, Tray, NoIcon

如果在脚本的最顶部使用此子命令, 那么当脚本启动时, 托盘图标可能会短暂地显示出来. 要避免这种情况, 请使用 #NoTrayIcon. 如果托盘图标当前是隐藏的, 则内置变量 A_IconHidden 的值为 1, 否则为 0.

移除菜单项的图标 [AHK_L 17+]

从指定的菜单项中删除图标(如果有的话).

Menu, MenuName, NoIcon, MenuItemName

MenuItemName 是菜单项的名称或位置(详细信息请参阅 MenuItemName).

Tip

改变托盘图标的工具提示.

Menu, Tray, Tip , Text

托盘图标的工具提示是在鼠标悬停在托盘图标上时显示的. 要创建多行的工具提示, 请在每行之间使用换行符(`n), 例如 Line1`nLine2. 仅显示 Text 中的前 127 个字符, 并且如果 Text 中存在 tab 字符, 则首个此字符后的内容被截除. 如果忽略 Text, 工具提示将恢复到默认文本. 内置变量 A_IconTip 包含工具提示的当前文本(如果文本处于默认状态, 则为空).

在 Windows 10 及更早版本中, 要显示包含 & 符号的工具提示文本, 请用两个附加的 & 符号转义 & 符号. 例如, 指定 A &&& B 将在工具提示中显示 "A & B".

Show

显示 MenuName.

Menu, MenuName, Show , X, Y

允许用户使用方向键, 菜单快捷键(下划线字母) 或鼠标选择菜单项. 可以显示包括托盘菜单在内的任何菜单, 但 GUI 菜单栏除外. 如果同时省略 X 和 Y, 则菜单显示在鼠标光标的当前位置. 如果仅省略其中一个, 则用鼠标光标的位置代替省略的这个. X 和 Y 相对于活动窗口. 预先指定 CoordMode, Menu 可以让它们相对于整个屏幕.

Color

改变菜单的背景颜色为 ColorValue.

Menu, MenuName, Color, ColorValue , Single

ColorValue 是 16 种 HTML 基础颜色之一或 6 位的 RGB 颜色值(请参阅颜色图标). 将 ColorValue 留空(或指定单词 Default) 来恢复菜单的默认颜色. 如果单词 Single 没有作为下一个参数出现, 则任何附加到此菜单的子菜单都会改变颜色.

Click

设置必须点击多少次托盘图标才能选择其默认菜单项.

Menu, Tray, Click, ClickCount

ClickCount 中指定 1 来允许单击选择托盘菜单的默认菜单项. 在 ClickCount 中指定 2 来恢复到默认行为(双击). 例如: Menu, Tray, Click, 1. ClickCount 大于 2 时等同于 2, 而 ClickCount 小于 1 时等同于 1.

MainWindow

允许通过托盘图标打开脚本的主窗口, 在默认情况下, 编译嵌入的脚本是无法打开的.

Menu, Tray, MainWindow

这个子命令恢复了托盘菜单中的 "Open" 菜单项, 除非使用了 NoStandard 子命令, 它还可以启用主窗口的 "View" 菜单中的项目,如 "Lines most recently executed(最近执行的行)", 它允许查看脚本的源代码和其他信息.

对于既没有编译也没有嵌入的脚本, 这种模式是默认的.

NoMainWindow

防止通过托盘图标打开主窗口.

Menu, Tray, NoMainWindow

这个子命令从托盘菜单中移除标准的 "Open" 菜单项. 它也禁用了主窗口的 View 菜单中的项目, 如 "Lines most recently executed". 然而, 当脚本运行时遇到下列命令时, 它们仍然能够显示主窗口并选择相应的视图选项: ListLines, ListVars, ListHotkeysKeyHistory.

这个子命令并不妨碍主窗口被 WinShow 显示或被 ControlGetText 或类似的方法检查, 但它确实阻止了脚本的源代码和其他信息通过主窗口暴露出来, 除非脚本调用了上述的某个命令.

这种模式对于已经编译嵌入的脚本来说是默认的.

[v1.1.34+]: 这个子命令甚至可以在未编译的脚本中使用.

UseErrorLevel

当菜单命令生成错误时, 跳过任何警告对话框和线程终止.

Menu, MenuName, UseErrorLevel , Off

如果脚本中从未使用过此子命令, 则它默认为 OFF. 每当 Menu 命令遇到错误时, OFF 设置会显示一个对话框并终止当前线程. 指定 Menu, Tray, UseErrorLevel 来阻止显示对话框和终止线程; 作为替代, 如果遇到问题则 ErrorLevel 被设置为 1, 否则为 0. 要让此子命令转回 off, 请为下一个参数指定 OFF(或在 [v1.1.30+] 中, 指定 0). 此设置是全局的, 这意味着它影响所有的菜单, 而不只是 MenuName.

菜单项的名称或位置. 一些通用规则适用于所有使用该参数的子命令:

Win32 菜单

当菜单项被添加到菜单中或被修改时, 每个菜单项的名称和其他属性会被 Menu 命令记录下来, 但实际上 Win32 菜单并不会被马上创建. 这种情况发生在菜单或父菜单被附加到一个 GUI 或者首次被显示或者菜单在最近一次显示后被 "销毁". 下列任意一种情形都会导致 Win32 菜单被销毁:

当 Win32 菜单被销毁时, 每一个 Win32 菜单的子菜单和父菜单也可能被销毁.

当一个包含标准项的菜单重新创建它的 Win32 菜单时, 标准项目将被放置在顶部.

任何通过 Win32 API 调用直接对菜单进行的修改仅适用与菜单的当前 "实例" , 在菜单被销毁后丢失.

在首次添加到菜单中时每个菜单项都会被分配到一个 ID. 脚本不能依靠某个菜单项来接收其特定 ID, 但可以像 MenuGetHandle 示例中那样使用 GetMenuItemID 获取该 ID. 此 ID 不可以用在 Menu 命令中, 却可以用于多种 Win32 函数.

备注

菜单通常看起来像这样:

Menu

菜单和菜单项的名称长度最多可达 260 个字符.

分割线可通过 Menu, MyMenu, Add 来增加(也就是忽略其他所有参数). [v1.1.23+]: 要单独删除分割线, 确定他们在菜单中的位置. 例如, 使用 Menu, MyMenu, Delete, 3& 如果分隔符之前有两个项目. 还可以 Menu, MyMenu, DeleteAll 然后重新添加自定义菜单项.

新的菜单项总是添加到菜单的底部. 对于托盘菜单: 要把您的菜单项放到标准菜单项的上面, (在添加完自定义菜单项后) 执行 Menu, tray, NoStandard 后面接着执行 Menu, tray, Standard.

不能使用任何菜单子命令单独操作标准菜单项, 例如 "Pause Script" 和 "Suspend Hotkeys".

如果一个菜单项已变得完全空了(例如使用 Menu, MyMenu, DeleteAll), 则无法把它显示出来. 如果托盘菜单变成空的, 则右击和双击托盘图标将没有效果(此时通常使用 #NoTrayIcon 更好).

如果一个菜单项的子程序已经运行而用户再次选择相同的菜单项, 则会创建一个新线程运行相同的子程序, 并中断之前的线程. 要缓冲这样的事件到以后执行, 请在子程序的首行使用 Critical(不过, 这样也将缓冲/延迟其他线程, 例如按下的热键).

每当通过菜单项运行子程序时, 它会使用设置(例如 SendMode) 的默认值开始. 这些默认值可以在自动执行段改变.

内置变量 A_ThisMenuItemA_ThisMenuItemPos 分别包含了最近用户选择的自定义菜单项的名称和位置(如果没有则为空). 同样地, A_ThisMenu 是选择的 A_ThisMenuItem 的菜单名称. 这些变量可用于在创建的菜单内容不总是相同的时候. 在这种情况下, 通常最好把所有这样的菜单项指向相同的标签, 并在此标签中引用上面的变量来决定执行什么动作.

要让非热键且非 GUI 的脚本持续运行(例如仅包含自定义菜单或菜单项的脚本), 请使用 #Persistent.

GUI, 线程, Thread, Critical, #NoTrayIcon, Gosub, Return, SetTimer, #Persistent

示例

添加一个新菜单项到托盘图标菜单的底部.

#Persistent  ; 让脚本持续运行, 直到用户退出.
Menu, Tray, Add  ; 创建分隔线.
Menu, Tray, Add, Item1, MenuHandler  ; 创建新菜单项.
return

MenuHandler:
MsgBox You selected %A_ThisMenuItem% from menu %A_ThisMenu%.
return

创建一个弹出菜单, 当用户按下热键时显示.

; 添加一些菜单项来创建弹出菜单.
Menu, MyMenu, Add, Item1, MenuHandler
Menu, MyMenu, Add, Item2, MenuHandler
Menu, MyMenu, Add  ; 添加分隔线.

; 添加子菜单到上面的菜单中.
Menu, Submenu1, Add, Item1, MenuHandler
Menu, Submenu1, Add, Item2, MenuHandler

; 创建第一个菜单的子菜单(右箭头指示符). 当用户选择它时会显示第二个菜单.
Menu, MyMenu, Add, My Submenu, :Submenu1

Menu, MyMenu, Add  ; 在子菜单下添加分隔线.
Menu, MyMenu, Add, Item3, MenuHandler  ; 在子菜单下添加另一个菜单项.
return  ; 脚本的自动运行段结束.

MenuHandler:
MsgBox You selected %A_ThisMenuItem% from the menu %A_ThisMenu%.
return

#z::Menu, MyMenu, Show  ; 即按下 Win-Z 热键来显示菜单.

演示了一些菜单子命令.

#Persistent
#SingleInstance
Menu, Tray, Add ; 分隔符
Menu, Tray, Add, TestToggle&Check
Menu, Tray, Add, TestToggleEnable
Menu, Tray, Add, TestDefault
Menu, Tray, Add, TestStandard
Menu, Tray, Add, TestDelete
Menu, Tray, Add, TestDeleteAll
Menu, Tray, Add, TestRename
Menu, Tray, Add, Test
return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TestToggle&Check:
Menu, Tray, ToggleCheck, TestToggle&Check
Menu, Tray, Enable, TestToggleEnable ; 同时启用了下一行的测试, 因为它不能撤销自己的禁用状态.
Menu, Tray, Add, TestDelete ; 类似于上面.
return

TestToggleEnable:
Menu, Tray, ToggleEnable, TestToggleEnable
return

TestDefault:
if (Default = "TestDefault")
{
    Menu, Tray, NoDefault
    Default := ""
}
else
{
    Menu, Tray, Default, TestDefault
    Default := "TestDefault"
}
return

TestStandard:
if (Standard != false)
{
    Menu, Tray, NoStandard
    Standard := false
}
else
{
    Menu, Tray, Standard
    Standard := true
}
return

TestDelete:
Menu, Tray, Delete, TestDelete
return

TestDeleteAll:
Menu, Tray, DeleteAll
return

TestRename:
if (NewName != "renamed")
{
    OldName := "TestRename"
    NewName := "renamed"
}
else
{
    OldName := "renamed"
    NewName := "TestRename"
}
Menu, Tray, Rename, %OldName%, %NewName%
return

Test:
MsgBox, You selected "%A_ThisMenuItem%" in menu "%A_ThisMenu%".
return

演示如何添加图标到其菜单项.

Menu, FileMenu, Add, Script Icon, MenuHandler
Menu, FileMenu, Add, Suspend Icon, MenuHandler
Menu, FileMenu, Add, Pause Icon, MenuHandler
Menu, FileMenu, Icon, Script Icon, %A_AhkPath%, 2 ; 使用文件中的第二个图标组
Menu, FileMenu, Icon, Suspend Icon, %A_AhkPath%, -206 ; 使用资源标识符 206 表示的图标
Menu, FileMenu, Icon, Pause Icon, %A_AhkPath%, -207 ; 使用资源标识符 207 表示的图标
Menu, MyMenuBar, Add, &File, :FileMenu
Gui, Menu, MyMenuBar
Gui, Add, Button, gExit, Exit This Example
Gui, Show
return

MenuHandler:
return

Exit:
ExitApp

演示了使用绑定函数对象传递额外的参数时, 使用函数而不是子程序

; 绑定参数到函数并返回绑定函数对象:
BoundGivePar := Func("GivePar").Bind("First", "Test one")
BoundGivePar2 := Func("GivePar").Bind("Second", "Test two")

; 创建菜单并显示:
Menu MyMenu, Add, Give parameters, % BoundGivePar
Menu MyMenu, Add, Give parameters2, % BoundGivePar2
Menu MyMenu, Show

; 定义自定义函数 GivePar:
GivePar(a, b, ItemName, ItemPos, MenuName)
{
    MsgBox % "a:`t`t" a "`n"
           . "b:`t`t" b "`n"
           . "ItemName:`t" ItemName "`n"
           . "ItemPos:`t`t" ItemPos "`n"
           . "MenuName:`t`t" MenuName
}