1、前言 javascript
通過上幾篇的學習,如今咱們已經掌握了ActiveX的整個開發過程,但要發揮ActiveX的真正威力,必須依靠JS。下面一塊兒來學習吧!html
2、JS調用ActiveX方法 java
只需在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>
3、ActiveX調用JS方法 ui
1. 引入`Microsoft.mshtml`程序集,該程序集位於`C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll`
2. 實現COM類`IOleClientSite`this
C#spa
[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`code
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
5、踩過的坑
1. 若在IE9下沒法加載ActiveX控件
檢查是否爲64位的IE9。32位的ActiveX控件不能在64位的IE上使用。(經過「任務管理器」查看進程名稱,若爲瀏覽器進程名稱後跟32就是32位的)
6、總結
《.Net魔法堂:史上最全的ActiveX開發教程》系列總算整理完了,起個博眼球的標題,但願系列的內容不會讓你們失望啦。謝謝收看,哈哈!
尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/3823687.html ^_^肥仔John