VS.NET的工具窗口指的是类似“解决方案资源管理器”,“类视图”,“工具箱”这样停靠在上下左右侧边的窗口。而如代码编辑窗口这样的窗口,需要用VSIP进行开发,外接程序插件是没有办法开发这类窗口的。
根据MSDN里的资料,如果要开发侧边工具窗口,是件非常繁琐的事情。因为VS.NET是基于COM开发的,所以开发出来的侧边工具窗口也需要实现一系列接口,也就是说,不能直接使用.NET程序集。幸而已经有人做了这件事情,开发了一个将.NET用户控件包装成COM组件的容器VSUserControlHostLib,使得我们只需要开发出.NET用户控件,就可以将其嵌入到VS集成环境里了
开发步骤:
1、 生成Addin项目
2、 在项目中添加VSUserControlHost.dll引用
3、 在Connect.cs文件的OnConnection方法中添加显示窗口的代码
下面是代码示例:(添加在OnConnect方法中)
//GUID串可以用VS开发环境里菜单命令“工具à创建GUID”弹出的对话框创建
![]()
string guidstr = "{65FADCBF-63D2-448b-8A4B-393D7E751345}";
![]()
object objTemp = null;
![]()
VSUserControlHostLib.IVSUserControlHostCtl objControl = null;
![]()
//create the 'Explorer' tool window
![]()
/**//*
![]()
[C#]
![]()
返回一个 Window 对象
![]()
public Window CreateToolWindow(
![]()
AddIn AddInInst, //必选项。其生存期决定工具窗口生存期的 AddIn 对象
![]()
string ProgID, //必选项。Document 对象或 ActiveX 控件的编程 ID。
![]()
string Caption, //新工具窗口的标题
![]()
string GuidPosition, //新工具窗口的唯一标识符,可用作 Window.Item 的索引
![]()
ref object DocObj //工具窗口中要承载的 Document 对象或控件
![]()
);
![]()
*/
![]()
//这里先生成容器窗口,返回的控件对象在objTemp里
![]()
windowExplorer = applicationObject.Windows.CreateToolWindow(
![]()
addInInstance,
![]()
"VSUserControlHost.VSUserControlHostCtl",
![]()
"菜单浏览器",
![]()
guidstr,
![]()
ref objTemp);
![]()
//使用容器窗口时,必须在调用该容器控件前设置其为可见,否者将会不能正常显示
![]()
windowExplorer.Visible = true;
![]()
windowExplorer.IsFloating = false;
![]()
//将返回的工具窗口转换为容器对象
![]()
objControl = (VSUserControlHostLib.IVSUserControlHostCtl)objTemp;
![]()
System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
![]()
//用容器对象包含用户控件,
![]()
menuExplorer = (MenuExplore)objControl.HostUserControl(asm.Location,
![]()
"MenuBrowser.MenuExplore");
![]()
//设置窗口的图标
![]()
//windowExplorer.SetTabPicture(…)
![]()
//将DTE对象赋给窗口
![]()
menuExplorer.Application = applicationObject;
![]()
说明:
l 生成工具窗口:
以上代码先用CreateToolWindow函数生成工具窗口,工具窗口里承载的VSUserControlHost.VSUserControlHostCtl类型控件由objTemp对象返回
l 设置可见性:
将工具窗口设置为可见,非浮动
l 获取IVSUserControlHostCtl接口:
将返回的工具窗口中承载的控件对象objTemp转换为IVSUserControlHostCtl接口类型,并赋给objControl对象
l 加载用户控件:
用objControl的HostUserControl方法加载指定程序集的指定用户控件对象,上面代码中因为MenuBrowser.MenuExplore类是在插件项目的程序集里,所以用System.Reflection.Assembly.GetExecutingAssembly()方法获取当前程序集位置。如果用户控件是在其他程序集里,需要根据实际情况指定程序集位置
4、 最后还应该在OnDisconnection方法里关闭窗口
if(windowExplorer!= null)
![]()
...{
![]()
windowExplorer.Visible = false;
![]()
}
下图就是笔者用来列举所有的系统菜单对象名称的一个插件,使用的就是工具窗口
图-2 在VS集成环境中使用工具窗口