Page 1 of 2
cGetFile() and Multiple file selection
Posted: Tue Mar 24, 2009 10:50 am
by anserkk
Hi,
What should I do to enable multiple file selection ( Using Ctrl Key + Mouse Click or Shift Key + Mouse click) when using the function cGetFile().
For eg: In Outlook express, when you compose a new message and if you try to add attachements, you can select multiple files using the Shit/Ctrl Key + Mouse click. I am trying to give similiar functionality in my app.
Is that possible using the FWH Function cGetFile() ? If possible then, is there any sample showing how the values are returned ? Will it be an array containing the FilePath+FileNames. ?
Regards
Anser
Re: cGetFile() and Multiple file selection
Posted: Tue Mar 24, 2009 12:09 pm
by StefanHaupt
Anser,
here is a modified function cGetFile() to allow multiple file selection.
Code: Select all
#define OFN_READONLY 0x00000001
#define OFN_OVERWRITEPROMPT 0x00000002
#define OFN_HIDEREADONLY 0x00000004
#define OFN_NOCHANGEDIR 0x00000008
#define OFN_SHOWHELP 0x00000010
#define OFN_ENABLEHOOK 0x00000020
#define OFN_ENABLETEMPLATE 0x00000040
#define OFN_ENABLETEMPLATEHANDLE 0x00000080
#define OFN_NOVALIDATE 0x00000100
#define OFN_ALLOWMULTISELECT 0x00000200
#define OFN_EXTENSIONDIFFERENT 0x00000400
#define OFN_PATHMUSTEXIST 0x00000800
#define OFN_FILEMUSTEXIST 0x00001000
#define OFN_CREATEPROMPT 0x00002000
#define OFN_SHAREAWARE 0x00004000
#define OFN_NOREADONLYRETURN 0x00008000
#define OFN_NOTESTFILECREATE 0x00010000
#define OFN_NONETWORKBUTTON 0x00020000
#define OFN_NOLONGNAMES 0x00040000 // force no long names for 4.x modules
#define OFN_EXPLORER 0x00080000 // new look commdlg
#define OFN_NODEREFERENCELINKS 0x00100000
#define OFN_LONGNAMES 0x00200000 // force long names for 3.x modules
#define OFN_ENABLEINCLUDENOTIFY 0x00400000 // send include message to callback
#define OFN_ENABLESIZING 0x00800000
#define OFN_DONTADDTORECENT 0x02000000
#define OFN_FORCESHOWHIDDEN 0x10000000 // Show All files including System and hidden files
#define OFN_EX_NOPLACESBAR 0x00000001 // show the left bar, called "placesbar"
FUNCTION SelectFiles ()
local cFile, i
LOCAL nFlag := nOR( OFN_ALLOWMULTISELECT, OFN_HIDEREADONLY, OFN_EXPLORER )
LOCAL lSave := .f.
LOCAL cPath
LOCAL aFiles := {}
cFile := cGetFileX ("All | *.*" ,"Select the files to backup", "*.*", "C:\", lSave, .T., nFlag,"*.*",.t. )
if EMPTY( cFile ) .or. Valtype (cFile) = "N" // Errorcode
MsgAlert ("Common Dialogbox Error: "+ Str (cFile,6))
endif
IF Valtype(cFile) = "A"
FOR i := 1 TO Len (cFile)
cFile[i] := IIF (SubStr (cFile[i],4,1)=="\",cFileDisc (cFile[i])+"\"+cFileName (cFile[i]),cFile[i])
AAdd (aFiles, cFile[i])
NEXT
ELSE
AAdd (aFiles, cFile)
ENDIF
RETURN (aFiles)
//------------------------------------------------------------------//
#pragma BEGINDUMP
#include <Windows.h>
#include <CommDlg.h>
#include <ClipApi.h>
#include <HbApi.h>
//#include <shlobj.h>
static far WORD wIndex;
static far char Title[] = "Select the file";
static char szDirName[ MAX_PATH ];
HB_FUNC( CGETFILEX ) // ( cFileMask, cTitle, nDefaultMask, ;
// cInitDir, lSave, lLongNames, nFlags, ;
// cIniFile, lHidePlacesBar ) --> cFileName
{
OPENFILENAME ofn;
LPSTR pFile, pFilter, pDir, pTitle;
WORD w = 0, wLen;
BYTE bIndex = ( BYTE ) hb_parni( 3 );
BOOL bSave = IF( PCOUNT() > 4 && ISLOGICAL( 5 ), hb_parl( 5 ), FALSE );
BOOL bLongNames = hb_parl( 6 );
DWORD dwFlags = IF( PCOUNT() > 6 && ISNUM( 7 ), hb_parnl( 7 ), 2060 );
BOOL bHideBar = IF( PCOUNT() > 8 && ISLOGICAL( 9 ), hb_parl( 9 ), FALSE );
char cFullName[64][1024];
char cCurDir[512];
char cFileName[512];
int iPosition = 0;
int iNumSelected = 0;
int n;
char buffer[65536];
DWORD dwErr;
if( PCOUNT() < 1 )
{
hb_retc( "" );
return;
}
// alloc for title
pTitle = ( LPSTR ) hb_xgrab( 128 );
if ( PCOUNT() > 1 && ISCHAR( 2 ) )
{
wLen = ( WORD ) min( ( unsigned long ) 127, hb_parclen( 2 ) );
_bcopy( pTitle, hb_parc( 2 ), wLen );
* ( pTitle + wLen ) = 0;
}
else
{
pTitle = Title;
}
// alloc for initial dir
pDir = ( LPSTR ) hb_xgrab( 128 );
if ( PCOUNT() > 3 && ISCHAR( 4 ) )
{
wLen = ( WORD ) min( ( unsigned long ) 127, hb_parclen( 4 ) );
_bcopy( pDir, hb_parc( 4 ), wLen );
* ( pDir + wLen ) = 0;
}
else
{
* ( pDir ) = 0;
}
// alloc for file
if ( dwFlags & OFN_ALLOWMULTISELECT )
pFile = ( LPSTR ) hb_xgrab( 32768 );
else
pFile = ( LPSTR ) hb_xgrab( 128 );
if ( PCOUNT() > 7 && ISCHAR( 8 ) )
{
wLen = ( WORD ) min( ( unsigned long ) 127, hb_parclen( 8 ) );
_bcopy( pFile, hb_parc( 8 ), wLen );
}
else
{
wLen = ( WORD ) min( ( unsigned long ) 127, hb_parclen( 1 ) );
_bcopy( pFile, hb_parc( 1 ), wLen );
}
* ( pFile + wLen ) = 0;
// alloc for mask
pFilter = ( LPSTR ) hb_xgrab( 400 );
wLen = ( WORD ) min( ( unsigned long ) 398, hb_parclen( 1 ) );
_bcopy( pFilter, hb_parc( 1 ), wLen );
* ( pFilter + wLen ) = 0;
while( * ( pFilter + w ) )
{
if( * ( pFilter + w ) == '|' )
{
* ( pFilter + w ) = 0;
if ( PCOUNT() < 8 )
* (pFile) = 0;
}
w++;
}
* ( pFilter + wLen ) = 0;
* ( pFilter + wLen + 1 ) = 0;
_bset( ( char * ) &ofn, 0, sizeof( OPENFILENAME ) );
ofn.lStructSize = sizeof( OPENFILENAME );
ofn.hwndOwner = GetActiveWindow();
ofn.lpstrFilter = pFilter;
ofn.lpstrFile = buffer; //pFile;
ofn.lpstrInitialDir = pDir;
ofn.lpstrTitle = pTitle;
ofn.lpstrCustomFilter = 0; // NIL;
ofn.nFilterIndex = bIndex ? bIndex: 1;
ofn.nMaxFile = dwFlags & OFN_ALLOWMULTISELECT ? 32768 : 128;
ofn.lpstrFileTitle = 0; // NIL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR |
IF( bSave, OFN_HIDEREADONLY, 0 ) |
IF( bLongNames, OFN_LONGNAMES, 0 );
if( dwFlags )
ofn.Flags = dwFlags;
if( bHideBar )
ofn.FlagsEx = OFN_EX_NOPLACESBAR;
wIndex = 0;
buffer[0] = 0 ;
if( bSave )
{
if( GetSaveFileName( &ofn ) )
hb_retc( pFile );
else
hb_retc( "" );
}
else
{
if( GetOpenFileName( &ofn ) )
if ( dwFlags & OFN_ALLOWMULTISELECT )
//hb_retclen( pFile, 32768 );
{
wsprintf(cCurDir,"%s\\",&buffer[iPosition]);
iPosition=iPosition+strlen(cCurDir);//+1;
do
{
iNumSelected++;
wsprintf(cFileName,"%s",&buffer[iPosition]);
iPosition=iPosition+strlen(cFileName)+1;
wsprintf(cFullName[iNumSelected],"%s\%s",cCurDir,cFileName);
}
while( (strlen(cFileName)!=0) && ( iNumSelected <= 63 ) );
if(iNumSelected > 1)
{
hb_reta( iNumSelected - 1 );
for (n = 1; n < iNumSelected; n++)
{
hb_storc( cFullName[n], -1, n );
}
}
else
{
hb_retc( &buffer[0] );
}
}
else
hb_retc( &buffer[0] ); //( pFile );
else
{
dwErr = CommDlgExtendedError(); // get error code
hb_retni( dwErr );
}
}
//wIndex = ( WORD ) ofn.nFilterIndex;
hb_xfree( pFilter );
hb_xfree( pFile );
hb_xfree( pDir );
hb_xfree( pTitle );
hb_xfree (buffer);
}
#pragma ENDDUMP
Re: cGetFile() and Multiple file selection
Posted: Tue Mar 24, 2009 12:20 pm
by anserkk
Thankyou Mr.Stefan,
I shall try it.
Regards
Anser
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 7:07 am
by anserkk
Dear Mr.Stefan,
When I tried to use the Function cGetFileX(), I am getting GPF in Windows XP and Windows 7. cGetFileX() is displaying the window to select the files and after selecting the file/files and when I click on the "Open" button on the dialog, application quits abnormaly.
Is there anything else that I have to take care while using the function?. I have used your sample without any changes.
Regards
Anser
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 7:54 am
by frose
Hello Stefan,
compile with the following errors and warnings:
Code: Select all
C:\FWH\include\fwHarb.h(78): warning: [ISO] No newline at end of file.
my_cgetfile.prg(187): error: Unknown field 'FlagsEx' of 'struct tagOFNA'.
my_cgetfile.prg(187): error: Undeclared identifier 'OFN_EX_NOPLACESBAR'.
my_cgetfile.prg(213): warning: Unrecognized character escape sequence '\\%'.
my_cgetfile.prg(71): warning: Static 'szDirName' is not referenced.
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 8:22 am
by StefanHaupt
Anser, Frank,
I copied this portion of code from my application, there it is working. But maybe I forgot something. I will make some tests and create a new sample.
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 11:41 am
by StefanHaupt
Anser, Frank,
the code compiles fine here, without errors. I´m using xHarbour 1.0 from Feb. 2008. I don´t know if it compiles with harbour because I don´t use it.
I made a new sample, you can download exe and source here
http://www.file-upload.net/download-161 ... X.zip.html
The sample is working here with XP, XP64, Vista and Server 2008.
Anser,
I don´t have Windows 7, so please could run the sample and report your results. Thanks
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 12:14 pm
by anserkk
Dear Mr.Stefan,
Your new cGetFileEx is working fine in XP as well as in Windows 7
Thankyou very much.
Regards
Anser
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 1:45 pm
by frose
Stefan,
still have these two errors:
error: Unknown field 'FlagsEx' of 'struct tagOFNA'.
error: Undeclared identifier 'OFN_EX_NOPLACESBAR'.
Annotating the line 'ofn.FlagsEx = OFN_EX_NOPLACESBAR;' helps
Don't ask me why. Perhaps because I'm using a different C compiler (xCC)?
Thank you very much
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 2:39 pm
by carlos vargas
Hace tiempo yo tenia ese problema que codigo c compilado correctamente con bcc me daba problema al compilar con xcc.
encontre que:
En algunas ocaciones, al compilar codigo C con pelles c o xcc, es necesario definir una constantes antes de los encabezados la cual indica el windows para el cual sera usado, no recuerdo de momento cual es la constante, pero si buscas en los encabezados del compilador c veras al inicio una definciones que permiten la compilacion condicional de ciertos archivos , creo recordar que es algo como WINNT.
salu2
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 3:06 pm
by carlos vargas
Estimado encontre la constante
ya he probado que sin ella, la compilacion falla, pero con ella es un exito
salu2
Code: Select all
#pragma BEGINDUMP
#define _WIN32_WINNT 0x0500 /*agregar esto*/
#include <Windows.h>
#include <CommDlg.h>
#include <ClipApi.h>
#include <HbApi.h>
//#include <shlobj.h>
static far WORD wIndex;
static far char Title[] = "Select the file";
static char szDirName[ MAX_PATH ];
Re: cGetFile() and Multiple file selection
Posted: Wed Apr 29, 2009 3:26 pm
by frose
Carlos,
¡muchas gracias!
Please excuse me, my spanish knowledge is really 'poco', so I tried to translate your post via Google:
Some time ago I had this problem c code compiled fine with me bcc problem when compiling with XCC.
found that:
On some occasions, to compile C code with co pelle XCC is necessary to define a constant before the headers which indicate the windows for which will be used, I do not recall at the moment which is constant, but if you look at the headers of the compiler c really a definition at the outset that allow conditional compilation of certain files, which is something I remember as WINNT.
So I understand rudimental what you mean - probably caused by poor knowledge regarding C and compilers and not regarding my spanish -, so it's not clear for me, what I have to do exactly to avoid this error.
On the other hand, most of the other FWH users are using BCC as Antonio wrote some time ago:
Borland seems to be the most popular by FWH users.
Perhaps it's the best to switch to the Borland Compiler?
Re: cGetFile() and Multiple file selection
Posted: Thu Apr 30, 2009 7:58 am
by StefanHaupt
frose wrote:still have these two errors:
error: Unknown field 'FlagsEx' of 'struct tagOFNA'.
error: Undeclared identifier 'OFN_EX_NOPLACESBAR'.
Annotating the line 'ofn.FlagsEx = OFN_EX_NOPLACESBAR;' helps
Don't ask me why. Perhaps because I'm using a different C compiler (xCC)?
Frank,
I´m using BCC 5.5, maybe with xCC (uses PellesC) it does not compile correct. There maybe some differences in the header files or in the syntax, I don´t know. My C knowledge is not as good as it should be, I´m happy to get it compiled with Borland
From msdn :
OPENFILENAME Structure
The OPENFILENAME structure contains information that the GetOpenFileName and GetSaveFileName functions use to initialize an Open or Save As dialog box. After the user closes the dialog box, the system returns information about the user's selection in this structure.
Syntax
typedef struct tagOFN {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCTSTR lpstrFilter;
LPTSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPTSTR lpstrFile;
DWORD nMaxFile;
LPTSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCTSTR lpstrInitialDir;
LPCTSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCTSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAME, *LPOPENFILENAME;
So FlagsEx should be known if you set _WIN32_WINNT >= 0x0500, maybe the struct is not correct defined with PellesC, OFN_EX_NOPLACESBAR can be replaced with 0x1.
Re: cGetFile() and Multiple file selection
Posted: Thu Apr 30, 2009 8:13 am
by frose
Carlos, Stefan,
yes, '#define _WIN32_WINNT 0x0500' is the solution!
¡muchas gracias!
Thank you very much
Re: cGetFile() and Multiple file selection
Posted: Thu Apr 30, 2009 9:21 am
by anserkk
Dear Mr.Stefan
I want the user to select only the JPG files. With the regular cGetFile (which comes bundled with FWH) I used to give the following parameters and the Select file Dialog will show only the JPG files available in the folder, so that the user will not get a chance to select files other than jpg's
Code: Select all
cFiles:=cGetFile( "*.jpg", "Please select the JPG file to be attached" )
But with the cGetFileEx() I am not able to do that. Eventhoug I have given *.jpg, the file open dialog is displaying all the file types and the user is able to select any files. The parameters used is given below
Code: Select all
nFlag := nOR( OFN_ALLOWMULTISELECT, OFN_HIDEREADONLY, OFN_EXPLORER )
cFile := cGetFileEX ("*.jpg" ,"Select the JPG files", "*.jpg", "E:\Test\", .F., .T., nFlag,"*.jpg",.t. )
Screen Snapshot
Any idea where I am wrong ? Which is the right parameter ?. I am not an expert in C and could not understand the Parameters while reading the C code of the function cGetFileEx()
Regards
Anser