Using CLIPBOARD to store and later paste a list of files/attachments

Thanks Mike and Good Day to you,

Supposing I just want to highlight three (or any number of) random documents (.docx) or jpegs in Windows Explorer - i.e. I won’t yet have a clearly defined list that I can pre-set in the code - and then paste these chosen files somewhere within my Clarion app. Does the Clarion CLIPBOARD() function, or some other function, inherently know which files have been selected by the user in Windows and, if so, can it be interrogated to reveal & list their names? Hope that makes sense. Most documentation I can find seems to suggest that CLIPBOARD can only handle/return strings.

Other options are:

  1. Drag & Drop, Clarion DROPID(’~FILE’)
  2. Use FileLookupButton control template or FILEDIALOGA() to let the user select files from inside the Clarion application.

That is what i normally do to let users select files.
I am not aware of any examples to allow copy-pasting multiple file(names) from explorer into Clarion.

Thanks Eric,

The filedialog thing would be ok, AND DRAG&DROP might work for a single file, but here

our users are asking to be able to copy file(s) from anywhere within Explorer or Outlook

and paste them into the Clarion app, where they will be attached(added)to a database file

using a “Paste” button. It sounds like the CLIPBOARD function is pretty limited.

Gary

Not sure if i understand what you need, but Drag&Drop does work for multiple files. It will be a comma or semicolon separated list of filenames.
ps. Somehow the first selected file will be the last in that list.

Ok, thanks. That’s interesting. If will investigate drag & drop and will write some test code to see
whether it will do what I need.

Yes, I also think that the included CLIPBOARD support doesn’t help in cases like the one mentioned or vice versa, when you need to assign the name of a file that can then be pasted with Windows Explorer.
Copying a file to the clipboard so you can paste it into Explorer or an email message or whatever

Perhaps using the APIs you can achieve it. Look at the CF_HDROP format
Shell Clipboard Formats
How to Get the File Path from Clipboard in Windows Explorer?

If you want to try a simple example where you can select multiple files in Windows Explorer and drag them into a Clarion application, try this test.clw example:
https://clarionhub.com/t/drop-file-name-to-a-specific-row-in-the-list/5537/15

1 Like

I can say, based on past experience, that supporting this stuff can be a whole lot of work, even if you’re already comfortable with these APIs. We hired a dev around 15 years ago to help us to support all of the explorer features in a SysTree and SysList. It was very involved. Worked, though.

Thanks all for the updates. For the moment, it does look like we’d be quicker getting our proposed “Paste” button to invoke a small c# .exe, which could then use the ready-made Microsoft functions to copy a list of selected files to the database file we use for attachments. After that I’ll be ready to retire.

This took me all of about 5 minutes. Maybe it’s what you want?

ClipboardTest.clw (1.2 KB)

2 Likes

That’s a nice small code example! I’ll paste it here to allow seeing it without download.

       PROGRAM

UINT      EQUATE(UNSIGNED)
LPSTR     EQUATE(CSTRING)
BOOLEAN   EQUATE(BYTE)           

  MAP
    Module('Windows API')
      DragQueryFileA(UINT, UINT, *LPSTR, UINT),UINT,PASCAL,RAW
      OpenClipboard(UINT),BOOLEAN,PASCAL,RAW
      CloseClipboard(),BOOLEAN,PASCAL,RAW
      GetClipboardData(UINT),UINT,PASCAL,RAW
      GetLastError(),LONG,PASCAL
    END
  END

HDROP      UINT
OUTSTRING  CSTRING(255)
NUMFILES   UINT
RESULT     UINT
SUCCESS    BOOLEAN

    CODE
       
    SUCCESS = OpenClipboard(0)
    HDROP = GetClipboardData(15)
    NUMFILES = DragQueryFileA(HDROP, 0FFFFFFFFH, OUTSTRING, 255)
    Message('There are ' & NUMFILES & ' files on the clipboard')
    LOOP I# = 0 TO  NUMFILES-1
        RESULT = DragQueryFileA(HDROP, I#, OUTSTRING, 255)
        IF RESULT > 0 THEN
            Message(OUTSTRING,'DragQueryFileA ' & I#)
        END
    END   
    SUCCESS = CloseClipboard()      

You may want to add an error message to know why it failed:

        RESULT = DragQueryFileA(HDROP, I#, OUTSTRING, 255)
        IF RESULT > 0 THEN
            Message(OUTSTRING,'DragQueryFileA ' & I#)
        ELSE            
            Message('DragQueryFileA Error ' & GetLastError() ,'DragQueryFileA ' & I#)            
        END


Devuna does have this repo with OLE Drag and Drop


I have this code that enumerates the different formats on the clipboard

2 Likes

Thanks both,
I’ll be trying those out as soon as I can make time and will report back here
with my results.

This copy files function is in Capesoft WinEvent5
It definatly works, because I extended the function to make it work and passed the code on to Bruce :slight_smile:

I’m pleased to report that the code segment posted above works and took less than ten minutes to implement. Please accept my proposal of marriage, if indeed this is permitted in your time zone and/or state legislature. I’m sure my wife is fine with it.

2 Likes

One minor drawback appears to be that if you open Outlook, select an email, highlight an attachment, right-click & copy, this is not picked up by the functions and the message reads as having “zero files in the clipboard”. However, this probably only needs a small tweak, is way better than what we had before.

I was considering “flag this reply” since it caused a raucous amount of laughter just behind my keyboard, thereby negating several minutes of valuable work time. :rofl:

3 Likes

You could use my enumerator to see what’s there

1 Like

Thanks, it’ll probably be late next week before I return to the enhancement, but I will
keep this in mind, definitely.

Outlook uses a type of ‘virtual folders’ when copying attachments to the clipboard, so you’d have to use the CFSTR_FILECONTENTS and CFSTR_FILEDESCRIPTOR formats. It’s not as straight forward as getting a list of files from Explorer, so perhaps somebody else here already has a working example? If not I could probably put something together - if and when I have some spare time!

Edit: The OLE Drag & Drop example you can find in Github (posted previously by Carl) has what you need.

Thanks chaps. They’ve switched me to another bit of work, but I hope to return to this
later next week.

Carl’s project is very helpful in finding the information items available on the clipboard. Also this utility:

Explorer and Outlook enter data to the clipboard differently, here is an example for both cases:
-Read paths and names of copied files from windows explorer (CF_HDROP)
-Read the names of attached files copied from Outlook 365 and the content of the first one only (FileGroupDescriptor and FileContents)

GetFilesAttachments.clw (3,1 KB)

All done only with the included CLIPBOARD function. In the case of CF_HDROP (copying from the explorer) it uses a single API to convert Unicode to Ansi, so the included support does help, although as you can see in the code, access through APIs is easier in this case.

From Outlook there is a difficulty if you select multiple files to copy. The technique to access the attachments from the second onwards is more complex, to access the lindex field. There is code in the mentioned Devuna Ole Drag and Drop project that references the IDataObject interface GetData method, FORMATETC structure.



https://social.msdn.microsoft.com/Forums/vstudio/en-US/affcf9cd-704d-4ea2-b80b-4c09062af72d/how-extract-an-outlook-attachment-from-the-clipboard-?forum=wpf
2 Likes