次の手順では、ATL バージョン 2.1 または ATL バージョン 3.0 と MSP 基本クラスを使用して MSP を実装する方法について説明します。 ライブラリとヘッダーの詳細と一覧については、「 TAPI 3 MSP 基本クラス」を参照してください。 このトピックに含まれるコンテンツは、開発者が ATL と COM を理解しており、ATL を使用して COM DLL を実装した経験があることを前提としています。
ATL 2.1 または ATL 3.0 を使用して および MSP を実装するには
MSP の IDL ファイルを作成します。 このファイルは、MSP の CLSID を定義します。 MSP の "コクラス" を ITMSPAddress インターフェイスの実装として宣言し、このインターフェイスをクラス オブジェクトの既定のインターフェイスとして宣言します。 ITMSPAddress の定義については、ファイル "msp.idl" をインポートします。 MSP のタイプ ライブラリに MSP の "コクラス" を含めます。 MSP でプライベート (カスタム) インターフェイスがサポートされている場合は、ここで定義し、タイプ ライブラリに含めます。 次のコード例は、カスタム インターフェイスを使用せずに、上記のように IDL ファイルです。
import "msp.idl"; [ uuid(4DDB6D35-3BC1-11d2-86F2-006008B0E5D2), version(2.0), helpstring("Wave MSP 2.0 Type Library") ] library WAVEMSPLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ uuid(4DDB6D36-3BC1-11d2-86F2-006008B0E5D2), helpstring("Wave MSP Class") ] coclass WaveMSP { [default] interface ITMSPAddress; }; };
TSP を変更して、Tapi3.dllが要求したときに MSP の CLSID をアドバタイズします。 (1) TSP 関数TSPI_lineNegotiateTSPIVersionで TSP がTAPI_VERSION3_0以上ネゴシエートできることを確認し、(2) TSP LINEDEVCAPS 構造体に dwDevCapFlags メンバーに LINEDEVCAPFLAGS_MSP フラグが設定されていること、(3) TSP が TSPI 関数 TSPI_lineMSPIdentifyで MSP CLSID を返すようにします。 これは、IDL ファイルで指定されたのと同じ CLSID である必要があります。たとえば、前の手順の IDL ファイルの例の 2 番目の "uuid" 行です。
プラットフォーム ソフトウェア開発キット (SDK) にある MSPBase サンプル アプリケーションをコンパイルして、MSPBaseSample.lib ライブラリを作成します。
MSP DLL を MSPBaseSample.lib ライブラリにリンクします。
MSP 基底クラス定義用 SDK から Mspbase.h を含めます。
DLL エクスポート (DllMain など) を実装します。 Microsoft Visual C++は、これらを自動的に生成します。 DllMain のDLL_PROCESS_ATTACHとDLL_PROCESS_DETACHで、それぞれ MSPLOGREGISTER マクロと MSPLOGDEREGISTER マクロを使用して、DLL のログ機能を有効にします。 MSPLOGDEREGISTER 呼び出しで DLL の名前を指定します。
Msplog.h で定義されている LOG マクロを使用して、基底クラスと同じ方法でトレース メッセージを出力します。 DLL にログ記録を含める MSPLOG プリプロセッサ シンボルを定義します。ログがない DLL をビルドするには、未定義のままにしておきます。
MSP のアドレスを実装する CMSPAddress からクラスを派生させます。 IDL ファイルで指定した CLSID に対して CoCreate を要求されたときに、アドレス クラスのインスタンスを作成するように ATL に指示するグローバル ATL オブジェクト マップを宣言します。 また、ATL CComCoClass テンプレートからアドレス クラスを派生させ、アドレス クラスにDECLARE_REGISTRY_RESOURCEID宣言を含めます。 他の ATL COM DLL と同様に、対応するリソース スクリプトとヘッダー ファイルを作成します。
アドレス クラスに必要な CMSPAddress オーバーライドを実装します。 MSPAddressAddRef と MSPAddressRelease の場合は、指定されたヘルパー関数テンプレートを呼び出します。 GetCallMediaTypes の場合は、MSP でサポートされているすべての TAPIMEDIAMODEs ORed を一緒に含む DWORD ビットマップを返すだけです。 CreateMSPCall と ShutdownMSPCall の場合は、E_NOTIMPLを返し、この時点で MSP をコンパイルしてリンクします。 次に、TAPI 3 アプリケーションから MSP を登録してインスタンス化できることを確認しますが、呼び出しは正常に作成されません。
CMSPCallMultiGraph からクラスを派生して、MSP 呼び出しオブジェクトを実装します。 ストリームごとのフィルター グラフ モデルが要件に適合しない場合は、CMSPCallMultiGraph の代わりに CMSPCallBase から派生させることができます。これにより、タスクの複雑さが増します (この記事の執筆時点では、すべての MSP が CMSPCallMultiGraph から直接呼び出しオブジェクトを派生させます)。 アドレス オブジェクトに CreateMSPCall と ShutdownMSPCall を実装し、指定されたヘルパー関数テンプレートを使用して特定の種類の呼び出しオブジェクトを作成およびシャットダウンします。 呼び出しオブジェクトで、 CreateStreamObject を オーバーライドしてE_NOTIMPLを返します。 対応するアドレス メソッドと同じ方法で MSPCallAddRef と MSPCallRelease をオーバーライドします。 ここでも、MSP をコンパイルしてリンクできる必要があります。これで、呼び出しを作成およびシャットダウンできるようになりますが、呼び出しでは役に立つストリーミングは行われません。
MSP ストリーム オブジェクトを実装するために、CMSPStream からクラスを派生させます。 呼び出しオブジェクトで CreateStreamObject を実装してストリーム オブジェクトを作成および初期化します (通常は、ATL CreateInstance を呼び出し、ITStream の ATL _InternalQueryInterfaceを呼び出し、ストリーム オブジェクトで Init を呼び出します)。 固定数のストリームをサポートするには (これは、呼び出しの他のエンドポイントによるストリーム構成の変更をサポートしていない MSP では一般的です)、呼び出しオブジェクト で Init、 CreateStream、 RemoveStream をオーバーライドします。 (呼び出し Init は最初にすべてのストリームを作成し、 CreateStream と RemoveStream は、アプリケーションがストリームを作成または削除するのを防ぐために適切な TAPI エラー コードを返します)。 それ以外の場合は、呼び出しの Init メソッドをオーバーライドして、呼び出しに要求されたメディアの種類を使用してストリームの初期の既定の構成を作成します。 呼び出しの Init メソッドで既定のストリーム オブジェクトを作成する場合は、 InternalCreateStream ヘルパー メソッドを使用します。
ストリーム オブジェクトを実装します。 必要なオーバーライドは 、単 にストリームのフレンドリ名を返す get_Name メソッドのみです。 さらに、他のいくつかのメソッドをオーバーライドする必要があります。 オーバーライドするメソッドは、実装と、フィルター グラフの構築と分解に関連するさまざまなタスクをいつ実行するかによって異なります。 これらのタスクには、適切な "トランスポート" フィルター、コーデックなどを作成し、適切な時間にフィルター グラフに挿入してフィルター グラフから削除することが含まれます。 また、選択したターミナルをストリームに接続するには、ターミナル オブジェクトの ITTerminalControl インターフェイスを使用する必要があります。 ストリーム オブジェクトの SelectTerminal と UnselectTerminal をオーバーライドして、ストリームが受け入れるターミナル構成を制限することができます。各ストリームを 1 つのターミナルに制限すると、フィルター グラフの構築は特に簡略化されますが、ビデオ プレビューなどのアプリケーション機能は犠牲になります。 実装に応じて、StartStream、StopStream、PauseStream、Initialize、Shutdown、SelectTerminal、UnselectTerminal メソッド、またはプライベート TSP 通信に基づく独自のメソッドに、グラフの構築、分解、およびターミナル接続コードを配置します。 ターミナルが選択されていないストリームは、目的のグラフの状態を追跡する必要があることに注意してください。 StartStream 呼び出しの後に、このようなストリームで SelectTerminal 呼び出しを行うと、データ ストリームが生成される必要があります。 これらのメソッドの大部分をオーバーライドして、ストリームの状態に応じて、それぞれのケースで正しい構築、分解、接続、切断が行われるようにします。
TSP 通信を実装します。 CMSPAddress::ReceiveTSPAddressData または CMSPCallBase::ReceiveTSPCallData をオーバーライドします。または、アドレス オブジェクトで PostEvent を呼び出すか、呼び出しオブジェクトの HandleStreamEvent を呼び出します (呼び出しオブジェクトまたはストリーム オブジェクトのいずれか)。
アドレス オブジェクトで PostEvent を使用するか、呼び出しオブジェクト (呼び出しオブジェクトまたはストリーム オブジェクトのいずれか) で HandleStreamEvent を使用して、Tapi3.dll経由で呼び出しメディア イベントをアプリケーションに送信します。 通常、ストリーム オブジェクトでは、ストリームの実装方法に応じて、ProcessGraphEvent、StopStream、StartStream、PauseStream、SelectTerminal、UnselectTerminal メソッドなどのオーバーライドされたメソッドでこれを行います。
既存のオブジェクト (アドレス、呼び出し、ストリーム) に必要なプライベート インターフェイスまたはサブストリームを実装します。 通常は存在しません。 プライベート インターフェイスを実装する場合は、IDL ファイルからタイプ ライブラリのリビドーを指定してください。 つまり、アプリケーション プログラマは、カスタム インターフェイスを使用するときに MSP タイプ ライブラリを使用する必要があります。 MSP 基本クラスに実装されている標準の MSP インターフェイスは、Tapi3.dllの LIBID を使用するため、すべての TAPI 3 アプリケーションからアクセスできます。
MSP 固有の静的または動的ターミナル オブジェクト、または既定の静的ターミナル (一般的ではない) の置換を実装する場合は、提供されたターミナル 基本クラスを使用できます。 ターミナル オブジェクトを作成する代替または追加のメソッドを提供するには、アドレス オブジェクトのさまざまなメソッドをオーバーライドする必要があります。
Address、Call、Stream、Terminal オブジェクトに IObjectSafety インターフェイスを実装します。 ディスパッチ マッパーを使用して MSP オブジェクトのインターフェイスのクエリを実行するには、オブジェクトをこれらのインターフェイスでのスクリプト作成に安全としてマークします。 これを行うには、オブジェクトに IObjectSafety インターフェイスを実装します。 CMSPObjectSafetyImpl (Msputils.h で提供されるヘルパー クラス) から派生し、クラスの ATL COM_MAPに IObjectSafety を追加すると、公開されるすべてのインターフェイスでのスクリプト作成にオブジェクトが安全になります。 MSP オブジェクトでディスパッチ マッパーを使用することは暗黙的である可能性があることに注意してください。 MSP アドレスと MSP 呼び出しは、TAPI アドレスおよび TAPI 呼び出しオブジェクトによって集計されます。 TAPI オブジェクトでディスパッチ マッパーを使用して、集約された MSP オブジェクトによって公開されるインターフェイスを照会する場合、集約された MSP オブジェクトに対して要求されたインターフェイスの安全性が問い合わされます。