VS 2019 扩展入门到放弃(一)
先吐糟一下 csdn 吧,这是直接从我的 docx 文档复制上来,发现布局很多都是乱的,尤其是 序列号。有点尴尬而有奇葩。不想改了,将就着吧(有意思的是,改了一下文章,连个保存按钮都没有)
目录
预设
需要先配置好的项目
- 创建
点击之后基本上没的,写上你的项目名称即可,但这里我使用的是 TopLevelMenu 作为项目名称,我也建议你也是
- 创建项目文件,如果不创建,它的.vsct 布局文件就不会出现
需要留意一下,一些项目文件并非使用 ‘Command’ 表示该类型文件,但他是 C# 源文件没错,如果出现差错,请复制我的代码。现在我认为你选对了,并且名称改为 TestCommand.cs ,这个名称并不重要。
你现在需要在这个 C# 源码中添加以下代码
添加一个成员
// 这个需要在 TestCommand 的 CommandId 下方添加构造函数中添加
public const int cmdidTestSubCmd = 0x0105;
在构造函数中添加代码
// 这个需要在 TestCommand 构造函数中添加
CommandID subCommandID = new CommandID( CommandSet,
cmdidTestSubCmd );
MenuCommand subItem = new MenuCommand( new EventHandler( SubItemCallback ),
subCommandID );
commandService.AddCommand( subItem );
添加 TestCommand 成员函数
// 而这个仅仅是一个 TestCommand 成员函数,在被创建 MenuCommand 时候已经被当做一个事件函数注册入 vs 内部
private void SubItemCallback( object sender, EventArgs e ) {
ThreadHelper.ThrowIfNotOnUIThread( );
IVsUIShell uiShell = this.package.GetService< SVsUIShell, IVsUIShell >( );
Guid clsid = Guid.Empty;
int result;
uiShell.ShowMessageBox( 0,
ref clsid,
"TestCommand",
string.Format( CultureInfo.CurrentCulture,
"Inside TestCommand.SubItemCallback()",
this.ToString( ) ),
tring.Empty,
0,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
OLEMSGICON.OLEMSGICON_INFO,
0,
out result );
}
.vsct 文件
一般用于配置布局页面,也就是说你即便创建了一些控件,如果你不显示它,那你就永远都没有机会见他一面。
- 简单的说明
- CommandTable 元素
- 位于文档的最高级别,是一般vsct文档的 root 元素
- 常见为以下代码
- CommandTable 元素
<CommandTable xmlns=http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable xmlns:xs="http://www.w3.org/2001/XMLSchema">
-
- Extern 元素
- 用于导入一些功能集合
- Extern 元素
如
<Extern href="stdidcmd.h" />
如
<Extern href="vsshlids.h" />
-
- Commands 元素
- 指令包的使用,他可以使用一个由 GuidSymbol 声明的包来完成布局
- 需要指定 package 属性为已存在的 GuidSymbol 的 name 属性内容
- 如
- Commands 元素
<Commands package="guidTopLevelMenuPackage" />
<!-- ...... -->
<GuidSymbol name="guidTopLevelMenuPackage" value="{f2ed75c5-2661-4e0c-8415-8980c9a0b955}" />
-
- Symbols 元素
- 可以包含多个符号,其中子节点 GuidSymbol 尤其重要
- Menus 元素
- 包含所有菜单,其中包括子菜单,这些菜单都是使用 Menu元素声明
- Menu 元素
- 声明单个菜单,它是一个菜单实例
- 需要指定 guid 属性为已存在的 GuidSymbol 的 name 属性内容
- 需要指定 priority 属性为 16 进制
- 事实上这个属性干嘛用的我也不知道
- Parent 子节点
- 他决定菜单悬挂在那个菜单上
- 提供 id 作为它悬挂的菜单,他是 IDSymbol 或一般字面值,而且它总是存在,不存在它就会被隐藏
- guid 属性仅仅作为可访问的 GuidSymbol节点下的 IDSymbol
- Strings 子节点
- 仅仅作为一个现实在界面而存在
- 它的子节点 ButtonText 的内容作为它现实在用户的文字
- 它的子节点 CommandName 仍然值得探索
- Groups 元素
- 它保存所有 Group 元素,这些子元素作为真正影响的布局的功能
- Group 元素
- 该元素影响布局
- 它的布局悬挂在那个控件上则由 Parent子节点界定,可以参考 Menu 中 Parent 一节
- Group 中的 Parent 只能指定 Menu,不能指定其他 Group,这尤其重要。
- 需要自己菜单,可以使用 Menu 放置在 Group 上,而这个 Group 则放在顶级 Menu 上,这里可以把 Menu 当做一个 Button 控件
- Symbols 元素
- 项目文件内容
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- VisualStudio 命令集 -->
<Extern href="stdidcmd.h" />
<!-- shell 命令集. -->
<Extern href="vsshlids.h" />
<!-- 指定的包 -->
<Commands package="guidTopLevelMenuPackage">
<!-- 创建菜单 -->
<Menus>
<Menu guid="guidTopLevelMenuPackageCmdSet" id="TopLevelMenu" priority="0x700" type="Menu">
<!--放置位置-->
<Parent guid="guidSHLMainMenu" id="IDG_VS_MM_TOOLSADDINS" />
<Strings>
<ButtonText>测试菜单</ButtonText>
</Strings>
</Menu>
<Menu guid="guidTopLevelMenuPackageCmdSet" id="SubMenu" priority="0x700" type="Menu">
<!--子菜单-->
<Parent guid="guidTopLevelMenuPackageCmdSet" id="MyMenuGroup" />
<Strings>
<ButtonText>Sub Menu</ButtonText>
<CommandName>Sub Menu</CommandName>
</Strings>
</Menu>
</Menus>
<!-- 控件布局 -->
<Groups>
<Group guid="guidTopLevelMenuPackageCmdSet" id="MyMenuGroup" priority="0x0600">
<!-- 布局应用 -->
<Parent guid="guidTopLevelMenuPackageCmdSet" id="TopLevelMenu" />
</Group>
<Group guid="guidTopLevelMenuPackageCmdSet" id="SubMenuGroup" priority="0x0000">
<Parent guid="guidTopLevelMenuPackageCmdSet" id="SubMenu" />
</Group>
</Groups>
<!-- 创建按钮 -->
<Buttons>
<!--guid 表示使用那个组,但他还是需要制定一个 guid, type 指定类型-->
<Button guid="guidTopLevelMenuPackageCmdSet" id="TestCommandId" priority="0x0100" type="Button">
<!--Parent guid 指示要使用那个 GuidSymbol 值和, id 指示使用那个 guid-->
<Parent guid="guidTopLevelMenuPackageCmdSet" id="MyMenuGroup" />
<!--图标-->
<Icon guid="guidImages" id="bmpPic1" />
<!--显示内容-->
<Strings>
<ButtonText>测试按钮</ButtonText>
</Strings>
</Button>
<Button guid="guidTopLevelMenuPackageCmdSet" id="cmdidTestSubCommand" priority="0x0000" type="Button">
<Parent guid="guidTopLevelMenuPackageCmdSet" id="SubMenuGroup" />
<Icon guid="guidImages" id="bmpPic2" />
<Strings>
<CommandName>cmdidTestSubCommand</CommandName>
<ButtonText>子集菜单命令</ButtonText>
</Strings>
</Button>
</Buttons>
<Bitmaps>
<Bitmap guid="guidImages" href="Resources\TestCommand.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough" />
</Bitmaps>
</Commands>
<Symbols>
<!-- 包 guid-->
<GuidSymbol name="guidTopLevelMenuPackage" value="{f2ed75c5-2661-4e0c-8415-8980c9a0b955}" />
<!-- 用户 guid (含自动代码生成)-->
<GuidSymbol name="guidTopLevelMenuPackageCmdSet" value="{9503d469-3fb1-43fc-a1c3-3b99f7cbde20}">
<IDSymbol name="MyMenuGroup" value="0x1020" />
<IDSymbol name="TestCommandId" value="0x0100" />
<IDSymbol name="TopLevelMenu" value="0x1021" />
<IDSymbol name="SubMenu" value="0x1100" />
<IDSymbol name="SubMenuGroup" value="0x1150" />
<IDSymbol name="cmdidTestSubCommand" value="0x0105" />
</GuidSymbol>
<GuidSymbol name="guidImages" value="{a29e72bf-1fb6-4505-9863-024c75880c8c}">
<IDSymbol name="bmpPic1" value="1" />
<IDSymbol name="bmpPic2" value="2" />
<IDSymbol name="bmpPicSearch" value="3" />
<IDSymbol name="bmpPicX" value="4" />
<IDSymbol name="bmpPicArrows" value="5" />
<IDSymbol name="bmpPicStrikethrough" value="6" />
</GuidSymbol>
</Symbols>
</CommandTable>
结果
可以尝试点击 ‘测试按钮’或 ‘子集菜单命令’