visual vbs tutorial tiempo significado script eventos español ejecucion crear church events com vbscript c++builder

events - tutorial - Exponer un controlador de eventos a los usuarios de VBScript de mi objeto COM



vbscript tutorial español (3)

Estoy un poco confuso sobre los detalles, pero tal vez el siguiente enlace podría ayudar:

http://msdn.microsoft.com/en-us/library/ms974564.aspx

Parece que su objeto de servidor necesita implementar IProvideClassInfo y luego llama a ConnectObject en su código de VBScript. Ver también:

http://blogs.msdn.com/ericlippert/archive/2005/02/15/373330.aspx

Supongamos que tengo un objeto COM al que los usuarios pueden acceder a través de una llamada como:

Set s = CreateObject("Server")

Lo que me gustaría hacer es permitir que el usuario especifique un controlador de eventos para el objeto, así:

Function ServerEvent MsgBox "Event handled" End Function s.OnDoSomething = ServerEvent

¿Es esto posible y, de ser así, cómo expongo esto en mi biblioteca de tipos en C ++ (específicamente BCB 2007)?


Así es como lo hice hace poco. Agregue una interfaz que implemente IDispatch y un coclass para esa interfaz a su 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; };

Esta es la declaración de la clase 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; };

La clave aquí es la implementación de las interfaces IConnectionPointImpl e IConnectionPointContainerImpl y el mapa del punto de conexión. La definición del método OnServerEvent se ve así:

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; }

Debe proporcionar una forma para que su cliente especifique su controlador para sus eventos. Puede hacer esto con un método dedicado como "SetHandler" o algo así, pero prefiero que el controlador sea un argumento para el método que se llama de manera asincrónica. De esta forma, el usuario solo tiene que llamar a un método:

STDMETHOD(DoSomethingAsynchronous)( IServerEvents *pCallback );

Guarde el puntero en IServerEvents y luego, cuando desee activar su evento, simplemente llame al método:

m_pCallback->OnServerEvent();

En cuanto al código VB, la sintaxis para tratar los eventos es un poco diferente de lo que sugirió:

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

Espero que esto ayude.


Terminé siguiendo la técnica descrita aquí .