我在 Rubberduck(一个进程中的 VBE 插件)中有一个方法,它将图片和蒙版分配给CommandBarControl
(按钮)。它在将图像添加到 Excel、Word 等的 VBE 时效果很好,但在将图像添加到 SolidWorks VBE 时它会因访问冲突而失败。
public static void SetButtonImage(CommandBarButton button, Image image, Image mask)
{
button.FaceId = 0;
if (image == null || mask == null)
{
return;
}
try
{
button.Picture = AxHostConverter.ImageToPictureDisp(image);
button.Mask = AxHostConverter.ImageToPictureDisp(mask);
}
catch (COMException exception)
{
Logger.Debug("Button image could not be set for button [" + button.Caption + "]\n" + exception);
}
}
我从KB286460 了解到- 如何为 Office XP 命令栏设置遮罩和图片属性
Mask 和 Picture 属性定义为类型 IPictureDisp,它是 Stdole 库的成员。IPictureDisp 使用无法跨进程边界编组的方法。因此,Mask 和 Picture 属性只能在进程内调用(VBA 宏、自动化插件和 ActiveX DLL在进程内运行)。
我从如何处理 AccessViolationException中知道我可以用HandleProcessCorruptedStateExceptions
属性装饰方法,但我认为我不想继续使用损坏的状态。也许这个腐败的国家是良性的,我可以继续吗?
有趣的是,Visual Studio 的 Autos 窗口Picture
可以毫无问题地处理访问异常:
似乎 SolidWorks VBE 在某种程度上没有将 Rubberduck 视为与 CommandBarButtons 处于同一进程中。这表明其他 VBE 主机可能会这样做。
编辑我不确定它是否相关,但我在 Windows 10 下运行旧版本的 SolidWorks 2006,为了使其运行,我已将其配置为以管理权限运行。
我知道访问Picture
/Mask
属性会导致 AccessViolation,但是在实际尝试访问该属性之前如何确定该属性是否可读/可写?
我可以检查主机应用程序是否是 SolidWorks,但我宁愿采用更通用的方法,适用于具有相同行为的任何主机。