关于ActiveX控件的开发,网上很多例子,昨天也整整研究一天才捋顺了.

网上大部分例子都是js调用控件的方法,由于要实现在html页面"相应"控件的事件,整整折腾一天.

关键点在于 "创建ActiveX控件" 的 第2,和第7

该技术局限性较大,如浏览器端需安装 .net 框架,仅限于IE浏览器.

关于ActiveX的证书及浏览器安装时设置,可参考 http://www.cnblogs.com/weixing/archive/2013/06/28/3161165.html 这也是我看到比较详细的介绍了.

创建ActiveX控件
1.创建一个类库;
2.项目属性-应用程序-程序集信息-"使程序集COM可见"勾上;
3.项目属性-生成-"为COM互操作注册"勾上.(这个折腾一天,否则注册事件不可用);
4.创建接口: IObjectSafety (注意GUID不能变);
5.创建ActiveX控件的基类并实现IObjectSafety,ActiveX控件可以继承它来减少代码;
6.创建一个ActiveX自定义控件如:ActiveXDemo1;
7.定义ActiveXDemo1的"方法接口"及"事件接口".(如使用自定义事件需用此方式), "事件接口"成员应加上[DispId(x)]标识;
8.创建ActiveX控件完成.

IObjectSafety  接口定义

  1. [ComImport, Guid("4A359FBB-C9A4-494E-B048-AC068DB4FCB2")] //该GUID不能变
  2. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  3. public interface IObjectSafety
  4. {
  5. [PreserveSig]
  6. int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
  7.  
  8. [PreserveSig()]
  9. int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
  10. }
  11. }

ActiveX控件基类(ActiveXControlBase)

  1. public class ActiveXControlBase : IObjectSafety
  2. {
  3. #region IObjectSafety 成员
  4.  
  5. private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
  6. private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
  7. private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
  8. private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
  9. private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
  10.  
  11. private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
  12. private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
  13. private const int S_OK = 0;
  14. private const int E_FAIL = unchecked((int)0x80004005);
  15. private const int E_NOINTERFACE = unchecked((int)0x80004002);
  16.  
  17. private bool _fSafeForScripting = true;
  18. private bool _fSafeForInitializing = true;
  19.  
  20. public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
  21. {
  22. int Rslt = E_FAIL;
  23.  
  24. string strGUID = riid.ToString("B");
  25. pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
  26. switch (strGUID)
  27. {
  28. case _IID_IDispatch:
  29. case _IID_IDispatchEx:
  30. Rslt = S_OK;
  31. pdwEnabledOptions = 0;
  32. if (_fSafeForScripting == true)
  33. pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
  34. break;
  35. case _IID_IPersistStorage:
  36. case _IID_IPersistStream:
  37. case _IID_IPersistPropertyBag:
  38. Rslt = S_OK;
  39. pdwEnabledOptions = 0;
  40. if (_fSafeForInitializing == true)
  41. pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
  42. break;
  43. default:
  44. Rslt = E_NOINTERFACE;
  45. break;
  46. }
  47.  
  48. return Rslt;
  49. }
  50.  
  51. public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
  52. {
  53. int Rslt = E_FAIL;
  54.  
  55. string strGUID = riid.ToString("B");
  56. switch (strGUID)
  57. {
  58. case _IID_IDispatch:
  59. case _IID_IDispatchEx:
  60. if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) &&
  61. (_fSafeForScripting == true))
  62. Rslt = S_OK;
  63. break;
  64. case _IID_IPersistStorage:
  65. case _IID_IPersistStream:
  66. case _IID_IPersistPropertyBag:
  67. if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) &&
  68. (_fSafeForInitializing == true))
  69. Rslt = S_OK;
  70. break;
  71. default:
  72. Rslt = E_NOINTERFACE;
  73. break;
  74. }
  75.  
  76. return Rslt;
  77. }
  78.  
  79. #endregion
  80. }

  自定义ActiveX控件

  1. [ComVisible(true)]
  2. [Guid("684AAD87-C086-4F27-AE55-941A1AAC7212")]
  3. [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  4. public interface IThreadDemoEvent
  5. {
  6. [DispId(1)] //使用事件,必须加上该标识
  7. void ShowMessage1(string str_Msg);
  8. [DispId(2)]
  9. void ShowMessage2(string str_Msg);
  10. }
  11.  
  12. [ComVisible(true)]
  13. [Guid("4D12136B-9545-423B-A110-B9405ADF8B30")]
  14. [InterfaceType(ComInterfaceType.InterfaceIsDual)]
  15. public interface IThreadDemo
  16. {
  17. string StartTimer();
  18. string StopTimer();
  19. }
  20.  
  21. [Guid("2B4FCB85-A3B7-43BD-B104-7380E7F3483F"),
  22. ClassInterface(ClassInterfaceType.AutoDual),
  23. ComDefaultInterface(typeof(IThreadDemo)),
  24. ComSourceInterfaces(typeof(IThreadDemoEvent)),
  25. ComVisible(true)
  26. ]
  27. public class ActivexThreadDemo : ActiveXControlBase, IThreadDemo
  28. {
  29. ~ActivexThreadDemo()
  30. {
  31. ShowMessage1("释放了啊");
  32. }
  33.  
  34. Thread _th;
  35. bool _isStop;
  36.  
  37. public event ShowMessageHandle ShowMessage1;
  38. public event ShowMessageHandle ShowMessage2;
  39.  
  40. void ThreadMethd()
  41. {
  42. while (true)
  43. {
  44. Thread.Sleep(3000);
  45. if (ShowMessage1 != null)
  46. {
  47. ShowMessage1.Invoke(DateTime.Now.ToString());
  48. }
  49. if (_isStop) break;
  50. }
  51. _th.Abort();
  52. _th = null;
  53. }
  54.  
  55. public string StartTimer()
  56. {
  57. if (_th == null)
  58. {
  59. _isStop = false;
  60. _th = new Thread(ThreadMethd);
  61. _th.IsBackground = false;
  62. _th.Start();
  63. return "开起计时";
  64. }
  65. if (ShowMessage2 != null)
  66. {
  67. ShowMessage2("执行了 StartTimer");
  68. }
  69. return "已经开起过计时;";
  70. }
  71.  
  72. public string StopTimer()
  73. {
  74. if (_isStop)
  75. {
  76. return "已经停止计时了!";
  77. }
  78. else
  79. {
  80. _isStop = true;
  81. return "停止计时";
  82. }
  83. }
  84. }

  

注意:
不能使用泛型委托来声明事件,如:public event Action<T> ShowMessageHandle;
当类里面包含 static成员,刷新页面不会清空
跨线程触发事件: [事件].Invoke(参数1,参数2 ...);

ActiveX控件Setup
1.创建Installer项目;
2.右击项目 添加->项目输出 打开添加项目输出组对话框,并选择ActiveX控件类库;
3.主输出文件的属性 Register 值为 vsdrpCOM (关键),RemovePreviousVersions 设置为true

web页面测试;
1.创建一个object 标签,calassid为控件GUID
<object id="ActiveXObj1" classid="clsid:3BCF612C-91CF-4543-83BB-FD2331FDDCB6" ></object>
2.调用控件方法
var r = document.ActiveXObj1.Test1();
3."注册控件的事件"
<script language="javascript" type="text/javascript" for="ActiveXObj1" event="ShowMessage1(msg)">
alert("ActiveXObj1 :"+ msg )
</script>

  1. <html xmlns="http://www.w3.org/1999/xhtml">
  2. <head>
  3. <title>ActiveX测试页面</title>
  4.  
  5. <script type="text/javascript">
  6.  
  7. function test1() {
  8. var r = document.ActiveXObj1.Test1();
  9. window.status = r;
  10. }
  11.  
  12. function StartTimer() {
  13. alert(document.ActiveThreadEvent);
  14. var r = document.ActiveThreadEvent.StartTimer();
  15. window.status = r;
  16. }
  17. function StopTimer() {
  18. var r = document.ActiveThreadEvent.StopTimer();
  19. window.status = r;
  20. }
  21. </script>
  22. <!--事件的注册-->
  23. <script language="javascript" type="text/javascript" for="ActiveXObj1" event="ShowMessage1(msg)">
  24. alert("ActiveXObj1 :"+ msg )
  25. </script>
  26. <script language="javascript" type="text/javascript" for="ActiveXObj1" event="ShowMessage2(msg)">
  27. alert("ActiveXObj1:" + msg)
  28. </script>
  29.  
  30. <!--线程事件注册-->
  31. <script language="javascript" type="text/javascript" for="ActiveThreadEvent" event="ShowMessage1(msg)">
  32. alert("ActiveThreadEvent :"+ msg )
  33. </script>
  34. <script language="javascript" type="text/javascript" for="ActiveThreadEvent" event="ShowMessage2(msg)">
  35. alert("ActiveThreadEvent:" + msg)
  36. </script>
  37. </head>
  38. <body>
  39. <object id="ActiveXObj1" classid="clsid:3BCF612C-91CF-4543-83BB-FD2331FDDCB6" ></object>
  40. <br />
  41. <object id="ActiveThreadEvent" classid="clsid:2B4FCB85-A3B7-43BD-B104-7380E7F3483F" ></object>
  42. <br />
  43. <br />
  44. <input type="button" value="测试4-相应事件!" onclick="test1();" /><br />
  45. <input type="button" value="开始计时!" onclick="StartTimer();" /><br />
  46. <input type="button" value="停止计时!" onclick="StopTimer();" /><br />
  47.  
  48. </body>
  49. </html>

源码共享:  戳我

c# ActiveX 控件的开发的更多相关文章

  1. [转]C#开发ActiveX控件,.NET开发OCX控件案例

    引自:百度   http://hi.baidu.com/yanzuoguang/blog/item/fe11974edf52873aaec3ab42.html 讲下什么是ActiveX控件,到底有什么 ...

  2. C#开发ActiveX控件,.NET开发OCX控件案例 【转】

    http://xiaochen.2003.4.blog.163.com/blog/static/480409672012530227678/ 讲下什么是ActiveX控件,到底有什么作用?在网页中又如 ...

  3. 用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件

    用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件用C#编写ActiveX控件 开发浏览器控件这是本控件开发完成后的一个简单应用.我们可以利用它以本地文件夹为单位来批量更新服务器的 ...

  4. C#ActiveX控件开发学习

    一:C#ActiveX控件开发注意事项   1:C#开发的ActiveX控件只可在装有Framework的系统上才能用. 2:只有IE浏览器支持. 3:初次安装需要导入代码签名证书及其证书链的方式, ...

  5. 使用C#开发ActiveX控件(新)

    前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动态处理能力.通常ActiveX控件都是 ...

  6. 使用C#开发ActiveX控件(新) 转 http://www.cnblogs.com/yilin/p/csharp-activex.html

    前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动态处理能力.通常ActiveX控件都是 ...

  7. C#开发ActiveX控件

    昨天写了篇博客<Winform 程序嵌入WPF程序 并发送消息>,没有说明为什么要嵌入WPF程序,那么今天就来唠叨唠叨其中的一个使用场景,开发ActiveX控件 首先,新建一个类库工程Hu ...

  8. 使用C#开发ActiveX控件

    使用C#开发ActiveX控件(新) 前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动 ...

  9. [转]使用C#开发ActiveX控件全攻略

    前言: 这段时间因为工作的需要,研究了一下ActiveX控件.总结如下: 先说说ActiveX的基本概念. 根据微软权威的软件开发指南MSDN(Microsoft Developer Network) ...

随机推荐

  1. [摘]string.jion() 解决办法

    for (int j = 1; j <= 5; j++)            {                List<int> list = new List<int&g ...

  2. 嵌入式 详解udev

    如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Linux改变了几次策略.在Linux早期,设备文件仅仅是是一些带有适当的属性集的普通文件,它由mknod命令创建,文件存放在/dev ...

  3. 开发者必须知道的HTML5十五大新特性

    HTML5想必大家都很熟悉了,因为太多的媒体在讨论这一技术.然而,你能准确地说出HTML5带来了哪些新特性吗?本文总结了HTML5带来的15项你必须知道的新特性. 一起来看下: 1.新的文档类型  ( ...

  4. C++静态成员总结(转)

    类中的静态成员真是个让人爱恨交加的特性.我决定好好总结一下静态类成员的知识点,以便自己在以后面试中,在此类问题上不在被动. 静态类成员包括静态数据成员和静态函数成员两部分. 一 静态数据成员: 类体中 ...

  5. FastJson只序列化java对象的部分属性

    public class Student { private int id; private String name; private int age; //get set方法略 } 如下方法: St ...

  6. 安装Sikulix

    1.sikulix可以在xp,win7,8,10 Mac 10.10.x 以及Linux/Unix 系统上安装 2.安装Java支持 3.下载sikulisetup1.1.0.jar(那里下前篇有介绍 ...

  7. Android 者开发如何选择测试机列表

    Android 系统已经分化成多种不同的定制版本,制造厂商的不同手机使用的硬件千差万别.差异化带来良好的用户体验的同时,也给开发者带来的适配的问题.于是每个开发团队都需要面临选择测试机列表的问题.我基 ...

  8. 数字图像去噪典型算法及matlab实现

    原文地址http://jncumter.blog.51cto.com/812546/243961   图像去噪是数字图像处理中的重要环节和步骤.去噪效果的好坏直接影响到后续的图像处理工作如图像分割.边 ...

  9. Scrum概述

    • 敏捷方法是一类软件开发流程的泛称: • 敏捷方法是相对于传统的瀑布式软件过程提出的: • 敏捷方法可以用敏捷宣言(4条).敏捷原则(12条)来概括: • 敏捷原则通过一系列的敏捷实践来体现出来: ...

  10. Linux_系统信息

    公司里一些仿真软件得进Linux系统,好奇公司用的什么Linux版本,于是搜罗了几个命令如下: 1  uname - Print system info -a, print all info -s, ...