unit UnitDropFile;



interface
uses UnitClipQueue, UnitMisc;

type TDropFileAction = (
    DFA_ASFILE,
    DFA_PASTE,
    DFA_ASHANDLE
);

//function DropFile(ci : TClipItem; dfa : TDropFileAction = DFA_PASTE; target : Thandle = 0) : boolean; overload;
function DropFile(ci : TClipItem) : boolean; overload;
function DropFile(ci : TClipItem; target : THandle) : boolean; overload;
function DropFileHandle(ci : TClipItem; var handle : THandle) : boolean; overload;

implementation

uses Windows, WinAPI.messages, Classes, UnitPaste, ShlObj, ClipBrd,
UnitFrmEditTextExternal, Vcl.FileCtrl, System.SysUtils;



function DropFile(ci : TClipItem; dfa : TDropFileAction; var target : Thandle) : boolean; overload;
var
    hdrop: PDropFiles;
    hGlobal: THandle;
    len: Integer;

    filename : string;
    path : string;
    ext : string;
begin
    // save clip as normal text
    path := UnitMisc.GetAppPath + 'PasteAsFile\';
    ForceDirectories(path);
    case ci.GetFormatType  of
    FT_RICHTEXT:
        ext := '.rtf';
    FT_PICTURE:
        ext := '.bmp';
    else
        ext := '.txt';
    end;
//    filename := path + 'PopupClip'+IntToStr(Random(30))+ext;
    filename := path + 'PopupClip'+ext;
    frmEditTextExternal.SaveClip(filename, ci);


    // create HDROP structure
    filename := filename + #0 + #0;
    len := Length(filename) * 2;


    hGlobal := GlobalAlloc(
        GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, SizeOf(TDropFiles) + len
    );

    hdrop := GlobalLock(hGlobal);

    hdrop^.pFiles := SizeOf(TDropFiles);
    hdrop^.fWide := true;
    Move(filename[1], (PByte(hdrop) + SizeOf(TDropFiles))^, Len);
    GlobalUnlock(hGlobal);

    if dfa = DFA_PASTE then begin
//    if true then begin
        Clipboard.SetAsHandle(CF_HDROP, hGlobal);
        // PASTE
        Paste.SendCTRL_V;
    end else if dfa = DFA_ASFILE then begin
        result := PostMessage(target, WM_DROPFILES, hGlobal, 0);
        if result then begin
            GlobalFree(hGlobal);
//          TODO: research a proper way to free the memory
        end;
    end else if dfa = DFA_ASHANDLE then begin
        target := hGlobal;
    end;


end;


function DropFile(ci : TClipItem) : boolean;
var
    h : THandle;
begin
    DropFile(ci, DFA_PASTE, h);
end;
function DropFile(ci : TClipItem; target : Thandle) : boolean; overload;
begin
    DropFile(ci, DFA_ASFILE, target);
end;
function DropFileHandle(ci : TClipItem; var handle : THandle) : boolean; overload;
begin
    DropFile(ci, DFA_ASHANDLE, handle);
end;

initialization
finalization
end.
