原码以及makeCAB包下载地址:
http://files.iyunv.com/zouyang/HelloDaniel.rar
一、环境:
操作系统:Win7
开发工具:Visual Studio 2010
.NET版本:4.0
开发语言:C#
下载makeCAB压缩包,这里面包含了制作数字签名和制作cab的几个exe程序
保存路径:D:\makeCAB
需要编辑的系统环境变量设置:(下面的系统变量)
这样做是为了方便后面在cmd里调用。
二、编写ActiveX控件
1、创建一个新的Windows窗体控件库
2、重命名UserControl1.cs 为HelloDanielActiveX.cs
3、拖1个GroupBox和2个Label控件到界面上
4、为控件添加一个方法,用来设置Label中显示当前时间
#region Javascript调用ActiveX的方法
// 设置当前时间
public void SetTime(string timeStr)
{
this.label2.Text = timeStr;
}
#endregion
5、新建一个接口
下面是这个接口的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace HelloDaniel
{
[ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectSafety
{
[PreserveSig]
int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions,
[MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
[PreserveSig()]
int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask,
[MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
}
}
6、在控件中实现这个接口
关于实现这个接口,篇幅较长,可以在这篇文章找到:http://www.pinvoke.net/default.aspx/Interfaces/IObjectSafety.html
7、为控件添加Guid、ProgId和ComVisible属性
Guid的获得应该是这样的:
点击复制,然后将你得到的Guid号Copy下,粘贴到下面代码里面。
然后,右键单击项目HelloDaniel——>属性,在应用程序中选择程序集信息
把使程序集COM可见的对勾打上。
同时,在属性——>【生成】项中选择为COM互操作注册
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using mshtml;
using System.Reflection;
namespace HelloDaniel
{// {6DCD51C2-33FD-4556-842F-419B6AA3C252}
[Guid("6DCD51C2-33FD-4556-842F-419B6AA3C252"), ProgId("HelloDaniel.HelloDanielActiveX"), ComVisible(true)]
public partial class HelloDanielActiveX : UserControl, IObjectSafety
{
private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
private const int S_OK = 0;
private const int E_FAIL = unchecked((int)0x80004005);
private const int E_NOINTERFACE = unchecked((int)0x80004002);
private bool _fSafeForScripting = true;
private bool _fSafeForInitializing = true;
public HelloDanielActiveX()
{
InitializeComponent();
}
public int GetInterfaceSafetyOptions(ref Guid riid,
ref int pdwSupportedOptions,
ref int pdwEnabledOptions)
{
int Rslt = E_FAIL;
string strGUID = riid.ToString("B");
pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
switch (strGUID)
{
case _IID_IDispatch:
case _IID_IDispatchEx:
Rslt = S_OK;
pdwEnabledOptions = 0;
if (_fSafeForScripting == true)
pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
break;
case _IID_IPersistStorage:
case _IID_IPersistStream:
case _IID_IPersistPropertyBag:
Rslt = S_OK;
pdwEnabledOptions = 0;
if (_fSafeForInitializing == true)
pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
break;
default:
Rslt = E_NOINTERFACE;
break;
}
return Rslt;
}
public int SetInterfaceSafetyOptions(ref Guid riid,
int dwOptionSetMask,
int dwEnabledOptions)
{
int Rslt = E_FAIL;
string strGUID = riid.ToString("B");
switch (strGUID)
{
case _IID_IDispatch:
case _IID_IDispatchEx:
if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) &&
(_fSafeForScripting == true))
Rslt = S_OK;
break;
case _IID_IPersistStorage:
case _IID_IPersistStream:
case _IID_IPersistPropertyBag:
if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) &&
(_fSafeForInitializing == true))
Rslt = S_OK;
break;
default:
Rslt = E_NOINTERFACE;
break;
}
return Rslt;
}
#region Javascript调用ActiveX的方法
///
/// 设置当前时间
///
///
public void SetTime(string timeStr)
{
this.label2.Text = timeStr;
}
#endregion
#region ActiveX调用Javascript的函数 方法一
///
/// HTMLWindow2Class对象
///
private mshtml.IHTMLWindow2 html = null;
///
/// 调用Javascript
///
///
///
private void button1_Click(object sender, EventArgs e)
{
html.execScript("CallByActiveX('" + this.label2.Text + "');", "javascript");
//CallJavaScript(this.label2.Text);
}
///
/// 将window对象传递进来
///
/// The obj.
public void SetHtml(object obj)
{
html = obj as mshtml.IHTMLWindow2;
}
#endregion
#region ActiveX调用Javascript的函数 方法二
///
/// 调用Javascript
///
/// The filenames.
private void CallJavaScript(string param)
{
//反射获取当前的控件的ClientSite
Type typeIOleObject = this.GetType().GetInterface("IOleObject", true);
object oleClientSite = typeIOleObject.InvokeMember("GetClientSite",
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
null,
this,
null);
//获取Container
IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite;
IOleContainer pObj;
oleClientSite2.GetContainer(out pObj);
//参数数组
object[] args = new object[1];
args[0] = param;
//获取页面的Script集合
IHTMLDocument pDoc2 = (IHTMLDocument)pObj;
object script = pDoc2.Script;
try
{
//调用JavaScript方法OnScaned并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理
script.GetType().InvokeMember("ShowNowTime", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
null,
script,
args);
}
catch { }
}
#endregion