古詩詞大全網 - 個性簽名 - C#構建帶事件的簽名ActiveX組件

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

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

第壹步 創建ActiveX項目

使用.NET語言編寫的ActiveX控件的主體就是壹個類庫,首先我們來創建這個類庫項目。打開Visual Studio 2008,File-New-Project,選擇Class Library,創建壹個類庫項目。

創建ActiveX項目

第二步 編寫ActiveX主體

ActiveX的主體包括方法定義接口、事件定義接口(可選)、實現這些接口的ActiveX主體類三個部分。下面是筆者原創的Demo。

首先,我們創建方法定義接口:

///summary

/// 該接口定義了ActiveX的方法

////summary

[

Guid("F3BD342F-14E1-4347-BFBD-F449DD070DF9"),

InterfaceType(ComInterfaceType.InterfaceIsDual),

ComVisible(true)]

publicinterfaceIBosnMaActiveX

{

[DispId(1)]

void Start();

[DispId(2)]

void Stop();

}

該接口內的成員會暴露給外部調用。這裏我們提供兩個簡單方法Start和Stop。使用工具(Visual Studio - Tools - Create GUID)生成自己的GUID。

接下來定義事件接口:

///summary

/// 該接口定義了ActiveX的事件

////summary

[ComVisible(true)]

[Guid("C4F9F24F-B860-4e79-945D-B9A281950C82")]

[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]

publicinterfaceBosnMaActiveXEvents

{

[DispId(21)]

void OnRecorderStarted();

[DispId(22)]

void OnRecorderStopped();

[DispId(23)]

void OnRecorderVolumeChanged(int value);

}

這裏我們為ActiveX定義三個事件,分別為OnRecorderStarted、OnRecorderStopped 、OnRecorderVolumeChanged(帶壹個int參數)。

最後我們編寫集成方法接口和事件接口的ActiveX主體類:

[

Guid("78E683CE-EC77-40b0-B0C3-4060FFC70A93"),

ProgId("ActiveXOfBosnMa.BosnMaActiveX"),

ClassInterface(ClassInterfaceType.None),

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事件,並在3秒後引發OnRecorderVolumeChanged

////summary

publicvoid Start()

{

OnRecorderStarted();

SimpleHandler d = Work;

d.BeginInvoke(null, null);

}

publicvoid Work()

{

Thread.Sleep(3000);

OnRecorderVolumeChanged(53);

}

///summary

/// 調用該方法將引發OnRecorderStopped事件

////summary

publicvoid Stop()

{

OnRecorderStopped();

}

#endregion

}

這裏要註意主體類的事件名稱要與事件接口(在上例中為BosnMaActiveXEvents)中的方法名相同。在BosnAcX中我們實現了IBosnMaActiveX中的方法,當調用Start()時引發壹個OnRecorderStarted事件,並在3秒後引發壹個OnRecorderVolumeChanged事件,在調用Stop()時引發壹個OnRecorderStopped事件。

編譯並註冊ActiveX

編譯整個項目將輸出dll。

然後我們啟動命令行CMD(如果是Vista/Win7使用管理員方式打開),使用以下命令註冊控件.

C:D: //轉到.dll所在目錄,筆者為了方便將.dll copy到了D盤根目錄

D:regasm activexofbosnma.dll /codebase /tlb

*regasm命令在%systemroot%Microsoft.NETFrameworkv2.x.xxxx目錄下,將該目錄註冊到用戶環境變量中即可不使用完全限定名運行該命令。

*使用regasm activexofbosnma.dll /codebase /tlb /unregister可以反註冊,在ActiveX代碼變更時重編譯後,需要先反註冊再註冊。

測試ActiveX

最後我們創建壹個html頁面來測試該ActiveX.

html

headrunat="server"

title/title

objectid="myAcX"name="myAcX"classid="clsid:78E683CE-EC77-40b0-B0C3-4060FFC70A93"

/object

scriptlanguage="javascript"for="myAcX"type="text/javascript"event="OnRecorderVolumeChanged(v);"

MyDiv.innerHTML = 'In javascript: Get Volume:'+v;

/script

scriptlanguage="javascript"for="myAcX"type="text/javascript"event="OnRecorderStarted"

MyDiv.innerHTML = 'In javascript: OnRecorderStarted';

/script

scriptlanguage="javascript"for="myAcX"type="text/javascript"event="OnRecorderStopped"

MyDiv.innerHTML = 'In javascript: OnRecorderStopped';

/script

/head

body

form

scriptlanguage="javascript"type="text/jscript"

function Button1_onclick() {

myAcX.Start();

}

function Button2_onclick() {

myAcX.Stop();

}

function RecorderVolumeChanged(v) {

alert('volume:' + v);

}

/script

divid="MyDiv"Nothing happened/div

p

inputid="Button1"type="button"value="Start"onclick="Button1_onclick()"/nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;

inputid="Button2"type="button"value="Stop"onclick="Button2_onclick()"//p

/form

/body

/html

測試效果

首先使用IE打開測試頁面

允許ActiveX交互後進入主界面,點擊Start按鈕會收到ActiveX返回的OnRecorderStarted事件。

三秒過後收到Volume事件

最後點擊Stop按鈕會收到OnRecorderStopped事件。

安全性

為了標記ActiveX控件為安全的(避免彈出“該控件是不安全的”警告),需要實現IObjectSafety接口。

using System;

using System.Collections.Generic;

using System.Runtime.InteropServices;

using System.ComponentModel;

using System.Text;

namespace ActiveXOfBosnMa

{

[

Serializable,

ComVisible(true)

]

publicenumObjectSafetyOptions

{

INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001,

INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002,

INTERFACE_USES_DISPEX = 0x00000004,

INTERFACE_USES_SECURITY_MANAGER = 0x00000008

};

//

// MS IObjectSafety Interface definition

//

[

ComImport(),

Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"),

InterfaceType(ComInterfaceType.InterfaceIsIUnknown)

]

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 won't complain about the

// ActiveX object not being safe

//

publicclassIObjectSafetyImpl : IObjectSafety

{

privateObjectSafetyOptions m_options =

ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER |

ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;

#region [IObjectSafety implementation]

publiclong GetInterfaceSafetyOptions(refGuid iid, outint pdwSupportedOptions, outint pdwEnabledOptions)

{

pdwSupportedOptions = (int)m_options;

pdwEnabledOptions = (int)m_options;

return 0;

}

publiclong SetInterfaceSafetyOptions(refGuid iid, int dwOptionSetMask, int dwEnabledOptions)

{

return 0;

}

#endregion

};

}

並實現以下兩個方法:

#region Implementation of IObjectSafety

privateObjectSafetyOptions m_options =

ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER |

ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;

publiclong GetInterfaceSafetyOptions(refGuid iid, outint pdwSupportedOptions, outint pdwEnabledOptions)

{

pdwSupportedOptions = (int)m_options;

pdwEnabledOptions = (int)m_options;

return 0;

}

publiclong SetInterfaceSafetyOptions(refGuid iid, int dwOptionSetMask, int dwEnabledOptions)

{

return 0;

}

#endregion