C#であるAndroid端末のファイルのドロップ処理を実装する場合の注意
動作確認環境:Windows 10 64ビット、Microsoft Visual Studio 2019、C# 7.3
本文
あるAndroid機種はメーカーの公開するドライバをインストールすることでエクスプローラーで内部および外部ストレージを操作できますが、ドラッグ&ドロップ処理の実装は通常のファイル・フォルダと異なっています。そのため、C#では通常のファイルと同様にData.GetData(DataFormats.FileDrop)でファイルパスの一覧を取得することができません。
具体的にはデスクトップの通常のファイル・フォルダと特殊フォルダ、あるAnrdoid機種の外部ストレージ・内部ストレージ、フォルダ・テキストファイルのドラッグ&ドロップ時の動作は次表の通りです。
場所 | デスクトップ | あるAnrdoid機種 | |||
項目 | 通常フォルダ | 通常テキストファイル | 特殊フォルダ*1 | ストレージ*2 | フォルダ・テキストファイル |
可能な操作 | |||||
Copy | ○ | ○ | ○ | ||
Move | ○ | ○ | ○ | ○ | |
Link | ○ | ○ | ○ | ||
フォーマット*3 | |||||
DragContext | ○ | ○ | ○ | ○ | |
DragImageBits | ○ | ○ | ○ | ○ | |
DragSourceHelperFlags | ○ | ○ | ○ | ○ | |
FileContents | ○ | ○ | |||
FileDrop | ○ | ○ | |||
FileGroupDescriptorW | ○ | ○ | |||
FileName | ○ | ○ | |||
FileNameW | ○ | ○ | |||
InShellDragLoop | ○ | ○ | ○ | ○ | |
Preferred DropEffect | ○ | ○ | |||
Shell IDList Array | ○ | ○ | ○ | ○ | |
UsingDefaultDragImage | ○ | ||||
WPD NSE | ○ | ||||
WPD NSE PnPDevicePath | ○ | ||||
WPD NSE StoragePUID | ○ | ||||
WPD Storage Attributes | ○ |
- WPDはおそらくWindows Portable Device。
FileDropフォーマットが存在しないことに対する対処
あるAndroid端末ではドロップ時の情報(以下、ドロップオブジェクト)にFileDropフォーマットが設定されないため、Data.GetData(DataFormats.FileDrop)は失敗します。これは特殊なファイル・フォルダ(オブジェクト)にはファイルシステム上のパスが存在しないために発生しています。Data.GetData("Shell IDList Array")を使用することでアイテムIDリスト(LPITEMIDLIST)の配列であるCIDA構造体を取得することができ、これとWin32 APIを組み合わせることで表示名(ファイル名として表示される名前)などを取得・設定することができます。
DragOverイベントハンドラにおけるData.Effect設定の注意
あるAndroid端末はDaagOverイベントハンドラのData.AllowedEffectにCopy | Moveを設定します。したがって、Effectにこれ以外の値、例えばLinkを設定した場合、カーソルは禁止マークとなり、DragDropイベントも発生しません。特別な対応が不要であればAllowedEffectを設定しておくことで回避できます。