/VSTDragDrop_win.pas

http://github.com/foxblock/PNDTools · Pascal · 128 lines · 96 code · 12 blank · 20 comment · 7 complexity · d43a87d8c6c768c97184f4d9a0e616b6 MD5 · raw file

  1. {*******************************************************}
  2. { }
  3. { Functions for VirtualTree Drag&Drop implementation }
  4. { }
  5. {*******************************************************}
  6. unit VSTDragDrop_win;
  7. interface
  8. uses
  9. VirtualTrees,
  10. vstUtils,
  11. ActiveX, ShellAPI, Classes, Types, Windows;
  12. type
  13. { Implements the drag&drop functions called by the files tree in frmMain
  14. VSTDragDrop is called on dropping a file (or any content), identifies the
  15. dropped content and calles AddItem ultimately
  16. GetFileListFromObj is a helper function to transfer an IDataObject into
  17. filepath strings, which will get added to a passed StringList }
  18. TDragEvent = class
  19. procedure VSTDragDrop(Sender: TBaseVirtualTree;
  20. Source: TObject; DataObject: IDataObject; Formats: TFormatArray;
  21. Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
  22. procedure GetFileListFromObj(const DataObj: IDataObject;
  23. FileList: TStringList);
  24. end;
  25. implementation
  26. uses ComObj;
  27. procedure TDragEvent.VSTDragDrop(Sender: TBaseVirtualTree;
  28. Source: TObject; DataObject: IDataObject; Formats: TFormatArray;
  29. Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
  30. var
  31. I, j: Integer;
  32. MyList: TStringList;
  33. begin
  34. MyList := TStringList.Create;
  35. Sender.BeginUpdate;
  36. try
  37. for i := 0 to High(formats) - 1 do
  38. begin
  39. if Formats[i] = CF_HDROP then // Explorer drop
  40. begin
  41. GetFileListFromObj(DataObject, MyList);
  42. //here we have all filenames
  43. for j:=0 to MyList.Count - 1 do
  44. begin
  45. if Mode = dmOnNode then
  46. begin
  47. AddItem(Sender,Sender.DropTargetNode,MyList.Strings[j]);
  48. end else
  49. begin
  50. AddItem(Sender,nil,MyList.Strings[j]);
  51. end;
  52. end;
  53. end else
  54. if Formats[i] = CF_VIRTUALTREE then // VirtualTree drop
  55. begin
  56. case Mode of
  57. dmNowhere: Sender.ProcessDrop(DataObject,nil,Effect,amAddChildLast);
  58. dmAbove: Sender.ProcessDrop(DataObject,Sender.DropTargetNode,Effect,amInsertBefore);
  59. dmOnNode:
  60. begin;
  61. if not IsFile(Sender,Sender.DropTargetNode) then
  62. Sender.ProcessDrop(DataObject,Sender.DropTargetNode,Effect,amAddChildLast);
  63. end;
  64. dmBelow: Sender.ProcessDrop(DataObject,Sender.DropTargetNode,Effect,amInsertAfter);
  65. end;
  66. end;
  67. end;
  68. finally
  69. MyList.Free;
  70. Sender.SortTree(0,sdAscending,true);
  71. Sender.EndUpdate;
  72. end;
  73. end;
  74. procedure TDragEvent.GetFileListFromObj(const DataObj: IDataObject;
  75. FileList: TStringList);
  76. var
  77. FmtEtc: TFormatEtc; // specifies required data format
  78. Medium: TStgMedium; // storage medium containing file list
  79. DroppedFileCount: Integer; // number of dropped files
  80. I: Integer; // loops thru dropped files
  81. FileNameLength: Integer; // length of a dropped file name
  82. FileName: String; // name of a dropped file
  83. Buffer: Array [0..MAX_PATH] of Char;
  84. begin
  85. // Get required storage medium from data object
  86. FmtEtc.cfFormat := CF_HDROP;
  87. FmtEtc.ptd := nil;
  88. FmtEtc.dwAspect := DVASPECT_CONTENT;
  89. FmtEtc.lindex := -1;
  90. FmtEtc.tymed := TYMED_HGLOBAL;
  91. OleCheck(DataObj.GetData(FmtEtc, Medium));
  92. try
  93. try
  94. // Get count of files dropped
  95. DroppedFileCount := DragQueryFile(Medium.hGlobal, $FFFFFFFF, nil, 0);
  96. // Get name of each file dropped and process it
  97. for I := 0 to Pred(DroppedFileCount) do
  98. begin
  99. // get length of file name, then name itself
  100. FileNameLength := DragQueryFile(Medium.hGlobal, I, @buffer, sizeof(buffer));
  101. FileName := buffer;
  102. //SetLength(FileName, FileNameLength);
  103. //DragQueryFileW(Medium.hGlobal, I, PWideChar(FileName), FileNameLength + 1);
  104. // add file name to list
  105. FileList.Append(FileName);
  106. end;
  107. finally
  108. // Tidy up - release the drop handle
  109. // don't use DropH again after this
  110. DragFinish(Medium.hGlobal);
  111. end;
  112. finally
  113. ReleaseStgMedium(Medium);
  114. end;
  115. end;
  116. end.