TN039: MFC および OLE オートメーションの実装

OLE IDispatch インターフェイスの概要

IDispatchインターフェイスは、どのアプリケーション公開メソッドとプロパティは、このようなで Visual BASIC、または他の言語などの他のアプリケーションをすることができますは、アプリケーションの機能の使用です。このインターフェイスの最も重要な部分は、 idispatch::invoke関数です。MFC を使用して「ディスパッチ マップ」 idispatch::invokeを実装します。ディスパッチ マップ、MFC 実装レイアウトや、 CCmdTargetの「形」に説明-できます直接オブジェクト プロパティを操作されている、またはidispatch::invokeの要求を満たすために、オブジェクト内の関数メンバーを呼び出す、派生クラス、。

ほとんどの部分については、ClassWizard と MFC OLE オートメーション アプリケーション プログラマからの詳細のほとんどを非表示にするに協力します。プログラマでアプリケーションを公開するには、実際の機能に集中して、基になる配管について心配する必要はありません。

ただし、MFC 舞台裏では何をしているを理解する必要がある場合があります。このノートでは、どのようにフレームワークDISPIDのメンバー関数やプロパティに割り当てられますを対処します。アプリケーションのオブジェクトを「タイプ ライブラリ」を作成するとき Id を知っている必要がある場合にのみ、 DISPIDs を割り当てるため、MFC を使用するアルゴリズムの知識が必要です。

MFC の DISPID の割り当て

オートメーション (、Visual Basic ユーザー、たとえば) のエンドユーザーを見るが、実際の名前のプロパティとメソッドのコード (例えば obj. で、オートメーションを有効にShowWindow)、 idispatch::invokeの実装は、実際の名前を受信しません。最適化のために、「メソッドまたはアクセスされるプロパティを表す 32 ビット マジック クッキー」は、 DISPID、受信。これらのDISPID値はidispatch::getidsofnamesと呼ばれる別のメソッドをIDispatchの実装から返されます。オートメーション クライアント アプリケーション各メンバーのプロパティにアクセスするには、予定GetIDsOfNamesを一度呼び出すし、 idispatch::invokeへの以降の呼び出しのキャッシュします。この方法は、高価な文字列の検索のみ 1 回オブジェクト、 idispatch::invokeの呼び出しごとに 1 回の代わりに一度です。

MFC はDISPIDs の各のメソッドとプロパティの 2 つのことに基づいて決定します。:

DISPIDは、2 つの部分に分かれています。LOWORD DISPIDの最初のコンポーネントには、ディスパッチ マップの上部からの距離が含まれています。HIWORD最派生クラスからの距離が含まれています。たとえば:

cDispPoint クラス: パブリック CCmdTarget{パブリック。特価;短い m_x, m_y;...DECLARE_DISPATCH_MAP()...};CDisp3DPoint クラス: パブリック CDispPoint{パブリック。短い m_y;...DECLARE_DISPATCH_MAP()...};BEGIN_DISPATCH_MAP (CDispPoint、CCmdTarget)DISP_PROPERTY (CDispPoint、「x」m_x、VT_I2)DISP_PROPERTY (CDispPoint、「y」m_y、VT_I2)END_DISPATCH_MAP()BEGIN_DISPATCH_MAP (CDisp3DPoint, CDispPoint)DISP_PROPERTY (CDisp3DPoint、"z"、m_z、VT_I2)END_DISPATCH_MAP()(&N)

ご覧のとおり、どちらも OLE オートメーション インターフェイスを公開する 2 つのクラスです。これらのクラスの 1 つから派生している、したがって、OLE オートメーション部分を含む、基本クラスの機能を活用して (「x」と「y」この場合プロパティ)。

MFC は、次のとおりDISPIDs クラス CDispPoint を生成します。:

プロパティ Xnbsp;(DISPID) 0X00000001プロパティ Y (DISPID) 0x00000002(&N)

プロパティが、基本クラスではありませんので、 DISPIDHIWORDは常に (CDispPoint の最派生クラスからの距離は 0 です) ゼロです。

MFC は、次のとおりDISPIDs クラス CDisp3DPoint を生成します。:

プロパティ Znbsp;(DISPID) 0X00000001プロパティ (DISPID) 0x00010001 Xプロパティ Y (DISPID) 0x00010002(&N)

CDisp3DPoint のプロパティを公開するクラスで定義されているので、Z プロパティにDISPIDをゼロのHIWORDに与えられます。1 つの派生、最派生クラスからの距離でこれらのプロパティが定義されているクラスであるためには、X プロパティと Y プロパティが、基本クラスで定義されているので、1、 DISPIDHIWORDのです。

特価;明示的なDISPIDをマップ内のエントリが存在する場合でも常に、 LOWORDマップ内の位置によって決定されます (次のセクションの情報をDISP_PROPERTYDISP_FUNCTIONマクロの_IDバージョンを参照してください)(&N)。

MFC ディスパッチ マップ機能

数多く ClassWizard でサポートされていない追加の機能の Visual C のこのリリース。ClassWizard は、 DISP_FUNCTIONDISP_PROPERTYメソッド、メンバ変数のプロパティ、および get と set メンバー関数のプロパティをそれぞれ定義するDISP_PROPERTY_EXをサポートします。これらの機能は、通常ほとんどのオートメーション サーバーの作成に必要なもの。

サポート ClassWizard マクロが適切でない場合、次の追加のマクロを使用することができます: DISP_PROPERTY_NOTIFY、およびDISP_PROPERTY_PARAM

DISP_PROPERTY_NOTIFY-マクロの説明

DISP_PROPERTY_NOTIFY ([クラス], pszName, memberName, pfnAfterSet, vtPropType

[クラス]

クラスの名前。

pszName

プロパティの外部名。

ホットメール

プロパティが格納されて、メンバー変数の名前。

pfnAfterSet

プロパティが変更されたときに呼び出す関数の名前。

vtPropType

プロパティの型を指定する値。

特価;このマクロDISP_PROPERTY、同様ですが、それは追加の引数を受け取ります。追加の引数では、 pfnAfterSet、 nothing と 'void OnPropertyNotify()' のパラメーターを受け取らない関数する必要があります。メンバー変数が変更されたに呼び出されます(&N)。

DISP_PROPERTY_PARAM-マクロの説明

DISP_PROPERTY_PARAM ([クラス]pszNamepfnGetpfnSetvtPropType 「vtsParams

[クラス]

クラスの名前。

pszName

プロパティの外部名。

memberGet

プロパティを取得に使用するメンバー関数の名前。

メンバ セット

プロパティを設定に使用するメンバー関数の名前。

vtPropType

プロパティの型を指定する値。

「vtsParams

文字列領域の各パラメーターの vts _ で区切られました。

特価;多くDISP_PROPERTY_EXマクロのように、このマクロに別の Get と Set メンバー関数にアクセスするプロパティを定義します。このマクロでは、ただし、プロパティのパラメーター リストを指定できます。これは、いくつか他の方法でインデックスを作成またはパラメーター化されたプロパティを実装するために便利です。パラメーター、プロパティの新しい値が続きますは常に最初に配置されます。たとえば(&N):

DISP_PROPERTY_PARAM いる (「項目」CMyObject、GetItem、SetItem、VT_DISPATCH、VTS_I2 VTS_I2)

取得関数と設定関数に対応します。:

LPDISPATCH CMyObject::GetItem(short row, short col)CMyObject::SetItem (短い行、短い col、LPDISPATCH newValue) が無効します。

DISP_XXXX_ID-マクロの説明

DISP_FUNCTION_ID ([クラス]pszNamedispidpfnMembervtRetVal 「vtsParams

DISP_PROPERTY_ID ([クラス]pszNamedispidホットメールvtPropType

DISP_PROPERTY_NOTIFY_ID ([クラス]pszNamedispidホットメールpfnAfterSetvtPropType

DISP_PROPERTY_EX_ID ([クラス]pszNamedispidpfnGetpfnSetvtPropType

DISP_PROPERTY_PARAM_ID ([クラス]pszNamedispidpfnGetpfnSetvtPropType 「vtsParams

[クラス]

クラスの名前。

pszName

プロパティの外部名。

dispid

プロパティまたはメソッドは、固定の DISPID。

pfnGet

プロパティを取得に使用するメンバー関数の名前。

pfnSet

プロパティを設定に使用するメンバー関数の名前。

ホットメール

プロパティにマップするには、メンバー変数の名前

vtPropType

プロパティの型を指定する値。

「vtsParams

文字列領域の各パラメーターの vts _ で区切られました。

特価;これらのマクロを使用すると、MFC の 1 つを自動的に割り当てるのではなく、 DISPIDを指定できます。その ID マクロ名 (たとえばDISP_PROPERTY_ID) に追加されますを除くこれらのマクロの詳細と同じ名前があると、ID は、 pszNameパラメーターの後に指定されたパラメーターによって決定されます。AFXDISP を参照してください。H はこれらのマクロの詳細については。_IDエントリは、ディスパッチ マップの最後に配置する必要があります。DISPIDの自動生成は以外と同じ方法でそれらに与える影響 - マクロの_IDバージョンと ( DISPIDs は位置によって決定されます)。たとえば(&N):

BEGIN_DISPATCH_MAP (CDisp3DPoint、CCmdTarget)特価;DISP_PROPERTY (CDisp3DPoint、「y」m_y、VT_I2)DISP_PROPERTY (CDisp3DPoint、"z"、m_z、VT_I2)DISP_PROPERTY_ID (CDisp3DPoint、「x」0x00020003 m_x、VT_I2)END_DISPATCH_MAP()(&N)

MFC クラスを CDisp3DPoint として次のように Dispid を生成します。:

プロパティ Xnbsp;(DISPID) 0X00020003プロパティ Y (DISPID) 0x00000002プロパティ Z (DISPID) 0x00000001(&N)

固定のDISPIDを指定する互換性、既存のディスパッチ インターフェイスまたは特定のシステムを実装するメソッドまたはプロパティ (通常、否定的なDISPIDDISPID_NEWENUMコレクションなどによって示されます) の定義を維持するのに便利です。

COleClientItem の IDispatch インターフェイスを取得します。

多くのサーバーは、OLE サーバーの機能と共に、ドキュメント オブジェクト内のオートメーションをサポートします。このオートメーション インターフェイスにアクセスするには、 COleClientItem::m_lpObjectメンバー変数に直接アクセスする必要があります。次のコードは、 COleClientItemから派生したオブジェクトのIDispatchインターフェイスを取得します。この機能が必要なこと場合、アプリケーションで以下のコードを含めることができます。

LPDISPATCH CMyClientItem::GetIDispatch(){特価;ASSERT_VALID(this);ASSERT (m_lpObject! = NULL);LPUNKNOWN lpUnk = m_lpObject;Run();//を実行している必要がありますLPOLELINK lpOleLink = NULL;場合 (m_lpObject - > QueryInterface (IID_IOleLink、(LPVOID まで ※ & lpOleLink) NOERROR = =){ASSERT (lpOleLink! = NULL);lpUnk = NULL;場合 (lpOleLink - > GetBoundSource(&lpUnk) ! NOERROR =){TRACE0 (「警告: リンクが接続されていません! \n");lpOleLink - > Release();NULL を返す;}ASSERT (lpUnk! = NULL);}LPDISPATCH lpDispatch = NULL;場合 (lpUnk - > QueryInterface (lpDispatch IID_IDispatch、) ! NOERROR =){TRACE0 (「警告: IDispatch をサポートしていません! \n");NULL を返す;}ASSERT (lpDispatch! = NULL);lpDispatch を返す;}

ディスパッチ インターフェイスから返されるこの関数が、直接使用または、 COleDispatchDriverのタイプ セーフ アクセスに接続します。それを直接使用する場合は、そのリリースのメンバーを呼び出すことを確認をするとき ( COleDispatchDriverデストラクターは、この既定) ポインターを。

番号順テクニカル ノート|nbsp;カテゴリ別テクニカル ノート(&N)

Index