diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 87a105bca4..59b27a931d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,23 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-05-27 19:25 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) + * contrib/hbwin/wapi_wingdi.c + * contrib/hbwin/hbolesrv.c + ! Fixed for msvcarm. + + * contrib/hbwin/hbwin.ch + * contrib/hbwin/win_shell.c + + contrib/hbwin/tests/testcopy.prg + + Added: + WIN_SHFileOperation( [], [], [|], [|], + [], [<@lAnyOperationAborted>], + [], [] ) -> + ; Przemek, if you have some time pls review s_StringList() + function which I adapted from similar function in win_dlg.c, + but it might not be perfect. '<\0><\0><\0>' format + is required by this SHFileOperation() Windows function. + 2010-05-27 19:08 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/contrib/hbwin/hbolesrv.c % improved the performance and reduced memory usage by using hash diff --git a/harbour/contrib/hbwin/hbolesrv.c b/harbour/contrib/hbwin/hbolesrv.c index 6931c4534e..6d03deca8e 100644 --- a/harbour/contrib/hbwin/hbolesrv.c +++ b/harbour/contrib/hbwin/hbolesrv.c @@ -783,12 +783,12 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, PVOID pvReserved ) switch( dwReason ) { case DLL_PROCESS_ATTACH: - s_hInstDll = hInstance; + s_hInstDll = ( HINSTANCE ) hInstance; s_lLockCount = s_lObjectCount = 0; s_IClassFactoryObj.lpVtbl = ( IClassFactoryVtbl * ) &IClassFactory_Vtbl; - DisableThreadLibraryCalls( hInstance ); + DisableThreadLibraryCalls( ( HMODULE ) hInstance ); s_fInit = !hb_vmIsActive(); if( s_fInit ) diff --git a/harbour/contrib/hbwin/hbwin.ch b/harbour/contrib/hbwin/hbwin.ch index 77a0ef87a4..4b7d99ae07 100644 --- a/harbour/contrib/hbwin/hbwin.ch +++ b/harbour/contrib/hbwin/hbwin.ch @@ -692,6 +692,56 @@ #define WIN_MB_MODEMASK 0x00003000 #define WIN_MB_MISCMASK 0x0000C000 +/* WIN_SHFILEOPERATION() functions */ +#define WIN_FO_MOVE 0x0001 +#define WIN_FO_COPY 0x0002 +#define WIN_FO_DELETE 0x0003 +#define WIN_FO_RENAME 0x0004 + +/* WIN_SHFILEOPERATION() flags */ +#define WIN_FOF_MULTIDESTFILES 0x0001 +#define WIN_FOF_CONFIRMMOUSE 0x0002 +#define WIN_FOF_SILENT 0x0004 +#define WIN_FOF_RENAMEONCOLLISION 0x0008 +#define WIN_FOF_NOCONFIRMATION 0x0010 +#define WIN_FOF_WANTMAPPINGHANDLE 0x0020 +#define WIN_FOF_ALLOWUNDO 0x0040 +#define WIN_FOF_FILESONLY 0x0080 +#define WIN_FOF_SIMPLEPROGRESS 0x0100 +#define WIN_FOF_NOCONFIRMMKDIR 0x0200 +#define WIN_FOF_NOERRORUI 0x0400 +#define WIN_FOF_NOCOPYSECURITYATTRIBS 0x0800 +#define WIN_FOF_NORECURSION 0x1000 +#define WIN_FOF_NO_CONNECTED_ELEMENTS 0x2000 +#define WIN_FOF_WANTNUKEWARNING 0x4000 + +/* WIN_SHFILEOPERATION() results */ +#define HB_WIN_DE_SAMEFILE 0x71 /* The source and destination files are the same file. */ +#define HB_WIN_DE_MANYSRC1DEST 0x72 /* Multiple file paths were specified in the source buffer, but only one destination file path. */ +#define HB_WIN_DE_DIFFDIR 0x73 /* Rename operation was specified but the destination path is a different directory. Use the move operation instead. */ +#define HB_WIN_DE_ROOTDIR 0x74 /* The source is a root directory, which cannot be moved or renamed. */ +#define HB_WIN_DE_OPCANCELLED 0x75 /* The operation was cancelled by the user, or silently cancelled if the appropriate flags were supplied to SHFileOperation. */ +#define HB_WIN_DE_DESTSUBTREE 0x76 /* The destination is a subtree of the source. */ +#define HB_WIN_DE_ACCESSDENIEDSRC 0x78 /* Security settings denied access to the source. */ +#define HB_WIN_DE_PATHTOODEEP 0x79 /* The source or destination path exceeded or would exceed MAX_PATH. */ +#define HB_WIN_DE_MANYDEST 0x7A /* The operation involved multiple destination paths, which can fail in the case of a move operation. */ +#define HB_WIN_DE_INVALIDFILES 0x7C /* The path in the source or destination or both was invalid. */ +#define HB_WIN_DE_DESTSAMETREE 0x7D /* The source and destination have the same parent folder. */ +#define HB_WIN_DE_FLDDESTISFILE 0x7E /* The destination path is an existing file. */ +#define HB_WIN_DE_FILEDESTISFLD 0x80 /* The destination path is an existing folder. */ +#define HB_WIN_DE_FILENAMETOOLONG 0x81 /* The name of the file exceeds MAX_PATH. */ +#define HB_WIN_DE_DEST_IS_CDROM 0x82 /* The destination is a read-only CD-ROM, possibly unformatted. */ +#define HB_WIN_DE_DEST_IS_DVD 0x83 /* The destination is a read-only DVD, possibly unformatted. */ +#define HB_WIN_DE_DEST_IS_CDRECORD 0x84 /* The destination is a writable CD-ROM, possibly unformatted. */ +#define HB_WIN_DE_FILE_TOO_LARGE 0x85 /* The file involved in the operation is too large for the destination media or file system. */ +#define HB_WIN_DE_SRC_IS_CDROM 0x86 /* The source is a read-only CD-ROM, possibly unformatted. */ +#define HB_WIN_DE_SRC_IS_DVD 0x87 /* The source is a read-only DVD, possibly unformatted. */ +#define HB_WIN_DE_SRC_IS_CDRECORD 0x88 /* The source is a writable CD-ROM, possibly unformatted. */ +#define HB_WIN_DE_ERROR_MAX 0xB7 /* MAX_PATH was exceeded during the operation. */ +#define HB_WIN_DE_UNKNOWN_ 0x402 /* An unknown error occurred. This is typically due to an invalid path in the source or destination. This error does not occur on Windows Vista and later. */ +#define HB_WIN_DE_ERRORONDEST_ 0x10000 /* An unspecified error occurred on the destination. */ +#define HB_WIN_DE_ROOTDIR_ERRORONDEST_ 0x10074 /* Destination is a root directory and cannot be renamed. */ + /* ------------------------------- */ /* Deprecated constants and macros */ /* ------------------------------- */ diff --git a/harbour/contrib/hbwin/tests/testcopy.prg b/harbour/contrib/hbwin/tests/testcopy.prg new file mode 100644 index 0000000000..2791119370 --- /dev/null +++ b/harbour/contrib/hbwin/tests/testcopy.prg @@ -0,0 +1,29 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * + * Copyright 2009 Viktor Szakats (harbour.01 syenar.hu) + * www - http://www.harbour-project.org + * + */ + +#include "hbwin.ch" + +PROCEDURE Main() + LOCAL a := {} + LOCAL lAbort + + ? "0x" + hb_numtohex( WIN_SHFileOperation( NIL, WIN_FO_COPY, { "testcopy.prg", "olesrv1.prg" }, "testcopy1",; + WIN_FOF_WANTMAPPINGHANDLE, @lAbort,; + a, "Harbour SHFile 1" ) ) + ? lAbort + + ? "0x" + hb_numtohex( WIN_SHFileOperation( NIL, WIN_FO_COPY, "testcopy.prg" + Chr( 0 ) + "olesrv1.prg" + Chr( 0 ), "testcopy2",; + WIN_FOF_WANTMAPPINGHANDLE, @lAbort,; + a, "Harbour SHFile 2" ) ) + ? lAbort + + RETURN diff --git a/harbour/contrib/hbwin/wapi_wingdi.c b/harbour/contrib/hbwin/wapi_wingdi.c index f7c9c69e66..94295c05be 100644 --- a/harbour/contrib/hbwin/wapi_wingdi.c +++ b/harbour/contrib/hbwin/wapi_wingdi.c @@ -61,10 +61,10 @@ /* For Arc() */ #if defined( HB_OS_WIN_CE ) #include "hbwince.h" +#else + #include #endif -#include - static void s_hb_hashSetCItemNL( PHB_ITEM pHash, const char * pszKey, long v ) { PHB_ITEM pKey = hb_itemPutC( NULL, pszKey ); diff --git a/harbour/contrib/hbwin/win_shell.c b/harbour/contrib/hbwin/win_shell.c index 882a265ff1..e9208e13a2 100644 --- a/harbour/contrib/hbwin/win_shell.c +++ b/harbour/contrib/hbwin/win_shell.c @@ -7,6 +7,7 @@ * Windows API functions (shellapi.h - shell32.dll) * * Copyright 2010 Przemyslaw Czerpak + * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) * www - http://www.harbour-project.org * * This program is free software; you can redistribute it and/or modify @@ -61,6 +62,7 @@ #endif #include "hbwapi.h" +#include "hbapiitm.h" #include @@ -100,3 +102,209 @@ HB_FUNC( WIN_SHELLNOTIFYICON ) wapi_ret_L( Shell_NotifyIcon( HB_ISLOG( 6 ) ? ( hb_parl( 6 ) ? NIM_ADD : NIM_DELETE ) : NIM_MODIFY, &tnid ) ); } + +/* Details: + http://msdn.microsoft.com/en-us/library/bb762164(VS.85).aspx + http://msdn.microsoft.com/en-us/library/bb759795(v=VS.85).aspx +*/ + +#if ! defined( HB_OS_WIN_CE ) + +#if defined( __MINGW32__ ) + +typedef struct _SHNAMEMAPPING +{ + LPTSTR pszOldPath; + LPTSTR pszNewPath; + int cchOldPath; + int cchNewPath; +} SHNAMEMAPPING, *LPSHNAMEMAPPING; + +#endif + +typedef struct +{ + UINT uNumberOfMappings; + LPSHNAMEMAPPING lpSHNameMapping; +} HANDLETOMAPPINGS; + +static LPTSTR s_StringList( int iParam, DWORD * pdwIndex ) +{ + PHB_ITEM pItem = hb_param( iParam, HB_IT_ARRAY | HB_IT_STRING ), pArrItem; + LPTSTR lpStr = NULL; + DWORD dwMaxIndex = 0; + + if( pItem ) + { + HB_SIZE nLen, nSize, nTotal, n, n1; + + if( HB_IS_ARRAY( pItem ) ) + { + nSize = hb_arrayLen( pItem ); + for( n = nLen = 0; n < nSize; ++n ) + { + pArrItem = hb_arrayGetItemPtr( pItem, n + 1 ); + if( HB_IS_STRING( pArrItem ) ) + { + n1 = HB_ITEMCOPYSTR( pArrItem, NULL, 0 ); + if( n1 ) + nLen += n1 + 1; + } + } + if( nLen ) + { + nTotal = nLen + 1; + lpStr = ( LPTSTR ) hb_xgrab( nTotal * sizeof( TCHAR ) ); + for( n = nLen = 0; n < nSize; ++n ) + { + pArrItem = hb_arrayGetItemPtr( pItem, n + 1 ); + if( HB_IS_STRING( pArrItem ) ) + { + n1 = HB_ITEMCOPYSTR( pArrItem, + lpStr + nLen, nTotal - nLen ); + if( n1 ) + { + nLen += n1 + 1; + dwMaxIndex++; + } + } + } + lpStr[ nLen ] = 0; + } + } + else + { + nLen = HB_ITEMCOPYSTR( pItem, NULL, 0 ); + if( nLen ) + { + lpStr = ( LPTSTR ) hb_xgrab( ( nLen * 1 + 2 ) * sizeof( TCHAR ) ); + + HB_ITEMCOPYSTR( pItem, lpStr, nLen + 1 ); + + for( n = n1 = 0; n < nLen; ++n ) + { + if( lpStr[ n ] == 0 ) + { + ++n1; + if( lpStr[ n + 1 ] == 0 ) + break; + } + } + + if( n1 == 0 ) + { + HB_ITEMCOPYSTR( pItem, lpStr + nLen + 1, nLen + 1 ); + lpStr[ nLen * 1 + 2 ] = 0; + dwMaxIndex = 1; + } + else + { + if( n == nLen && lpStr[ n - 1 ] != 0 ) + { + lpStr[ n + 1 ] = 0; + ++n1; + } + if( ( n1 & 1 ) == 0 ) + dwMaxIndex = ( DWORD ) n1; + else + { + hb_xfree( lpStr ); + lpStr = NULL; + } + } + } + } + } + + if( pdwIndex ) + { + if( dwMaxIndex < *pdwIndex ) + *pdwIndex = dwMaxIndex; + else if( dwMaxIndex && *pdwIndex == 0 ) + *pdwIndex = 1; + } + + return lpStr; +} + +#endif + +/* WIN_SHFileOperation( [], [], [|], [|], + [], [<@lAnyOperationAborted>], + [], [] ) -> */ +HB_FUNC( WIN_SHFILEOPERATION ) +{ + int iRetVal; +#if defined( HB_OS_WIN_CE ) + iRetVal = -1; +#else + SHFILEOPSTRUCT fop; + + void * hProgressTitle; + + fop.hwnd = wapi_par_HWND( 1 ); + fop.wFunc = ( UINT ) hb_parni( 2 ); + fop.pFrom = ( LPCTSTR ) s_StringList( 3, NULL ); + fop.pTo = ( LPCTSTR ) s_StringList( 4, NULL ); + fop.fFlags = ( FILEOP_FLAGS ) hb_parnl( 5 ); + fop.fAnyOperationsAborted = FALSE; + fop.hNameMappings = NULL; + fop.lpszProgressTitle = HB_PARSTR( 8, &hProgressTitle, NULL ); + + iRetVal = SHFileOperation( &fop ); + hbwapi_SetLastError( GetLastError() ); + + hb_storl( fop.fAnyOperationsAborted, 6 ); + + if( fop.pFrom ) + hb_xfree( ( void * ) fop.pFrom ); + + if( fop.pTo ) + hb_xfree( ( void * ) fop.pTo ); + + hb_strfree( hProgressTitle ); + + if( ( fop.fFlags & FOF_WANTMAPPINGHANDLE ) != 0 ) + { + HANDLETOMAPPINGS * hm = ( HANDLETOMAPPINGS * ) fop.hNameMappings; + PHB_ITEM pArray = hb_param( 7, HB_IT_ARRAY ); + + if( pArray ) + hb_arraySize( pArray, 0 ); + + /* Process hNameMappings */ + if( hm ) + { + PHB_ITEM pTempItem = hb_itemNew( NULL ); + UINT tmp; + LPSHNAMEMAPPING pmap = hm->lpSHNameMapping; + HB_BOOL bIsWin9x = hb_iswin9x(); + + for( tmp = 0; tmp < hm->uNumberOfMappings; ++tmp ) + { + hb_arrayNew( pTempItem, 2 ); + + if( bIsWin9x ) + { + /* always returns non-UNICODE on Win9x systems */ + hb_arraySetCL( pTempItem, 1, ( char * ) pmap[ tmp ].pszOldPath, pmap[ tmp ].cchOldPath ); + hb_arraySetCL( pTempItem, 2, ( char * ) pmap[ tmp ].pszNewPath, pmap[ tmp ].cchNewPath ); + } + else + { + /* always returns UNICODE on NT and upper systems */ + HB_ARRAYSETSTRLEN( pTempItem, 1, ( LPTSTR ) pmap[ tmp ].pszOldPath, pmap[ tmp ].cchOldPath ); + HB_ARRAYSETSTRLEN( pTempItem, 2, ( LPTSTR ) pmap[ tmp ].pszNewPath, pmap[ tmp ].cchNewPath ); + } + + hb_arraySetForward( pTempItem, ( HB_SIZE ) ( tmp + 1 ), pTempItem ); + } + + hb_itemRelease( pTempItem ); + + SHFreeNameMappings( hm ); + } + } +#endif + hb_retni( iRetVal ); +}