IDropTarget
COM公式ドキュメント
IDropTarget インターフェイスは、アプリケーションでドラッグ アンド ドロップ操作を提供するために実装するインターフェイスの 1 つです。
メソッド 4
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
ドロップを受け入れられるかどうか、および受け入れられる場合はドロップの効果を示します。
| pDataObj | IDataObject* | in | データ オブジェクトの IDataObject インターフェイスへのポインターです。このデータ オブジェクトには、ドラッグ アンド ドロップ操作で転送されるデータが含まれます。ドロップが発生すると、このデータ オブジェクトはターゲットに取り込まれます。 |
| grfKeyState | MODIFIERKEYS_FLAGS | in | キーボードの修飾キーの現在の状態です。指定できる値は、MK_CONTROL、MK_SHIFT、MK_ALT、MK_BUTTON、MK_LBUTTON、MK_MBUTTON、MK_RBUTTON の各フラグの組み合わせです。 |
| pt | POINTL | in | 現在のカーソル座標をスクリーン座標で格納する POINTL 構造体です。 |
| pdwEffect | DROPEFFECT* | inout | 入力時は、DoDragDrop 関数の pdwEffect パラメーターの値へのポインターです。戻り時には、ドロップ操作の結果を示す DROPEFFECT フラグのいずれかを格納する必要があります。 |
戻り値
このメソッドは成功時に S_OK を返します。その他の値には次のものがあります。
| 戻り値 | 説明 |
|---|---|
| 予期しないエラーが発生しました。 | |
| 入力時に pdwEffect パラメーターが NULL です。 | |
| この操作に使用できるメモリが不足していました。 |
解説(Remarks)
DragEnter を直接呼び出すことはありません。代わりに、DoDragDrop 関数が、ユーザーが最初にドロップ ターゲットの登録済みウィンドウ内へマウスをドラッグしたときに、ドロップの効果を判断するためにこのメソッドを呼び出します。
DragEnter を実装するには、次の 3 つの点を確認して、ターゲットがソース データ オブジェクト内のデータを使用できるかどうかを判断する必要があります。
- データ オブジェクトで指定された形式とメディア
- pdwEffect の入力値
- 修飾キーの状態
IDropTarget::DragEnter への入力時には、pdwEffect パラメーターに DoDragDrop 関数の pdwOkEffect パラメーターに指定された効果が設定されています。IDropTarget::DragEnter メソッドは、これらの効果のいずれかを選択するか、ドロップを無効にする必要があります。
次の修飾キーはドロップの結果に影響します。
| キーの組み合わせ | ユーザーに表示されるフィードバック | ドロップ効果 |
|---|---|---|
| CTRL + SHIFT | = | DROPEFFECT_LINK |
| CTRL | + | DROPEFFECT_COPY |
| キーなし、または SHIFT | なし | DROPEFFECT_MOVE |
戻り時には、このメソッドは効果、すなわち DROPEFFECT フラグのいずれかを pdwEffect パラメーターに書き込む必要があります。DoDragDrop はこのパラメーターを受け取り、自身の pdwEffect パラメーターに書き込みます。ドロップの効果は、pdwEffect パラメーターを通じて DoDragDrop からソースに伝達されます。その後、DoDragDrop 関数は IDropSource::GiveFeedback を呼び出し、ソース アプリケーションがターゲット ウィンドウを通じて適切な視覚的フィードバックをユーザーに表示できるようにします。
ユーザーにターゲットのフィードバックを提供し、DoDragDrop 関数にドロップの効果を伝えることで、DoDragDrop 関数がドロップの効果をソースに伝達できるようにします。
| grfKeyState | MODIFIERKEYS_FLAGS | in | キーボードの修飾キーの現在の状態です。有効な値は、MK_CONTROL、MK_SHIFT、MK_ALT、MK_BUTTON、MK_LBUTTON、MK_MBUTTON、MK_RBUTTON の各フラグの組み合わせです。 |
| pt | POINTL | in | 現在のカーソル座標をスクリーン座標で格納する POINTL 構造体です。 |
| pdwEffect | DROPEFFECT* | inout | 入力時は、DoDragDrop 関数の pdwEffect パラメーターの値へのポインターです。戻り時には、ドロップ操作の結果を示す DROPEFFECT フラグのいずれかを格納する必要があります。 |
戻り値
このメソッドは成功時に S_OK を返します。その他の値には次のものがあります。
| 戻り値 | 説明 |
|---|---|
| 予期しないエラーが発生しました。 | |
| pdwEffect の値が無効です。 | |
| この操作に使用できるメモリが不足していました。 |
解説(Remarks)
DragOver を直接呼び出すことはありません。DoDragDrop 関数は、ユーザーが特定のターゲット ウィンドウ上でマウスを移動するたびにこのメソッドを呼び出します。DoDragDrop は、ドラッグ アンド ドロップ操作がキャンセルされた場合、ユーザーがターゲット ウィンドウの外へマウスをドラッグした場合、またはドロップが完了した場合にループを終了します。
IDropTarget::DragOver の実装では、IDropTarget::DragEnter と同様の機能を提供する必要があります。データ オブジェクトの形式とメディアを定義する FORMATETC と、修飾キーの状態を調べて、データをターゲットにドロップする効果を判断する必要があります。マウスの位置もドロップの効果の判断に関与する場合があります。次の修飾キーはドロップの結果に影響します。
| キーの組み合わせ | ユーザーに表示されるフィードバック | ドロップ効果 |
|---|---|---|
| CTRL + SHIFT | = | DROPEFFECT_LINK |
| CTRL | + | DROPEFFECT_COPY |
| キーなし、または SHIFT | なし | DROPEFFECT_MOVE |
ドロップの効果は、pdwEffect を通じて DoDragDrop からソースに伝達されます。その後、DoDragDrop 関数は IDropSource::GiveFeedback を呼び出し、ソース アプリケーションが適切な視覚的フィードバックをユーザーに表示できるようにします。
IDropTarget::DragOver への入力時には、pdwEffect パラメーターに DoDragDrop 関数の pdwOkEffect パラメーターに渡された許可される効果が設定されている必要があります。IDropTarget::DragOver メソッドは、これらの効果のいずれかを選択するか、ドロップを無効にできる必要があります。
戻り時には、pdwEffect に DROPEFFECT フラグのいずれかが設定されます。この値はその後 DoDragDrop の pdwEffect パラメーターに渡されます。妥当な値は、ドラッグされたデータをターゲットにコピーする DROPEFFECT_COPY、ソース データへのリンクを作成する DROPEFFECT_LINK、またはドラッグされたデータをソース アプリケーションからターゲットへ完全に移動できるようにする DROPEFFECT_MOVE です。
ターゲット ウィンドウに適切な視覚的フィードバックを提供することも望ましいでしょう。前回の IDropTarget::DragOver の呼び出し、または最初の IDropTarget::DragEnter から、すでに何らかのターゲット フィードバックが表示されている場合があります。このフィードバックがもはや適切でない場合は、削除する必要があります。
効率上の理由から、データ オブジェクトは IDropTarget::DragOver に渡されません。直前の IDropTarget::DragEnter の呼び出しで渡されたデータ オブジェクトが利用可能であり、それを使用できます。
IDropTarget::DragOver が処理を完了すると、DoDragDrop 関数は IDropSource::GiveFeedback を呼び出し、ソース アプリケーションが適切な視覚的フィードバックをユーザーに表示できるようにします。
実装者への注意
この関数は DoDragDrop ループ中に頻繁に呼び出されるため、DragOver メソッドの実装は可能な限り最適化することが理にかなっています。ターゲットのフィードバックを削除し、データ オブジェクトを解放します。
戻り値
このメソッドは成功時に S_OK を返します。その他の値には次のものがあります。
| 戻り値 | 説明 |
|---|---|
| この操作に使用できるメモリが不足しています。 |
解説(Remarks)
このメソッドを直接呼び出すことはありません。DoDragDrop 関数は、次のいずれかの場合にこのメソッドを呼び出します。
- ユーザーが特定のターゲット ウィンドウの外へカーソルをドラッグしたとき。
- ユーザーが現在のドラッグ アンド ドロップ操作をキャンセルしたとき。
ソース データをターゲット ウィンドウに取り込み、ターゲットのフィードバックを削除し、データ オブジェクトを解放します。
| pDataObj | IDataObject* | in | ドラッグ アンド ドロップ操作で転送されるデータ オブジェクトの IDataObject インターフェイスへのポインターです。 |
| grfKeyState | MODIFIERKEYS_FLAGS | in | キーボードの修飾キーの現在の状態です。指定できる値は、MK_CONTROL、MK_SHIFT、MK_ALT、MK_BUTTON、MK_LBUTTON、MK_MBUTTON、MK_RBUTTON の各フラグの組み合わせです。 |
| pt | POINTL | in | 現在のカーソル座標をスクリーン座標で格納する POINTL 構造体です。 |
| pdwEffect | DROPEFFECT* | inout | 入力時は、DoDragDrop 関数の pdwEffect パラメーターの値へのポインターです。戻り時には、ドロップ操作の結果を示す DROPEFFECT フラグのいずれかを格納する必要があります。 |
戻り値
このメソッドは成功時に S_OK を返します。その他の値には次のものがあります。
| 戻り値 | 説明 |
|---|---|
| OLE ドラッグ アンド ドロップ操作がキャンセルされました。 | |
| 予期しないエラーが発生しました。 | |
| pdwEffect パラメーターが無効です。 | |
| この操作に使用できるメモリが不足しています。 |
解説(Remarks)
このメソッドを直接呼び出すことはありません。DoDragDrop 関数は、ユーザーがドラッグ アンド ドロップ操作を完了したときにこのメソッドを呼び出します。
Drop を実装するには、データ オブジェクトをターゲットに取り込む必要があります。pDataObj を通じて利用できる IDataObject で利用可能な形式と、修飾キーの現在の状態を使用して、リンクや埋め込みなど、データをどのように取り込むかを判断します。
データの取り込みに加えて、IDropTarget::DragLeave メソッドと同様に、クリーンアップも行う必要があります。
- 現在表示されているターゲット フィードバックをすべて削除します。
- データ オブジェクトへの参照をすべて解放します。
- 表示されているソース フィードバックをすべて削除します。
- 操作が移動であった場合にデータを削除するなど、データに必要な変更を加えます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IDropTarget "{00000122-0000-0000-C000-000000000046}" #usecom global IDropTarget IID_IDropTarget "{}" #comfunc global IDropTarget_DragEnter 3 sptr,int,int,var #comfunc global IDropTarget_DragOver 4 int,int,var #comfunc global IDropTarget_DragLeave 5 #comfunc global IDropTarget_Drop 6 sptr,int,int,var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IDropTarget "{00000122-0000-0000-C000-000000000046}" #usecom global IDropTarget IID_IDropTarget "{}" #comfunc global IDropTarget_DragEnter 3 sptr,int,int,sptr #comfunc global IDropTarget_DragOver 4 int,int,sptr #comfunc global IDropTarget_DragLeave 5 #comfunc global IDropTarget_Drop 6 sptr,int,int,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。