*****************************************************************
***              ContextMenu AkelPad plugin v17.6             ***
*****************************************************************

2007-2017 Shengalts Aleksander aka Instructor (Shengalts@mail.ru)


*** 描述 ***

配置主菜单和编辑控件、MDI 标签、超链接和最近文件的上下文菜单。

注意:
- 按下 Ctrl 键同时鼠标左键点击在非特殊菜单项目将打开参数对话框并定位到该项目代码。
- 最近文件菜单在 Win95 中不能用。


*** 函数 ***

ContextMenu::Main
主会话。

ContextMenu::Show
显示用户菜单。


*** 语法 ***

变量:
  %f 活动文件
  %d 活动文件所在目录
  %a AkelPad 所在目录
  %m 菜单 ID (句柄)
  %i 菜单项目 ID
  %u URL 地址 (仅用于 "URL 菜单")
  %% 符号 %
  %系统变量%

注释:
  # 注释
  ; 注释

特殊菜单项目:
  SEPARATOR
    菜单项目分隔符。
  SEPARATOR1
    与 SEPARATOR 相同，但:
    - 如果序列中指定多个的 SEPARATOR1，那么将被合并成单一一个 SEPARATOR1;
    - 如果指定的 SEPARATOR1 在子菜单的开头或结束都将被移除。
  EXPLORER
    资源管理器菜单。
  FAVOURITES
    收藏夹文件列表。
  RECENTFILES
    最近文件菜单。
  LANGUAGES
    语言模块列表。
  OPENCODEPAGES
    重新打开文件的代码页列表。
  SAVECODEPAGES
    保存文件的代码页列表。
  MDIDOCUMENTS
    MDI 文档列表 (仅用于 "主菜单" 的 MDI 模式)。
  CLEAR
    清除菜单 (仅用于 "主菜单")。
  INCLUDE("MENU NAME")
    "MENU NAME"
      来自 "ContextMenu::Show menu" 的指定子菜单名.
    INCLUDE("SYNTAXTHEME")
      插入来自 "ContextMenu::Show menu" 的"SYNTAXTHEME" 子菜单项。
  SET(标记[, 附加参数])
    设置文字解析标记 (已经设置的标记不会被删除)。根据下列数字之和来设置:
      SET(1)
        SDI 模式时忽略下面的行。
      SET(2)
        MDI 模式时忽略下面的行。
      SET(4)
        PMDI 模式时忽略下面的行。
      SET(8)
        当从主菜单复制文字时，不捕捉热键。
      SET(16)
        非插件处理地创建菜单项 (关闭: 图标、Menu() 方法、特殊项 INCLUDE)。
        需要在第一个菜单项之前放置 SET(16) 和在最后一个菜单项之后放置 UNSET(16)。
      SET(32, "%a\AkelFiles\Plugs\Scripts.dll")
        如果“Scripts.dll”文件存在就解析下面的行。
      SET(64, If("expression"[, IfTrue, IfFalse]))
        如果结果不等于零就解析下面的行。
          "expression"
            表达式可以由下列组成:
            - 数学运算符:
              +, -, *, /, %, &, |, ^.
            - 逻辑运算符:
              >, <, ==, !=, >=, <=, &&, ||, x?y:z.
            - 注释:
              /*注释*/
            - 方法:
              SendMain(nMessage, wParam, lParam)
                nMessage
                  指定要发送给主窗口的消息。
                wParam
                  指定额外消息特定信息。
                lParam
                  指定额外消息特定信息。
              SendEdit(nMessage, wParam, lParam)
                nMessage
                  指定要发送给当前编辑窗口的消息。
                wParam
                  指定额外消息特定信息。
                lParam
                  指定额外消息特定信息。
              Call("Plugin::Function"[, 附加参数])
                - 如果调用一个插件，那么通过指定的参数 &nResult 传递退出代码。&nResult 必须放在外部调用语法请求指向一个整数的指针的位置。
                  SET(64, If(`Call("Coder::CodeFold", 1, &nResult)`)
                    若 CodeFold 窗口已打开就解析下面的行。
                - 如果调用一个脚本，那么就有必要使用外部调用 2 或 4，并且还可以通过 AkelPad.ScriptExitCode 从脚本传递退出代码。
                  SET(64, If(`Call("Scripts::Main", 4, "EvalCmd.js", 'if (AkelPad.GetEditFile(0)) AkelPad.ScriptExitCode(1);')`)
                    若当前文档已命令就解析下面的行。
                - 可以直接调用 Scripts 插件方法。
                  SET(64, If(`AkelPad.Constants._X64 == 1`))
                    若程序为 x64 就解析下面的行。
          IfTrue
            数值，如果表达式结果为真 (不等于零)。
          IfFalse
            数值，如果表达式结果为假 (等于零)。
        SET(64, If(`SendMain(1222 /*AKD_GETMAININFO*/, 5 /*MI_SAVESETTINGS*/, 0) == 2 /*SS_INI*/`))
          如果设置是保存到 ini 文件就解析下面的行。
      SET(128, If("expression"[, IfTrue, IfFalse]))
        设置菜单状态。
          "expression"
            请参阅 SET(64) 的说明。
          IfTrue
            0x0 //IFS_NORMAL    标准的菜单项。
            0x1 //IFS_CHECKED   复选的菜单项。
            0x2 //IFS_GRAYED    禁用变灰的菜单项。
            0x4 //IFS_DISABLED  禁用的菜单项。
          IfFalse
            0x0 //IFS_NORMAL    标准的菜单项。
            0x1 //IFS_CHECKED   复选的菜单项。
            0x2 //IFS_GRAYED    禁用变灰的菜单项。
            0x4 //IFS_DISABLED  禁用的菜单项。
        SET(128, If("SendMain(1223 /*AKD_GETFRAMEINFO*/, 69 /*FI_CARETOPTIONS*/, 0) & 0x2 /*CO_CARETVERTLINE*/", 0x1, 0x0))
          若插入点活动列已打开就复选上下面的菜单项。
        SET(128, If(`Call("Scripts::Main", 5, "SearchReplace.js", 2 /*SH_THISSCRIPT*/, &nResult)`, 0x1, 0x0))
          若 SearchReplace.js 正在运行就复选上下面的菜单项。
        SET(128, If(`AkelPad.IsPluginRunning("Coder::HighLight")`, 0x1, 0x0))
          若 Coder::HighLight 正在运行就复选上下面的菜单项。
  UNSET(标记)
    取消设置文字解析标记。请查阅 SET() 的描述。

菜单项目创建:
  [-]"[菜单项目文字]"  [Command() | Call() | +Call() | Exec() | OpenFile() | SaveFile() | Font() | Recode() | Insert() | Link() | Favourites() | Menu()] [Icon()]

  [-]"[菜单项目文字]"
    "我的菜单项目"
      菜单项目文字。
    -"我的菜单项目"
      有负号的菜单项目的状态不会被某种方法所改变(变为不可用，选上)。
    ""
      菜单项目无文字也可以被方法 Command() 所使用，插件将使用 Command() 所引用的主菜单项目的文字来代替。

    Command(数字[, 参数])
      Command(4162)
        方法调用 4162 的内部命令。本例子的这个代码用来打开 "转到行..." 对话框。
        查阅 AkelHelp-Eng.htm 或插件源码中的 AkelDLL.h 可了解完整的命令列表。
    Call("插件::函数"[, 附加参数])
      Call("Scripts::Main")
        方法将调用脚本插件的主函数。
    +Call("插件::函数"[, 附加参数])
      +Call("LineBoard::Main")
        方法将调用 LineBoard 插件的主函数。插件仍会在程序重启后运行。
    Exec("命令行"[, "工作目录"][, 等待][, 窗口样式])
      "命令行"
        命令行字符串。
      "工作目录"
        工作目录字符串。默认值为 ""。
      等待
        等待直到程序结束。1 - 等待, 0 - 立即返回(默认值)。
      窗口样式 (下列之一):
        0 隐藏窗口。
        1 保持原样 (默认值)。
        2 最小化窗口。
        3 最大化窗口。
        6 最小化窗口(非活动)。
        9 非最大化窗口。
        注意: 程序可能会忽略这个参数。
      Exec("notepad.exe")
        方法将调用 记事本。
      Exec(`notepad.exe`)
        方法将调用 记事本。
      Exec('notepad.exe')
        方法将调用 记事本。
      Exec('%windir%\notepad.exe')
        方法将调用 记事本。
      Exec(`rundll32.exe shell32,ShellExec_RunDLL "%f"`, "%d")
        方法将传递用 Windows 关联程序来打开活动文件。
    OpenFile("文件"[, 使用代码页][, 使用BOM])
      "文件"
        要打开的文件。
      使用代码页
        打开代码页。如果 -1 或未指定表示自动检测。
      使用BOM
        文件字节顺序标记。如果 -1 或未指定表示自动检测。
      OpenFile("C:\File.txt", 65001, -1)
        方法将使用 UTF-8 代码页打开文件。
    SaveFile("文件"[, 使用代码页][, 使用BOM])
      "文件"
        保存当前的文档到指定的文件名。
      使用代码页
        代码页。如果 -1 或未指定表示将会使用当前的代码页。
      使用BOM
        字节顺序标记。1 表示存在，0 表示不存在，-1 表示未指定将会使用当前的 BOM。
      SaveFile("C:\File.txt", 65001, 0)
        方法将使用无 BOM 的 UTF-8 代码页保存文件。
    Font("字体", 字形, 大小)
      "字体"
        字体, 例如："Courier". "" 表示不改变。
      字形 (下列之一):
        0  忽略.
        1  常规.
        2  粗体.
        3  斜体.
        4  粗斜体.
      大小
        字体大小. 0 表示不改变。
      Font("Courier", 4, 10)
        方法将设置 Courier 粗斜体，大小 10 pt.
    Recode(源编码, 目标编码)
      源编码
      来源代码页。值为 -1 表示自动检测。
      目标编码
      目标代码页。值为 -1 表示自动检测。
      Recode(1252, 437)
        方法将重新编码文字的代码页从 1252 到 437。
    Insert("文字"[, 转义符序列])
      "文字"
        要插入的文字。
      转义符序列:
        0 - "文字" 不包含转义符序列 (默认值)。
        1 - "文字" 包含转义符序列。
           转义符序列集与程序的查找/替换对话框的相同，并且:
           "\s" - 将替换为编辑窗口中的选定区域的文字；
           "\|" - 设置插入点的位置在插入文本之后。
      Insert("一些字符串")
        方法将用指定的文字替换选定区域。
      Insert("<B>\s</B>", 1)
        方法将围起选定区域。
      Insert("\[0031 0032 0033]", 1)
        方法将替换选定区域为 "123"。
    Link(数字)
      Link(1)
        方法将打开超链接 (仅用于 "URL 菜单")。
      Link(2)
        方法将复制超链接 (仅用于 "URL 菜单")。
      Link(3)
        方法将选择超链接 (仅用于 "URL 菜单")。
      Link(4)
        方法将剪切超链接 (仅用于 "URL 菜单")。
      Link(5)
        方法将使用剪贴板文本来替换超链接 (仅用于 "URL 菜单")。
      Link(6)
        方法将删除超链接 (仅用于 "URL 菜单")。
    Favourites(数字)
      Favourites(1)
        方法将添加当前文件到收藏夹 (带对话框)。
      Favourites(2)
        方法将添加当前文件到收藏夹 (不带对话框)。
      Favourites(3)
        方法将打开整理收藏夹的对话框。
      Favourites(4)
        方法将从收藏夹中删除当前文件。
    Menu("菜单名")
      "菜单名"
        "ContextMenu::Show 菜单" 指定的子菜单的名称。
      Menu("SYNTAXTHEME")
        方法将插入 "ContextMenu::Show 菜单" 的 "SYNTAXTHEME" 子菜单。

    Icon(["文件"][, 索引])
      Icon("Shell32.dll", 47)
        图标位于文件 Shell32.dll，索引号 47。
      Icon("%a\AkelFiles\Plugs\Explorer.dll")
        图标位于文件 Explorer.dll，索引号 0。
      Icon("%a\AkelFiles\Plugs\Toolbar\MyIcon.ico")
        图标位于文件 MyIcon.ico。
      Icon(12)
        图标位于文件 ToolBar.dll，索引号 12。

例:
  "重新编码选定区域" Command(4182)
  "" Command(4182)
  "排序行" Call("Format::LineSortStrAsc")
  -"拼写检查" Call("Scripts::Main", 1, "SpellCheck.js", "")
  "语法高亮显示" +Call("Coder::Highlight")
  "注册表编辑器" Exec("regedit.exe") Icon("regedit.exe")


子菜单的创建:
  "[子菜单文本]" [Index() | Break() | Icon()]
  {
  }

  "[子菜单文本]"
    "My Submenu"
      子菜单文本。

    Index(数字)
      Index(-1)
        如果子菜单的数字为负数，方法就插入子菜单到主菜单的指定位置，从主菜单的末尾开始算起。
    Break(数字)
      Break(-1)
        与 Index() 相同，但子菜单被插入到主菜单的新的一行。
    Icon (["文件"] [索引])
      Icon(0)
        请参考菜单项目创建的说明。方法 Icon() 对主菜单中的子菜单不起作用。

例:
  "代码页(&C)" Index(-1)
  {
    "打开为 ANSI	Alt+W" Command(4122)
    "打开为 OEM	Alt+D" Command(4123)
    "打开为 UTF-16LE (标准)	Alt+L" Command(4125)
    "打开为 UTF-16BE	Alt+B" Command(4126)
    "打开为 UTF-8	Alt+U" Command(4127)
    SEPARATOR
    "打开为(&O)" Icon("%a\AkelFiles\Plugs\ToolBar.dll", 36)
    {
      OPENCODEPAGES
    }
    SEPARATOR
    "另存为 ANSI	Shift+Alt+W" Command(4131)
    "另存为 OEM	Shift+Alt+D" Command(4132)
    "另存为 UTF-16LE (标准)	Shift+Alt+L" Command(4134)
    "另存为 UTF-16BE	Shift+Alt+B" Command(4135)
    "另存为 UTF-8	Shift+Alt+U" Command(4136)
    "另存为 UTF-8 (无 BOM)" Command(4137)
    SEPARATOR
    "另存为(&S)" Icon("%a\AkelFiles\Plugs\ToolBar.dll", 5)
    {
      SAVECODEPAGES
    }
    SEPARATOR
    "检测代码页	Alt+F5" Command(4121)
  }


*** 外部调用 ContextMenu::Main ***

Call("ContextMenu::Main", 1, INDEX, "STRING")
  参数:
    1
      打开对话框并选择菜单。
    INDEX
      下拉框索引号 (默认值为 0)。
    STRING
      查找字符串并选定 (默认值为 "")。
Call("ContextMenu::Main", 2, OPERATION)
  参数:
    2
      外部调用操作收藏夹文件列表。
    OPERATION
      操作数字。请查阅 Favourites() 方法的说明。

Call("ContextMenu::Main", 10)
  参数:
    10
      无对话框地启动/停止 插件。

*** 外部调用 ContextMenu::Show ***

Call("ContextMenu::Show", 1, "X", "Y", INDEX, "SUBMENU", *MENUHEIGHT)
  参数:
    1
      在指定位置打开用户菜单。
    "X"
      X 屏幕坐标位置 (默认值为 "-1")。
    "Y"
      Y 屏幕坐标位置 (默认值为 "-1")。
    INDEX
      仅根据数字打开指定的子菜单。如果等于 -1 将显示所有菜单 (默认值)。
    "SUBMENU"
      仅根据名称打开指定的子菜单。INDEX 必须等于 -1。
    *MENUHEIGHT
      指向一个接收菜单高度的缓冲器的指针。如果有指定，那么菜单不打开。
  备注:
    - 如果 X 和 Y 等于 "-1"，将使用编辑窗口的左上角位置。
    - 如果 X 和 Y 等于 "-2"，将使用编辑窗口的右上角位置。
    - 如果 X 和 Y 等于 "-3"，将使用编辑窗口的右下角位置。
    - 如果 X 和 Y 等于 "-4"，将使用编辑窗口的左下角位置。
    - 如果 X 和 Y 等于 "-5"，将使用编辑窗口的插入点位置。
    - 如果 X 和 Y 等于 "-6"，将使用鼠标指针的位置。
    - INDEX 基于零。

Call("ContextMenu::Show", 2, "X", "Y")
  参数:
    2
      在指定位置打开主菜单。
    "X"
      X 屏幕坐标位置 (默认值为 "-1")。
    "Y"
      Y 屏幕坐标位置 (默认值为 "-1")。
  备注:
    - 如果 X 和 Y 等于 "-1"，将使用编辑窗口的左上角位置。
    - 如果 X 和 Y 等于 "-2"，将使用编辑窗口的右上角位置。
    - 如果 X 和 Y 等于 "-3"，将使用编辑窗口的右下角位置。
    - 如果 X 和 Y 等于 "-4"，将使用编辑窗口的左下角位置。
    - 如果 X 和 Y 等于 "-5"，将使用编辑窗口的插入点位置。
    - 如果 X 和 Y 等于 "-6"，将使用光标的位置。
