Zum Hauptinhalt springen
Einige der Objekte in ABBYY FineReader Engine sind sogenannte „verknüpfbare Objekte“. Das bedeutet, dass sie die Schnittstelle IConnectionPointContainer implementieren. Verknüpfbare Objekte unterstützen die Kommunikation zwischen ABBYY FineReader Engine und seinen Clientanwendungen.
Unter Linux unterstützt das als Out-of-Process-Server geladene Engine-Objekt die Arbeit mit Callbacks nicht.
Für Windows-Benutzer stellt jedes der verknüpfbaren FRE-Objekte Verbindungspunkte von zwei Typen bereit — einen mit einer Dispatch-Schnittstelle und einen mit einer von IUnknown abgeleiteten Schnittstelle. Die Dispatch-Schnittstelle ist für die automatische Verwendung in Visual Basic und ähnlichen Umgebungen vorgesehen, während die vtbl-basierte Schnittstelle für den Einsatz in C++ geeignet ist.
In der folgenden Tabelle finden Sie die Liste der verknüpfbaren Objekte in ABBYY FineReader Engine und die entsprechenden Callback-Schnittstellen (Dispinterfaces):
Dispinterfaces sind Windows-spezifisch.
ObjektCallback-Schnittstelle (Dispinterface)
FRDocumentIFRDocumentEvents (DIFRDocumentEvents)
FRPagesIFRPagesEvents (DIFRPagesEvents)
FRPageIFRPageEvents (DIFRPageEvents)
ImageDocumentIImageDocumentEvents (DIImageDocumentEvents)
Windows Visual Components Eine ABBYY FineReader Engine-Clientanwendung, die Benachrichtigungen über bestimmte Ereignisse in ABBYY FineReader Engine erhalten möchte, sollte Schnittstellen eines bestimmten Typs implementieren und die Objekte, die diese Schnittstellen implementieren, bei den entsprechenden verknüpfbaren Objekten „advise“.
Es gibt zwei globale Methoden zum Verbinden und Trennen der Verbindung mit der Benachrichtigungsquelle:
HRESULT AdviseFREngineObject( IUnknown* object, IUnknown* callback, DWORD* cookie );
HRESULT UnAdviseFREngineObject( IUnknown* object, DWORD cookie );
class CFRDocumentCallback: public IFRDocumentEvents {
public:
...
    // Einfache Implementierung der IUnknown-Methoden bereitstellen
    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;
    }
}
// Implementierung der IFRDocumentEvents-Methoden bereitstellen
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; }
};
// Annahme: Das FRDocument-Objekt wurde bereits empfangen
IFRDocument* document;
// Callback-Objekt erstellen
CFRDocumentCallback callbackObject;
// Listener mit der Benachrichtigungsquelle verbinden
DWORD cookie; // Eine Variable zum Speichern des vom Advise-Aufruf zurückgegebenen Cookies
AdviseFREngineObject( frDocument, &callbackObject, &cookie );
// Dokument verarbeiten
...
// Nach der Benachrichtigung wird der Listener nicht mehr benötigt und sollte abgemeldet werden
UnadviseFREngineObject( frDocument, cookie );
Diese Methoden erwarten eines der verknüpfbaren Objekte als object-Argument und die entsprechende Callback-Schnittstelle als callback-Argument.Sie müssen die erforderliche Schnittstelle implementieren und das die Schnittstelle implementierende Objekt bei den entsprechenden verknüpfbaren Objekten „registrieren”. Als Beispiel verwenden wir das FRDocument-Objekt.
  1. Implementieren Sie die IFRDocumentEvents-Schnittstelle. Da sie von der IUnknown-Schnittstelle abgeleitet ist, muss das Client-Objekt auch die IUnknown-Methoden implementieren:
  2. Anschließend kann die CFRDocumentCallback-Klasse verwendet werden, um Benachrichtigungen vom FRDocument-Objekt zu empfangen. Registrieren Sie dieses Objekt bei der Benachrichtigungsquelle (Fehlerbehandlung wird der Übersichtlichkeit halber weggelassen):
Linux-Benutzer können auch das Beispiel EventsHandling zu Rate ziehen.
Der Rest dieses Themas gilt für Benutzer von FRE für Windows.
Für Windows:
Deklarieren Sie das verknüpfbare Objekt einfach mit WithEvents und implementieren Sie die Methoden der entsprechenden Callback-Schnittstelle. Außerdem müssen Sie den dem Ereignis zugeordneten Ereignishandler explizit angeben.Für das FRDocument-Objekt ist die Vorgehensweise wie folgt:
  1. Deklarieren Sie das FRDocument-Objekt mit 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
or simply use the FRDocument object for processing if you define the event handling methods with Handles keyword:
document = Engine.CreateFRDocument
document.AddImageFile("D:\Demo.tif")
document.Process()
  1. Implementieren Sie die erforderlichen Methoden der DIFRDocumentEvents-Dispatch-Schnittstelle in einer Sub ähnlich der folgenden.
Wenn Sie die Ereignisbehandlung zu einem beliebigen Zeitpunkt während der Programmausführung starten und beenden möchten (mithilfe der Anweisungen AddHandler und RemoveHandler):oder geben Sie einfach an, dass diese Prozedur ein bestimmtes Ereignis behandelt (verwenden Sie das Schlüsselwort Handles bei der Definition):
  1. Verbinden Sie den implementierten Ereignishandler mit der Ereignisquelle, verwenden Sie das FRDocument-Objekt zur Verarbeitung, und trennen Sie anschließend den Handler:
In C++ müssen Sie die erforderliche Schnittstelle implementieren, einen Verbindungspunkt abrufen und das Objekt, das die Schnittstelle implementiert, bei den entsprechenden verknüpfbaren Objekten registrieren („advise“). Wir verwenden das FRDocument-Objekt als Beispiel.
  1. Implementieren Sie die Schnittstelle IFRDocumentEvents. Da sie von der Schnittstelle IUnknown abgeleitet ist, sollte das Client-Objekt auch die IUnknown-Methoden implementieren:
class CFRDocumentEventsListener : public IFRDocumentEvents {
public:
...
    // Einfache Implementierung der IUnknown-Methoden bereitstellen. Sie können auch
    // durch Vererbung von einer Standardklasse mit COM-Unterstützung implementiert werden
    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;
    }
    // Implementierung der IFRDocumentEvents-Methoden bereitstellen
 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; }
};
// Angenommen, wir haben das FRDocument-Objekt bereits erhalten
IFRDocument* document;
// IConnectionPointContainer für das FRDocument-Objekt abfragen
IConnectionPointContainer* pContainer=0;
document->QueryInterface(IID_IConnectionPointContainer, (void**)&pContainer);
// Einen Zeiger auf die Schnittstelle IConnectionPoint an einem Verbindungspunkt innerhalb des verknüpfbaren Objekts abrufen
IConnectionPoint* pPoint=0;
pContainer->FindConnectionPoint(__uuidof(IFRDocumentEvents),
                                &pPoint);
// Eine Verbindung zwischen der Klasse CFRDocumentEventsListener und dem Verbindungspunkt herstellen
CFRDocumentEventsListener listener;
IUnknown* listenerUnknown=0;
listener.QueryInterface(IID_IUnknown, (void**)&listenerUnknown);
// Listener bei der Benachrichtigungsquelle registrieren
DWORD cookie; // Eine Variable zum Speichern des von der Methode IConnectionPoint::Advise zurückgegebenen Cookie-Werts
pPoint->Advise(listenerUnknown, &cookie);
// Das Dokument verarbeiten
...
// Nach der Benachrichtigung wird der Listener nicht mehr benötigt und sollte deregistriert werden
pPoint->Unadvise(cookie);
  1. Die Klasse CFRDocumentEventsListener kann dann verwendet werden, um Benachrichtigungen vom FRDocument-Objekt zu empfangen. Registrieren Sie dieses Objekt bei der Benachrichtigungsquelle (die Fehlerbehandlung ist ausgelassen):
Das Verfahren in C# ist ähnlich wie in Visual Basic .NET. Sie müssen die erforderlichen Methoden der Callback-Schnittstelle implementieren und die implementierten Ereignishandler mit der Ereignisquelle verbinden. Wir verwenden das FRDocument-Objekt als Beispiel.
  1. Implementieren Sie die erforderlichen Methoden der Schnittstelle 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. Verbinden Sie den Ereignishandler mit der Ereignisquelle, verwenden Sie das FRDocument-Objekt für die Verarbeitung und trennen Sie den Handler anschließend wieder:
Windows-Benutzer sollten die COM-Dokumentation konsultieren, um eine ausführlichere Beschreibung verknüpfbarer Objekte zu erhalten. Sie können auch das Beispiel EventsHandling verwenden, das in FRE für Linux für C++ sowie für Windows für C#, C++ mit Native COM Support, Raw C++ und Visual Basic .NET bereitgestellt wird.