ActiveX(二)Js 監聽 ActiveX中的事件


 

在上一篇隨筆:ActiveX(一)第一個簡單的Demo 中,已經可以實現 js 單向調用 ActiveX 中的方法,在很多情況下ActiveX中的方法的執行時相對耗時、耗性能的。在這樣的情況下、ActiveX的方法執行會使用異步策略,那么方法異步時,js又如何獲取異步執行結果呢?方案無非兩種,一種是輪訓、一種是Notify。

 

如果是Notify,Js如何監聽其事件呢? 這將是本篇隨筆接下來的重點: 

繼續上一個Demo,假設,技術需求如下:當按回車時、ActiveX將密碼框中的密碼主動推給Js (使用Notify機制)。

在常規開發中,ActiveX的代碼如下即可:

    [Guid("30A3C1B8-9A9A-417A-9E87-80D0EE827658")]
    public partial class PasswordControl : UserControl
    {
        public delegate void NotifyHandler(string pwd);

        /// <summary>
        /// 在js中監聽該事件
        /// </summary>
        public event NotifyHandler OnNotify;

        public PasswordControl()
        {
            InitializeComponent();
        }

        public string GetPwd()
        {
            return this.txtPwd.Text;
        }

        private void txtPwd_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((Keys)e.KeyChar == Keys.Enter)
            {
                // 回車 觸發事件
                if (this.OnNotify != null)
                {
                    this.OnNotify(this.txtPwd.Text);
                }
            }
        }
    }

 

我們只需要在 Js 中監聽相應的事件、即可完成技術需求。

但是、經過嘗試,都無法監聽到ActiveX中的事件,於是 Google了一下、 找到了解決方案。

1)添加一個新接口,

2)為新接口添加一個新的GUID,(不能和 PasswordControl 的GUID 相同

3)添加屬性:    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]

4)添加 和 需要監聽的事件 相同簽名的方法。

即,形成如下所示的代碼:

    [Guid("FDA0A081-3D3B-4EAB-AE01-6A40FDDA9A60")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IComEvents
    {
        [DispId(0x00000001)]
        void OnNotify(string pwd);
    }

5) 為PasswordControl 添加屬性: [ComSourceInterfaces(typeof(IComEvents))]

即、如下所示:

    [ComSourceInterfaces(typeof(IComEvents))]
    [Guid("30A3C1B8-9A9A-417A-9E87-80D0EE827658")]
    public partial class PasswordControl : UserControl
    {
        //... 其他代碼
    }    

 

6)Js端用如下的方式監聽事件:

    <script language="Javascript" event="OnNotify(pwd)" for="activieX">
        function activieX::OnNotify(pwd) {
            console.info("密碼:" + pwd);
        }
    </script>

event:指定監聽的事件

for:指定監聽對象

js函數名稱使用 :[監聽對象]::[監聽事件]的形式,注意、中間是兩個冒號。

這樣,Js就可以在密碼框敲回車的時候、接收到ActiveX推送的密碼了。 是不是很簡單呢?

 

 

有兩點需要注意:

1、事件所對應的delegate需自定義、不要使用系統的Action<T>

2、js函數名稱使用 :[監聽對象]::[監聽事件]的形式,中間是兩個冒號。

 

測試項目源碼:TestActiveX.zip

(未完待續...)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM