# Menu

创建、删除、修改以及显示菜单和菜单项。更改托盘图标和它的提示。控制是否允许打开已编译脚本的主窗口。

Menu, MenuName, Cmd [, P3, P4, P5]

#### 参数

MenuName | 它可以是 TRAY 或者任何自定义菜单的名称。自定义菜单的名称在第一次和 Add 命令一起使用时就会自动地创建这个自定义菜单。例如：Menu, MyMenu, Add, Item1 一旦被创建，就可以用 Show 命令来显示自定义菜单。通过 Add 命令，它也可以附着为一个或多个其它菜单的子菜单。
Cmd, P3, P4, P5 | 这 4 个参数相互依赖。可用的组合如下所示。

## 添加或者改变菜单项

Add [, MenuItemName, Label-or-Submenu, Pn]: 此命令有多个用途，如添加菜单项、为其更新一个新的子菜单或标签、或者将普通菜单项转换成子菜单(或者相反)。如果 MenuItemName 还不存在，它将被添加到菜单。否则，MenuItemName 将会被最新指定的 Label-or-Submenu 所更新。

要添加一个菜单分割线，只需省略所有三个参数。

当用户选择菜单项时，将以一个新的线程运行标签子程序(类似 Gosub 和热键子程序)。如果省略了 Label-or-Submenu，那么 MenuItemName 将同时作为标签和菜单项的名称使用。

要让 MenuItemName 成为子菜单(就是一个菜单项在它被选择时会打开一个新的菜单)，那么给 Label-or-Submenu 指定一个冒号后跟一个已存在的自定义菜单 MenuName 即可。例如：

    Menu, MySubmenu, add, Item1
    Menu, tray, add, This Menu Item Is A Submenu, :MySubmenu

最后一个参数可以包含字母 P 后跟一个菜单的线程优先级，比如 P1。如果在添加菜单项时省略此参数，优先级将是标准的默认值 0。如果在更新菜单项时省略，菜单项的优先级将不做改变。要仅仅改变现有的菜单项的优先级，可以省略参数 Label-or-Submenu。优先级使用十进制数字(不是十六进制)。

Delete [, MenuItemName]: 从菜单删除 MenuItemName。标准菜单项比如 Exit (见下文)不能被单独地删除。如果 d efault 菜单项被删除，其效果如同使用了 NoDefault 选项。如果省略 MenuItemName，整个 MenuName 菜单将被删除，同时删除在其它菜单中使用 MenuName 作为子菜单的任何菜单项。

DeleteAll: 从菜单中删除所有自定义的菜单项，使菜单留空，除非它包含了 standard 菜单项(见下文)。不同于 Delete 命令删除整个菜单(如上文)，空菜单仍然存在，因此将它用作子菜单的任何其它菜单仍将保留这些子菜单。

Rename, MenuItemName [, NewName]: 将 MenuItemName 变更为 NewName (如果 NewName 为空，MenuItemName 将转换为分割线)。NewName 不能和任何已存在的自定义菜单项同名。菜单项当前的目标标签和子菜单不变。

Check, MenuItemName: 在菜单的 MenuItemName 前添加一个可见的对钩标识(如果还没有的话)。

Uncheck, MenuItemName: 从 MenuItemName 移除对钩标识(如果有的话)。

ToggleCheck, MenuItemName: 如果没有对钩标识则添加一个；否则，将它移除。

Enable, MenuItemName: 允许用户再次选择 MenuItemName，如果它先前被禁用(变灰)的话。

Disable, MenuItemName: 使 MenuItemName 变成灰色以表示用户不能选择它。

ToggleEnable, MenuItemName: 如果 MenuItemName 之前可用，则禁用它；否则，将启用它。

Default [, MenuItemName]: 将 MenuItemName 设为菜单的默认项并加粗它的字体(目前在 TRAY 以外的菜单中设置默认项，仅是改变外观而已)。当用户双击托盘图标时，将开启它的默认菜单项。如果没有默认项，双击将没有任何效果。如果省略 MenuItemName，将和下文的 NoDefault 作用相同。

NoDefault: 对于托盘菜单：将菜单改回到它标准菜单的默认项，对未编译脚本来说是 OPEN，而已编译脚本则没有(除非当 MainWindow 选项生效时)。如果之前使用了下面的 NoStandard 命令而导致 OPEN 菜单项不存在的话，那么将没有默认项，因此双击托盘图标也将没有任何效果。对于 TRAY 以外的菜单：任何现有的默认项将变回非加粗字体。

Standard: 在菜单底部插入标准菜单项(如果它们还不存在的话)。此命令可用于托盘菜单或者任何其它菜单。

NoStandard: 从托盘菜单移除所有标准的(非自定义的)菜单项(如果它们存在的话)。

## 改变托盘图标或提示( MenuName 必须是 TRAY)

Icon [, FileName, IconNumber, 1]: 将脚本的图标更改为 FileName 内图标中的一个。支持下列类型的文件：ICO, CUR, ANI, EXE, DLL, CPL, SCR 以及其它包含图标资源的类型。要使用文件内首个以外的图标组，将它的编号指定给 IconNumber (如果省略，那么它默认为 1)。例如，2 将会从第二个图标组加载默认图标。指定星号(*)给 FileName 可以将脚本恢复到它的默认图标。

最后一个参数：要冻结图标，可将末尾参数设为 1，要解冻则设为 0 (或留空从而保持冻结/解冻状态不做改变)。当图标已被冻结时，Pause 和 Suspend 将不能改变图标。注意：要冻结当前的图标，可以像后面例子一样使用 1 或 0 ：Menu, Tray, Icon,,, 1

修改托盘图标也会改变 InputBox, Progress 以及随后创建的 GUI 窗口所显示的图标。已编译脚本即使在编译时已经指定过自定义的图标也会受其影响。注意：如果先前使用例如 #NoTrayIcon 隐藏了托盘图标，那么改变图标是不会反隐藏它的；要这样做的话，可以使用 Menu, Tray, Icon (不带参数)。

从除了 .ICO 外的其他文件类型加载托盘图标时，可能会产生轻微的变形。特别是 16x16 的图标。要避免这种情况，将想要的托盘图标保存在 .ICO 文件里。

操作系统的 DLL 和 CPL 文件包含的一些图标可能会很有用。例如：Menu, Tray, Icon, Shell32.dll, 174 ;省略 Dll 的路径以便它也能用在 Windows 9x 上。

内置变量 A_IconNumber 和 A_IconFile 包含了当前图标(如果是默认图标，两者都为空)的序号和名称(带完整的路径)。

Icon (不带参数): 如果不存在托盘图标则创建它。如果脚本里也存在 #NoTrayIcon 指令的话，此命令将废除它。

NoIcon: 如果存在托盘图标则移除它。如果在脚本的最顶部使用此命令，托盘图标可能在装载脚本时暂时地可见。要避免这种情况，可以使用 #NoTrayIcon 代替。如果当前托盘图标被隐藏，内置变量 A_IconHidden 为 1，否则为 0。

Tip [, Text]: 改变托盘图标的提示，其在鼠标悬停于图标上面时会显示。要创建一个多行的提示，在每一行中间使用换行符(`n)，例如：Line1`nLine2。将只显示 Text 的前 127 个字符。如果省略 Text，提示将被恢复为默认文本。内置变量 A_IconTip 包含了当前提示的文本(如果是默认文本则为空)。

## 杂项命令

Show [, X, Y]: 显示 MenuName，允许用户通过方向键、菜单快捷键(加下划线的字母)或者鼠标来选择菜单项。可以显示包括托盘菜单在内的任何菜单，除了GUI 菜单栏外。如果省略 X 和 Y ，菜单会在当前的鼠标光标位置显示。如果只省略了它们中的一个，那么会用鼠标光标的位置来代替它。X 和 Y 是相对于激活窗口的。事先指定 "CoordMode, Menu" 可以使它们相对于整个屏幕。

Color, ColorValue [, Single]: 将菜单的背景色改成 ColorValue，它是 16 种 HTML 基础颜色之一或者是 6 位的 RGB 颜色值(请看颜色表)。将 ColorValue 留空(或指定为单词 Default)可以将菜单恢复为它的默认颜色。如果没有在下个参数中指定单词 Single，那么附在这个菜单上的任何子菜单也将被改变颜色。此命令在 Windows 95/NT 上无效。

Click, ClickCount: 将 ClickCount 指定为 1 来允许单击激活托盘菜单的默认菜单项。将它指定为 2 可以返回到默认行为(双击)。例如：Menu, Tray, Click, 1

MainWindow: 此命令只影响已编译脚本。它允许通过托盘图标来打开脚本的主窗口，反之则打不开。它也能启用主窗口的 View 菜单项，比如 "Lines most recently executed" 就可以查看脚本的源代码和其他信息。MenuName 必须是 TRAY。

NoMainWindow (默认): 此命令只影响已编译脚本。它使脚本恢复为它的默认行为，也就是说它会防止主窗口被打开。即使此选项生效，但在脚本运行时遇上 ListLines, ListVars, ListHotkeys 和 KeyHistory 命令时，它们仍可以显示主窗口。MenuName 必须是 TRAY。

UseErrorLevel [, off]: 如果在脚本中从未使用过此命令，那么它默认为 OFF。每当 Menu 命令遇到错误时，OFF 设置会显示一个对话框并终止当前线程。指定 Menu, Tray, UseErrorLevel 可以阻止对话框显示和线程终止；取代它们的是，如果遇到问题 ErrorLevel 将被设为 1，否则为 0。要将此选项调回 off，可以把下个参数设为 OFF。此设置是全局性的，这意味着它会影响所有的菜单，而不仅仅是菜单 MenuName。

## 注意

要给菜单项的某个字母加下划线，那么在那个字母前加一个 & 符号。当菜单显示时，可以按键盘上相应的按键来选择此菜单项。要显示一个原义的 & 符号，只需指定两个连续的 & 符号，例如：Save && Exit

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

当引用已有的菜单或菜单项时，名称不区分大小写，但是必须包含 & 符号。例如：&Open

可以使用 Menu, tray, add (即省略其他所有的参数)来给菜单添加分割线。不过，当前还不能单独删除分割线。要绕弯解决这种情况，可使用 Menu, tray, DeleteAll，然后重新添加你的自定义菜单项。

新的菜单项总是添加到菜单的底部。对于托盘菜单：要将你的菜单项放在标准菜单项的上面(在添加完你的菜单项后)，可以运行 Menu, tray, NoStandard 后跟 Menu, tray, Standard。

不能使用任何菜单子命令来单独地操作标准菜单项，比如 "Pause Script" 和 "Suspend Hotkeys"。

如果菜单已完全变空，比如使用了 Menu, MyMenu, DeleteAll 命令，则它不会被显示。如果托盘菜单变空，那么右击和双击托盘图标将不起任何作用(这种情况下，通常使用 #NoTrayIcon 会更好)。

如果菜单项的子程序运行时，用户再次选择了同个菜单项，那么将创建一个新的线程来运行那个相同的子程序，并打断之前的线程。如果想缓存并迟些执行的话，将 Critical 作为子程序的首行(不过，这么做同样会缓冲/推迟其它的线程，比如按了一个热键)。

每当通过菜单项启动一个子程序时，都将会刷新设置比如 SendMode 的默认值。可以在自动执行部分修改这些默认值。

内置变量 A_ThisMenuItem 和 A_ThisMenuItemPos 分别包含了最近用户选择的自定义菜单项的名称和位置(如果没有则为空)。类似地，A_ThisMenu 是选择的 A_ThisMenuItem 的菜单名称。当创建的菜单内容不会一直相同时，这些变量就会很有用。在这种情况下，通常最好给这些菜单项指定相同的标签，然后把那些标签关联到上面的变量，从而确定要执行的动作。

要让一个没有热键、无 GUI 的脚本持续运行，比如仅包含了自定义菜单或菜单项的脚本，可以使用 #Persistent。

## 相关命令

GUI, Threads, Thread, Critical, #NoTrayIcon, Gosub, Return, SetTimer, #Persistent

## 示例

    ;示例 #1: 该脚本在托盘图标菜单底部添加了一个新的菜单项。

    #Persistent  ;保持脚本运行，直到用户退出它。
    Menu, tray, add  ;创建一条分割线。
    Menu, tray, add, Item1, MenuHandler  ;创建一个新的菜单项。
    return

    MenuHandler:
    MsgBox 你从 %A_ThisMenu% 菜单中选择了 %A_ThisMenuItem% 菜单项。
    return

    ;示例 #2: 该脚本创建了一个弹出菜单，当用户按热键 Win-Z 将显示它。

    ;通过添加菜单项来创建弹出菜单。
    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 你从 %A_ThisMenu% 菜单中选择了 %A_ThisMenuItem% 菜单项。
    return

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

    ;示例 #3: 该脚本演示了多个菜单命令。

    #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 <> n
    {
        menu, tray, NoStandard
        standard = n
    }
    else
    {
        menu, tray, Standard
        standard = y
    }
    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, 你在 "%A_ThisMenu%" 菜单选择了 "%A_ThisMenuItem%"。
    return

翻译：lwjiee 修正：天堂之门 2008年11月20日