Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Copy Files using ShFileOperation
Message
 
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00727693
Message ID:
00728650
Views:
38
Nice, thanks a lot. It now returns 6 - The handle is invalid...

:)

So, the evolution is: 1223->127->6

And here is a test program to produce an error (if you remove \*.* in dest. string, the copy command works fine):
********************************************************************
*  Description.......: CopyFiles - allows to copy multiple files using ShFileOperation function
*  Calling Samples...: CopyFiles('C:\My Documents\*.Doc','d:\Test\*.Doc','Move')
*  Parameter List....: cSourceString, cDestString, cOperation
*  Created by........: Ed Rauh/Sergey Berezniker
*  Modified by.......:
********************************************************************
*!*	This API call performs several different Windows-style file operations, including copying, moving and deleting files. While running, you may have the Windows File operation animation displayed. THe API call requires a data structure that contains pointers; the VFP sample code uses ClsHeap to handle the necessary memory management issues.
*!*	--------------------------------------------------------------------------------
*!*	Members
*!*	hwnd
*!*	Window handle to the dialog box to display information about the status of the file operation.
*!*	wFunc
*!*	Value that indicates which operation to perform. This member can be one of the following values:
*!*	FO_COPY
*!*	Copy the files specified in the pFrom member to the location specified in the pTo member.
*!*	FO_DELETE
*!*	Delete the files specified in pFrom.
*!*	FO_MOVE
*!*	Move the files specified in pFrom to the location specified in pTo.
*!*	FO_RENAME
*!*	Rename the file specified in pFrom. You cannot use this flag to rename multiple files with a single function call. Use FO_MOVE instead.
*!*	pFrom
*!*	Address of a buffer to specify one or more source file names. These names must be fully qualified paths. Standard DOS wild cards, such as "*", are permitted in the filename position. Although this member is declared as a null-terminated string, it is used as a buffer to hold multiple file names. Each file name must be terminated by a single NULL character. An additional NULL character must be appended to the end of the final name to indicate the end of pFrom.
*!*	pTo
*!*	Address of a buffer to contain the name of the destination file or directory. This parameter must be set to NULL if it is not used. Like pFrom, the pTo member is also a double-NULL terminated string and is handled in much the same way. However, pTo must meet the following specifications:
*!*	Wildcard characters are not supported.
*!*	Copy and Move operations can specify destination directories that do not exist and the system will attempt to create them. The system normally displays a dialog box to ask the user if they want to create the new directory. To suppress this dialog box and have the directories created silently, set the FOF_NOCONFIRMDIR flag in fFiles.
*!*	For Copy and Move operations, the buffer can contain multiple destination file names if the fFlags member specifies FOF_MULTIDESTFILES.
*!*	Pack multiple names into the string in the same way as for pFrom.
*!*	Use only fully-qualified path names. Using relative pathnames will have unpredictable results.
*!*	fFlags
*!*	Flags that control the file operation. This member can take a combination of the following flags: Flag Description
*!*	FOF_ALLOWUNDO Preserve Undo information, if possible. If pFrom does not contain fully qualified path and file names, this flag is ignored.
*!*	FOF_FILESONLY Perform the operation on files only if a wildcard file name (*.*) is specified.
*!*	FOF_MULTIDESTFILES The pTo member specifies multiple destination files (one for each source file) rather than one directory where all source files are to be deposited.
*!*	FOF_NOCONFIRMATION Respond with "Yes to All" for any dialog box that is displayed.
*!*	FOF_NOCONFIRMMKDIR Do not confirm the creation of a new directory if the operation requires one to be created.
*!*	FOF_NO_CONNECTED_ELEMENTS Version 5.0. Do not move connected files as a group. Only move the specified files.
*!*	FOF_NOCOPYSECURITYATTRIBS Version 4.71. Do not copy the security attributes of the file.
*!*	FOF_NOERRORUI Do not display a user interface if an error occurs.
*!*	FOF_NORECURSION Only operate in the local directory. Don't operate recursively into subdirectories.
*!*	FOF_RENAMEONCOLLISION Give the file being operated on a new name in a move, copy, or rename operation if a file with the target name already exists.
*!*	FOF_SILENT Do not display a progress dialog box.
*!*	FOF_SIMPLEPROGRESS Display a progress dialog box but do not show the file names.
*!*	FOF_WANTMAPPINGHANDLE If FOF_RENAMEONCOLLISION is specified and any files were renamed, assign a name mapping object containing their old and new names to the hNameMappings member.
*!*	FOF_WANTNUKEWARNING Version 5.0. Send a warning if a file is being destroyed during a delete operation rather than recycled. This flag partially overrides FOF_NOCONFIRMATION.

*!*	fAnyOperationsAborted
*!*	Value that receives TRUE if the user aborted any file operations before they were completed, or FALSE otherwise.
*!*	hNameMappings
*!*	A handle to a name mapping object containing the old and new names of the renamed files. This member is used only if the fFlags member includes the FOF_WANTMAPPINGHANDLE flag. Treat hNameMappings as a pointer to a structure whose first member is an INT value, followed by an array of SHNAMEMAPPING structures. The INT value will be set to the number of structures in the array. Each SHNAMEMAPPING structure will contain the old and new path name for one of the renamed files.
*!*	Note: The handle must be freed with SHFreeNameMappings.

*!*	lpszProgressTitle
*!*	Address of a string to use as the title of a progress dialog box. This member is used only if fFlags includes the FOF_SIMPLEPROGRESS flag.
*!*	Remarks
*!*	If the pFrom or pTo members are unqualified names, the current directories are taken from the global current drive and directory settings as managed by the GetCurrentDirectory and SetCurrentDirectory functions.

*!*	If pFrom is set to a filename, deleting the file with FO_DELETE will not move it to the Recycle Bin, even if the FOF_ALLOWUNDO flag is set. You must use a full pathname.

*!*	See Also
*!*	For a complete application that uses the SHFILEOPSTRUCT structure and explains how to setup the SHNAMEMAPPING structure,
*!*	 see the Knowledge Base Article Q151799 at http://support.microsoft.com/support/kb/articles/Q151/7/99.asp.

*!*	Requirements
*!*	Version 4.00 and later of Shell32.dll

*!*	Windows NT/2000: Requires Windows NT 4.0 or later.
*!*	Windows 95/98: Requires Windows 95 or later.
*!*	Header: Declared in shellapi.h.
*  Copy usage example, single file source mask, single destination
*  The directory structure will be copied recursively, and the
*  Windows Copy animation and progress dialog will be shown.  Do not
*  require user to OK overwrites or creation of new subfolders
*  Progress dialog will appear in the current active window
*
*  ClsHeap can be found in the Files section
*
#INCLUDE SHFileOperations.h

lparameters tcSource, tcDestination, tcAction, tlCanceled
local lcSourceString, lcDestString, nStringBase, lcFileOpStruct, lnFlag, lnStringBase    , lcProgressTitle
local oHeap, lcAction, lcActionText, lcOpt, lnRetCode

declare integer SHFileOperation in SHELL32.dll string @ LPSHFILEOPSTRUCT
declare integer GetActiveWindow in WIN32API
declare integer GetLastError in WIN32API
declare integer FormatMessage in kernel32.dll ;
	integer dwFlags, ;
	string @lpSource, ;
	integer dwMessageId, ;
	integer dwLanguageId, ;
	string @lpBuffer, ;
	integer nSize, ;
	integer Arguments

set procedure to CLSHEAP additive
oHeap = createobject('Heap')

lcAction = upper(iif( empty( m.tcAction) or vartype(m.tcAction) <> "C", "COPY", m.tcAction))

do case
case m.lcAction = "COPY"
	lcActionText = proper("COPY")
	lnAction = FO_COPY
case m.lcAction = "MOVE"
	lcActionText = proper("MOVE")
	lnAction = FO_MOVE
case m.lcAction = "DELETE"
	lcActionText = proper("DELETE")
	lnAction = FO_DELETE
case m.lcAction = "RENAME"
	lcActionText = proper("RENAME")
	lnAction = FO_RENAME
otherwise
	return null
endcase

lcOpt = ""
if vartype(m.tcSource)<>"C"
	tcSource = 'C:\DataEntry\*.*'
endif

if vartype(m.tcDestination)<>"C"
	tcDestination = 'c:\MyNewDir\*.*'
endif

lcSourceString = m.tcSource + chr(0) + chr(0)
lcDestString   = m.tcDestination + chr(0) + chr(0)
lnStringBase   = oHeap.AllocBlob(m.lcSourceString + m.lcDestString)
*!*	lcProgressTitle = m.lcActionText  + " File '" + m.tcSource + "'" + "" + ;
*!*		iif(m.lcAction="DELETE", "", " to '" + m.tcDestination + "'") + chr(0)+ chr(0)
*!*	lnProgressTitle = oHeap.AllocBlob(m.lcProgressTitle)

lnFlag = FOF_NOCONFIRMATION + FOF_NOCONFIRMMKDIR + FOF_NOERRORUI

if not ("*" $ m.tcSource or "?" $ m.tcSource )
*lnFlag = lnFlag + FOF_SIMPLEPROGRESS
endif

*!*	lcFileOpStruct  = NumToLONG(GetActiveWindow()) + ; && _screen.hWnd
*!*	    NumToLONG(m.lnAction) + ;
*!*		NumToLONG(m.lnStringBase) + ;
*!*		NumToLONG(m.lnStringBase + len(m.lcSourceString)) + ;
*!*		NumToWORD(m.lnFlag) + ;
*!*		NumToLONG(0) + ;
*!*		NumToLONG(0) + ;
*!*		NumToLONG(m.lnProgressTitle )

lcFileOpStruct = NumToDWORD(GetActiveWindow()) + ;
	NumToDWORD(m.lnAction) + ;
	NumToDWORD(m.lnStringBase) + ;
	NumToDWORD(m.lnStringBase + len(m.lcSourceString)) + ;
	NumToDWORD(FOF_NOCONFIRMATION + FOF_NOCONFIRMMKDIR) + ;
	chr(0) + ;
	NumToDWORD(0) + ;
	NumToLONG(0)

lnRetCode = SHFileOperation(@lcFileOpStruct)
if m.lnRetCode<> 0
	local lcErrBuffer, lcErrorMess, liNewErr, lnErrorCode
	lcErrBuffer = repl(chr(0),1000)
	lnErrorCode = GetLastError()
	liNewErr = FormatMessage(0x1000;
		,.null., lnErrorCode, 0, @lcErrBuffer,500,0)
	lcErrorMess = transform(m.lnErrorCode) + "    " + ;
		left(m.lcErrBuffer, at(chr(0),m.lcErrBuffer)- 1 )
	=messagebox("API Error - " + m.lcErrorMess,48,m.lcActionText+ " failed")
endif
* Did user cancel operation?
tlCanceled = ( substr(m.lcFileOpStruct, 19, 4) <> NumToLONG(0) )

return (m.lnRetCode = 0)
If it's not broken, fix it until it is.


My Blog
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform