命令实现
若要在 VSPackage 中实现命令,必须执行以下任务:
在 .vsct 文件中,设置一个命令组,然后将该命令添加到其中。 有关详细信息,请参阅 Visual Studio 命令表 (.vsct) 文件。
将命令注册到 Visual Studio。
实现命令。
以下部分介绍如何注册和实现命令。
向 Visual Studio 注册命令
如果命令显示在菜单上,则必须将它 ProvideMenuResourceAttribute 添加到 VSPackage,并将其用作菜单的名称或其资源 ID 的值。
[ProvideMenuResource("Menus.ctmenu", 1)]
public sealed class MyPackage : Package
{
// ...
}
此外,还必须将命令注册到 .OleMenuCommandService 如果 VSPackage 派生自 Package,则可以使用GetService此方法获取此服务。
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (mcs is not null)
{
// Create the command for the menu item.
CommandID menuCommandID = new CommandID(guidCommandGroup, myCommandID);
MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
mcs.AddCommand(menuItem);
}
实现命令
可通过多种方式实现命令。 如果需要静态菜单命令(即始终以相同方式显示命令)在同一菜单上,请使用 MenuCommand 上一部分中的示例所示创建命令。 若要创建静态命令,必须提供负责执行命令的事件处理程序。 由于命令始终处于启用状态且可见,因此无需将其状态提供给 Visual Studio。 如果要根据特定条件更改命令的状态,可以将命令创建为类的 OleMenuCommand 实例,并在其构造函数中提供事件处理程序来执行命令,并在 QueryStatus
命令状态发生更改时通知 Visual Studio。 还可以作为命令类的一部分实现 IOleCommandTarget ,或者,如果在项目中提供命令,则可以实现 IVsHierarchy 。 这两个接口和 OleMenuCommand 类都具有通知 Visual Studio 命令状态更改的方法,以及提供命令执行的其他方法。
将命令添加到命令服务时,它将成为命令链之一。 为命令实现状态通知和执行方法时,请注意仅提供该特定命令,并将所有其他情况传递到链中的其他命令。 如果无法传递命令(通常通过返回 OLECMDERR_E_NOTSUPPORTED),Visual Studio 可能会停止正常工作。
QueryStatus 方法
如果要实现QueryStatus该方法或QueryStatusCommand方法,检查命令所属的命令集的 GUID 和命令的 ID。 请遵循这些指导:
如果无法识别 GUID,则任一方法的实现必须返回 OLECMDERR_E_UNKNOWNGROUP。
如果任一方法的实现识别 GUID 但尚未实现命令,则该方法应返回 OLECMDERR_E_NOTSUPPORTED。
如果任一方法的实现同时识别 GUID 和命令,则该方法应使用以下OLECMDF标志设置每个命令(在
prgCmds
参数中)的命令标志字段:OLECMDF_SUPPORTED
:支持该命令。OLECMDF_INVISIBLE
:该命令不应可见。OLECMDF_LATCHED
:该命令已打开并显示为已检查。OLECMDF_ENABLED
:已启用该命令。OLECMDF_DEFHIDEONCTXTMENU
:如果命令出现在快捷菜单上,则应隐藏该命令。OLECMDF_NINCHED
:命令是菜单控制器,未启用,但其下拉菜单列表不为空,仍可用。 (此标志很少使用。
如果使用标志在 .vsct 文件中
TextChanges
定义了该命令,请设置以下参数:将
rgwz
参数的pCmdText
元素设置为命令的新文本。将
cwActual
参数的pCmdText
元素设置为命令字符串的大小。
此外,请确保当前上下文不是自动化函数,除非命令专门用于处理自动化函数。
若要指示你支持特定命令,请返回 S_OK。 对于所有其他命令,返回 OLECMDERR_E_NOTSUPPORTED。
在下面的示例中,该方法 QueryStatus
首先确保上下文不是自动化函数,然后找到正确的命令集 GUID 和命令 ID。 命令本身设置为启用和支持。 不支持其他任何命令。
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
{
if (!VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
{
if (pguidCmdGroup == VSConstants.VSStd2K && cCmds > 0)
{
// make the Right command visible
if ((uint)prgCmds[0].cmdID == (uint)VSConstants.VSStd2KCmdID.RIGHT)
{
prgCmds[0].cmdf = (int)Microsoft.VisualStudio.OLE.Interop.Constants.MSOCMDF_ENABLED | (int)Microsoft.VisualStudio.OLE.Interop.Constants.MSOCMDF_SUPPORTED;
return VSConstants.S_OK;
}
}
}
return Constants.OLECMDERR_E_NOTSUPPORTED;
}
执行方法
方法 Exec
的实现类似于方法的 QueryStatus
实现。 首先,请确保上下文不是自动化函数。 然后,测试 GUID 和命令 ID。 如果无法识别 GUID 或命令 ID,则返回 OLECMDERR_E_NOTSUPPORTED。
若要处理命令,请执行该命令,并在执行成功时返回 S_OK 。 命令负责错误检测和通知;因此,如果执行失败,则返回错误代码。 以下示例演示如何实现执行方法。
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
{
if (!VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
{
if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
{
if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RIGHT)
{
// execute the command
return VSConstants.S_OK;
}
}
}
return Constants.OLECMDERR_E_NOTSUPPORTED;
}