Set and Get Clipboard Files (Windows, MacOS)
Posted: Tue Apr 25, 2023 6:02 pm
After I had the function running for MacOS, I also implemented it for Windows. Still missing for Linux 
Org Link: MacOS Tips & Tricks
Update v1.01.4
Org Link: MacOS Tips & Tricks
Update v1.01.4
Code: Select all
;-TOP
; Comment : Set and Get Clipboard Files
; Author : mk-soft
; Version : v1.01.4
; Create : 24.04.2023
; Update : 25.04.2023
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
;-- Window
Procedure SetClipboardFile(FileName.s)
Protected r1, Size, len, *hGlobal, *dropfiles.DROPFILES
len = StringByteLength(FileName) + SizeOf(Character)
size = len + SizeOf(Character) + SizeOf(DROPFILES)
*hGlobal = GlobalAlloc_(#GHND, size)
If *hGlobal
*dropfiles = GlobalLock_(*hGlobal)
If *dropfiles
*dropfiles\pFiles = SizeOf(DROPFILES)
*dropfiles\fNC = #False
*dropfiles\fWide = #True
PokeS(*dropfiles + SizeOf(DROPFILES), FileName)
GlobalUnlock_(*dropfiles)
If OpenClipboard_(0)
r1 = SetClipboardData_(#CF_HDROP, *hGlobal)
CloseClipboard_()
EndIf
EndIf
GlobalFree_(*hGlobal)
EndIf
ProcedureReturn r1
EndProcedure
Procedure SetClipboardFiles(List Files.s())
Protected r1, Size, len, *hGlobal, *dropfiles.DROPFILES, *ofs
ForEach Files()
len + StringByteLength(Files()) + SizeOf(Character)
Next
size = len + SizeOf(Character) + SizeOf(DROPFILES)
*hGlobal = GlobalAlloc_(#GHND, size)
If *hGlobal
*dropfiles = GlobalLock_(*hGlobal)
If *dropfiles
*dropfiles\pFiles = SizeOf(DROPFILES)
*dropfiles\fNC = #False
*dropfiles\fWide = #True
*ofs = *dropfiles + SizeOf(DROPFILES)
ForEach Files()
PokeS(*ofs, Files())
*ofs + StringByteLength(Files()) + SizeOf(Character)
Next
GlobalUnlock_(*dropfiles)
If OpenClipboard_(0)
r1 = SetClipboardData_(#CF_HDROP, *hGlobal)
CloseClipboard_()
EndIf
EndIf
GlobalFree_(*hGlobal)
EndIf
ProcedureReturn r1
EndProcedure
Procedure GetClipboardFiles(List Files.s())
Protected cnt, *hGlobal, *dropfiles.DROPFILES, *ofs1.Character, *ofs2.ascii
ClearList(Files())
If IsClipboardFormatAvailable_(#CF_HDROP)
If OpenClipboard_(0)
*hGlobal = GetClipboardData_(#CF_HDROP)
If *hGlobal
*dropfiles = GlobalLock_(*hGlobal)
If *dropfiles\fWide
*ofs1 = *dropfiles + *dropfiles\pFiles
While *ofs1\c
AddElement(Files())
Files() = PeekS(*ofs1)
*ofs1 + StringByteLength(Files()) + SizeOf(Character)
Wend
Else
*ofs2 = *dropfiles + *dropfiles\pFiles
While *ofs2\a
AddElement(Files())
Files() = PeekS(*ofs2, -1, #PB_Ascii)
*ofs2 + StringByteLength(Files(), #PB_Ascii) + SizeOf(Ascii)
Wend
EndIf
GlobalUnlock_(*dropfiles)
GlobalFree_(*hGlobal)
cnt = ListSize(Files())
EndIf
CloseClipboard_()
EndIf
EndIf
ProcedureReturn cnt
EndProcedure
CompilerCase #PB_OS_Linux
;-- Linux TODO
CompilerCase #PB_OS_MacOS
;-- macOS
Macro CocoaString(NSString)
PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
EndMacro
Procedure SetClipboardFile(FileName.s)
Protected r1, pool, fileURL, objectsToCopy, pasteboard
pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
fileURL = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @FileName)
objectsToCopy = CocoaMessage(0, 0, "NSArray arrayWithObject:", fileURL)
pasteboard = CocoaMessage(0, 0, "NSPasteboard generalPasteboard")
CocoaMessage(0, pasteboard, "clearContents")
r1 = CocoaMessage(0, pasteboard, "writeObjects:", objectsToCopy)
CocoaMessage(0, pool, "release")
ProcedureReturn r1
EndProcedure
Procedure SetClipboardFiles(List Files.s())
Protected r1, pool, fileURL, objectsToCopy, pasteboard, filename.s, cnt
pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
cnt = ListSize(Files())
objectsToCopy = CocoaMessage(0, 0, "NSMutableArray arrayWithCapacity:", cnt)
ForEach Files()
filename = Files()
fileURL = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @filename)
CocoaMessage(0, objectsToCopy, "addObject:", fileURL)
Next
pasteboard = CocoaMessage(0, 0, "NSPasteboard generalPasteboard")
CocoaMessage(0, pasteboard, "clearContents")
r1 = CocoaMessage(0, pasteboard, "writeObjects:", objectsToCopy)
CocoaMessage(0, pool, "release")
ProcedureReturn r1
EndProcedure
Procedure GetClipboardFiles(List Files.s())
Protected pool, number, dictionary, classURL, arrayObjects, pasteboard, urls, fileURL, string, cnt, index
ClearList(Files())
pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
number = CocoaMessage(0, 0, "NSNumber numberWithBool:", #True)
dictionary = CocoaMessage(0, 0, "NSDictionary dictionaryWithObject:", number, "forKey:$", @"NSPasteboardURLReadingFileURLsOnlyKey")
classURL = CocoaMessage(0, 0, "NSURL class")
arrayObjects = CocoaMessage(0, 0, "NSArray arrayWithObject:", classURL)
pasteboard = CocoaMessage(0, 0, "NSPasteboard generalPasteboard")
urls = CocoaMessage(0, pasteboard, "readObjectsForClasses:", arrayObjects, "options:", dictionary)
cnt = CocoaMessage(0, urls, "count")
If cnt >= 1
For index = 0 To cnt - 1
fileURL = CocoaMessage(0, urls, "objectAtIndex:", index)
string = CocoaMessage(0, fileURL, "path")
AddElement(Files())
Files() = CocoaString(string)
Next
EndIf
CocoaMessage(0, pool, "release")
ProcedureReturn cnt
EndProcedure
CompilerEndSelect
; ****
CompilerIf #PB_Compiler_IsMainFile
;-- Examples
#example = 3
CompilerIf #example = 1
filename.s = OpenFileRequester("", "", "", 0)
If filename
r1 = SetClipboardFile(filename)
If r1
Debug "Ok"
Else
Debug "False"
EndIf
EndIf
CompilerElseIf #example = 2
Global NewList FileList.s()
filename.s = OpenFileRequester("", "", "", 0, #PB_Requester_MultiSelection)
While filename
AddElement(FileList())
FileList() = filename
filename = NextSelectedFileName()
Wend
If FileSize(FileList())
r1 = SetClipboardFiles(FileList())
If r1
Debug "Ok"
Else
Debug "False"
EndIf
EndIf
CompilerElseIf #example = 3
Global NewList FileList.s()
If GetClipboardFiles(FileList())
ForEach FileList()
Debug FileList()
Next
Else
Debug "No Clipboard Files"
EndIf
CompilerEndIf
CompilerEndIf