2008-09-14 23 views
8

假設我有哪些用戶可以通過調用訪問諸如COM對象:揭露的事件處理程序,以我的COM對象的VBScript的用戶

Set s = CreateObject("Server") 

我想什麼,能夠做的就是讓用戶指定的事件處理程序的對象,像這樣:

Function ServerEvent 

    MsgBox "Event handled" 

End Function 

s.OnDoSomething = ServerEvent 

這是可能的,如果是這樣,我怎麼在我的類型庫用C使本++(特別是BCB 2007)?

回答

5

這是我做到了剛剛結束。補充一點,實現IDispatch和組件類爲接口的IDL接口:

[ 
    object, 
    uuid(6EDA5438-0915-4183-841D-D3F0AEDFA466), 
    nonextensible, 
    oleautomation, 
    pointer_default(unique) 
] 
interface IServerEvents : IDispatch 
{ 
    [id(1)] 
    HRESULT OnServerEvent(); 
} 

//... 

[ 
    uuid(FA8F24B3-1751-4D44-8258-D649B6529494), 
] 
coclass ServerEvents 
{ 
    [default] interface IServerEvents; 
    [default, source] dispinterface IServerEvents; 
}; 

這是CServerEvents類的聲明:

class ATL_NO_VTABLE CServerEvents : 
    public CComObjectRootEx<CComSingleThreadModel>, 
    public CComCoClass<CServerEvents, &CLSID_ServerEvents>, 
    public IDispatchImpl<IServerEvents, &IID_IServerEvents , &LIBID_YourLibrary, -1, -1>, 
    public IConnectionPointContainerImpl<CServerEvents>, 
    public IConnectionPointImpl<CServerEvents,&__uuidof(IServerEvents)> 
{ 
public: 
    CServerEvents() 
    { 
    } 

    // ... 

BEGIN_COM_MAP(CServerEvents) 
    COM_INTERFACE_ENTRY(IServerEvents) 
    COM_INTERFACE_ENTRY(IDispatch) 
    COM_INTERFACE_ENTRY(IConnectionPointContainer) 
END_COM_MAP() 

BEGIN_CONNECTION_POINT_MAP(CServerEvents) 
    CONNECTION_POINT_ENTRY(__uuidof(IServerEvents)) 
END_CONNECTION_POINT_MAP() 

    // .. 

    // IServerEvents 
    STDMETHOD(OnServerEvent)(); 

private: 
    CRITICAL_SECTION m_csLock;   
}; 

這裏的關鍵是IConnectionPointImpl和IConnectionPointContainerImpl實施接口和連接點映射。該OnServerEvent方法的定義是這樣的:

STDMETHODIMP CServerEvents::OnServerEvent() 
{ 
    ::EnterCriticalSection(&m_csLock); 

    IUnknown* pUnknown; 

    for (unsigned i = 0; (pUnknown = m_vec.GetAt(i)) != NULL; ++i) 
    {  
     CComPtr<IDispatch> spDisp; 
     pUnknown->QueryInterface(&spDisp); 

     if (spDisp) 
     { 
      spDisp.Invoke0(CComBSTR(L"OnServerEvent")); 
     } 
    } 

    ::LeaveCriticalSection(&m_csLock); 

    return S_OK; 
} 

您需要爲您提供客戶指定的處理程序爲您的活動方式。你可以使用諸如「SetHandler」之類的專用方法來做到這一點,但我更喜歡使處理器成爲異步調用方法的參數。通過這種方式,用戶只需要調用一個方法:

STDMETHOD(DoSomethingAsynchronous)(IServerEvents *pCallback); 

商店的指針IServerEvents,然後當你要解僱你的事件,只要調用方法:

m_pCallback->OnServerEvent(); 

至於VB代碼,處理事件的語法與你所建議的有些不同:

Private m_server As Server 
Private WithEvents m_serverEvents As ServerEvents 

Private Sub MainMethod() 
    Set s = CreateObject("Server") 
    Set m_serverEvents = New ServerEvents 

    Call m_searchService.DoSomethingAsynchronous(m_serverEvents) 
End Sub 

Private Sub m_serverEvents_OnServerEvent() 
    MsgBox "Event handled" 
End Sub 

我希望這有助於。

+1

您提供的代碼是VB語法,而不是VBScript。 「As」關鍵字和「WithEvents」在VBScript中不可用。 – 2008-09-15 00:53:16

+0

@ 1800 INFORMATION, 你是對的。我已經使用了VB和VBScript,但是我已經使用VBScript做了很長時間了。我忘記了或沒有意識到這種特殊的差別。 – 2008-09-15 10:32:30

2

我最終按照描述的技術here

相關問題