c#中开发ActiveX的学习笔记

Posted 野狼谷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#中开发ActiveX的学习笔记相关的知识,希望对你有一定的参考价值。

1.为什么要用ActiveX?

网页本身的功能是有限的,要想实现一些网页本身不支持的功能,比如:网页上的p2p视频播放,就得靠ActiveX这种古老的技术。

2.c#能开发ActiveX吗?

严格意义上讲,c#是不能生成纯正ocx控件的,我们在vs.net中新建项目时,也找不到专门的"ActiveX项目"新建项,最多也只就能新建"类库"得到一个dll而非ocx(因此我们也无法用传统的regsvr32来注册该dll),但是c#能开发com组件,activeX控件本质上讲跟com是一类技术,所以用c#开发"能够让网页调用的com类库"还是可行的。

3.开发步骤:

(1)新建一个类库 (2)修改项目的"属性",在“生成”选项中把“输出”中的“为com互操作注册”勾中,然后再到“应用程序”选项中找到“程序集信息”按钮,点击它,在弹出的界面中勾中“使程序集COM可见(M)”

(3)修改AssemblyInfo.cs,增加[assembly: AllowPartiallyTrustedCallers()],完整内容类似下面这样:

复制代码
 1 using System.Reflection;  2 using System.Runtime.CompilerServices;  3 using System.Runtime.InteropServices;  4 using System.Security;  5   6 // General Information about an assembly is controlled through the following   7 // set of attributes. Change these attribute values to modify the information  8 // associated with an assembly.  9 [assembly: AssemblyTitle("ActiveXDemo")] 10 [assembly: AssemblyDescription("")] 11 [assembly: AssemblyConfiguration("")] 12 [assembly: AssemblyCompany("Microsoft")] 13 [assembly: AssemblyProduct("ActiveXDemo")] 14 [assembly: AssemblyCopyright("Copyright ? Microsoft 2009")] 15 [assembly: AssemblyTrademark("")] 16 [assembly: AssemblyCulture("")] 17 [assembly: AllowPartiallyTrustedCallers()] 18  19 // Setting ComVisible to false makes the types in this assembly not visible  20 // to COM components.  If you need to access a type in this assembly from  21 // COM, set the ComVisible attribute to true on that type. 22 [assembly: ComVisible(true)] 23  24 // The following GUID is for the ID of the typelib if this project is exposed to COM 25 [assembly: Guid("bd585d12-7f22-4b3f-959f-18efbfc53f94")] 26  27 // Version information for an assembly consists of the following four values: 28 // 29 //      Major Version 30 //      Minor Version  31 //      Build Number 32 //      Revision 33 // 34 // You can specify all the values or you can default the Build and Revision Numbers  35 // by using the \'*\' as shown below: 36 // [assembly: AssemblyVersion("1.0.*")] 37 [assembly: AssemblyVersion("1.0.0.0")] 38 [assembly: AssemblyFileVersion("1.0.0.0")]
复制代码

(4)新建一个IObjectSafety接口文件IObjectSafety.cs,内容如下:

复制代码
 1 using System;  2 using System.Collections.Generic;  3 using System.Text;  4 using System.Runtime.InteropServices;  5   6 namespace ActiveXDemo  7 {  8     [ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]  9     [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 10     public interface IObjectSafety 11     { 12         [PreserveSig] 13         int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions); 14  15         [PreserveSig()] 16         int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions); 17     } 18  19 }
复制代码

该内容除命名空间可以更改外,其它内容都是固定的,不要修改 (5)新建一个:Windows Forms-->“用户控件”,我们的主要逻辑就写在这里(还可以在它上面随便放置其它windows常用控件,跟winForm开发一样),不过首先要修改类定义,让其实现我们刚才定义的接口

复制代码
  1 using System;   2 using System.Runtime.InteropServices;   3 using System.Threading;   4 using System.Windows.Forms;   5    6    7 namespace ActiveXDemo   8 {   9     [Guid("8d7d8518-ca58-4863-b94d-3c616fda7b35")]  10     public partial class MyActiveX : UserControl,IObjectSafety  11     {  12         delegate void D(object obj);  13   14         public MyActiveX()  15         {  16             InitializeComponent();  17         }  18   19         #region IObjectSafety 成员  20   21         private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";  22         private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";  23         private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";  24         private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";  25         private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";  26   27         private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;  28         private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;  29         private const int S_OK = 0;  30         private const int E_FAIL = unchecked((int)0x80004005);  31         private const int E_NOINTERFACE = unchecked((int)0x80004002);  32   33         private bool _fSafeForScripting = true;  34         private bool _fSafeForInitializing = true;  35   36         public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)  37         {  38             int Rslt = E_FAIL;  39   40             string strGUID = riid.ToString("B");  41             pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;  42             switch (strGUID)  43             {  44                 case _IID_IDispatch:  45                 case _IID_IDispatchEx:  46                     Rslt = S_OK;  47                     pdwEnabledOptions = 0;  48                     if (_fSafeForScripting == true)  49                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;  50                     break;  51                 case _IID_IPersistStorage:  52                 case _IID_IPersistStream:  53                 case _IID_IPersistPropertyBag:  54                     Rslt = S_OK;  55                     pdwEnabledOptions = 0;  56                     if (_fSafeForInitializing == true)  57                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;  58                     break;  59                 default:  60                     Rslt = E_NOINTERFACE;  61                     break;  62             }  63   64             return Rslt;  65         }  66   67         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)  68         {  69             int Rslt = E_FAIL;  70             string strGUID = riid.ToString("B");  71             switch (strGUID)  72             {  73                 case _IID_IDispatch:  74                 case _IID_IDispatchEx:  75                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))  76                         Rslt = S_OK;  77                     break;  78                 case _IID_IPersistStorage:  79                 case _IID_IPersistStream:  80                 case _IID_IPersistPropertyBag:  81                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))  82                         Rslt = S_OK;  83                     break;  84                 default:  85                     Rslt = E_NOINTERFACE;  86                     break;  87             }  88   89             return Rslt;  90         }  91   92         #endregion  93   94         private void MyActiveX_Load(object sender, EventArgs e)  95         {  96               97         }  98   99  100         public void Start(object obj)  101         { 102             for (int i = 0; i < 10; i++) 103             { 104                 Thread t = new Thread(new ParameterizedThreadStart(ShowTime)); 105                 t.Start(obj.ToString() + ",线程:" + i.ToString());                 106             }         107         } 108  109         private void button1_Click(object sender, EventArgs e) 110         { 111             Start("Hello World"); 112         } 113  114         void ShowTime(object obj) 115         { 116             if (this.listBox1.InvokeRequired) 117             { 118                 D d = new D(DelegateShowTime); 119                 listBox1.Invoke(d, obj); 120             } 121             else 122             { 123                 this.listBox1.Items.Add(obj); 124             } 125  126              127         } 128  129  130         void DelegateShowTime(object obj) 131         { 132             this.listBox1.Items.Add(obj); 133         } 134  135  136     } 137 }
复制代码

#region IObjectSafety 成员 ... #endregion这一段的内容是固定的,不要修改,其它内容根据自己的业务要求自行修改,另外类前面要加上Guid的标识,以便网页调用时,能用CLSID="xxx"来调用

基本上这样弄完后,就可以在网页中,用类似下面这样的代码来本机调用了:

以上是关于c#中开发ActiveX的学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

# C# 学习笔记 类

C#基础及CLR基础学习笔记

C# 学习笔记(13)自己的串口助手

[游戏开发-学习笔记]菜鸟慢慢飞-官方教程学习小心得

C# 学习笔记-- C# 的基础语法

C#学习笔记