loop through clipboard content ?

ok, first draft.
given

Protected Structure NSRange
  location as Integer
  length as Integer
End Structure

then this methods returns all the actual types in a clipboard (on macos only for now)

Public Function ItemTypes(extends c As Clipboard) as String()
  #If Target64Bit
    Dim SizeOfPointer As Integer = 8
  #Else
    Dim SizeOfPointer As Integer = 4
  #EndIf
  
  #If targetMacOS
    ' NSObject
    Declare Function alloc Lib CocoaLib selector "alloc" (class_id As Ptr) As Ptr
    ' NSArray
    Declare Function initWithArray Lib CocoaLib selector "initWithArray:copyItems:" (obj_id As Ptr, anArray As Ptr, flag As Boolean) As Ptr
    Declare Function m_count Lib CocoaLib selector "count" ( obj As Ptr ) As UInteger
    Declare Sub getObjects Lib CocoaLib selector "getObjects:range:" (obj_id As Ptr, aBuffer As Ptr, aRange As NSRange)
    ' NSPasteBoard
    Declare Function NSClassFromString Lib CocoaLib (aClassName As CFStringRef) As Ptr
    Declare Function generalPasteboard Lib CocoaLib selector "generalPasteboard" (obj_id As Ptr) As Ptr
    Declare Function types Lib CocoaLib selector "types" (obj_id As Ptr) As Ptr
    ' NSString
    Declare Function CFRetain Lib CarbonLib (cf As Ptr) As CFStringRef
    
    Dim pasteboardRef As Ptr = generalPasteboard(NSClassFromString("NSPasteboard")) ' get actual general pasteboard
    If pasteboardRef <> Nil Then
      Dim anArrayRef,nsarray_id As Ptr
      anArrayRef = types(pasteboardRef)
      nsarray_id = initWithArray(alloc(NSClassFromString("NSArray")), anArrayRef, False)
      
      Dim retArray() As String
      
      Dim arrayRange As NSRange
      arrayRange.location = 0
      arrayRange.length = m_count( nsarray_id)
      Dim m As New MemoryBlock(SizeOfPointer*arrayRange.length)
      getObjects nsarray_id, m, arrayRange
      Dim n As Integer = arrayRange.length-1
      For i As Integer = 0 To n
        retArray.append CFRetain((m.Ptr(i*SizeOfPointer)))
      Next
      
      Return retArray
      
    End If
  #EndIf
End Function

I was silent because I was creating an example (MacOS’ El Capitan) of what I wrote earlier.

Temporary result: I was able to store a RTF Text and a Sound (MP3) in the Clipboard.

I do not know why the Text and Picture are not there.

Returned data from the Script Editor:

{{«class RTF », 3174}, {«class MPG3», 34056}}

Now, it is time for me to dinner, then watch TV. With a bit of luck, I will finish that simple project by tomorrow.

Nota: I stored in a Folder four files; Text, RTF, MP3 and PNG. I read then in a button sequencially (by file name) and place the data in the CLipboard using Clip.AddRawData(Sound_MB, "public.mp3") for example.

I think I do not use the correct public.<kind-name> entries for Text (I use the LR value: "public.text") and Picture (I used: "public.image").

this second method still extends the clipboard, and let you get the data you want as a string, given the datatype present in the clipboard you provide. still only for macos, will do other platforms as I need it. if any of you add this windows or linux feature, please contribute to this thread ! thanks.

Public Function ItemData(extends c as Clipboard, aClipboardDataType as String) as String
  
  #If targetMacOS
    ' NSData
    Declare Function m_length Lib CocoaLib selector "length" (id As Ptr) As Integer
    Declare Sub getBytes Lib CocoaLib selector "getBytes:length:" ( id As Ptr, buffer As Ptr, length As UInteger )
    ' NSPasteBoard
    Declare Function NSClassFromString Lib CocoaLib (aClassName As CFStringRef) As Ptr
    Declare Function generalPasteboard Lib CocoaLib selector "generalPasteboard" (obj_id As Ptr) As Ptr
    Declare Function dataForType Lib CocoaLib selector "dataForType:" (obj_id As Ptr, type As CFStringRef) As Ptr
    
    Dim pasteboardRef As Ptr = generalPasteboard(NSClassFromString("NSPasteboard")) ' get actual general pasteboard
    If pasteboardRef <> Nil Then
      
      Dim p As Ptr = dataForType ( pasteboardRef, aClipboardDataType)
      Dim sLen As UInteger = m_length( p)
      If sLen>0 Then
        Dim m As New MemoryBlock( sLen )
        getBytes   p, m, sLen
        Return m.StringValue( 0, sLen)
      Else
        Return ""
      End If
      
    End If
  #EndIf
  
  #If TargetWindows
    Raise New PlatformNotSupportedException
  #EndIf
  #If TargetLinux
    Raise New PlatformNotSupportedException
  #EndIf
  
End Function

this above method now gives me the tiff data I want, just had to cast it to a picture using picture.fromdata.

and another small useful method for the same price …

Public Function ItemTypesCount(extends c As Clipboard) as Integer
  Return c.ItemTypes.Ubound+1
  
End Function

Hi all,

the code to load RTF, TEXT, MP3 and PNG are meaningless, so are the code to store some data as String in MemoryBlock and so I do not copied them here.

I only shared the code to place these different resources in the Clipboard. The used UTI seems to be correct. The order of the lines below (lines that starts with: Clip.AddRawData) change nothing (exept the order of appearance of the class in the Clipboard.

Only MP3 and RTF appears in the Clipboard and I do not know why / I was not able to change the result. Probably my error (or Xojo ?). I checked in the debugger, the used variables (below) hold the data, but for some unknow reason, they are lost.

[code]// Fills the Clipboard
Dim Clip As New Clipboard

Clip.AddRawData(Pict_MB, “public.image”) // Pict_MB is a MemoryBlock where I stored an image as String
Clip.AddRawData(Sound_MB, “public.mp3”) // Sound_MB is a MemoryBlock where I stored a sound as String
Clip.AddRawData(Text_RTF, “public.rtf”) // Text_RTF is a MemoryBlock where I stored a text RTF source as String
Clip.AddRawData(Text_Raw, “public.text”) // Text_Raw is a MemoryBlock where I stored a Raw text as String

// Export the Clipboard
Clip.Close[/code]