diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 6dbdf12617..a9ef46bfac 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,32 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-02-13 02:38 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/contrib/hbwin/hbwin.ch + + added WIN_OFN_* constants + + * harbour/contrib/hbwin/win_dlg.c + + added WIN_GETOPENFILENAME( [[@]], [], ; + [], [], ; + [], [[@]], ; + [] ) + -> | + e"\0" + [ + e"\0" + ] | "" + + added WIN_GETSAFEFILENAME( [[@]], [], ; + [], [], ; + [], [[@]], ; + [] ) + -> | + e"\0" + [ + e"\0" + ] | "" + + * harbour/contrib/hbwin/wapi_winbase.c + * cleaned WAPI_GETSHORTNAME() function parameter to strictly respect + the following parameters syntax. + WAPI_GETSHORTPATHNAME( [, @ [, ] ] ) + -> < nShortLenght> + % eliminate double call to GetShortPathName() in WAPI_GETSHORTNAME() + when all parameters are given or second one is not passed by reference + % try to use static buffer to eliminate double call to GetShortPathName() + when WAPI_GETSHORTNAME() is called without 3-rd parameter + 2010-02-12 21:01 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * include/hbdefs.h * HB_BYTE made a synonym for HB_UCHAR. diff --git a/harbour/contrib/hbwin/hbwin.ch b/harbour/contrib/hbwin/hbwin.ch index 9d8a6f0eb6..a4fe4e1fe2 100644 --- a/harbour/contrib/hbwin/hbwin.ch +++ b/harbour/contrib/hbwin/hbwin.ch @@ -484,13 +484,45 @@ #define WIN_TA_BASELINE 24 /* WIN_SETPEN() pen styles */ -#define WIN_PS_SOLID 0 -#define WIN_PS_DASH 1 -#define WIN_PS_DOT 2 -#define WIN_PS_DASHDOT 3 -#define WIN_PS_DASHDOTDOT 4 -#define WIN_PS_NULL 5 -#define WIN_PS_INSIDEFRAME 6 +#define WIN_PS_SOLID 0 +#define WIN_PS_DASH 1 +#define WIN_PS_DOT 2 +#define WIN_PS_DASHDOT 3 +#define WIN_PS_DASHDOTDOT 4 +#define WIN_PS_NULL 5 +#define WIN_PS_INSIDEFRAME 6 + +/* WIN_GETOPENFILENAME()/WIN_GETSAVEFILENAME() */ +#define WIN_OFN_READONLY 0x00000001 +#define WIN_OFN_OVERWRITEPROMPT 0x00000002 +#define WIN_OFN_HIDEREADONLY 0x00000004 +#define WIN_OFN_NOCHANGEDIR 0x00000008 +#define WIN_OFN_SHOWHELP 0x00000010 +#define WIN_OFN_ENABLEHOOK 0x00000020 +#define WIN_OFN_ENABLETEMPLATE 0x00000040 +#define WIN_OFN_ENABLETEMPLATEHANDLE 0x00000080 +#define WIN_OFN_NOVALIDATE 0x00000100 +#define WIN_OFN_ALLOWMULTISELECT 0x00000200 +#define WIN_OFN_EXTENSIONDIFFERENT 0x00000400 +#define WIN_OFN_PATHMUSTEXIST 0x00000800 +#define WIN_OFN_FILEMUSTEXIST 0x00001000 +#define WIN_OFN_CREATEPROMPT 0x00002000 +#define WIN_OFN_SHAREAWARE 0x00004000 +#define WIN_OFN_NOREADONLYRETURN 0x00008000 +#define WIN_OFN_NOTESTFILECREATE 0x00010000 +#define WIN_OFN_NONETWORKBUTTON 0x00020000 +#define WIN_OFN_NOLONGNAMES 0x00040000 +#define WIN_OFN_EXPLORER 0x00080000 +#define WIN_OFN_NODEREFERENCELINKS 0x00100000 +#define WIN_OFN_LONGNAMES 0x00200000 +#define WIN_OFN_ENABLEINCLUDENOTIFY 0x00400000 +#define WIN_OFN_ENABLESIZING 0x00800000 +#define WIN_OFN_DONTADDTORECENT 0x02000000 +#define WIN_OFN_FORCESHOWHIDDEN 0x10000000 + +#define WIN_OFN_SHAREFALLTHROUGH 0x00000002 +#define WIN_OFN_SHARENOWARN 0x00000001 +#define WIN_OFN_SHAREWARN 0x00000000 /* ------------------------------- */ /* Deprecated constants and macros */ diff --git a/harbour/contrib/hbwin/wapi_winbase.c b/harbour/contrib/hbwin/wapi_winbase.c index 1d93bbdc22..f3eda22905 100644 --- a/harbour/contrib/hbwin/wapi_winbase.c +++ b/harbour/contrib/hbwin/wapi_winbase.c @@ -304,26 +304,39 @@ HB_FUNC( WAPI_GETSHORTPATHNAME ) if( lpszLongPath ) { - length = GetShortPathName( lpszLongPath, NULL, 0 ); - - if( length && HB_ISBYREF( 2 ) ) + if( HB_ISBYREF( 2 ) ) { - LPTSTR lpszShortPath; - DWORD cchBuffer = ( DWORD ) hb_parnl( 3 ); + TCHAR buffer[ HB_PATH_MAX ]; + DWORD cchBuffer = ( DWORD ) HB_SIZEOFARRAY( buffer ); + LPTSTR lpszShortPath = buffer; + HB_BOOL fSize = HB_ISNUM( 3 ); - if( cchBuffer ) - cchBuffer = HB_MIN( length, cchBuffer + sizeof( TCHAR ) ); - else - cchBuffer = length; + if( fSize ) /* the size of buffer is limited by user */ + { + cchBuffer = ( DWORD ) hb_parnl( 3 ); + if( cchBuffer == 0 ) + lpszShortPath = NULL; + else if( cchBuffer > ( DWORD ) HB_SIZEOFARRAY( buffer ) ) + lpszShortPath = ( LPTSTR ) hb_xgrab( cchBuffer * sizeof( TCHAR ) ); + } - lpszShortPath = ( LPTSTR ) hb_xgrab( cchBuffer * sizeof( TCHAR ) ); length = GetShortPathName( lpszLongPath, lpszShortPath, cchBuffer ); + if( !fSize && length > cchBuffer ) /* default buffer size was too small */ + { + cchBuffer = length; + lpszShortPath = ( LPTSTR ) hb_xgrab( cchBuffer * sizeof( TCHAR ) ); + length = GetShortPathName( lpszLongPath, lpszShortPath, cchBuffer ); + } hbwapi_SetLastError( GetLastError() ); - HB_STORSTR( length > cchBuffer ? NULL : lpszShortPath, 2 ); - hb_xfree( lpszShortPath ); + HB_STORSTRLEN( lpszShortPath, length > cchBuffer ? 0 : length, 2 ); + if( lpszShortPath && lpszShortPath != buffer ) + hb_xfree( lpszShortPath ); } - else if( length == 0 ) + else + { + length = GetShortPathName( lpszLongPath, NULL, 0 ); hbwapi_SetLastError( GetLastError() ); + } } hb_retnl( length ); hb_strfree( hLongPath ); diff --git a/harbour/contrib/hbwin/win_dlg.c b/harbour/contrib/hbwin/win_dlg.c index 32f51b213a..49cbb9233a 100644 --- a/harbour/contrib/hbwin/win_dlg.c +++ b/harbour/contrib/hbwin/win_dlg.c @@ -7,6 +7,11 @@ * Windows dialogs * * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) + * WIN_PRINTDLGDC() + * + * Copyright 2010 Przemyslaw Czerpak + * WIN_GETOPENFILENAME(), WIN_GETSAVEFILENAME() + * * www - http://www.harbour-project.org * * This program is free software; you can redistribute it and/or modify @@ -55,6 +60,9 @@ #if ! defined( HB_OS_WIN_CE ) +/* WIN_PRINTDLGDC( [@], [], [], [] ) + * -> + */ HB_FUNC( WIN_PRINTDLGDC ) { PRINTDLG pd; @@ -88,3 +96,203 @@ HB_FUNC( WIN_PRINTDLGDC ) } #endif + +static LPTSTR s_dialogPairs( 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, n2; + + 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 * 2 + 2; + } + else if( hb_arrayLen( pArrItem ) >= 2 ) + { + n1 = HB_ITEMCOPYSTR( hb_arrayGetItemPtr( pArrItem, 1 ), NULL, 0 ); + n2 = HB_ITEMCOPYSTR( hb_arrayGetItemPtr( pArrItem, 2 ), NULL, 0 ); + if( n1 && n2 ) + nLen += n1 + n2 + 2; + } + } + 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; + n1 = HB_ITEMCOPYSTR( pArrItem, + lpStr + nLen, nTotal - nLen ); + nLen += n1 + 1; + dwMaxIndex++; + } + } + else if( hb_arrayLen( pArrItem ) >= 2 ) + { + n1 = HB_ITEMCOPYSTR( hb_arrayGetItemPtr( pArrItem, 1 ), + lpStr + nLen, nTotal - nLen ); + if( n1 ) + { + n2 = HB_ITEMCOPYSTR( hb_arrayGetItemPtr( pArrItem, 2 ), + lpStr + nLen + n1 + 1, + nTotal - nLen - n1 - 1 ); + if( n2 ) + { + nLen += n1 + n2 + 2; + dwMaxIndex++; + } + } + } + } + lpStr[ nLen ] = 0; + } + } + else + { + nLen = HB_ITEMCOPYSTR( pItem, NULL, 0 ); + if( nLen ) + { + lpStr = ( LPTSTR ) hb_xgrab( ( nLen * 2 + 3 ) * 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 * 2 + 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; +} + +static void s_GetFileName( HB_BOOL fSave ) +{ + void * hInitDir, * hTitle, * hDefExt; + LPTSTR lpstrFilter; + OPENFILENAME ofn; + + memset( &ofn, 0, sizeof( OPENFILENAME ) ); +#if defined( OPENFILENAME_SIZE_VERSION_400 ) + ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; +#else + ofn.lStructSize = sizeof( ofn ); +#endif + ofn.hwndOwner = GetActiveWindow(); + ofn.hInstance = GetModuleHandle( NULL ); + + ofn.nFilterIndex = wapi_par_DWORD( 6 ); + ofn.lpstrFilter = lpstrFilter = s_dialogPairs( 5, &ofn.nFilterIndex ); + + ofn.nMaxFile = wapi_par_DWORD( 7 ); + if( ofn.nMaxFile < 0x100 ) + ofn.nMaxFile = ofn.nMaxFile == 0 ? 0x10000 : 0x100; + ofn.lpstrFile = ( LPTSTR ) + memset( hb_xgrab( ofn.nMaxFile * sizeof( TCHAR ) ), + 0, ofn.nMaxFile * sizeof( TCHAR ) ); + + ofn.lpstrInitialDir = HB_PARSTR( 3, &hInitDir, NULL ); + ofn.lpstrTitle = HB_PARSTR( 2, &hTitle, NULL ); + ofn.Flags = HB_ISNUM( 1 ) ? wapi_par_DWORD( 1 ) : + OFN_EXPLORER | OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY; + ofn.lpstrDefExt = HB_PARSTR( 4, &hDefExt, NULL ); + if( ofn.lpstrDefExt && ofn.lpstrDefExt[ 0 ] == '.' ) + ++ofn.lpstrDefExt; + + if( fSave ? GetSaveFileName( &ofn ) : GetOpenFileName( &ofn ) ) + { + HB_SIZE nLen; + for( nLen = 0; nLen < ofn.nMaxFile; ++nLen ) + { + if( ofn.lpstrFile[ nLen ] == 0 && + ( nLen + 1 == ofn.nMaxFile || ofn.lpstrFile[ nLen + 1 ] == 0 ) ) + break; + } + hb_stornint( ofn.Flags, 1 ); + hb_stornint( ofn.nFilterIndex, 6 ); + HB_RETSTRLEN( ofn.lpstrFile, nLen ); + } + else + hb_retc_null(); + + hb_xfree( ofn.lpstrFile ); + if( lpstrFilter ) + hb_xfree( lpstrFilter ); + + hb_strfree( hInitDir ); + hb_strfree( hTitle ); + hb_strfree( hDefExt ); +} + +/* WIN_GETOPENFILENAME( [[@]], [], [], [],; + * [], [[@]], [] ) + * -> | + e"\0" + [ + e"\0" + ] | "" + * + */ +HB_FUNC( WIN_GETOPENFILENAME ) +{ + s_GetFileName( HB_FALSE ); +} + +/* WIN_GETSAVEFILENAME( [[@]], [], [], [],; + * [], [[@]], [] ) + * -> | + e"\0" + [ + e"\0" + ] | "" + * + */ +HB_FUNC( WIN_GETSAVEFILENAME ) +{ + s_GetFileName( HB_TRUE ); +}