当前位置:  开发笔记 > 后端 > 正文

向我的COM对象的VBScript用户公开事件处理程序

如何解决《向我的COM对象的VBScript用户公开事件处理程序》经验,为你挑选了1个好方法。

假设我有一个COM对象,用户可以通过以下呼叫访问:

Set s = CreateObject("Server")

我希望能够做的是允许用户为对象指定事件处理程序,如下所示:

Function ServerEvent

   MsgBox "Event handled"

End Function

s.OnDoSomething = ServerEvent

这是可能的,如果是这样,我如何在我的C++类型库(特别是BCB 2007)中公开它?



1> Jeff Hillman..:

这就是我最近才做到的.添加一个实现IDispatch的接口和该接口的coclass到您的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,
    public CComCoClass,
    public IDispatchImpl,
    public IConnectionPointContainerImpl,
    public IConnectionPointImpl
{
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 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

我希望这有帮助.

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有