censv Posted December 7, 2023 Share Posted December 7, 2023 Just as I manually use the right mouse button to click on a file and select the copy command from the pop-up menu. Thanks in advance. Link to comment Share on other sites More sharing options...
Andreik Posted December 7, 2023 Share Posted December 7, 2023 (edited) expandcollapse popup;=============================================================================== ; ; Description: Copy Files to Clipboard Like Explorer does ; Parameter(s): $sFile - Full Path to File(s) ; $sSeperator - Seperator for multiple Files, Default = '|' ; Requirement(s): v3.1.1.122+ ; Return Value(s): On Success - True ; On Failure - False and ; Sets @ERROR to: 1 - Unable to Open Clipboard ; 2 - Unable to Empty Cipboard ; 3 - GlobalAlloc Failed ; 4 - GlobalLock Failed ; 5 - Unable to Create H_DROP ; 6 - Unable to Update Clipboard ; 7 - Unable to Close Clipboard ; 8 - GlobalUnlock Failed ; Author(s): Piccaso (Florian Fida) ; Note(s): ; ;=============================================================================== Func _ClipPutFile($sFile, $sSeperator = "|") Local $vDllCallTmp, $nGlobMemSize, $hGlobal, $DROPFILES, $i, $hLock Local $GMEM_MOVEABLE = 0x0002, $CF_HDROP = 15 $sFile = $sFile & $sSeperator & $sSeperator $nGlobMemSize = StringLen($sFile) + 20 ; 20 = size of DROPFILES whitout buffer $vDllCallTmp = DllCall("user32.dll", "int", "OpenClipboard", "hwnd", 0) If @error Or $vDllCallTmp[0] = 0 Then SetError(1) Return False EndIf $vDllCallTmp = DllCall("user32.dll", "int", "EmptyClipboard") If @error Or $vDllCallTmp[0] = 0 Then SetError(2) Return False EndIf $vDllCallTmp = DllCall("kernel32.dll", "long", "GlobalAlloc", "int", $GMEM_MOVEABLE, "int", $nGlobMemSize) If @error Or $vDllCallTmp[0] < 1 Then SetError(3) Return False EndIf $hGlobal = $vDllCallTmp[0] $vDllCallTmp = DllCall("kernel32.dll", "long", "GlobalLock", "long", $hGlobal) If @error Or $vDllCallTmp[0] < 1 Then SetError(4) Return False EndIf $hLock = $vDllCallTmp[0] $DROPFILES = DllStructCreate("dword;ptr;int;int;int;char[" & StringLen($sFile) & "]", $hLock) If @error Then SetError(5) Return False EndIf DllStructSetData($DROPFILES, 1, DllStructGetSize($DROPFILES) - StringLen($sFile)) DllStructSetData($DROPFILES, 2, 0) DllStructSetData($DROPFILES, 3, 0) DllStructSetData($DROPFILES, 4, 0) DllStructSetData($DROPFILES, 5, 0) DllStructSetData($DROPFILES, 6, $sFile) For $i = 1 To StringLen($sFile) If DllStructGetData($DROPFILES, 6, $i) = Asc($sSeperator) Then DllStructSetData($DROPFILES, 6, 0, $i) Next $vDllCallTmp = DllCall("user32.dll", "long", "SetClipboardData", "int", $CF_HDROP, "long", $hGlobal) If @error Or $vDllCallTmp[0] < 1 Then SetError(6) $DROPFILES = 0 Return False EndIf $vDllCallTmp = DllCall("user32.dll", "int", "CloseClipboard") If @error Or $vDllCallTmp[0] = 0 Then SetError(7) $DROPFILES = 0 Return False EndIf $vDllCallTmp = DllCall("kernel32.dll", "int", "GlobalUnlock", "long", $hGlobal) If @error Then SetError(8) $DROPFILES = 0 Return False EndIf $vDllCallTmp = DllCall("kernel32.dll", "int", "GetLastError") If $vDllCallTmp = 0 Then $DROPFILES = 0 SetError(8) Return False Else $DROPFILES = 0 Return True EndIf EndFunc ;==>_ClipPutFile Or you can use a more compact version of the script above: #include <Memory.au3> #include <Clipboard.au3> $sFilePath = '<path to your file>' _ClipPutFile($sFilePath) Func _ClipPutFile($sFile) Local $iLen = StringLen($sFile) + 2 _ClipBoard_Open(0) _ClipBoard_Empty() Local $hGlobal = _MemGlobalAlloc($iLen + 20, $GMEM_MOVEABLE) Local $hLock = _MemGlobalLock($hGlobal) Local $tDROPFILES = DllStructCreate("dword pFiles;long x;long y;int fNC;int fWide;char File[" & $iLen & "]", $hLock) $tDROPFILES.pFiles = DllStructGetSize($tDROPFILES) - $iLen $tDROPFILES.x = 0 $tDROPFILES.y = 0 $tDROPFILES.fNC = 0 $tDROPFILES.fWide = 0 $tDROPFILES.File = $sFile & Chr(0) & Chr(0) _ClipBoard_SetDataEx($hGlobal, $CF_HDROP) _MemGlobalUnlock($hGlobal) _ClipBoard_Close() _MemGlobalFree($hGlobal) EndFunc Edited December 7, 2023 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
censv Posted December 7, 2023 Author Share Posted December 7, 2023 1 hour ago, Andreik said: expandcollapse popup;=============================================================================== ; ; Description: Copy Files to Clipboard Like Explorer does ; Parameter(s): $sFile - Full Path to File(s) ; $sSeperator - Seperator for multiple Files, Default = '|' ; Requirement(s): v3.1.1.122+ ; Return Value(s): On Success - True ; On Failure - False and ; Sets @ERROR to: 1 - Unable to Open Clipboard ; 2 - Unable to Empty Cipboard ; 3 - GlobalAlloc Failed ; 4 - GlobalLock Failed ; 5 - Unable to Create H_DROP ; 6 - Unable to Update Clipboard ; 7 - Unable to Close Clipboard ; 8 - GlobalUnlock Failed ; Author(s): Piccaso (Florian Fida) ; Note(s): ; ;=============================================================================== Func _ClipPutFile($sFile, $sSeperator = "|") Local $vDllCallTmp, $nGlobMemSize, $hGlobal, $DROPFILES, $i, $hLock Local $GMEM_MOVEABLE = 0x0002, $CF_HDROP = 15 $sFile = $sFile & $sSeperator & $sSeperator $nGlobMemSize = StringLen($sFile) + 20 ; 20 = size of DROPFILES whitout buffer $vDllCallTmp = DllCall("user32.dll", "int", "OpenClipboard", "hwnd", 0) If @error Or $vDllCallTmp[0] = 0 Then SetError(1) Return False EndIf $vDllCallTmp = DllCall("user32.dll", "int", "EmptyClipboard") If @error Or $vDllCallTmp[0] = 0 Then SetError(2) Return False EndIf $vDllCallTmp = DllCall("kernel32.dll", "long", "GlobalAlloc", "int", $GMEM_MOVEABLE, "int", $nGlobMemSize) If @error Or $vDllCallTmp[0] < 1 Then SetError(3) Return False EndIf $hGlobal = $vDllCallTmp[0] $vDllCallTmp = DllCall("kernel32.dll", "long", "GlobalLock", "long", $hGlobal) If @error Or $vDllCallTmp[0] < 1 Then SetError(4) Return False EndIf $hLock = $vDllCallTmp[0] $DROPFILES = DllStructCreate("dword;ptr;int;int;int;char[" & StringLen($sFile) & "]", $hLock) If @error Then SetError(5) Return False EndIf DllStructSetData($DROPFILES, 1, DllStructGetSize($DROPFILES) - StringLen($sFile)) DllStructSetData($DROPFILES, 2, 0) DllStructSetData($DROPFILES, 3, 0) DllStructSetData($DROPFILES, 4, 0) DllStructSetData($DROPFILES, 5, 0) DllStructSetData($DROPFILES, 6, $sFile) For $i = 1 To StringLen($sFile) If DllStructGetData($DROPFILES, 6, $i) = Asc($sSeperator) Then DllStructSetData($DROPFILES, 6, 0, $i) Next $vDllCallTmp = DllCall("user32.dll", "long", "SetClipboardData", "int", $CF_HDROP, "long", $hGlobal) If @error Or $vDllCallTmp[0] < 1 Then SetError(6) $DROPFILES = 0 Return False EndIf $vDllCallTmp = DllCall("user32.dll", "int", "CloseClipboard") If @error Or $vDllCallTmp[0] = 0 Then SetError(7) $DROPFILES = 0 Return False EndIf $vDllCallTmp = DllCall("kernel32.dll", "int", "GlobalUnlock", "long", $hGlobal) If @error Then SetError(8) $DROPFILES = 0 Return False EndIf $vDllCallTmp = DllCall("kernel32.dll", "int", "GetLastError") If $vDllCallTmp = 0 Then $DROPFILES = 0 SetError(8) Return False Else $DROPFILES = 0 Return True EndIf EndFunc ;==>_ClipPutFile Or you can use a more compact version of the script above: #include <Memory.au3> #include <Clipboard.au3> $sFilePath = '<path to your file>' _ClipPutFile($sFilePath) Func _ClipPutFile($sFile) Local $iLen = StringLen($sFile) + 2 _ClipBoard_Open(0) _ClipBoard_Empty() Local $hGlobal = _MemGlobalAlloc($iLen + 20, $GMEM_MOVEABLE) Local $hLock = _MemGlobalLock($hGlobal) Local $tDROPFILES = DllStructCreate("dword pFiles;long x;long y;int fNC;int fWide;char File[" & $iLen & "]", $hLock) $tDROPFILES.pFiles = DllStructGetSize($tDROPFILES) - $iLen $tDROPFILES.x = 0 $tDROPFILES.y = 0 $tDROPFILES.fNC = 0 $tDROPFILES.fWide = 0 $tDROPFILES.File = $sFile & Chr(0) & Chr(0) _ClipBoard_SetDataEx($hGlobal, $CF_HDROP) _MemGlobalUnlock($hGlobal) _ClipBoard_Close() _MemGlobalFree($hGlobal) EndFunc Thanks for the reply, but neither code works. Link to comment Share on other sites More sharing options...
Solution Andreik Posted December 7, 2023 Solution Share Posted December 7, 2023 (edited) The code works but it's not unicode. #include <Memory.au3> #include <Clipboard.au3> #include <WinAPIConv.au3> $sFilePath = '<path to your file'> _ClipPutFile($sFilePath) Func _ClipPutFile($sFile) Local $iLen = StringLen($sFile) _ClipBoard_Open(0) _ClipBoard_Empty() Local $hGlobal = _MemGlobalAlloc(($iLen + 2) * 2 + 20, $GMEM_MOVEABLE) Local $hLock = _MemGlobalLock($hGlobal) $tDROPFILES = DllStructCreate("dword pFiles;long x;long y;int fNC;int fWide;wchar File[" & $iLen & "];wchar Null[2]", $hLock) $tDROPFILES.pFiles = DllStructGetPtr($tDROPFILES, 'File') - DllStructGetPtr($tDROPFILES, 'pFiles') $tDROPFILES.x = 0 $tDROPFILES.y = 0 $tDROPFILES.fNC = 0 $tDROPFILES.fWide = 1 _WinAPI_MultiByteToWideCharEx($sFile, DllStructGetPtr($tDROPFILES, 'File')) $tDROPFILES.Null = Chr(0) & Chr(0) _ClipBoard_SetDataEx($hGlobal, $CF_HDROP) _MemGlobalUnlock($hGlobal) _ClipBoard_Close() _MemGlobalFree($hGlobal) EndFunc Edited December 7, 2023 by Andreik censv 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Nine Posted December 7, 2023 Share Posted December 7, 2023 You should set .pFiles to 20, instead of the calculation (in the second script of @Andreik), because of alignment it may be shifted a few bytes. Now, you should try to debug yourself the script he gave to you. Seems that you are passing a file name longer than expected. Put some ConsoleWrite to see value of the variables and the return of functions along with @error, so you can determine what is going on. Instead of saying it is not working... “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
KaFu Posted December 7, 2023 Share Posted December 7, 2023 I think it's wrong to free the Mem, as it will be handled by the OS. Here's a snippet I use in SMF. expandcollapse popup#include <ClipBoard.au3> #include <WinAPISysWin.au3> Global Const $DROPFILES = "DWORD pFiles; int pt[2]; int fNC; int fWide;" Global Const $CFSTR_PREFERREDDROPEFFECT = "Preferred DropEffect" Global Const $CF_PREFERREDDROPEFFECT = _ClipBoard_RegisterFormat($CFSTR_PREFERREDDROPEFFECT) Global Const $DROPEFFECT_COPY = 1 Global Const $DROPEFFECT_MOVE = 2 _Clipboard_Copy_File(@ScriptFullPath) ; _Clipboard_Move_File(@ScriptFullPath) Func _Clipboard_Copy_File($sFile) Local $hClip = _ClipBoard_Open(_WinAPI_GetDesktopWindow()) If $hClip Then _ClipBoard_Empty() Local $HDROP = _CreateDROPFILES($sFile) ; Mem must NOT be freed via_MemGlobalFree(), as script will crash or fail. Mem will be handled by OS. Local $DROPEFFECT = _CreatePREFERREDDROPEFFECT($DROPEFFECT_COPY) ; Mem must NOT be freed via_MemGlobalFree(), as script will crash or fail. Mem will be handled by OS. _ClipBoard_SetDataEx($HDROP, $CF_HDROP) _ClipBoard_SetDataEx($DROPEFFECT, $CF_PREFERREDDROPEFFECT) _ClipBoard_Close() EndIf EndFunc ;==>_Clipboard_Copy_File Func _Clipboard_Move_File($sFile) Local $hClip = _ClipBoard_Open(_WinAPI_GetDesktopWindow()) If $hClip Then _ClipBoard_Empty() Local $HDROP = _CreateDROPFILES($sFile) ; Mem must NOT be freed via_MemGlobalFree(), as script will crash or fail. Mem will be handled by OS. Local $DROPEFFECT = _CreatePREFERREDDROPEFFECT($DROPEFFECT_MOVE) ; Mem must NOT be freed via_MemGlobalFree(), as script will crash or fail. Mem will be handled by OS. _ClipBoard_SetDataEx($HDROP, $CF_HDROP) _ClipBoard_SetDataEx($DROPEFFECT, $CF_PREFERREDDROPEFFECT) _ClipBoard_Close() EndIf EndFunc ;==>_Clipboard_Move_File ;=============================================================================== ; ; Function Name: _CreateDROPFILES ; Description:: Creates a DROPFILES-structure ; Parameter(s): $Files - Pipe-separated list of files to copy: example: C:\File1.bin|D:\AnotherFile.dat ; Requirement(s): COM/OLE UDF ; Return Value(s): HGLOBAL-Pointer to a DROPFILES structure ; Author(s): prog@ndy ; ;=============================================================================== ; http://www.autoitscript.com/forum/index.php?showtopic=91046&view=findpost&p=654849 ; http://www.autoit.de/index.php?page=Thread&postID=81909&highlight=hdrop#post81909 Func _CreateDROPFILES($Files) $Files = String($Files) Local $hMem = _MemGlobalAlloc(_DragDrop_SIZEOF($DROPFILES) + ((StringLen($Files) + 2) * 2), $GPTR) $Files = StringSplit($Files, "|") Local $stDROPFILES = DllStructCreate($DROPFILES, $hMem) Local $hPtr = $hMem + DllStructGetSize($stDROPFILES) DllStructSetData($stDROPFILES, "fWide", 1) DllStructSetData($stDROPFILES, 1, DllStructGetSize($stDROPFILES)) For $i = 1 To $Files[0] $next = DllStructCreate("wchar[" & StringLen($Files[$i]) + 1 & "]", $hPtr) DllStructSetData($next, 1, $Files[$i] & ChrW(0)) $hPtr += (StringLen($Files[$i]) + 1) * 2 Next Local $next = DllStructCreate("wchar[1]", $hPtr) DllStructSetData($next, 1, ChrW(0)) Return $hMem EndFunc ;==>_CreateDROPFILES ; Prog@ndy Func _CreatePREFERREDDROPEFFECT($dwEffect) Local $pMem = _MemGlobalAlloc(4, $GPTR) ; 4 bytes - 1 DWORD If Not $pMem Then Return SetError(1, 0, 0) DllStructSetData(DllStructCreate("DWORD", $pMem), 1, $dwEffect) Return $pMem EndFunc ;==>_CreatePREFERREDDROPEFFECT ; Author: Prog@ndy Func _DragDrop_SIZEOF($tagStruct) Return DllStructGetSize(DllStructCreate($tagStruct, 1)) EndFunc ;==>_DragDrop_SIZEOF Andreik and censv 2 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Andreik Posted December 7, 2023 Share Posted December 7, 2023 @KaFu That's true. I read now on MSDN: Quote If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. The application may not write to or free the data once ownership has been transferred to the system, but it can lock and read from the data until the CloseClipboard function is called. (The memory must be unlocked before the Clipboard is closed.) If the hMem parameter identifies a memory object, the object must have been allocated using the function with the GMEM_MOVEABLE flag. So it should be something like this: #include <Memory.au3> #include <Clipboard.au3> #include <WinAPIConv.au3> $sFilePath = '<path to your file'> _ClipPutFile($sFilePath) Func _ClipPutFile($sFile) Local $iLen = StringLen($sFile) _ClipBoard_Open(0) _ClipBoard_Empty() Local $hGlobal = _MemGlobalAlloc(($iLen + 2) * 2 + 20, $GMEM_MOVEABLE) Local $hLock = _MemGlobalLock($hGlobal) $tDROPFILES = DllStructCreate("dword pFiles;long x;long y;int fNC;int fWide;wchar File[" & $iLen & "];wchar Null[2]", $hLock) $tDROPFILES.pFiles = DllStructGetPtr($tDROPFILES, 'File') - DllStructGetPtr($tDROPFILES, 'pFiles') $tDROPFILES.x = 0 $tDROPFILES.y = 0 $tDROPFILES.fNC = 0 $tDROPFILES.fWide = 1 _WinAPI_MultiByteToWideCharEx($sFile, DllStructGetPtr($tDROPFILES, 'File')) $tDROPFILES.Null = Chr(0) & Chr(0) _ClipBoard_SetDataEx($hGlobal, $CF_HDROP) _MemGlobalUnlock($hGlobal) _ClipBoard_Close() EndFunc censv and KaFu 2 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
rudi Posted December 8, 2023 Share Posted December 8, 2023 (edited) Hello, use _ClipPutFile() If you place multiple FullFilePathNames, separated by "|" into one string, you can place them all-in-one to the clipboard, regardless of the folders these files are stored in. In your screenshot you already used this function, I didn't get, why you are not happy with that one? I used it in several "Collect files across many differnt folders" tools, no problems. $put2clip="C:\temp\File-1.txt|D:\OtherDrive\anotherfolder\file-2.txt|\\server\share\path\file-3.txt" _ClipPutFile($put2clip) Edited December 8, 2023 by rudi censv and ioa747 1 1 Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
KaFu Posted December 8, 2023 Share Posted December 8, 2023 4 hours ago, rudi said: use _ClipPutFile() really never saw that function. TheDcoder 1 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Andreik Posted December 8, 2023 Share Posted December 8, 2023 @KaFu I think he is talking about Piccaso's function (see second post in this thread) that support multiple files. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
KaFu Posted December 8, 2023 Share Posted December 8, 2023 _ClipPutFile() is in the standard UDFs (Misc.au3). OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Nine Posted December 8, 2023 Share Posted December 8, 2023 Yes and it is freeing memory TheDcoder and KaFu 1 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Andreik Posted December 8, 2023 Share Posted December 8, 2023 @NineYou should open a ticket so it could be fixed. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
censv Posted December 9, 2023 Author Share Posted December 9, 2023 17 hours ago, rudi said: In your screenshot you already used this function, I didn't get, why you are not happy with that one? Awesome, thank you. I wasn't aware of this function in standard udf before. The _ClipPutFile function you see was written by kind-hearted Andreik Link to comment Share on other sites More sharing options...
Nine Posted December 9, 2023 Share Posted December 9, 2023 17 hours ago, Andreik said: open a ticket so it could be fixed. yep -- done “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now