Re: Отловить событие OLE-объекта
От: Alex  
Дата: 22.03.04 23:21
Оценка:
Так же легко как в VB не получится. Нужно реализовать твой диспинтерфейс, примерно так (на работоспособность не проверял):



//хидер
#include <atl/atlbase.h>

class PACKAGE TMyEvents : public IMyEvents
{
private:
    LPUNKNOWN* server;
    DWORD Cookie;
public:
    __fastcall TMyEvents(), server(0){};
    __fastcall ~TMyEvents();
  // IUnknown
    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject);
    ULONG   STDMETHODCALLTYPE AddRef();
    ULONG   STDMETHODCALLTYPE Release();
  // IDispatch
    HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctInfo);
    HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT, LCID, ITypeInfo** ppTypeInfo);
    HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, LPOLESTR*, UINT, LCID, DISPID*);
    HRESULT STDMETHODCALLTYPE Invoke(DISPID dispid, REFIID iid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                                     VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgError);
    void __fastcall Connect(LPUNKNOWN _server);
    void __fastcall Disconnect();
};


//зеализация
__fastcall TMyEvents::~TMyEvents()
{
  Disconnect();
}

HRESULT STDMETHODCALLTYPE TMyEvents::QueryInterface(REFIID iid, void **ppvObject)
{
  *ppvObject = 0;
  if (iid == IID_IUnknown || iid == IID_IDispatch || iid == DIID_MyEvents){
    *ppvObject = this;
  }else
    return E_NOINTERFACE;
  return S_OK;
}

ULONG STDMETHODCALLTYPE TMyEvents::AddRef()
{
  return 2;//при желании можно сделать счётчик, но в принципе он сдесь не нужен
}

ULONG STDMETHODCALLTYPE TMyEvents::Release()
{
  return 1;//при желании можно сделать счётчик, но в принципе он сдесь не нужен
}

HRESULT STDMETHODCALLTYPE TMyEvents::GetTypeInfoCount(UINT* pctInfo)
{
  *pctInfo = 0;
  return S_OK;
}

HRESULT STDMETHODCALLTYPE TMyEvents::GetTypeInfo(UINT, LCID, ITypeInfo** ppTypeInfo)
{
  *ppTypeInfo = 0;
  return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE TMyEvents::GetIDsOfNames(REFIID, LPOLESTR*, UINT, LCID, DISPID*)
{
  return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE TMyEvents::Invoke(DISPID dispid, REFIID iid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgError)
{
  switch(dispid)
  {
    case 1://надо знать идентификатор твоего события
      ShowMessage("твоё событие пришло");
      break;
  }
  return S_OK;
}

void __fastcall TMyEvents::Connect(_server)
{
  if (server)
    Disconnect();
  server=_server;
  if (!server)
    return;
  server->AddRef();
  CComPtr<IConnectionPointContainer> icpc;
  if (SUCCEEDED(server->QueryInterface(IID_IConnectionPointContainer, (void**)&icpc)))
  {
    CComPtr<IConnectionPoint> icp;
    if (SUCCEEDED(icpc->FindConnectionPoint(Events_ID, &icp)))
      icp->Advise(this, &Cookie);
  }
}

void __fastcall TMyEvents::Disconnect()
{
  if (!server)
    return;
  CComPtr<IConnectionPointContainer> icpc;
  if (SUCCEEDED(server->QueryInterface(IID_IConnectionPointContainer, (void**)&icpc)))
  {
    CComPtr<IConnectionPoint> icp;
    if (SUCCEEDED(icpc->FindConnectionPoint(Events_ID, &icp)))
      icp->Unadvise(Cookie);
  }
  server->Release();
  server=0;
}

//используем так
TMyEvents MyEvents;
MyEvents.Connect(MyObject);//после этого события ловятся
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.