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

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

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

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

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

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

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

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

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

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

どちらの場合も、転送されたデータは データ オブジェクトに含まれます。 データ オブジェクトは、 IDataObject インターフェイスを公開するコンポーネント オブジェクト モデル (COM) オブジェクトです。 概念的には、すべてのシェル データ転送が従う必要がある 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 インターフェイスへのポインターをシステムに提供します。

注意

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

 

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

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

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

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

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