コネクション ポイント

ここでは、MFC クラス CCmdTargetCConnectionPoint を使用してコネクション ポイント (以前の OLE コネクション ポイント) を実装する方法について説明します。

従来の COM (コンポーネント オブジェクト モデル) では、インターフェイスにオブジェクトの機能を実装して公開する一般的な機構 (IUnknown::QueryInterface) を定義していました。 しかし、特定のインターフェイスを呼び出すというオブジェクトの機能を公開する機構を定義していませんでした。 つまり、従来の COM では、オブジェクトを指す内向きのポインター (このオブジェクトのインターフェイスを指すポインター) を処理する方法は定義していましたが、外向きのインターフェイス用の明示的なモデル (ほかのオブジェクトのインターフェイスを指すポインター) はありませんでした。 新しい COM には、この機能をサポートするためのコネクション ポイントというモデルが追加されています。

接続は、2 つの部分があります。ソース、およびインターフェイスを実装するオブジェクトと呼ばれるインターフェイスを呼び出すオブジェクトでは、シンクと呼ばれます。 コネクション ポイントはソースが公開するインターフェイスです。 ソースがコネクション ポイントを公開すると、シンクからソースに接続を確立できます。 コネクション ポイント機構 (IConnectionPoint インターフェイス) を通じて、シンク インターフェイスへのポインターがソース オブジェクトに渡されます。 このポインターを通じて、ソースは、シンク側の一連のメンバー関数にアクセスします。 たとえば、シンクが実装しているイベントを発生させるには、ソースはシンク実装の適切なメソッドを呼び出します。 コネクション ポイントの例を次の図に示します。

コネクション ポイントの実装

実装されたコネクション ポイント

MFC では、このモデルを CConnectionPoint クラスと CCmdTarget クラスに実装しています。 CConnectionPoint の派生クラスでは、IConnectionPoint インターフェイスを実装しているので、ほかのオブジェクトにコネクション ポイントを公開できます。 CCmdTarget の派生クラスでは、IConnectionPointContainer インターフェイスを実装しているので、オブジェクトの使用可能なすべてのコネクション ポイントを列挙したり、特定のコネクション ポイントを検索したりできます。

クラスに実装するコネクション ポイントごとにコネクション部を宣言する必要があります。 また、実装するコネクション ポイントの数とは関係なく、コネクション マップを 1 つ宣言する必要があります。 コネクション マップは ActiveX コントロールがサポートするコネクション ポイントを示すテーブルです。

簡単なコネクション マップとコネクション ポイントの例を以下に示します。 最初の例では、コネクション マップとコネクション ポイントを宣言し、2 番目の例では、宣言したマップとポイントを実装します。 CMyClass は CCmdTarget の派生クラスにする必要があります。 最初の例では、クラス宣言の protected セクションの下にコードを挿入しています。

class CMyClass : public CCmdTarget
{
protected:
   // Connection point for ISample interface
    BEGIN_CONNECTION_PART(CMyClass, SampleConnPt)
        CONNECTION_IID(IID_ISampleSink)
    END_CONNECTION_PART(SampleConnPt)

    DECLARE_CONNECTION_MAP()

BEGIN_CONNECTION_PART マクロと END_CONNECTION_PART マクロは、このコネクション ポイントを実装するために、埋め込みクラス XSampleConnPt (CConnectionPoint の派生クラス) を宣言しています。 CConnectionPoint のメンバー関数をオーバーライドするか、独自のメンバー関数を追加するときは、この 2 つのマクロ間に宣言します。 たとえば、この 2 つのマクロ間に CONNECTION_IIDを挿入すると、CConnectionPoint::GetIID メンバー関数がオーバーライドされます。

2 番目の例では、コントロールの実装ファイル (.cpp ファイル) 内にコードを挿入します。 このコードは、コネクション ポイント SampleConnPt を含むコネクション マップを実装します。

BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
    CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()

クラスに複数のコネクション ポイントがあるときは、BEGIN_CONNECTION_MAP マクロと END_CONNECTION_MAP マクロの間に CONNECTION_PART マクロを追加します。

最後に、EnableConnections への呼び出しをクラスのコンストラクターに追加します。 次に例を示します

CMyClass::CMyClass()
{
   EnableConnections();
}

このコードを挿入すると、CCmdTarget の派生クラスは ISampleSink インターフェイスにコネクション ポイントを公開します。 この例を次の図に示します。

MFC で実装したコネクション ポイント

コネクション ポイント実装 MFC

通常、コネクション ポイントは、"マルチキャスティング" をサポートします。マルチキャスティングとは、同じインターフェイスに関連付けられている複数のシンクにブロードキャストする機能です。 コネクション ポイント上のシンクごとに処理を繰り返してマルチキャストする方法を次に示します。

void CMyClass::CallSinkFunc()
{
    POSITION pos = m_xSampleConnPt.GetStartPosition();
    ISampleSink* pSampleSink;
    while( pos != NULL )
    {
        pSampleSink = (ISampleSink*)(m_xSampleConnPt.GetNextConnection(pos));
        if(pSampleSink != NULL)
            pSampleSink->SinkFunc();
    }
}

この例では、CConnectionPoint::GetConnections への呼び出しを通じて、コネクション ポイント SampleConnPt に現在ある一連のコネクションを取得しています。 さらに、各コネクションに対して処理を繰り返し、アクティブなコネクションごとに ISampleSink::SinkFunc を呼び出しています。

参照

概念

MFC COM