Saltar al contenido principal
Algunos de los objetos de ABBYY FineReader Engine son los llamados “objetos conectables”. Esto significa que implementan la interfaz IConnectionPointContainer. Los objetos conectables permiten la comunicación entre ABBYY FineReader Engine y sus clientes.
En Linux , el objeto Engine cargado como servidor fuera de proceso no admite el uso de callbacks.
Para los usuarios de Windows, cada uno de los objetos conectables de FRE proporciona puntos de conexión de dos tipos: uno que usa una interfaz dispatch y otro que usa la interfaz derivada de IUnknown. La interfaz dispatch está diseñada para su uso automático en Visual Basic y entornos similares, mientras que la interfaz basada en vtbl es adecuada para su uso en C++.
En la tabla siguiente, puede encontrar la lista de objetos conectables de ABBYY FineReader Engine y las interfaces de callback correspondientes (dispinterfaces):
Las dispinterfaces son específicas de Windows.
ObjetoInterfaz de callback (dispinterface)
FRDocumentIFRDocumentEvents (DIFRDocumentEvents)
FRPagesIFRPagesEvents (DIFRPagesEvents)
FRPageIFRPageEvents (DIFRPageEvents)
ImageDocumentIImageDocumentEvents (DIImageDocumentEvents)
Visual Components de Windows La aplicación cliente de ABBYY FineReader Engine que quiera recibir notificaciones de determinados eventos en ABBYY FineReader Engine debe implementar interfaces de un tipo específico y advise a los objetos que implementan estas interfaces a los objetos conectables correspondientes.
Hay dos métodos globales que se usan para conectarse y desconectarse del origen de notificaciones:
HRESULT AdviseFREngineObject( IUnknown* object, IUnknown* callback, DWORD* cookie );
HRESULT UnAdviseFREngineObject( IUnknown* object, DWORD cookie );
class CFRDocumentCallback: public IFRDocumentEvents {
public:
...
    // Proporciona una implementación sencilla de los métodos de IUnknown
    ULONG STDMETHODCALLTYPE AddRef() { return 1; }
    ULONG STDMETHODCALLTYPE Release() { return 1; }
    HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void** ppObject )
    {
        if( ppObject == 0 ) {
            return E_POINTER;
        }
    *ppObject = 0;
    if( riid == IID_IUnknown || riid == IID_IFRDocumentEvents )
    {
        *ppObject = this;
        AddRef();
        return S_OK;
    } else {
        return E_NOINTERFACE;
    }
}
// Proporciona una implementación de los métodos de IFRDocumentEvents
HRESULT STDMETHODCALLTYPE OnProgress(
IFRDocument* sender, int percentage, VARIANT_BOOL* cancel );
HRESULT STDMETHODCALLTYPE OnWarning(
IFRDocument* sender, int index, BSTR tip, VARIANT_BOOL* cancel );
HRESULT STDMETHODCALLTYPE OnPageProcessed(
    IFRDocument* sender, int index, PageProcessingStageEnum stage ) { return S_OK; }
};
// Supongamos que ya hemos recibido el objeto FRDocument
IFRDocument* document;
// Crear el objeto callback
CFRDocumentCallback callbackObject;
// Registrar el listener en el origen de notificaciones
DWORD cookie; // Variable para almacenar la cookie devuelta por el método Advise
AdviseFREngineObject( frDocument, &callbackObject, &cookie );
// Procesar el documento
...
// Después de la notificación, el listener ya no es necesario y se debe anular su registro
UnadviseFREngineObject( frDocument, cookie );
Estos métodos deben recibir uno de los objetos conectables como argumento object y la interfaz de callback correspondiente como argumento callback.Debe implementar la interfaz necesaria y “advise” el objeto que implementa la interfaz en los objetos conectables correspondientes. Usaremos el objeto FRDocument como ejemplo.
  1. Implemente la interfaz IFRDocumentEvents. Como deriva de la interfaz IUnknown, el objeto cliente también debe implementar los métodos de IUnknown:
  2. Después, la clase CFRDocumentCallback puede usarse para recibir notificaciones del objeto FRDocument. Advise este objeto en el origen de notificaciones (se omite el control de errores):
Los usuarios de Linux también pueden consultar el ejemplo EventsHandling.
El resto de este tema se aplica a los usuarios de FRE para Windows.
Para Windows:
Simplemente declare el objeto conectable con WithEvents e implemente los métodos de la interfaz de callback correspondiente. También deberá especificar explícitamente el controlador de eventos asociado al evento.Para el objeto FRDocument, el procedimiento será el siguiente:
  1. Declare el objeto FRDocument con WithEvents:
Private WithEvents document As FREngine.FRDocument
Private Sub document_RecognitionOnProgress(ByVal sender As FREngine.FRDocument, _
                                           ByVal Percentage As Integer, _
                                           ByRef cancel As Boolean)
...
End Sub
Private Sub document_RecognitionOnProgress(ByVal sender As FREngine.FRDocument, _
                                           ByVal Percentage As Integer, _
                                           ByRef cancel As Boolean) Handles document.OnProgress
...
End Sub
document = Engine.CreateFRDocument
document.AddImageFile("D:\Demo.tif")
AddHandler document.OnProgress, AddressOf Me.document_RecognitionOnProgress
document.Process()
RemoveHandler document.OnProgress, AddressOf Me.document_RecognitionOnProgress
o simplemente use el objeto FRDocument para el procesamiento si define los métodos de control de eventos con la palabra clave Handles:
document = Engine.CreateFRDocument
document.AddImageFile("D:\Demo.tif")
document.Process()
  1. Implemente los métodos necesarios de la dispinterface DIFRDocumentEvents en el Sub, de forma similar al siguiente.
Si desea iniciar y detener el control de eventos en cualquier momento durante la ejecución del programa (mediante las instrucciones AddHandler y RemoveHandler):o simplemente especifique que este procedimiento controla un evento determinado (use la palabra clave Handles al definirlo):
  1. Conecte el controlador de eventos implementado al origen del evento, use el objeto FRDocument para el procesamiento y, a continuación, desconecte el controlador:
En C++, debe implementar la interfaz necesaria, obtener un punto de conexión y hacer “advise” del objeto que implementa la interfaz a los objetos conectables correspondientes. Usaremos el objeto FRDocument como ejemplo.
  1. Implemente la interfaz IFRDocumentEvents. Como deriva de la interfaz IUnknown, el objeto cliente también debe implementar los métodos de IUnknown:
class CFRDocumentEventsListener : public IFRDocumentEvents {
public:
...
    // Proporciona una implementación sencilla de los métodos de IUnknown. También pueden
    // implementarse mediante herencia de alguna clase estándar con compatibilidad COM
    ULONG AddRef();
    ULONG Release();
    HRESULT QueryInterface(REFIID riid, void** ppvObject)
    {
        if( ppvObject == 0 )
            return E_INVALIDARG;
        if( riid == __uuidof(IFRDocumentEvents) ) {
            *ppvObject = static_cast<IFRDocumentEvents*>( this );
        } else if( riid == IID_IUnknown ) {
            *ppvObject = static_cast<IUnknown*>( this );
        } else {
            *ppvObject = 0;
            return E_NOINTERFACE;
        }
        AddRef();
        return S_OK;
    }
    // Proporciona la implementación de los métodos de IFRDocumentEvents
 HRESULT STDMETHODCALLTYPE OnProgress(
  IFRDocument* sender, int percentage, VARIANT_BOOL* cancel );
 HRESULT STDMETHODCALLTYPE OnWarning(
  IFRDocument* sender, int index, BSTR tip, VARIANT_BOOL* cancel );
 HRESULT STDMETHODCALLTYPE OnPageProcessed(
  IFRDocument* sender, int index, PageProcessingStageEnum stage ) { return S_OK; }
};
// Supongamos que ya hemos obtenido el objeto FRDocument
IFRDocument* document;
// Consultar IConnectionPointContainer en el objeto FRDocument
IConnectionPointContainer* pContainer=0;
document->QueryInterface(IID_IConnectionPointContainer, (void**)&pContainer);
// Obtener un puntero a la interfaz IConnectionPoint en un punto de conexión dentro del objeto conectable
IConnectionPoint* pPoint=0;
pContainer->FindConnectionPoint(__uuidof(IFRDocumentEvents),
                                &pPoint);
// Establecer una conexión entre la clase CFRDocumentEventsListener y el punto de conexión
CFRDocumentEventsListener listener;
IUnknown* listenerUnknown=0;
listener.QueryInterface(IID_IUnknown, (void**)&listenerUnknown);
// Hacer advise del listener al origen de las notificaciones
DWORD cookie; // Variable para almacenar la cookie devuelta por el método IConnectionPoint::Advise
pPoint->Advise(listenerUnknown, &cookie);
// Procesar el documento
...
// Después de la notificación, el listener deja de ser necesario y se debe hacer unadvise
pPoint->Unadvise(cookie);
  1. A continuación, la clase CFRDocumentEventsListener puede usarse para recibir notificaciones del objeto FRDocument. Haga advise de este objeto al origen de las notificaciones (se omite el control de errores):
El procedimiento en C# es similar al de Visual Basic .NET. Debe implementar los métodos necesarios de la interfaz de callback y conectar los controladores de eventos implementados al origen del evento. Usaremos el objeto FRDocument como ejemplo.
  1. Implemente los métodos necesarios de la interfaz IFRDocumentEvents:
private void document_RecognitionOnProgress(FREngine.IFRDocument sender, int Percentage, ref bool cancel)
{
 ...
}
FREngine.DIFRDocumentEvents_OnProgressEventHandler recognizeOnProgressHandler =
 new FREngine.DIFRDocumentEvents_OnProgressEventHandler(
 document_RecognitionOnProgress );
document.OnProgress += recognizeOnProgressHandler;
document.Process( null, null, null );
document.OnProgress -= recognizeOnProgressHandler;
  1. Conecte el controlador de eventos al origen del evento, use el objeto FRDocument para el procesamiento y, a continuación, desconecte el controlador:
Los usuarios de Windows deben consultar la documentación sobre COM para obtener una descripción más detallada de los objetos conectables. También puede consultar el ejemplo EventsHandling incluido en FRE para Linux para C++ y en Windows para C#, C++ con Native COM Support, raw C++ y Visual Basic .NET.