Имеется некий OLE-объект.
MyObject = CreateOleObject("XXX.XXX");
Этот объект имееет событие OnDataChange(...).
Может, для кого-нибудь это покажется элементарным, но как отловить это событие в своей программе?
И одна большая просьба, пусть пример кода будет на Builder'е. На VB для Excel я это уже видел, а на Си подобное не получится.
Так же легко как в 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);//после этого события ловятся
Во-первых, компильнуть этот пример у меня не получилось — несколько ошибок (не настолько уж я силен в Builder'е).
А во-вторых, событие с параметрами. Как их достать? Через
DISPPARAMS *pDispParams
?
Может, все-таки, есть пример по-проще?
Здравствуйте, L0N6, Вы писали:
LN>Во-первых, компильнуть этот пример у меня не получилось — несколько ошибок (не настолько уж я силен в Builder'е).
LN>А во-вторых, событие с параметрами. Как их достать? Через DISPPARAMS *pDispParams
?
LN>Может, все-таки, есть пример по-проще?
Чтобы сделать попроще надо использовать оболочки (например, TEventDispatcher), а этот пример демонстрирует как это делается.
Работоспособный пример (архив)
здесь.
Здравствуйте, Alex, Вы писали:
A>Чтобы сделать попроще надо использовать оболочки (например, TEventDispatcher), а этот пример демонстрирует как это делается.
A>Работоспособный пример (архив) здесь.
Огромное спасибо за пример, все заработало.
З.Ы. У меня получилось, что параметры, передаваемые вместе с событием, идут в обратном порядке. Это правильно?