デスクトップやエクスプローラからドラッグ&ドロップされたファイル名を
受け取る方法をご紹介します。
この機能を実現するには、簡単なWindows APIを以下の3つ使用します。
- DragAcceptFiles
- DragQueryFile
- DragFinish
まずドラッグ&ドロップを受け入れ可能にします。
フォームのCreateイベント等で実行すれば良いでしょう。
// 他のインスタンスからドラッグを受け入れる DragAcceptFiles(Handle, True);
これを実行する事で、指定されたHandleを持つウィンドウが
WM_DROPFILESというメッセージを受け取ることができるようになります。
このメッセージを受け取ったときにパラメータに含まれるファイル名を取り出せば、
ドラッグ&ドロップが完成です。
メッセージを受け取ったときにDropFilesという手続きを呼ぶようにします。
private宣言部などに以下のような宣言を追加します。
private procedure DropFiles(var msg: TMessage); message WM_DROPFILES;
例えば、DropFiles手続き内でドロップされたファイル名を
ListBoxに追加していく場合は、次のように書くことができます。
procedure TForm1.DropFiles(var msg: TMessage); var i, cnt: Integer; sBuff: Array [0..255] of Char; begin // DropされたFileの数を取得します cnt := DragQueryFile(msg.WParam, $FFFFFFFF, sBuff, 255); for i := 0 to cnt - 1 do begin // Dropされた個々のFileをFullPathで取得します DragQueryFile(msg.WParam, i, sBuff, 255); // 上の行で取得したFullPathをListBoxに追加 ListBox1.Items.Add(String(sBuff)); end; // Dropが終了したことを通知します DragFinish(msg.WParam); end;
ここまでのロジックでは、アプリケーションが管理者権限で実行中で、
かつUACが有効な環境下では、ドラッグ&ドロップが無効になってしまいます。
これはWindowsの仕様で、例えばメモ帳であっても、
UACが有効な環境下で管理者権限で実行した場合はファイルドロップを受け付けません。
Delphi/400において、管理者権限で実行中のアプリケーションでもドロップを有効にするには
「DragAcceptFiles」を記述する直前または直後に以下のロジックを追加します。
(※Delphi/400 XE5以降で標準対応)
// 他のインスタンスからドラッグを受け入れる
DragAcceptFiles(Handle, True);
// 管理者権限起動時でもドロップを受け付ける
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ADD);
(通常処理:ミガロ.情報マガジン「MIGARO News!!」Vol.32 2003年9月号より)
(管理者権限:ミガロ.情報マガジン「MIGARO News!!」Vol.223 2019年12月号より)