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 :wink:

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
Image
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