文章出處

一、前言                          

  經過上幾篇的學習,現在我們已經掌握了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


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()