前面已经用C#开发ActiveX控件,并成功嵌入到WEB网页中。下面讲述本人Javascript与ActiveX相互调用的步骤。
一、js调用ActiveX
1.1.在类库UserControls1.cs文件中添加三个函数(名字以123区分,未进行函数重载,原因是实践过程中发现js无法识别)
public void FunctionInActiveX()
{
MessageBox.Show(Properties.Resources.Str3, Properties.Resources.Str2, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
public object FunctionInActiveX2(object arg)
{
MessageBox.Show("javascript传过来的参数是:" + (arg == null ? "空" : arg.ToString()), Properties.Resources.Str2, MessageBoxButtons.OK, MessageBoxIcon.Information);
return "activex返回的字符串";
}
public double FunctionInActiveX3(double num1,double num2)
{
return num1 +num2;
}
如下图
1.2.在html为先前的Object标签元素添加ID为A_SHIJIERUCIMEIHAO,并添加相应javascript代码和网页按钮
<object id="A_SHIJIERUCIMEIHAO"
classid="clsid:9A15E63F-1761-4f99-B740-512AD1C63D7E"
>
<script type="text/javascript">
function CallActiveXFunction(){
var activeObj=document.getElementById("A_SHIJIERUCIMEIHAO");
if(activeObj){
activeObj.FunctionInActiveX();
alert(activeObj.FunctionInActiveX2("js的参数"));
alert("ActiveX计算返回的结果:"+activeObj.FunctionInActiveX3(1,2));
}
}
</script>
<input type="button" onClick="javascript:CallActiveXFunction();" value="网页的按钮"></input>
整体如下图
用IE打开该网页
1.3点击网页的按钮 并对所提示允许,(网上很多介绍在Activex实现如何去掉限制的方法,但都是C++的,现在我还不知道这里咋整)
后面依次弹出四个对话框
二、ActiveX调用js
这里主要根据网上的资料实践的。
先来个简单的方法(可能不实用),
首先由js调用activex控件方法,目的是把html的window窗体传递给activex控件,进而获得IHTMLWindow2对象,然后activex控件根据获得IHTMLWindow2对象再调用js函数。
2.1在html里面添加代码后如下:
<html>
<head>
<title>我要睡觉了</title>
<script type="text/javascript">
function CallActiveXFunction(){
var activeObj=document.getElementById("A_SHIJIERUCIMEIHAO");
if(activeObj){
activeObj.FunctionInActiveX();
alert(activeObj.FunctionInActiveX2("js的参数"));
alert("ActiveX计算返回的结果:"+activeObj.FunctionInActiveX3(1,2));
}
}
function setWindowToActiveX(){
var activeObj=document.getElementById("A_SHIJIERUCIMEIHAO");
if(activeObj){
activeObj.SetWindowOfHtml(window);
}
}
function funcInJS(obj){
alert("给ActiveX调用的js函数--"+obj);
}
</script>
</head>
<body onLoad="javascript:setWindowToActiveX();">
<b align=center>下面是嵌入的ActiveX控件哦</b>
</br>
<input type="button" onClick="javascript:CallActiveXFunction();" value="网页的按钮"></input>
</br>
<object id="A_SHIJIERUCIMEIHAO"
classid="clsid:9A15E63F-1761-4f99-B740-512AD1C63D7E"
>
</object>
</body>
</html>
2.2 activex控件中添加一个textbox控件用于输入要调用的js函数名称,一个按钮用于调用js函数
如下图
2.3添加引用Microsoft.mshtml.dll
2.4在UserControl1
.cs添加代码如下:
#region 调用js代码
IHTMLWindow2 htmlWin;
public void SetWindowOfHtml(object win)
{
htmlWin = (win as IHTMLWindow2);
}
public void CallJSFunction(string JSFuncName)
{
if (htmlWin == null || string.IsNullOrEmpty(JSFuncName))
{
MessageBox.Show("错误");
}
else
{
//调用js代码1,反射的方法;2,JS代码语法
//方法1。
htmlWin.GetType().InvokeMember(JSFuncName,
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
null, htmlWin, new object[] { "C#参数" });
//方法2。
string jsCode = string.Format("{0}('{1}')", JSFuncName, "C#参数");
htmlWin.execScript(jsCode, "jscript");
}
}
private void button2_Click(object sender, EventArgs e)
{
CallJSFunction(textBox1.Text);
}
#endregion
2.3运行程序,点击"调用js函数"按钮,结果如图:
好。后面用另一种比较复杂方法,但不用先由js调用activex控件代码....
首先用c#实现两个COM类,IOleClientSite和IOleContainer
[ComImport, Guid("00000118-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleClientSite
{
void SaveObject();
void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
void GetContainer(out IOleContainer ppContainer);
void ShowObject();
void OnShowWindow(bool fShow);
void RequestNewObjectLayout();
}
[ComImport, Guid("0000011B-0000-0000-C000-000000000046"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleContainer
{
void EnumObjects([In, MarshalAs(UnmanagedType.U4)] int grfFlags,
[Out, MarshalAs(UnmanagedType.LPArray)] object[] ppenum);
void ParseDisplayName([In, MarshalAs(UnmanagedType.Interface)] object pbc,
[In, MarshalAs(UnmanagedType.BStr)] string pszDisplayName,
[Out, MarshalAs(UnmanagedType.LPArray)] int[] pchEaten,
[Out, MarshalAs(UnmanagedType.LPArray)] object[] ppmkOut);
void LockContainer([In, MarshalAs(UnmanagedType.I4)] int fLock);
}
在UserControl1.cs中就可以编写如下的CallJavaScript方法:
private void CallJavaScript(string arg)
{
Type typeIOleObject = this.GetType().GetInterface("IOleObject", true);
object oleClientSite = typeIOleObject.InvokeMember("GetClientSite",
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
null, this, null);
IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite;
IOleContainer pObj;
oleClientSite2.GetContainer(out pObj);
//参数数组
object[] args = new object[1];
args[0] = arg;
//获取页面的Script集合
IHTMLDocument pDoc2 = (IHTMLDocument)pObj;
object script = pDoc2.Script;
try
{
//调用JavaScript方法funcInJS并传递参数
script.GetType().InvokeMember("funcInJS",
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, script, args);
}
catch { }
}
再添加一个按钮,单击事件添加代码
private void button3_Click(object sender, EventArgs e)
{
CallJavaScript("C#参数");
}
OK ,搞定