首页 > 代码库 > .Net魔法堂:史上最全的ActiveX开发教程——ActiveX与JS间交互篇

.Net魔法堂:史上最全的ActiveX开发教程——ActiveX与JS间交互篇

一、前言                          

  经过上几篇的学习,现在我们已经掌握了ActiveX的整个开发过程,但要发挥ActiveX的真正威力,必须依靠JS。下面一起来学习吧!

 

二、JS调用ActiveX方法                  

  只需在UserControl子类中(即自定义的ActiveX控件中),编写公共方法即可。

  C#

[Guid("0203DABD-51B8-4E8E-A1EB-156950EE1668")]public partial class Uploader : UserControl, IObjectSafety{    public Uploader(){      InitializeComponent();  }    // 被JS调用的ActiveX方法    public void SayHi(msg){        MessageBox.show(msg);    }}

 html

// 注意:object必须要写成<object></object>才能通过document.getElementById来获取<object classid="clsid:xxxxxxxxxx" id="ax"></object><script type="text/javascript">  document.getElementById(ax).SayHi(Test);// 调用ActiveX方法</script>

 

三、ActiveX调用JS方法                      

  1. 引入`Microsoft.mshtml`程序集,该程序集位于`C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll`
  2. 实现COM类`IOleClientSite`

  C#

[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(); }

  3. 实现COM类`IOleContainer`

  C#

[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); }

  4. 在用户控件中调用JS方法
  在MyUserControl.cs中

  C#

#region 调用js函数        private Type typeIOleObject = null;        private IOleClientSite oleClientSite = null;        private IOleContainer pObj = null;        /// <summary>        /// 调用JS函数        /// </summary>        /// <param name="fnName">js函数名</param>        /// <param name="args">入参</param>        protected void CallJS(string fnName, params object[] args)        {            if (typeIOleObject == null)            {                typeIOleObject = this.GetType().GetInterface("IOleObject", true);                object tmpOldClientSite = typeIOleObject.InvokeMember("GetClientSite",                 BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,                null,                this,                null);                oleClientSite = tmpOldClientSite as IOleClientSite;                oleClientSite.GetContainer(out pObj);            }            //获取页面的Script集合            IHTMLDocument pDoc2 = (IHTMLDocument)pObj;            object script = pDoc2.Script;            try            {                //调用JavaScript方法OnScaned并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理                script.GetType().InvokeMember(fnName,                BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,               null,                script,                args);            }            catch { }        }        #endregion

 

五、踩过的坑                          

  1. 若在IE9下无法加载ActiveX控件

   检查是否为64位的IE9。32位的ActiveX控件不能在64位的IE上使用。(通过“任务管理器”查看进程名称,若为浏览器进程名称后跟32就是32位的)

 

六、总结

  《.Net魔法堂:史上最全的ActiveX开发教程》系列总算整理完了,起个博眼球的标题,希望系列的内容不会让大家失望啦。谢谢收看,哈哈!

  尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/3823687.html ^_^肥仔John