Visual Studio C 中的第一个 ActiveX 创建指南

创作步骤

  1. 以管理员身份启动 Visual Studio 2013
  2. 安装 Visual Studio 扩展 Microsoft Visual Studio 安装程序项目
  3. 创建一个类库项目(WinFormActivex)
  4. 创建示例窗口表单(MainWindow)
  5. 创建一个新的组件接口(ILauncher)
  6. 创建一个新的安全接口(IObjectSafety)
  7. 创建实现接口并启动窗口的组件控件(Launcher)。
  8. 检查是否所有 GUID 都是由你生成的
  9. 检查项目是否标记为 COM
  10. 使用属性 Register = vsdrpCOM 创建具有 WinFormActivex 主要输出的安装项目(LauncherInstaller)
  11. 安装 LauncherInstaller
  12. 在资源管理器中运行测试页(test.html)

MainWindow 你可以创建一个普通的 Form,这里是预生成的。

public partial class MainWindow : Form
{
    public MainWindow()
    {
        InitializeComponent();
    }

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.textBox1 = new System.Windows.Forms.TextBox();
        this.textBox2 = new System.Windows.Forms.TextBox();
        this.SuspendLayout();
        //
        // textBox1
        //
        this.textBox1.Location = new System.Drawing.Point(42, 23);
        this.textBox1.Name = "textBox1";
        this.textBox1.Size = new System.Drawing.Size(100, 20);
        this.textBox1.TabIndex = 0;
        //
        // textBox2
        //
        this.textBox2.Location = new System.Drawing.Point(42, 65);
        this.textBox2.Name = "textBox2";
        this.textBox2.Size = new System.Drawing.Size(100, 20);
        this.textBox2.TabIndex = 0;
        //
        // MainWindow
        //
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(284, 261);
        this.Controls.Add(this.textBox2);
        this.Controls.Add(this.textBox1);
        this.Name = "MainWindow";
        this.Text = "MainWindow";
        this.ResumeLayout(false);
        this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.TextBox textBox1;
    private System.Windows.Forms.TextBox textBox2;
}

ILauncher

using System.Runtime.InteropServices;
namespace WinFormActivex
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("94D26775-05E0-4B9C-BC73-C06FE915CF89")]
    public interface ILauncher
    {
        void ShowWindow();
    }
}

IObjectSafety

[ComImport()]
[Guid("51105418-2E5C-4667-BFD6-50C71C5FD15C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IObjectSafety
{
    [PreserveSig()]
    int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions);
    [PreserveSig()]
    int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions);
    }

启动器请在此处生成你的 GUID。

 [ComVisible(true)]
 [ClassInterface(ClassInterfaceType.None)]
 [Guid("D100C392-030A-411C-92B6-4DBE9AC7AA5A")]
 [ProgId("WinFormActivex.Launcher")]
 [ComDefaultInterface(typeof(ILauncher))]
 public class Launcher : UserControl, ILauncher, IObjectSafety
 {
     #region [ ILauncher ]

     public void ShowWindow()
     {
         var f = new MainWindow();
         f.StartPosition = FormStartPosition.Manual;
         f.Location = Screen.AllScreens[0].Bounds.Location;
         f.WindowState = FormWindowState.Normal;
         f.WindowState = FormWindowState.Maximized;
         f.ShowInTaskbar = false;
         f.Show();
     }

     #endregion

     #region [ IObjectSafety ]

     public enum ObjectSafetyOptions
     {
         INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001,
         INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002,
         INTERFACE_USES_DISPEX = 0x00000004,
         INTERFACE_USES_SECURITY_MANAGER = 0x00000008
     };

     public int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
     {
         ObjectSafetyOptions m_options = ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER | ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;
         pdwSupportedOptions = (int)m_options;
         pdwEnabledOptions = (int)m_options;
         return 0;
     }

     public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
     {
         return 0;
     }

     #endregion
 }

test.html 请检查你的 CLSID 是否匹配(启动器)GUID。

<html>
    <head>
        <objectname="activexLauncher" style='display:none' id='activexLauncher' classid='CLSID:D100C392-030A-411C-92B6-4DBE9AC7AA5A' codebase='WinFormActivex'></object>
      <script language="javascript">
        <!-- Load the ActiveX object  -->
        var x = new ActiveXObject("WinFormActivex.Launcher");
        alert(x.GetText());
      </script>
    </head>
    <body>
    </body>
</html>

参考