我正在尝试为 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}"
您需要
TestComponent
成为 WinForms 用户控件;对于 WPF UI,您需要该用户控件来容纳可以加载 XAML 用户控件的 WPF 互操作主机(停靠/填充包含的用户控件)。
Rubberduck 2.x 就是这么做的 ☺️
请注意,本机窗口和 WinForms 用户控件之间的 COM 互操作存在许多怪癖,这些怪癖可能会导致很难正确地拆除并彻底关闭您的插件(这是 Rubberduck 3.x 放弃使用的部分原因)他们)。