上一节介绍了一个ActiveX的例子,后续的文章将针对这个例子进行扩充和说明。这篇文章将介绍C#如何在ActiveX控件中调用javascript的函数,这里参考网上的例子介绍两种方法,虽然代码不一样,但是殊途同归。而且都使用了mshtml。
1、方法一
(1)在VS项目中添加Com对象引用:Microsoft Html Object Library(mshtml.tlb)
(2)ActiveX中公开一个方法,传递window对象到ActiveX中
ActiveX中公开一个方法,接受传递进来的参数
? /// <summary> ??????? /// 将window对象传递进来 ??????? /// </summary> ??????? /// <param name="obj">The obj.</param> ??????? public void SetHtml(object obj) ??????? { ??????????? html = (mshtml.HTMLWindow2Class)obj; ??????? }
在页面中调用ActiveX的公开方法,传递当前window对象进去:
?
window.onload = function() { ??????????? document.HelloBossma.SetHtml(this); ??????? };
(3)在ActiveX控件中添加一个按钮,当点击这个按钮时,触发页面中的javascript。
点击按钮的方法:
/// <summary> ??????? /// 调用页面Javascript ??????? /// </summary> ??????? /// <param name="sender"></param> ??????? /// <param name="e"></param> ??????? private void button1_Click(object sender, EventArgs e) ??????? { ??????????? html.execScript("CallByActiveX();", "javascript"); ??????? }
现在卸载掉原来的ActiveX控件,安装新的控件,打开页面,点击按钮,看到如下效果,说明成功。
调用javascript时还可以传递参数,这里不做演示了,自己可以试一下。
参考:http://www.cnblogs.com/liubiqu/articles/92632.html
2、方法二
(1)在VS项目中添加Com对象引用:Microsoft Html Object Library(mshtml.tlb)
和第一种方法相同。
(2)用c#实现两个COM类,IOleClientSite和IOleContainer
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace HelloBossma { ??? [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, ??????????? [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); ??? } }
(3)在ActiveX中编写CallJavascript方法:
/// <summary> ??????? /// 调用Javascript ??????? /// </summary> ??????? /// <param name="Filenames">The filenames.</param> ?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 { } ??????? }
点击按钮时的操作:
/// <summary> ??????? /// 调用Javascript ??????? /// </summary> ??????? /// <param name="sender"></param> ??????? /// <param name="e"></param> ??????? private void button1_Click(object sender, EventArgs e) ??????? { ?????????????????????? CallJavaScript(this.label2.Text); ??????? }
(4)网页中的javascript
function ShowNowTime(nowtime) { ??????????? alert("当前时间:" + nowtime); ??????? }
卸载原来的ActiveX控件,重新安装,实际效果:
参考:http://blog.csdn.net/sabty/archive/2009/05/10/4165342.aspx
这篇文档到这里就结束了,关于这两个方法的使用,如果有问题,欢迎和我交流!
@leo
这里有例子下载:http://blog.bossma.cn/dotnet/visual-studio-2008-csharp-activex-summary-4/
不错的文章,但我想请问下,在Activex调用js的第二种方法中:
用c#实现两个COM类,IOleClientSite和IOleContainer
这两个接口如何实现呢?有参考实现么?
找了好久,谢谢你能整理的这么详细!
发表评论
相关文章
国内AI资源汇总,AI聊天、AI绘画、AI写作、AI视频、AI设计、AI编程、AI音乐等,国内顺畅访问,无需科学上网。
扫码或点击进入:萤火AI大全
文章分类
最新评论