Working with Connectable Objects (COM-based API)
The Client object in the ABBYY FineReader Server Open API is a so-called "connectable object". This means that it implements the IConnectionPointContainer interface. A connectable object ensures communication between the Open API and its clients.
This connectable object provides connection points of two types — one that uses a dispatch interface, and one that uses an interface derived from IUnknown. The dispatch interface is designed for automatic use in Visual Basic and similar environments, while the vtbl-based interface is suitable for use in C++.
An Open API client application that needs to receive notifications of certain events in the Open API must implement interfaces of a specific type and "advise" objects implementing these interfaces to the corresponding connectable objects.
In Visual Basic this is done by simply declaring the object WithEvents and implementing the corresponding methods of the callback interface. The procedure for Visual Basic is described in the IClientEvents interface.
Below follows an example of connecting an object on the client side.
class CClientEventsListener : public IClientEvents {
public:
...
// Provide simple implementation of IUnknown methods. They may also be
// implemented through inheritance from some standard class with COM support
ULONG AddRef();
ULONG Release();
HRESULT QueryInterface(REFIID iid, void** ppvObject)
{
if( ppvObject == 0 )
return E_INVALIDARG;
if( riid == __uuidof(IClientEvents) ) {
*ppvObject = static_cast<IClientEvents*>( this );
} else if( riid == IID_IUnknown ) {
*ppvObject = static_cast<IUnknown*>( this );
} else {
*ppvObject = 0;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
// Provide IClientEvents method implementation
HRESULT OnJobComplete(BSTR, IXmlResult*);
};
Thus we have a CClientEventsListener class that may be used to receive notifications from the Client object. The following section of code advises this object to the notifications source (error handling is omitted):
// Suppose that we have already created the Client object
IClient* client;
IConnectionPointContainer* pContainer=0;
client->QueryInterface(IID_IConnectionPointContainer, (void**)&pContainer);
IConnectionPoint* pPoint=0;
pContainer->FindConnectionPoint(__uuidof(IClientEvents),
&pPoint);
CClientEventsListener listener;
IUnknown* listenerUnknown=0;
listener.QueryInterface(IID_IUnknown, (void**)&listenerUnknown);
// A variable to store the cookie returned from the IConnectionPoint::Advise method
DWORD cookie;
pPoint->Advise(listenerUnknown, &cookie);
...
// After notification, the listener is no longer needed and should be unadvised
pPoint->Unadvise(cookie);
Refer to documentation on COM for a more detailed description of connectable objects.
See also
26.03.2024 13:49:49