原始出处:http://www.cnblogs.com/Charltsing/p/VBEtoolwindow.html
最近有人问起使用C#在VBE插件中创建toolwindow的事情,由于VBE窗口控件的容器是ActiveX UserDocument,而C#不支持这个东西,所以只会拉控件的弟兄们可以放弃了。
当然,C#也有替代办法,毕竟这个编程语言是微软亲儿子,没什么东西是它实现不了的,哈哈。
先介绍一下toolwindow:toolwindows是可停靠的,无模式的窗口,大家在VBE界面中看到的各种窗口都属于Toolwindows,使用鼠标拖拽就可以改变窗口的停靠方式,并且VBE会在注册表中记住它,这给我们编写友好的用户界面提供了方便。当然,toolwindow也是有缺点的,自定义的toolwindow需要处理很多事情,例如按键消息、Resize等问题,而且界面需要使用自定义控件等等,这给业余开发带来了难度。
目前toolwindow开发在网上只能找到vb6和vb.net的资料,C#没有Sample。
经过一天的研究,我写了一个应用例子,集成到了我的Smart Indenter for VBE插件里(免费下载),供大家使用测试。
下面简单介绍一下如何用C#在VBE插件中创建toolwindow。
1、在项目中,添加一个用户控件,取名为UserControlHost(用户控件即UserControl控件,用来代替ActiveX UserDocument)。在类中设置允许com交互的属性参数,guid可以在vs工具菜单里面生成,不要和Addins的guid一样。progid可以自己起名,组件名与Addins的一致即可,类名自己起。具体代码如下。
[ComVisible(true), Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"), ProgId("YourAddins.UserControlHost")]
public partial class UserControlHost : UserControl
{
public UserControlHost()
{
InitializeComponent();
this.BackColor = Color.White; //改成白底,统一风格。
//其他Button之类的控件可以通过vs的工具箱拖拽。使用UserControl创建C#的自定义窗体组件在百度有很多代码,可以自行搜索参考。
}
}
2、在Addins类中,定义两个变量
private Microsoft.Vbe.Interop.VBE VBE;
private Microsoft.Vbe.Interop.AddIn AddInInstance;
3、在OnConnection事件中,获取VBE和AddInInstance
public void OnConnection(object application, ext_ConnectMode ConnectMode, object AddInInst, ref System.Array custom)
{
VBE = (Microsoft.Vbe.Interop.VBE)application;
AddInInstance = (Microsoft.Vbe.Interop.AddIn)AddInInst;
}
4、在VBE界面建立一个菜单,菜单中建立一个CommandBarButton并取名为Toolwindow(代码略),在Toolwindow的Click事件中,写入如下代码
public void Toolwindow_Click(Office.CommandBarButton ctrl, ref bool cancel)
{
object Docobj = null;
if (toolwinow!=null)
{
toolwinow.Visible = true;
}
else
{
toolwinow = VBE.Windows.CreateToolWindow(
AddInInstance,
"YourAddins.UserControlHost",
"toolwindow窗口标题",
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
ref Docobj);
UserControlHost DocObject = Docobj as UserControlHost;
toolwinow.Visible = true;
//下面的代码请自行加入
//调整UserControl窗口尺寸以适应toolwindow
//获取DocObject的父窗体句柄,并监听toolwindow resize消息,调整UserControl窗口尺寸
}
}
5、创建toolwindow的函数是CreateToolWindow,注意GUID和progid要与创建UserControl的相同。
6、上面的代码只是创建了toolwindow。如果要真正使用这个窗口,你还需要通过创建一个NativeWindow来监听toolwindow消息,以便处理resize事件。监听的窗口句柄通过API.WindowsAPI.GetParent(DocObject.Handle)语句获取。NativeWindow的使用例子可以看一下msdn中的代码。
7、插件最终会有两个GUID和两个ProgID,分别是给Addins和UserControl注册用的,注意不要相同。
8、安装插件时,不需要单独注册UserControl。正常使用插件注册命令:Regasm /codebase youraddins.dll 即可。注意32位和64位office请分别使用对应位数的regasm注册。
需要说明的是,创建的toolwindow第一次运行,弹出来的是个比较小的窗口(200X100)。自己用鼠标调整尺寸,或者拖拽到最右侧停靠窗口尺寸会自动调整。以后再启动toolwindow,VBE会记住这个窗体位置或尺寸。删除这个记忆可以通过手工删除注册表相关键值HKEY_CURRENT_USER\SOFTWARE\Microsoft\VBA\7.1\Common\Dock来清除记忆,不同的vba版本可能位置略有不同,把7.1换成相应版本即可。
如果有什么问题,可以联系QQ:564955427
界面演示(Smart Indenter for VBE)
**************************************************************************************
下面是一些资料链接
http://www.cnblogs.com/Duiker/archive/2005/10/19/257625.html
http://www.activevb.de/tutorials/tut_addin/addin6.html
https://www.codeproject.com/Articles/310710/VBE-CreateToolWindow
https://www.mztools.com/articles/2012/mz2012017.aspx