PageRenderTime 4ms CodeModel.GetById 1ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

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