Выставьте обработчик событий пользователям VBScript моего COM-объекта

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
8
задан GEOCHET 25 June 2009 в 23:19
поделиться

3 ответа

Это - то, как я сделал это просто недавно. Добавьте интерфейс, который реализует 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<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

Я надеюсь, что это помогает.

5
ответ дан 5 December 2019 в 20:20
поделиться

Я закончил после техники, описанной здесь.

1
ответ дан 5 December 2019 в 20:20
поделиться

Я являюсь немного туманным в деталях, но возможно ссылка ниже могла бы помочь:

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

Похоже, что Ваш серверный объект должен реализовать IProvideClassInfo и затем Вы звоните ConnectObject в Вашем коде VBScript.См. также:

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

2
ответ дан 5 December 2019 в 20:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: