◆ [Delphi] WM_DROPFILESメッセージを利用してドラッグ&ドロップの実現を試みる ⇒ 失敗
こんばんワイン。どーもボキです。

[Delphi] TShellListViewからエクスプローラへドラッグ&ドロップするでは、OLEを利用した(サンプルを転用した)。

EXEウィンドウへのドロップを受け付けるには、WM_DROPFILESメッセージを処理すればよいので、
Explorerへも同様にWM_DROPFILESメッセージでドロップするファイルパスを渡してやればよいのでは?と作ってみた。結果はNG

Explorerにドロップしてもウンともスンとも言わない。以下の参考サイトの3にもか書かれていたが、WM_DROPFILESメッセージの処理では上手く行かないと思われる。
メモ帳へのドロップは、タイトルバー位置(TextEditorWindow)ならばドロップしたファイルが開かれるが、それ以外の領域では反応しない。

参考サイト
 1.Delphi6 ローテクTipsウィンドウハンドルから実行ファイル名を取得
 2.Torry's Delphi Pages > ...send data to another program by auto-drag&drop?
 3.Visual Basic 掲示板 > WM_DROPFILEメッセージの引数の構造体は?
unit Unit1;

interface

uses
ShellAPI,
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ShellCtrls, ExtCtrls, StdCtrls, ShlObj, ActiveX, ComObj;

type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
ShellTreeView1: TShellTreeView;
Splitter1: TSplitter;
GroupBox2: TGroupBox;
ShellListView: TShellListView;
procedure ShellListViewEndDrag(Sender, Target: TObject; X, Y: Integer);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation


{$R *.dfm}

{ TForm1 }


function MakeDrop(const FileNames: array of string): THandle;
// Creates a hDrop Object
// erzeugt ein hDrop Object
var
i, size: Integer;
dt: PDragInfoA;
p: PChar;
begin
// Calculate memory size needed
// berechne notwendig Speichergrose
size := SizeOf(TDragInfoA) +1;
for i := 0 to High(FileNames) do
Inc(size, Length(FileNames[i]) +1);
// allocate the memory
// alloziere den speicher
Result := GlobalAlloc(GHND or GMEM_SHARE, size);

if Result <> 0 then begin
dt := GlobalLock(Result);
if dt <> nil then
try
// fill up with dt
// fulle daten
dt.uSize := SizeOf(TDragInfoA);
p := PChar(@dt.grfKeyState) + 4;
dt.lpFileList := p;
// filenames at the at of the header (separated with #0)
// am ende des headers nun die filenamen getrennt mit #0
for i := 0 to High(FileNames) do begin
size := Length(FileNames[i]);
Move(Pointer(FileNames[i])^, p^, size);
Inc(p, size + 1);
end;
finally
GlobalUnlock(Result);
end
else begin
GlobalFree(Result);
Result := 0;
end;
end;
end;


// ドラッグ終了時にPostMessageを発行
procedure TForm1.ShellListViewEndDrag(Sender, Target: TObject; X, Y: Integer);
var
lpt_Pos : TPoint;
lh_Handle : HWND;
_SLV : TShellListView;
sarr : Array of String;
i,idx : integer;
hdrp : hDrop;
begin
//マウスカーソルの位置を取得(スクリーン座標)
GetCursorPos(lpt_Pos);
//マウスカーソル下のウィンドウを取得し
lh_Handle := WindowFromPoint(lpt_Pos);
if lh_Handle = 0 then exit;

// 選択パスの取得
_SLV := TShellListView(Sender);
SetLength(sarr, _SLV.SelCount);
idx := 0;
for i := 0 to _SLV.Items.Count -1 do begin
if not _SLV.Items[i].Selected then continue;

sarr[idx] := _SLV.Folders[i].PathName;
Inc(idx);
end;

// WM_DROPFILESを発行
hdrp := MakeDrop(sarr);
if hdrp <> 0 then PostMessage(lh_Handle, WM_DROPFILES, hdrp, 0);
GlobalFree(hdrp);
end;


end.


[PR]
by yozda | 2015-04-30 22:20 | プログラミング | Trackback | Comments(0)
トラックバックURL : http://yozda.exblog.jp/tb/21178504
トラックバックする(会員専用) [ヘルプ]
<< LINE6 Mobile In... [Delphi] TFileL... >>