Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Place a File reference on the Clipboard for pasting into email

Windows Clipboard

Place a File reference on the Clipboard for pasting into email

by  wgcs  Posted    (Edited  )
Ever want a user to email a certain file from your application (eg, a data file), but have trouble getting across how to "browse" to find that file? How about just putting a reference to the file on the clipboard and letting them "Paste" it into an email (which attaches it to the email)?

This is tested with Eudora v5 and Outlook 2003 and works!

[highlight red][sup][white]Update[/white][/sup][/highlight] Now you can pass either a single file by name, or an array of files. The array can be single or multi-dimentioned. If multi-dimentioned (like the result of ADIR()), the first column is used. (I have a feeling that Single-dimentioned arrays will Not work in VFP6, though I have only tested on VFP9)

It Seems that these multiple-file-selections work with Eudora, but not Outlook, which only gets the first item. Oh, well, maybe someone will offer help with "Shell IDList Array"s.

Code:
FUNCTION PutFileOnClipboard
LPARAMETERS tc_or_a_FilePath

* Author William GC Steinford
* Date: 3/10/2005

LOCAL lcPath, lnLen, lnI, lcFile, lcAsciiFile, lcUnicodeFile, lcUnicodeHDrop, ;
      cf, lnHWnd, lcHDrop, hText, lnPtr, lcData, hData

#define CF_TEXT             1
#define CF_HDROP            15

DECLARE INTEGER GetActiveWindow IN win32api 
DECLARE INTEGER OpenClipboard IN WIN32API ;
  LONG HWND_hWndNewOwner
DECLARE INTEGER RegisterClipboardFormat IN WIN32API ;
  STRING @ LPCTSTR_lpszFormat
DECLARE INTEGER EmptyClipboard IN win32api
DECLARE LONG GlobalAlloc IN WIN32API ;
  LONG UINT_uFlags, ;
  LONG SIZE_T_dwBytes
DECLARE LONG GlobalLock IN WIN32API ;
  LONG HGLOBAL_hMem
Declare LONG RtlMoveMemory IN WIN32API ;
  LONG ptrIntoHere, STRING @ cFromHere, LONG cb
DECLARE INTEGER GlobalUnlock IN WIN32API ;
  LONG HGLOBAL_hMem
DECLARE LONG SetClipboardData IN WIN32API ;
  INTEGER UINT_uFormat, ;
  LONG    HANDLE_hMem
Declare LONG GlobalFree IN win32api ;
  LONG hmem
DECLARE INTEGER CloseClipboard IN win32api

#define GMEM_MOVEABLE       0x0002
#define GMEM_DDESHARE       0x2000

*_CLIPTEXT = tcPlainText && tcRTFtext
lnhWnd = GetActiveWindow()
*/ Open the clipboard...
IF !OpenClipboard(lnhWnd)<>0
   MessageBox("Cannot open clipboard.")
   RETURN .f.
ENDIF


*// Empty anything already there...
EmptyClipboard()

cf = CF_HDROP && 15

lcAsciiFile   = tc_or_a_FilePath
lcUnicodeFile = STRCONV(STRCONV(tc_or_a_FilePath,1),5)

lcUnicodeHDrop = STRCONV(STRCONV(tc_or_a_FilePath,1),5)


* in VFP9, one dimention arrays are always treated like [x,1] two-dimentioned arrays.
*  this code may not work with VFP6,7,8.. it should just get skipped.
IF type('tc_or_a_FilePath[2,1]')='C'
  lcPath = JUSTPATH(lcAsciiFile)
  lcUnicodeHDrop = lcAsciiFile
  lnLen = ALEN(tc_or_a_FilePath,1)
  FOR lnI = 2 TO lnLen
    lcFile = IIF(EMPTY(JUSTPATH(tc_or_a_FilePath[lnI,1])),lcPath+tc_or_a_FilePath[lnI,1], tc_or_a_FilePath[lnI,1] )
    lcUnicodeHDrop = lcUnicodeHDrop+CHR(0)+lcFile
  ENDFOR
  lcUnicodeHDrop = STRCONV(STRCONV(lcUnicodeHDrop,1),5)
ENDIF

* 14 00 00 00    00 00 00 00
* 00 00 00 00    00 00 00 00
* 01 00 00 00    start of Unicode file path+name!

lcHDrop   = CHR(0x14)+REPLICATE(CHR(0),15) + CHR(1) + REPLICATE(CHR(0),3) ;
            + lcUnicodeHDrop + REPLICATE(CHR(0),4)

*// Allocate global memory for transfer...
hText = GlobalAlloc( BITOR(GMEM_MOVEABLE,GMEM_DDESHARE), LEN(lcHDrop) )

*// Put our string in the global memory...
lnPtr = GlobalLock(hText)

RtlMoveMemory( lnPtr, @lcHDrop, len(lcHDrop) )
GlobalUnlock(hText)

*// Put data on the clipboard!
SetClipboardData(cf, hText)

*// Free memory...
GlobalFree(hText)



* Place DropEffect on clipboard
lcData = CHR(5)+REPLICATE(CHR(0),3)
cf = RegisterClipboardFormat("Preferred DropEffect")
hData = GlobalAlloc( BITOR(GMEM_MOVEABLE,GMEM_DDESHARE), 4 )
lnPtr = GlobalLock(hText)
RtlMoveMemory( lnPtr, @lcData, 4 )
GlobalUnlock(hData)
SetClipboardData(cf, hData)
GlobalFree(hData)

* Place FileName on clipboard
lcData = ALLTRIM(lcAsciiFile)+CHR(0)
cf = RegisterClipboardFormat("FileName")
hData = GlobalAlloc( BITOR(GMEM_MOVEABLE,GMEM_DDESHARE), LEN(lcData) )
lnPtr = GlobalLock(hData)
RtlMoveMemory( lnPtr, @lcData, LEN(lcData) )
GlobalUnlock(hData)
SetClipboardData(cf, hData)
GlobalFree(hData)

* Place FileNameW on clipboard
lcData = ALLTRIM(STRCONV(lcUnicodeFile+CHR(0),5))
cf = RegisterClipboardFormat("FileNameW")
hData = GlobalAlloc( BITOR(GMEM_MOVEABLE,GMEM_DDESHARE), LEN(lcData) )
lnPtr = GlobalLock(hData)
RtlMoveMemory( lnPtr, @lcData, LEN(lcData) )
GlobalUnlock(hData)
SetClipboardData(cf, hData)
GlobalFree(hData)

*// Close clipboard...
CloseClipboard()
*

Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top