如何将文件从Explorer Shell拖放到Delphi应用程序中的VirtualTreeView控件中?
Mike Lischke在VirtualTreeView中提供了广泛的拖放支持,我正在使用TVirtualStringTree,它有一些on拖放事件,但我不知道如何让它接受从windows资源管理器shell将一些文件拖放到我的应用程序中的shell。我想在将文件拖到拖放控件上时加载这些文件 我尝试使用Anders Melander提供的第三方代码集来处理拖放操作,但由于VirtualTreeView已经将自己注册为拖放目标,因此我无法使用它 编辑:我找到了一个简单的解决方法:在VT.TreeOptions.MiscOptions中关闭toAcceptOLEDrop。如何将文件从Explorer Shell拖放到Delphi应用程序中的VirtualTreeView控件中?,delphi,drag-and-drop,windows-shell,virtualtreeview,Delphi,Drag And Drop,Windows Shell,Virtualtreeview,Mike Lischke在VirtualTreeView中提供了广泛的拖放支持,我正在使用TVirtualStringTree,它有一些on拖放事件,但我不知道如何让它接受从windows资源管理器shell将一些文件拖放到我的应用程序中的shell。我想在将文件拖到拖放控件上时加载这些文件 我尝试使用Anders Melander提供的第三方代码集来处理拖放操作,但由于VirtualTreeView已经将自己注册为拖放目标,因此我无法使用它 编辑:我找到了一个简单的解决方法:在VT.TreeO
如果有人知道一种使用VirtualTreeView的方法,而不使用第三方OLE shell拖放库,也不使用其广泛的OLE拖放支持来提取从shell中拖入的文件名列表,那就太酷了。我使用这种方法来捕获(接收)从资源管理器拖入TWinControl的文件。
您可以在控件上测试它。在标准TTreeView中工作正常 将ShellAPI添加到使用中 在私人部分:
private
originalEditWindowProc : TWndMethod;
procedure EditWindowProc(var Msg:TMessage);
// accept the files dropped
procedure FilesDrop(var Msg: TWMDROPFILES);
在创建表单时:
// Assign procedures
originalEditWindowProc := TreeView1.WindowProc;
TreeView1.WindowProc := EditWindowProc;
// Aceptar ficheros arrastrados // Accept the files
ShellAPI.DragAcceptFiles(TreeView1.Handle, True);
这两个程序是:
// Al arrastrar ficheros sobre el TV. On drop files to TV
procedure TForm1.FilesDrop(var Msg: TWMDROPFILES);
var
i:Integer;
DroppedFilename:string;
numFiles : longInt;
buffer : array[0..MAX_PATH] of char;
begin
// Número de ficheros arrastrados // Number of files
numFiles := DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0) ;
// Recorrido por todos los arrastrados // Accept all files
for i := 0 to (numFiles - 1) do begin
DragQueryFile(Msg.Drop, i, @buffer, sizeof(buffer));
// Proteccion
try
DroppedFilename := buffer;
// HERE you can do something with the file...
TreeView1.Items.AddChild(nil, DroppedFilename);
except
on E:Exception do begin
// catch
end;
end;
end;
end;
procedure TForm1.EditWindowProc(var Msg: TMessage);
begin
// if correct message, execute the procedure
if Msg.Msg = WM_DROPFILES then begin
FilesDrop(TWMDROPFILES(Msg))
end
else begin
// in other case do default...
originalEditWindowProc(Msg) ;
end;
end;
我希望这对你有用
关于。我的实现(与Delphi 2010配合得非常好。必须添加ActiveX和ShellApi以用于编译):
procedure TfMain.vstTreeDragDrop(Sender: TBaseVirtualTree; Source: TObject;
DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState;
Pt: TPoint; var Effect: Integer; Mode: TDropMode);
var
I, j: Integer;
MyList: TStringList;
AttachMode: TVTNodeAttachMode;
begin
if Mode = dmOnNode then
AttachMode := amInsertBefore
else if Mode = dmAbove then
AttachMode := amInsertBefore
else if Mode = dmBelow then
AttachMode := amInsertAfter
else
AttachMode := amAddChildLast;
MyList := TStringList.Create;
try
for i := 0 to High(formats) - 1 do
begin
if (Formats[i] = CF_HDROP) then
begin
GetFileListFromObj(DataObject, MyList);
//here we have all filenames
for j:=0 to MyList.Count - 1 do
begin
Sender.InsertNode(Sender.DropTargetNode, AttachMode);
end;
end;
end;
finally
MyList.Free;
end;
end;
procedure TfMain.GetFileListFromObj(const DataObj: IDataObject;
FileList: TStringList);
var
FmtEtc: TFormatEtc; // specifies required data format
Medium: TStgMedium; // storage medium containing file list
DroppedFileCount: Integer; // number of dropped files
I: Integer; // loops thru dropped files
FileNameLength: Integer; // length of a dropped file name
FileName: string; // name of a dropped file
begin
// Get required storage medium from data object
FmtEtc.cfFormat := CF_HDROP;
FmtEtc.ptd := nil;
FmtEtc.dwAspect := DVASPECT_CONTENT;
FmtEtc.lindex := -1;
FmtEtc.tymed := TYMED_HGLOBAL;
OleCheck(DataObj.GetData(FmtEtc, Medium));
try
try
// Get count of files dropped
DroppedFileCount := DragQueryFile(
Medium.hGlobal, $FFFFFFFF, nil, 0
);
// Get name of each file dropped and process it
for I := 0 to Pred(DroppedFileCount) do
begin
// get length of file name, then name itself
FileNameLength := DragQueryFile(Medium.hGlobal, I, nil, 0);
SetLength(FileName, FileNameLength);
DragQueryFileW(
Medium.hGlobal, I, PWideChar(FileName), FileNameLength + 1
);
// add file name to list
FileList.Append(FileName);
end;
finally
// Tidy up - release the drop handle
// don't use DropH again after this
DragFinish(Medium.hGlobal);
end;
finally
ReleaseStgMedium(Medium);
end;
end;