Create a toolwindow for the VBA editor with .NET(C#).

原始出处: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

 

posted @ 2017-08-23 10:07  Charltsing  阅读(991)  评论(0编辑  收藏  举报