ドラッグ アンド ドロップとクリップボードを使用したシェル オブジェクトの転送

多くのアプリケーションでは、ユーザーがマウスでデータをドラッグ アンド ドロップするか、クリップボードを使用して、別のアプリケーションにデータを転送できます。 転送できるデータの多くの種類の中には、ファイルやフォルダーなどのシェル オブジェクトがあります。 シェル データ転送は 2 つのアプリケーション間で行うことができますが、ユーザーはデスクトップまたは Windows Explorer との間でシェル データを転送することもできます。

ファイルは最も一般的に転送されるシェル オブジェクトですが、シェルのデータ転送には、シェル名前空間にあるさまざまなオブジェクトが関与する場合があります。 たとえば、アプリケーションでファイルをごみ箱などの仮想フォルダーに転送したり、Microsoft以外の名前空間拡張機能からオブジェクトを受け入れたりする必要がある場合があります。 名前空間拡張機能を実装する場合は、ドロップ ソースとターゲットとして適切に動作できる必要があります。

このドキュメントでは、アプリケーションでシェル オブジェクトを使用してドラッグ アンド ドロップとクリップボードのデータ転送を実装する方法について説明します。

シェル オブジェクトでのドラッグ アンド ドロップのしくみ

アプリケーションでは、多くの場合、シェル データを転送する方法をユーザーに提供する必要があります。 次に、例をいくつか示します。

  • Windows エクスプローラーまたはデスクトップからファイルをドラッグし、アプリケーションにドロップします。
  • Windows エクスプローラーでファイルをクリップボードにコピーし、アプリケーションに貼り付けること。
  • アプリケーションからごみ箱にファイルをドラッグする。

これらのシナリオとその他のシナリオを処理する方法の詳細については、「 シェル データ転送シナリオの処理」を参照してください。 このドキュメントでは、Shellデータ転送の背後にある一般的な原則に焦点を当てています。

Windowsには、アプリケーションがシェル データを転送するための 2 つの標準的な方法が用意されています。

  • ユーザーは、1 つ以上のファイルなどのシェル データをクリップボードに切り取りまたはコピーします。 もう 1 つのアプリケーションは、クリップボードからデータを取得します。
  • ユーザーは、ソース アプリケーションのデータを表すアイコンをドラッグし、そのアイコンを対象アプリケーションが所有するウィンドウにドロップします。

どちらの場合も、転送されたデータは データ オブジェクトに含まれます。 データ オブジェクトは、 IDataObject インターフェイスを公開するコンポーネント オブジェクト モデル (COM) オブジェクトです。 図式的に言うと、すべてのShellデータ転送が従う必要がある3つの重要な手順があります。

  1. ソースは、転送されるデータを表すデータ オブジェクトを作成します。
  2. ターゲットは、データ オブジェクトの IDataObject インターフェイスへのポインターを受け取ります。
  3. ターゲットは IDataObject インターフェイスを呼び出して、そこからデータを抽出します。

クリップボードとドラッグ アンド ドロップのデータ転送の違いは、主に IDataObject ポインターをソースからターゲットに転送する方法にあります。

クリップボードのデータ転送

クリップボードは、シェル データを転送する最も簡単な方法です。 基本的な手順は、標準のクリップボードのデータ転送に似ています。 ただし、データ自体ではなくデータ オブジェクトへのポインターを転送するため、標準のクリップボード API ではなく OLE クリップボード API を使用する必要があります。 次の手順では、OLE クリップボード API を使用してクリップボードでシェル データを転送する方法について説明します。

  1. データ ソースは、データを格納するデータ オブジェクトを作成します。
  2. データ ソースは OleSetClipboard を呼び出します。これにより、データ オブジェクトの IDataObject インターフェイスへのポインターがクリップボードに配置されます。
  3. ターゲットは OleGetClipboard を呼び出して、データ オブジェクトの IDataObject インターフェイスへのポインターを取得します。
  4. ターゲットは IDataObject::GetData メソッドを呼び出してデータを抽出します。
  5. 一部のシェル データ転送では、データ転送の結果に関するフィードバックをデータ オブジェクトに提供するために、ターゲットがデータ オブジェクトの IDataObject::SetData メソッドを呼び出す必要がある場合もあります。 この種類の操作の例については、「 最適化された移動操作の処理」 を参照してください。

ドラッグ アンド ドロップによるデータ転送

実装はやや複雑ですが、ドラッグ アンド ドロップのデータ転送には、クリップボードよりもいくつかの大きな利点があります。

  • ドラッグ アンド ドロップの転送は、簡単なマウスの動きで実行でき、クリップボードよりも柔軟で直感的に操作できます。
  • ドラッグ アンド ドロップを使用すると、操作が視覚的に示されます。 ユーザーは、アイコンがソースからターゲットへ移動するのを追うことができます。
  • ドラッグ アンド ドロップにより、データが利用可能になると、ターゲットに通知されます。

ドラッグ アンド ドロップ操作では、データ オブジェクトを使用してデータを転送することもできます。 ただし、ドロップ ソースは、クリップボード転送に必要な機能に加えて、機能を提供する必要があります。

  • ドロップ ソースでは、 IDropSource インターフェイスを公開するオブジェクトも作成する必要があります。 システムは、操作の進行中に IDropSource を使用してソースと通信します。
  • ドラッグ アンド ドロップ データ オブジェクトは、カーソルの移動を追跡し、データ オブジェクトを表すアイコンを表示する役割を担います。

ドロップ ターゲットでは、クリップボードの転送を処理するために必要以上の機能も提供する必要があります。

  • ドロップ ターゲットは IDropTarget インターフェイスを公開する必要があります。 カーソルがターゲット ウィンドウの上にある場合、システムは IDropTarget を使用して、カーソル位置などの情報をターゲットに提供し、データがドロップされたときに通知します。
  • ドロップ ターゲットは、 RegisterDragDrop を呼び出してシステムに自身を登録する必要があります。 この関数は、ターゲット ウィンドウへのハンドルと、ターゲット アプリケーションの IDropTarget インターフェイスへのポインターをシステムに提供します。

Note

ドラッグ アンド ドロップ操作の場合、アプリケーションは OleInitialize を使用して COM を初期化する必要があります。CoInitialize ではありません。

 

次の手順では、ドラッグ アンド ドロップでシェル データを転送するために通常使用される基本的な手順の概要を示します。

  1. ターゲットは RegisterDragDrop を呼び出して、システムに IDropTarget インターフェイスへのポインターを与え、ドロップ ターゲットとしてウィンドウを登録します。
  2. ユーザーがドラッグ アンド ドロップ操作を開始すると、ソースはデータ オブジェクトを作成し、DoDragDrop を呼び出してドラッグ ループを開始します。
  3. カーソルがターゲット ウィンドウの上にある場合、システムはターゲットの IDropTarget メソッドのいずれかを呼び出してターゲットに通知します。 システムは、カーソルがターゲット ウィンドウに入ったときに IDropTarget::DragEnter を呼び出し、カーソルがターゲット ウィンドウ を通過するときに IDropTarget::DragOver を呼び出します。 どちらのメソッドも、ドロップ ターゲットに現在のカーソル位置と、Ctrl キーや Alt キーなどのキーボード修飾子キーの状態を提供します。 カーソルがターゲット ウィンドウから離れると、システムは IDropTarget::DragLeave を呼び出してターゲットに通知します。 これらのメソッドのいずれかが戻ると、システムは IDropSource インターフェイスを呼び出して戻り値をソースに渡します。
  4. ユーザーがマウス ボタンを離してデータをドロップすると、システムはターゲットの IDropTarget::Drop メソッドを 呼び出します。 メソッドのパラメーターの中には、データ オブジェクトの IDataObject インターフェイスへのポインターがあります。
  5. ターゲットは、データ オブジェクトの IDataObject::GetData メソッドを呼び出してデータを抽出します。
  6. 一部のシェル データ転送では、データ転送の結果に関するフィードバックをソースに提供するために、ターゲットがデータ オブジェクトの IDataObject::SetData メソッドを呼び出す必要がある場合もあります。
  7. ターゲットでのデータ オブジェクトの処理が完了すると、IDropTarget::Drop から制御が戻ります。 データ転送が完了したことをソースに通知するために、システムはソースの DoDragDrop 呼び出しに戻ります。
  8. 特定の データ転送シナリオによっては、ソースが DoDragDrop によって返される値と、ターゲットによってデータ オブジェクトに渡される値に基づいて追加のアクションを実行する必要がある場合があります。 たとえば、ファイルが移動されると、移動元はこれらの値をチェックして、元のファイルを削除する必要があるかどうかを判断する必要があります。
  9. ソースがデータ オブジェクトを解放します。

上で説明した手順はシェル データ転送に適した一般的なモデルですが、シェル データ オブジェクトに含めることができるさまざまな種類のデータがあります。 また、アプリケーションで処理する必要があるさまざまなデータ転送シナリオもあります。 各データ型とシナリオには、手順における 3 つの主要なステップに対して多少異なるアプローチが必要です。

  • ソースがシェル データを格納するデータ オブジェクトを構築する方法。
  • ターゲットがデータ オブジェクトからシェル データを抽出する方法。
  • ソースがデータ転送操作を完了する方法。

シェル データ オブジェクトは、ソースがシェル データ オブジェクトを構築する方法と、そのデータ オブジェクトをターゲットで処理する方法の一般的な説明を提供します。 『シェル データ転送シナリオの処理』では、いくつかの一般的なシェル データ転送シナリオを処理する方法について詳しく説明します。