PowerPoint幻灯片中的ActiveX控件

时间:2013-08-31 13:00:24

标签: c# .net powerpoint office-interop

我创建了一个非常简单的程序并将其作为ActiveX控件公开。我想要做的是将此控件嵌入到PowerPoint幻灯片中。该计划的代码如下:

namespace WindowsFormsApplication1
{
    [ProgId("Tomor.Form1")]
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Text = "Clicked";
        }
    }
}

我已经对Make the assembly COM-visible进行了批评,并检查了Register for COM-interop。我还实现了RegisterClassUnregisterClass方法(但这里没有显示,请参阅this,以获得精确的实现),并且已经能够使用regasm成功注册它。可执行程序。我也可以使用Tomor1.Form从另一个项目访问该界面。现在,我试图将此控件插入PowerPoint幻灯片,如下所示:

      PowerPoint.Shape s = Sld.Shapes.AddOLEObject(0, 0, 400, 400, "Tomor.Form1");

但是,我得到的只是启动时出现以下错误:

  
      
  • $ exception {“无法从注册表中读取密钥(来自HRESULT的异常:0x80040150(REGDB_E_READREGDB))”} System.Exception   {System.Runtime.InteropServices.COMException}
  •   

有趣的是,我可以通过导航到Compuer\HKEY_CLASSES_ROOT\Tomor1.Form\CLSID

来查看注册表中的“密钥”

1 个答案:

答案 0 :(得分:0)

即使我不太确定,我怀疑问题必须是ComRegisterFunction。我在其他地方找到了另一个实现,并且通过该实现,程序集已正确注册,并且可以从PowerPoint访问。 ComRegisterFunction的实现如下:

    [ComRegisterFunction]
    static void ComRegister(Type t)
    {
        string keyName = @"CLSID\" + t.GUID.ToString("B");
        using (RegistryKey key =
            Registry.ClassesRoot.OpenSubKey(keyName, true))
        {
            key.CreateSubKey("Control").Close();
            using (RegistryKey subkey = key.CreateSubKey("MiscStatus"))
            {
                // 131456 decimal == 0x20180.
                long val = (long)
                    (OLEMISC.OLEMISC_INSIDEOUT
                    | OLEMISC.OLEMISC_ACTIVATEWHENVISIBLE
                    | OLEMISC.OLEMISC_SETCLIENTSITEFIRST);
                subkey.SetValue("", val);
            }
            using (RegistryKey subkey = key.CreateSubKey("TypeLib"))
            {
                Guid libid =
                    Marshal.GetTypeLibGuidForAssembly(t.Assembly);
                subkey.SetValue("", libid.ToString("B"));
            }
            using (RegistryKey subkey = key.CreateSubKey("Version"))
            {
                Version ver = t.Assembly.GetName().Version;
                string version =
                  string.Format("{0}.{1}", ver.Major, ver.Minor);
                subkey.SetValue("", version);
            }
        }
    }