メインコンテンツへスキップ
ABBYY FineReader Engine の一部のオブジェクトは、いわゆる「connectable objects」です。つまり、これらのオブジェクトは IConnectionPointContainer インターフェイスを実装しています。connectable objects は、ABBYY FineReader Engine とクライアントとの通信をサポートします。
Linux では、アウトオブプロセスサーバーとして読み込まれた Engine オブジェクトでは、コールバックを使用した処理はサポートされていません。
Windows ユーザー向けに、各 FRE connectable object では 2 種類の接続ポイントが提供されます。1 つは dispatch インターフェイスを使用するもの、もう 1 つは IUnknown から派生したインターフェイスを使用するものです。dispatch インターフェイスは Visual Basic などの環境で自動的に使用されるよう設計されており、vtbl ベースのインターフェイスは C++ での使用に適しています。
以下の表に、ABBYY FineReader Engine の connectable objects と、それぞれに対応する Callback インターフェイス (dispinterface) の一覧を示します。
dispinterface は Windows 固有です。
オブジェクトCallback インターフェイス (Dispinterface)
FRDocumentIFRDocumentEvents (DIFRDocumentEvents)
FRPagesIFRPagesEvents (DIFRPagesEvents)
FRPageIFRPageEvents (DIFRPageEvents)
ImageDocumentIImageDocumentEvents (DIImageDocumentEvents)
Windows ビジュアルコンポーネント ABBYY FineReader Engine で特定のイベント通知を受け取りたいクライアントアプリケーションは、特定の型のインターフェイスを実装し、それらのインターフェイスを実装するオブジェクトを対応する connectable objects に「advise」する必要があります。
通知ソースへの接続と切断には、2 つのグローバル メソッドを使用します。
HRESULT AdviseFREngineObject( IUnknown* object, IUnknown* callback, DWORD* cookie );
HRESULT UnAdviseFREngineObject( IUnknown* object, DWORD cookie );
class CFRDocumentCallback: public IFRDocumentEvents {
public:
...
    // 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;
    }
}
// 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; }
};
// FRDocument オブジェクトはすでに取得済みとします
IFRDocument* document;
// Callback オブジェクトを作成
CFRDocumentCallback callbackObject;
// リスナーを通知ソースに登録
DWORD cookie; // Advise メソッドから返される cookie を格納する変数
AdviseFREngineObject( frDocument, &callbackObject, &cookie );
// ドキュメントを処理
...
// 通知後はリスナーが不要になるため、登録を解除
UnadviseFREngineObject( frDocument, cookie );
これらのメソッドには、object 引数として Connectable Objects のいずれかを、callback 引数として対応する Callback インターフェイスを渡す必要があります。必要なインターフェイスを実装し、そのインターフェイスを実装したオブジェクトを、対応する Connectable Objects に対して “advise” する必要があります。ここでは、FRDocument オブジェクトを例として使用します。
  1. IFRDocumentEvents インターフェイスを実装します。これは IUnknown インターフェイスから派生しているため、クライアント オブジェクトでは IUnknown メソッドも実装する必要があります。
  2. その後、CFRDocumentCallback クラスを使用して FRDocument オブジェクトから通知を受け取ることができます。このオブジェクトを通知ソースに advise します (エラー処理は省略しています) 。
Linux ユーザーは、EventsHandling サンプルも参照できます。
このトピックの残りは、Windows 版 FRE のユーザーに適用されます。
Windows の場合:
Connectable Objects を WithEvents で宣言し、対応する Callback インターフェイスのメソッドを実装するだけです。また、イベントに関連付けるイベント ハンドラーを明示的に指定する必要もあります。FRDocument オブジェクトでは、手順は次のようになります。
  1. FRDocument オブジェクトを 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. 次の例のように、Sub 内で DIFRDocumentEvents dispinterface の必要なメソッドを実装します。
プログラムの実行中に任意のタイミングでイベント処理を開始および停止する場合 (AddHandler ステートメントと RemoveHandler ステートメントを使用) :または、このプロシージャが特定のイベントを処理することを指定します (定義時に Handles キーワードを使用) :
  1. 実装したイベント ハンドラーをイベント ソースに接続し、FRDocument オブジェクトを使用して処理を実行したら、ハンドラーを切断します。
C++ では、必要なインターフェイスを実装し、接続ポイントを取得して、そのインターフェイスを実装するオブジェクトを対応する connectable objects に「advise」する必要があります。ここでは FRDocument オブジェクトを例に説明します。
  1. IFRDocumentEvents インターフェイスを実装します。これは IUnknown インターフェイスから派生しているため、クライアントオブジェクトでは IUnknown のメソッドも実装する必要があります。
class CFRDocumentEventsListener : public IFRDocumentEvents {
public:
...
    // IUnknown メソッドの簡易実装を提供します。これらは
    // 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;
    }
    // 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; }
};
// FRDocument オブジェクトはすでに取得済みであるとします
IFRDocument* document;
// FRDocument オブジェクトに対して IConnectionPointContainer を照会します
IConnectionPointContainer* pContainer=0;
document->QueryInterface(IID_IConnectionPointContainer, (void**)&pContainer);
// connectable object 内の接続ポイントにある IConnectionPoint インターフェイスへのポインターを取得します
IConnectionPoint* pPoint=0;
pContainer->FindConnectionPoint(__uuidof(IFRDocumentEvents),
                                &pPoint);
// CFRDocumentEventsListener クラスと接続ポイントの間に接続を確立します
CFRDocumentEventsListener listener;
IUnknown* listenerUnknown=0;
listener.QueryInterface(IID_IUnknown, (void**)&listenerUnknown);
// 通知ソースに listener を advise します
DWORD cookie; // IConnectionPoint::Advise メソッドから返される cookie を格納する変数
pPoint->Advise(listenerUnknown, &cookie);
// ドキュメントを処理します
...
// 通知後は listener が不要になるため、advise を解除する必要があります
pPoint->Unadvise(cookie);
  1. その後、CFRDocumentEventsListener クラスを使用して FRDocument オブジェクトから通知を受け取ることができます。このオブジェクトを通知ソースに advise します (エラー処理は省略しています) 。
C# の手順は Visual Basic .NET の場合と似ています。コールバックインターフェイスの必要なメソッドを実装し、実装したイベントハンドラーをイベントソースに接続する必要があります。ここでは FRDocument オブジェクトを例に説明します。
  1. 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. イベントハンドラーをイベントソースに接続し、FRDocument オブジェクトで処理を実行した後、ハンドラーを切断します。
Windows ユーザーは、connectable objects の詳細について COM のドキュメントを参照してください。 Linux 版 FRE の C++ 向け、および Windows 版 FRE の C#、Native COM Support を使用する C++、raw C++、Visual Basic .NET 向けに提供されている EventsHandling サンプルも参照できます。