无法创建工具窗口(vbide、vba 的 com 插件扩展)

问题描述 投票:0回答:1

我正在尝试为 VBIDE 编写一个简单的扩展,但一直坚持创建一个可停靠窗口。我收到的错误是在线

HRESULT 0x800401F3

_window = windows.CreateToolWindow(
                        _addin,
                        "VBAaddin.TestComponent",
                        "My CoolDoc", 
                        guid, 
                        ref control
                    );

扩展代码:

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Extensibility;
using Microsoft.Vbe.Interop;
using VB = Microsoft.Vbe.Interop;

namespace VBAaddin
{
    [
        ComVisible(true),
        ProgId("VBAaddin.Extension"),
        Guid("60A72993-8B93-4C71-81E8-87BC6DD85F5D"),
        ClassInterface(ClassInterfaceType.None),
        ComDefaultInterface(typeof(IDTExtensibility2)),
        EditorBrowsable(EditorBrowsableState.Never)
    ]
public class Extension : IDTExtensibility2
    {
        private VB.VBE _vbe;
        private VB.AddIn _addin;
        private VB.Window _window;
        public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
        {
            _vbe = (VB.VBE)Application;
            _addin = (VB.AddIn)AddInInst;

            switch (ConnectMode)
            {
                case ext_ConnectMode.ext_cm_Startup:
                    break;
                case ext_ConnectMode.ext_cm_AfterStartup:
                    InitializeExtension();
                    break;
            }
        }

        private void InitializeExtension()
        {
            MessageBox.Show("Initializing");
            try
            {
                try
                {
                    object control = null;
                    const string guid = "9A195073-D54B-4FFD-883C-EBBBEFD860F5";
                    Windows windows = _vbe.Windows;
                    _window = windows.CreateToolWindow(
                        _addin,
                        "VBAaddin.TestComponent",
                        "My CoolDoc", 
                        guid, 
                        ref control
                    );
                    _window.Visible = true;
                }
                catch (COMException exception)
                {
                    MessageBox.Show(exception.ToString());
                }
            }
            catch (Exception e)
            {
                MessageBox.Show($"{e.Message} {e.Source}");
            }

        }

        public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
        {
        }

        public void OnAddInsUpdate(ref Array custom)
        {
        }

        public void OnStartupComplete(ref Array custom)
        {
               InitializeExtension();
        }

        public void OnBeginShutdown(ref Array custom)
        {
        }
    }
}

测试组件:

using System.Runtime.InteropServices;
using System.Windows.Controls;

namespace VBAaddin
{
    [
        ComVisible(true),
        ProgId("VBAaddin.TestComponent"),
        Guid("9A195073-D54B-4FFD-883C-EBBBEFD860F5")
    ]
    public partial class TestComponent : UserControl
    {
        public TestComponent()
        {
            InitializeComponent();
        }
    }
}

测试组件.xaml:

<UserControl x:Class="VBAaddin.TestComponent"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:VBAaddin"
             mc:Ignorable="d" 
             d:DesignHeight="200" d:DesignWidth="300">
    <Grid>
        <TextBox HorizontalAlignment="Center" Margin="0,82,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

    </Grid>
</UserControl>

reg:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE\6.0\Addins\VBAaddin.Extension]
"Description"="VBAaddin"
"FriendlyName"="VBAaddin"
"LoadBehavior"=dword:00000003

[HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE\6.0\Addins64\VBAaddin.Extension]
"Description"="VBAaddin"
"FriendlyName"="VBAaddin"
"LoadBehavior"=dword:00000003

[HKEY_CLASSES_ROOT\CLSID\{60A72993-8B93-4C71-81E8-87BC6DD85F5D}]
@="VBAaddin.Extension"

[HKEY_CLASSES_ROOT\CLSID\{60A72993-8B93-4C71-81E8-87BC6DD85F5D}\ProgId]
@="VBAaddin.Extension"

[HKEY_CLASSES_ROOT\VBAaddin.Extension]
@="VBAaddin.Extension"

[HKEY_CLASSES_ROOT\VBAaddin.Extension\CLSID]
@="{60A72993-8B93-4C71-81E8-87BC6DD85F5D}"

[HKEY_CLASSES_ROOT\VBAaddin.TestComponent]
@="VBAaddin.TestComponent"

[HKEY_CLASSES_ROOT\CLSID\{9A195073-D54B-4FFD-883C-EBBBEFD860F5}]
@="VBAaddin.TestComponent"

[HKEY_CLASSES_ROOT\VBAaddin.TestComponent\CLSID]
@="{9A195073-D54B-4FFD-883C-EBBBEFD860F5}"
c# .net com add-in vbide
1个回答
0
投票

您需要

TestComponent
成为 WinForms 用户控件;对于 WPF UI,您需要该用户控件来容纳可以加载 XAML 用户控件的 WPF 互操作主机(停靠/填充包含的用户控件)。

Rubberduck 2.x 就是这么做的 ☺️

请注意,本机窗口和 WinForms 用户控件之间的 COM 互操作存在许多怪癖,这些怪癖可能会导致很难正确地拆除并彻底关闭您的插件(这是 Rubberduck 3.x 放弃使用的部分原因)他们)。

© www.soinside.com 2019 - 2024. All rights reserved.