共用方式為


使用拖放和剪貼簿傳輸 Shell 物件

許多應用程式可讓使用者使用滑鼠拖放資料,或使用剪貼簿將資料傳輸到另一個應用程式。 許多可以傳輸的資料類型包括 Shell 物件,例如檔案或資料夾。 殼層資料傳輸可以在兩個應用程式之間進行,但使用者也可以從桌面或 Windows 檔案總管來回傳輸 Shell 資料。

雖然檔案是最常傳輸的 Shell 物件,但殼層資料傳輸可能會牽涉到 Shell 命名空間中找到的任何各種物件。 例如,您的應用程式可能需要將檔案傳送至虛擬資料夾,例如回收站,或接受來自非 Microsoft 命名空間副檔名的物件。 如果您要實作命名空間延伸模組,它必須能夠正常作為卸載來源和目標。

本檔討論應用程式如何使用 Shell 物件實作拖放和剪貼簿資料傳輸。

拖放如何與殼層物件搭配運作

應用程式通常需要為使用者提供傳輸殼層資料的方式。 部份範例如下:

  • 從 Windows 檔案總管或桌面拖曳檔案,並將它放在應用程式上。
  • 將檔案複製到 Windows 檔案總管中的剪貼簿,並將其貼到應用程式中。
  • 將檔案從應用程式拖曳至回收站。

如需如何處理這些案例和其他案例的詳細討論,請參閱 處理殼層資料傳輸案例。 本檔著重于 Shell 資料傳輸背後的一般原則。

Windows 提供兩種標準方式,讓應用程式傳輸殼層資料:

  • 使用者剪下或複製 Shell 資料,例如一或多個檔案至剪貼簿。 另一個應用程式會從剪貼簿擷取資料。
  • 使用者拖曳代表來源應用程式資料的圖示,並將圖示放在目標擁有的視窗上。

在這兩種情況下,傳輸的資料會包含在 資料物件中。 資料物件是元件物件模型 (COM) 公開 IDataObject 介面的物件。 實際上,所有 Shell 資料傳輸都必須遵循三個基本步驟:

  1. 來源會建立代表要傳送之資料的資料物件。
  2. 目標會接收資料物件的 IDataObject 介面指標。
  3. 目標會呼叫 IDataObject 介面,以從中擷取資料。

剪貼簿和拖放資料傳輸之間的差異主要在於 如何將 IDataObject 指標從來源傳輸到目標。

剪貼簿資料傳輸

剪貼簿是傳輸 Shell 資料最簡單的方式。 基本程式類似于標準剪貼簿資料傳輸。 不過,因為您要傳送資料物件的指標,而不是資料本身,所以您必須使用 OLE 剪貼簿 API,而不是標準剪貼簿 API。 下列程式概述如何使用 OLE 剪貼簿 API,透過剪貼簿傳輸殼層資料:

  1. 資料來源會建立資料物件來包含資料。
  2. 資料來源會呼叫 OleSetClipboard,將指標放在剪貼簿上的資料物件的 IDataObject 介面。
  3. 目標會呼叫 OleGetClipboard 來擷取資料物件的 IDataObject 介面指標。
  4. 目標會藉由呼叫 IDataObject::GetData 方法來擷取資料。
  5. 使用某些 Shell 資料傳輸時,目標可能也需要呼叫資料物件的 IDataObject::SetData 方法,以針對資料傳輸結果提供資料物件的意見反應。 如需這類作業的範例,請參閱 處理優化移動作業

拖放資料傳輸

雖然實作較為複雜,但拖放資料傳輸對於剪貼簿有一些顯著的優點:

  • 拖放傳輸可以透過簡單的滑鼠移動來完成,讓作業比剪貼簿更有彈性且直覺。
  • 拖放可為使用者提供作業的視覺標記法。 使用者可以遵循圖示,因為它從來源移至目標。
  • 拖放功能會在資料可用時通知目標。

拖放作業也會使用資料物件來傳輸資料。 不過,卸載來源必須提供剪貼簿傳輸所需的功能:

  • 卸載來源也必須建立公開 IDropSource 介面的物件。 當作業正在進行時,系統會使用 IDropSource 與來源通訊。
  • 拖放資料物件負責追蹤資料指標移動,並顯示圖示來代表資料物件。

卸載目標也必須提供比處理剪貼簿傳輸所需的功能更多:

  • 卸載目標必須公開 IDropTarget 介面。 當游標位於目標視窗上方時,系統會使用 IDropTarget 來提供目標,並提供資料指標位置等資訊,並在卸載資料時通知它。
  • 卸載目標必須藉由呼叫 RegisterDragDrop向系統註冊本身。 此函式會為系統提供目標視窗的控制碼,以及目標應用程式的 IDropTarget 介面指標。

注意

針對拖放作業,您的應用程式必須使用 OleInitialize初始化 COM,而不是 CoInitialize

 

下列程式概述通常用來以拖放方式傳輸殼層資料的基本步驟:

  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 資料物件中。 您的應用程式可能需要處理的一些不同資料傳輸案例。 每個資料類型和案例都需要稍微不同的方法,才能執行程式中的三個主要步驟:

  • 來源如何建構資料物件以包含 Shell 資料。
  • 目標如何從資料物件擷取 Shell 資料。
  • 來源如何完成資料傳輸作業。

Shell Data Object提供來源如何建構 Shell 資料物件的一般討論,以及如何由目標處理該資料物件。 處理殼層資料傳輸案例 會詳細討論如何處理一些常見的殼層資料傳輸案例。