Page 1 of 1

SHFileOperation()

PostPosted: Sun Nov 06, 2022 5:58 am
by Jimmy
hi,

i found file \fwh\samples\dlgfile.prg which use SHFileOperation (copy, delete and move like Explorer)
when try HB_FUNC( SHFILE ) under 64 Bit it fail :(

here revised Version for 32 Bit and 64 Bit
Code: Select all  Expand view
HB_FUNC( SHFILE )
{
   #ifndef _WIN64
      HWND hWnd = ( HWND ) hb_parnl( 1 );
   #else
      HWND hWnd = ( HWND ) hb_parnll( 1 );
   #endif

   SHFILEOPSTRUCT sh;

   memset( ( char * ) &sh, 0, sizeof( sh ) );

   sh.hwnd   = hWnd ;
   sh.wFunc  = ( UINT ) hb_parnl( 2 );
   sh.pFrom  = ( LPSTR ) hb_parc( 3 );
   sh.pTo    = ( LPSTR ) hb_parc( 4 );
   sh.fFlags = ( FILEOP_FLAGS ) hb_parnl( 5 );

   hb_retnl( SHFileOperation( &sh ) );
}

Re: SHFileOperation()

PostPosted: Thu Nov 17, 2022 7:49 am
by Jimmy
hi,

API ShFileOperation is the Way Windows Explorer "copy","move", "rename" or "delete" Files / Folder

Demo Sample c:\fwh\samples\dlgfile.prg does show how it work but only for single File
also HB_FUNC(SHFILE) is for 32 Bit only and need to be enhance for 64 Bit (see above)

here Sample how to use for multi Files / Folder
Code: Select all  Expand view
LOCAL lConfirm   := .F.
LOCAL lPaperbin  := .F.
   ...
   FOR ii := 1 TO iMax
      ...
      AADD( acFiles, cSourceDir + cFile )
      IF cAction = "DELETE"
         AADD( acTarget, "" + CHR( 0 ) )
      ELSE
         AADD( acTarget, cTargetDir + cFile )
      ENDIF
   NEXT
   lRet := DoSH3func( cAction, lConfirm, lPaperbin, acFiles, acTarget )


Code: Select all  Expand view
FUNCTION DoSH3func( cAction, lConfirm, lPaperbin, acFiles, acTarget )
LOCAL iMax   := LEN( acFiles )
LOCAL lRet   := .F.
LOCAL nHWnd, nFunc, fFlag

   fFlag := FOF_SIMPLEPROGRESS

   DO CASE
      CASE cAction = "COPY"
         nFunc := FO_COPY
      CASE cAction = "MOVE"
         nFunc := FO_MOVE
      CASE cAction = "DELETE"
         nFunc := FO_DELETE
      CASE cAction = "RENAME"
         nFunc := FO_RENAME
   ENDCASE

   IF iMax > 1
      fFlag := nOr( fFlag, FOF_MULTIDESTFILES )
   ENDIF

   IF lPaperbin
      fFlag := nOr( fFlag, FOF_ALLOWUNDO )
   ENDIF

   IF lConfirm
   ELSE
      //  fFlag += FOF_NOCONFIRMATION + FOF_NOCONFIRMMKDIR + FOF_RENAMEONCOLLISION
      fFlag := nOr( fFlag, FOF_NOCONFIRMATION, FOF_NOCONFIRMMKDIR )
   ENDIF

   // ===========================================================================
   // Function ShellFile( hParentWnd, aFiles, aTarget, nFunc, nFlag )
   //
   // Purpose:
   // Performs a copy, move, rename, or delete operation on a file system object.
   // Parameters:
   //   aFiles  is an Array of Source-Filenamestrings, or a single Filenamestring
   //   aTarget is an Array of Target-Filenamestrings, or a single Filenamestring
   //   nFunc   determines the action on the files:
   //           FO_MOVE, FO_COPY, FO_DELETE, FO_RENAME
   //   fFlag   Option Flag ( see the file SHELL32.CH )
   //
   // ===========================================================================

   lRet := ShellFiles( nHWnd, acFiles, acTarget, nFunc, fFlag )

   SysWait( 0.5 )

RETURN lRet


Code: Select all  Expand view
FUNCTION ShellFiles( hWnd, acFiles, acTarget, nFunc, fFlag )
LOCAL cTemp
LOCAL cx
LOCAL lRet  := .T.

   // SourceFiles, convert Array to String
   //
   DEFAULT acFiles TO CHR( 0 )
   IF VALTYPE( acFiles ) == "A"
      cTemp := ""
      FOR cx := 1 TO LEN( acFiles )
         cTemp += acFiles[ cx ] + CHR( 0 )
      NEXT
      acFiles := cTemp
   ENDIF
   acFiles += CHR( 0 )

   // TargetFiles, convert Array to String
   //
   DEFAULT acTarget TO CHR( 0 )
   IF VALTYPE( acTarget ) == "A"
      cTemp := ""
      FOR cx := 1 TO LEN( acTarget )
         cTemp += acTarget[ cx ] + CHR( 0 )
      NEXT
      acTarget := cTemp
   ENDIF
   acTarget += CHR( 0 )

   // call SHFileOperation
   //
   DO CASE
      CASE nFunc = FO_COPY
         lRet := SHFile( hWnd, FO_COPY, acFiles, acTarget, fFlag )
      CASE nFunc = FO_MOVE
         lRet := SHFile( hWnd, FO_MOVE, acFiles, acTarget, fFlag )
      CASE nFunc = FO_DELETE
         lRet := SHFile( hWnd, FO_DELETE, acFiles, acTarget, fFlag )
      CASE nFunc = FO_RENAME
         lRet := SHFile( hWnd, FO_RENAME, acFiles, acTarget, fFlag )
   ENDCASE

RETURN lRet

Re: SHFileOperation()

PostPosted: Thu Nov 17, 2022 8:24 am
by Antonio Linares
Dear Jimmy,

Many thanks for pointing us to adapt such function to 64 bits. We have removed it from the examples and made it part of FWH for next FWH build:
* New: function SHFileOperation(). Please review samples\dlgfile.prg. Many thanks to Jimmy
for telling us to adapt it to 64 bits and we have made it part of FWH, removing it from
dlgfile.prg sample