熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

使用C#構建帶事件的簽名ActiveX組件

2013-11-13 10:17:54  來源: .NET編程 

  使用C#構建帶事件的簽名ActiveX組件具體辦法:

  第一步 創建ActiveX項目
    使用NET語言編寫的ActiveX控件的主體就是一個類庫首先我們來創建這個類庫項目打開Visual Studio File>New>Project選擇Class Library創建一個類庫項目
    創建ActiveX項目
    第二步 編寫ActiveX主體
    ActiveX的主體包括方法定義接口事件定義接口(可選)實現這些接口的ActiveX主體類三個部分下面是筆者原創的Demo
    首先我們創建方法定義接口:
    ///<summary>
    /// 該接口定義了ActiveX的方法
    ///</summary>
    [
    Guid(FBDFEBFBDFDDDF)
    InterfaceType(ComInterfaceTypeInterfaceIsDual)
    ComVisible(true)]
    publicinterfaceIBosnMaActiveX
    {
    [DispId()]
    void Start();
    [DispId()]
    void Stop();
    }
    該接口內的成員會暴露給外部調用這裡我們提供兩個簡單方法Start和Stop使用工具(Visual Studio > Tools > Create GUID)生成自己的GUID
    接下來定義事件接口:
    ///<summary>
    /// 該接口定義了ActiveX的事件
    ///</summary>
    [ComVisible(true)]
    [Guid(CFFFBeDBAC)]
    [InterfaceType(ComInterfaceTypeInterfaceIsIDispatch)]
    publicinterfaceBosnMaActiveXEvents
    {
    [DispId()]
    void OnRecorderStarted();
    [DispId()]
    void OnRecorderStopped();
    [DispId()]
    void OnRecorderVolumeChanged(int value);
    }
    這裡我們為ActiveX定義三個事件分別為OnRecorderStartedOnRecorderStopped OnRecorderVolumeChanged(帶一個int參數)


    最後我們編寫集成方法接口和事件接口的ActiveX主體類:
    [
    Guid(ECEECbBCFFCA)
    ProgId(ActiveXOfBosnMaBosnMaActiveX)
    ClassInterface(ClassInterfaceTypeNone)
    ComDefaultInterface(typeof(IBosnMaActiveX))
    ComSourceInterfaces(typeof(BosnMaActiveXEvents))
    ComVisible(true)
    ]
    publicclassBosnAcX : IBosnMaActiveX IObjectSafety
    {
    #region Events Handlers Instances
    publicdelegatevoidVolumeChangedHandler(int value);
    publicdelegatevoidSimpleHandler();
    publiceventVolumeChangedHandler OnRecorderVolumeChanged;
    publiceventSimpleHandler OnRecorderStarted;
    publiceventSimpleHandler OnRecorderStopped;
    #endregion
    #region Implementation of IBosnMaActiveX
    ///<summary>
    /// 調用該方法將引發OnRecorderStarted事件並在秒後引發OnRecorderVolumeChanged
    ///</summary>
    publicvoid Start()
    {
    OnRecorderStarted();
    SimpleHandler d = Work;
    dBeginInvoke(null null);
    }
    publicvoid Work()
    {
    ThreadSleep();
    OnRecorderVolumeChanged();
    }
    ///<summary>
    /// 調用該方法將引發OnRecorderStopped事件
    ///</summary>
    publicvoid Stop()
    {
    OnRecorderStopped();
    }
    #endregion
    }
    這裡要注意主體類的事件名稱要與事件接口(在上例中為BosnMaActiveXEvents)中的方法名相同在BosnAcX中我們實現了IBosnMaActiveX中的方法當調用Start()時引發一個OnRecorderStarted事件並在秒後引發一個OnRecorderVolumeChanged事件在調用Stop()時引發一個OnRecorderStopped事件
    編譯並注冊ActiveX
    編譯整個項目將輸出dll
    圖 編譯ActiveX項目生成dll文件
    然後我們啟動命令行CMD(如果是Vista/Win使用管理員方式打開)使用以下命令注冊控件
    C:\>D:                       //轉到dll所在目錄筆者為了方便將dll copy到了D盤根目錄
    D:\>regasm activexofbosnmadll /codebase /tlb
    *regasm命令在%systemroot%\MicrosoftNET\Framework\vxxxxx\目錄下將該目錄注冊到用戶環境變量中即可不使用完全限定名運行該命令
    *使用regasm activexofbosnmadll /codebase /tlb /unregister可以反注冊在ActiveX代碼變更時重編譯後需要先反注冊再注冊
    圖 注冊和反注冊ActiveX控件
    測試ActiveX
    最後我們創建一個html頁面來測試該ActiveX
    <html>
    <headrunat=server>
    <title></title>
    <objectid=myAcXname=myAcXclassid=clsid:ECEECbBCFFCA>
    </object>
    <scriptlanguage=javascriptfor=myAcXtype=text/javascriptevent=OnRecorderVolumeChanged(v);>
    MyDivinnerHTML = In javascript: Get Volume:+v;
    </script>
    <scriptlanguage=javascriptfor=myAcXtype=text/javascriptevent=OnRecorderStarted>
    MyDivinnerHTML = In javascript: OnRecorderStarted;
    </script>
    <scriptlanguage=javascriptfor=myAcXtype=text/javascriptevent=OnRecorderStopped>
    MyDivinnerHTML = In javascript: OnRecorderStopped;
    </script>
    </head>
    <body>
    <form>
    <scriptlanguage=javascripttype=text/jscript>
    function Button_onclick() {
    myAcXStart();
    }
    function Button_onclick() {
    myAcXStop();
    }
    function RecorderVolumeChanged(v) {
    alert(volume: + v);
    }
    </script>
    <divid=MyDiv>Nothing happened</div>
    <p>
    <inputid=Buttontype=buttonvalue=Startonclick=Button_onclick()/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <inputid=Buttontype=buttonvalue=Stoponclick=Button_onclick()/></p>
    </form>
    </body>
    </html>


   測試效果
    首先使用IE打開測試頁面
    允許ActiveX交互後進入主界面點擊Start按鈕會收到ActiveX返回的OnRecorderStarted事件
    三秒過後收到Volume事件
    最後點擊Stop按鈕會收到OnRecorderStopped事件
    安全性
    為了標記ActiveX控件為安全的(避免彈出該控件是不安全的警告)需要實現IObjectSafety接口
    using System;
    using SystemCollectionsGeneric;
    using SystemRuntimeInteropServices;
    using SystemComponentModel;
    using SystemText;
    namespace ActiveXOfBosnMa
    {
    [
    Serializable
    ComVisible(true)
    ]
    publicenumObjectSafetyOptions
    {
    INTERFACESAFE_FOR_UNTRUSTED_CALLER = x
    INTERFACESAFE_FOR_UNTRUSTED_DATA = x
    INTERFACE_USES_DISPEX = x
    INTERFACE_USES_SECURITY_MANAGER = x
    };
    //
    // MS IObjectSafety Interface definition
    //
    [
    ComImport()
    Guid(CBBDCCCFFFCD)
    InterfaceType(ComInterfaceTypeInterfaceIsIUnknown)
    ]
    publicinterfaceIObjectSafety
    {
    [PreserveSig]
    long GetInterfaceSafetyOptions(refGuid iid outint pdwSupportedOptions outint pdwEnabledOptions);
    [PreserveSig]
    long SetInterfaceSafetyOptions(refGuid iid int dwOptionSetMask int dwEnabledOptions);
    };
    //
    // Provides a default Implementation for
    // safe scripting
    // This basically means IE wont complain about the
    // ActiveX object not being safe
    //
    publicclassIObjectSafetyImpl : IObjectSafety
    {
    privateObjectSafetyOptions m_options =
    ObjectSafetyOptionsINTERFACESAFE_FOR_UNTRUSTED_CALLER |
    ObjectSafetyOptionsINTERFACESAFE_FOR_UNTRUSTED_DATA;
    #region [IObjectSafety implementation]
    publiclong GetInterfaceSafetyOptions(refGuid iid outint pdwSupportedOptions outint pdwEnabledOptions)
    {
    pdwSupportedOptions = (int)m_options;
    pdwEnabledOptions = (int)m_options;
    return ;
    }
    publiclong SetInterfaceSafetyOptions(refGuid iid int dwOptionSetMask int dwEnabledOptions)
    {
    return ;
    }
    #endregion
    };
    }
    並實現以下兩個方法:
    #region Implementation of IObjectSafety
    privateObjectSafetyOptions m_options =
    ObjectSafetyOptionsINTERFACESAFE_FOR_UNTRUSTED_CALLER |
    ObjectSafetyOptionsINTERFACESAFE_FOR_UNTRUSTED_DATA;
    publiclong GetInterfaceSafetyOptions(refGuid iid outint pdwSupportedOptions outint pdwEnabledOptions)
    {
    pdwSupportedOptions = (int)m_options;
    pdwEnabledOptions = (int)m_options;
    return ;
    }
    publiclong SetInterfaceSafetyOptions(refGuid iid int dwOptionSetMask int dwEnabledOptions)
    {
    return ;
    }
    #endregion


From:http://tw.wingwit.com/Article/program/net/201311/13191.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.