by Richard Russell, October 2010

Windows Explorer lets you copy files from one place in the filesystem to another (e.g. from one folder to another, or from one drive to another) by means of Copy and Paste operations, analogous to how you might copy-and-paste text from one document to another. This article describes how you can access the Shell Clipboard from your BASIC program, so you can paste files that have been copied in Windows Explorer, or copy files that can then be pasted in Windows Explorer.

Pasting files from the Shell Clipboard uses a similar mechanism to that described in the article Receiving dropped files. The following code checks to see if there are any files on the Shell Clipboard and if so accesses them:
      CF_HDROP = 15
      MAX_PATH = 260
      DIM Buffer% MAX_PATH
      SYS "IsClipboardFormatAvailable", CF_HDROP TO res%
      IF res% THEN
        SYS "OpenClipboard", @hwnd%
        SYS "GetClipboardData", CF_HDROP TO hdata%
        IF hdata% THEN
          SYS "GlobalLock", hdata% TO hdropfiles%
          SYS "DragQueryFile", hdropfiles%, -1, 0, 0 TO nfiles%
          IF nfiles% THEN
            FOR I% = 0 TO nfiles%-1
              SYS "DragQueryFile", hdropfiles%, I%, Buffer%, MAX_PATH
              PRINT $$Buffer%
            NEXT I%
          SYS "DragFinish", hdropfiles%
          SYS "GlobalUnlock", hdata%
        SYS "CloseClipboard"
Here the filenames are simply printed to the screen. In practice you are likely to want to copy the files and/or to access their contents.

Copying files to the Shell Clipboard is slightly more involved, because you have to build the necessary data structure yourself. The code to do it is listed below; for convenience it uses the FNselectfiles function, to be found in the article Selecting multiple files, to select the file(s) to be copied:
      CF_HDROP = 15
      GMEM_ZEROINIT = &40
      GMEM_DDESHARE = &2000
      MAXFILES = 100
      DIM file$(MAXFILES)
      DIM dropfiles{pFiles%, pt{x%,y%}, fNC%, fWide%}
      nfiles% = FNselectfiles("Select one or more files", "*.*", file$())
      IF nfiles% THEN
        size% = DIM(dropfiles{}) + SUMLEN(file$()) + nfiles% + 1
        SYS "GlobalAlloc", GMEM_DDESHARE + GMEM_ZEROINIT, size% TO hdata%
        SYS "GlobalLock", hdata% TO mem%
        !mem% = DIM(dropfiles{})
        P% = mem% + !mem%
        FOR I% = 1 TO nfiles%
          $$P% = file$(I%)
          P% += LEN(file$(I%)) + 1
        SYS "GlobalUnlock", hdata%
        SYS "OpenClipboard", @hwnd%
        SYS "EmptyClipboard"
        SYS "SetClipboardData", CF_HDROP, hdata%
        SYS "CloseClipboard"