Page 1 of 1

Re: Multi file selection

Posted: Mon May 01, 2006 4:57 pm
by Vytas
Hi All,

I have been using cGetFile() to get user file selection. How do I go about allowing a user to select multiple files using the <Shift> and <Ctrl> keys? My search did not find anything perhaps I was not using the proper key words. Any guidance is appreciated.

Vytas

Posted: Mon May 01, 2006 9:48 pm
by James Bott
Vytas,

I found the messages below in my notes. I have not tried it so I don't know if it works. Let us know.

James

Code: Select all

From: "Dicky Low" <dicky@hartalega-bb.com.my>
Subject: Re: cGetFile()
Date: Wednesday, April 09, 2003 8:34 PM

Hi,

Found a solution. The 7th parameter of cGetFile() is the flags to control
the multiple files selection. But the cGetFile have a little bug which
ignore your previous flag if you pass in the 7th parameter.

To correct the cGetFile(), refer to line 164
   if( dwFlags )
      ofn.Flags = dwFlags;

Just change it to
   if( dwFlags )
      ofn.Flags |= dwFlags;

And everything will work perfectly well.

Lastly, the 7th parameter to pass in is hex 200 which is decimal 512

Regards
Dicky

"Marcelo Via Giglio" <via@dicyt.umss.edu.bo> wrote in message
news:3E93E70B.61D25D91@dicyt.umss.edu.bo...
> Hello,
>
> you can put the result of directory into Multisel Browse
> (Hernan's Browse)
>
> Regards
>
> Marcelo
>
> Dicky Low wrote:
>
> > Steve,
> >
> > I mean getting multiple files in the return. Your example below show
cPath,
> > and I assume it is single file selected and not multiple files like what
we
> > can do with windows explorer when you can select multiple files to
delete,
> > etc, etc...
> >
> > Regards
> > Dicky
> >
> > "Aberdeen IT" <operations@aberdeenit.com> wrote in message
> > news:3e93ddf8$1@oznt1.ozlan.local...
> > > Dicky
> > >
> > > This code works with FW2.1 ...
> > >
> > > cPath := cGetFile32("MS Word (*.doc) | *.doc |" + ;
> > >                                 "MS Excel (*.xls) | *.xls |" + ;
> > >                                 "Acrobat Reader (*.pdf) | *.pdf",
"Select
> > a
> > > file", 1)
> > >
> > > I cannot remember exactly what the last parameter does, but I think
it's
> > to
> > > highlight the starting element, i.e. the first element in the above
> > example.
> > >
> > > Regards
> > > Steve Lai
> > >
> > >
> > > "Dicky Low" <dicky@hartalega-bb.com.my> wrote in message
> > > news:3e93c98f@oznt1.ozlan.local...
> > > > Hi,
> > > >
> > > > Anyone has any ideas how can we select multiple files in cGetFile()
or
> > is
> > > > there any alternative function?
> > > >
> > > > Regards
> > > > Dicky Low
> > > >
> > > >
> > >
> > >
>

Posted: Tue May 02, 2006 2:07 pm
by Vytas
Hi James,

Thanks for the lead. I have confirmed that the seventh parameter set to 512 does in fact evoke the multi file selection option. However it also causes the file names to be displayed in short name format even if the lLongNames parameter is set to true. How to fix this problem is beyond my abilities.

My application can live with 8 character names however in this day and age others may not. If the revised code still returned the selected files in a space delimited string the parsing out of filenames containing spaces may present a bit of a challenge assuming that the item separator remains a space character.

Tanks,

Vytas

LOCAL ErrorFileDir := CurrentDrive + ":\" + "b4\AML"
LOCAL Files := cGetFile("AML File|*.txt|" + "DataBase | *.dbf |","Multi Select",1,ErrorFileDir,.f.,.t.,512)
LOCAL File := cGetFile("Txt File|*.txt|" + "DataBase | *.dbf |","Select One ",1,ErrorFileDir,.f.,.t.)
? Files,File

Output from first Multi select cGetFile
Z:\b4\AML\ BatName.txt CPM9PN~M.TXT

Output from first Single file select cGetFile
Z:\b4\AML\Copy (2) of AddProjection.txt

Posted: Tue May 02, 2006 4:16 pm
by James Bott
Vytas,

Perhaps this will help.

James

Code: Select all

From: "Enrico Maria Giordano" <e.m.giordano@emagsoftware.it>
Subject: Re: Long file names
Date: Friday, November 29, 2002 3:52 AM

Randal Ferguson wrote:
> 
> All,
> 
> I'm using cGetFile32 but the file name returned is the short file name.  How
> do I get the long file name?

A working sample follows:

#include "Fivewin.ch"


FUNCTION MAIN()

    ? CGETFILE32( "*.*", "Test", , , , 2060 )

    RETURN NIL

EMG

Posted: Tue May 02, 2006 5:48 pm
by Vytas
Hi James,

It does display the files in long name format. However using either 512 or 2060 as a WinAPI flag did not let me select more than one file. Either there is a magic number required that I do not know, or I am again on the wrong track to solving this issue.

Thanks again,

Vytas

Posted: Tue May 02, 2006 5:57 pm
by Enrico Maria Giordano
This is a better sample. But unfortunately it doesn't return the selected filenamed. :-(

Code: Select all

#include "Fivewin.ch"


#define OFN_ALLOWMULTISELECT 0x200
#define OFN_EXPLORER         0x80000


FUNCTION MAIN()

    ? CGETFILE( "*.*", "Test", , , , , NOR( OFN_ALLOWMULTISELECT, OFN_EXPLORER ) )

    RETURN NIL
EMG

Posted: Tue May 02, 2006 8:19 pm
by James Bott
Enrico,

What does it return? It should be returning an array, right?

James

Posted: Tue May 02, 2006 8:32 pm
by Enrico Maria Giordano
It should return the selected path name followed by the selected file names, each of them NULL separated with an extra NULL at the end. What I instead see is only the path name. I think that the cause is the _retc() API used inside CGETFILE() function.

EMG

Posted: Wed May 03, 2006 1:33 pm
by Vytas
Hi Enrico,

I get the same results as you. Is this a bug in FiveWin?

It seems that the only way to implement multi file select is by getting an array of files and then creating a multi item pick list. Or is there a better way?

Thanks,

Vytas

Posted: Wed May 03, 2006 1:38 pm
by Enrico Maria Giordano
Vytas wrote:I get the same results as you. Is this a bug in FiveWin?
I would not call it a bug. Simply, multifile selection is not yet implemented in cGetFile().

Let's hope it will be. :-)

EMG

Posted: Wed May 03, 2006 3:53 pm
by carlos vargas
sorry for my bad english

Enrico

Plase search in hwgui or minigui functions for open files, this functions in both library permit select multi file and return a array with the file select. the sources with minimal change work in fwh.


salu2
carlos vargas.

Posted: Wed May 03, 2006 6:06 pm
by Enrico Maria Giordano
Thank you, I will have a look at it.

EMG

Posted: Wed May 03, 2006 9:09 pm
by Enrico Maria Giordano
This is a working sample:

Code: Select all

#include "Fivewin.ch"


#define OFN_HIDEREADONLY     0x4
#define OFN_ALLOWMULTISELECT 0x200
#define OFN_EXPLORER         0x80000


FUNCTION MAIN()

    LOCAL cFile := CGETFILE( "*.*", "Test", , , , , NOR( OFN_ALLOWMULTISELECT, OFN_EXPLORER, OFN_HIDEREADONLY ) )

    LOCAL aFile := {}

    LOCAL cPath

    IF !EMPTY( cFile )
        cPath = LEFT( cFile, AT( CHR( 0 ), cFile ) - 1 )

        IF RIGHT( cPath, 1 ) != "\"; cPath += "\"; ENDIF

        WHILE .T.
            cFile = SUBSTR( cFile, AT( CHR( 0 ), cFile ) + 1 )
            IF LEFT( cFile, 1 ) = CHR( 0 ); EXIT; ENDIF
            AADD( aFile, cPath + LEFT( cFile, AT( CHR( 0 ), cFile ) - 1 ) )
        ENDDO

        IF LEN( aFile ) = 1
            aFile[ 1 ] = LEFT( aFile[ 1 ], LEN( aFile[ 1 ] ) - 1 )
        ENDIF
    ENDIF

    WQOUT( aFile )

    RETURN NIL


#pragma BEGINDUMP

#include <Windows.h>
#include <CommDlg.h>
#include <ClipApi.h>
#include <HbApi.h>

static far WORD wIndex;
static far char Title[] = "Select the file";


HB_FUNC( CGETFILE )          // ( cFileMask, cTitle, nDefaultMask, ;
                             // cInitDir, lSave, lLongNames, nFlags, ;
                             // cIniFile )  --> 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 );   

   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       = 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;

   wIndex = 0;

   if( bSave )
   {
      if( GetSaveFileName( &ofn ) )
         hb_retc( pFile );
      else
         hb_retc( "" );
   }
   else
   {
      if( GetOpenFileName( &ofn ) )
         if ( dwFlags & OFN_ALLOWMULTISELECT )
            hb_retclen( pFile, 32768 );
         else
            hb_retc( pFile );
      else
         hb_retc( "" );
   }

   wIndex = ( WORD ) ofn.nFilterIndex;

   hb_xfree( pFilter );
   hb_xfree( pFile );
   hb_xfree( pDir );
   hb_xfree( pTitle );
}

#pragma ENDDUMP
EMG

Posted: Fri May 05, 2006 3:45 pm
by Vytas
Hi Enrico,

Thanks for taking the time to solve the issue. I hope you will forgive me for asking how do I go about compiling and linking your sample code? I run a make file (listed below) and get the following errors. I suspect it has go something to do wil paths but I am not sure what I should be modifing.

Vytas

Z:\CTIPrg>D:\Borland\bcc55\bin\make -fvytas01.rmk
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
d:\harbour\bin\harbour .\VYTAS01.PRG /N /W /Oobj\ /Id:\fwh\include;d:\ha
rbour\include >> vjclip.log
d:\Borland\bcc55\bin\bcc32 -c -tWM -Id:\harbour\include -oobj\VYTAS01 ob
j\VYTAS01.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
obj\VYTAS01.c:
Error E2209 .\VYTAS01.PRG 41: Unable to open include file 'ClipApi.h'
Warning W8065 .\VYTAS01.PRG 57: Call to function 'PCOUNT' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 57: Call to function 'ISLOGICAL' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 57: Call to function 'IF' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 59: Call to function 'PCOUNT' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 59: Call to function 'IF' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 61: Call to function 'PCOUNT' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 71: Call to function 'PCOUNT' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 74: Call to function '_bcopy' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 87: Call to function 'PCOUNT' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 90: Call to function '_bcopy' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 105: Call to function 'PCOUNT' with no prototype infunction HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 108: Call to function '_bcopy' with no prototype infunction HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 113: Call to function '_bcopy' with no prototype infunction HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 121: Call to function '_bcopy' with no prototype infunction HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 129: Call to function 'PCOUNT' with no prototype infunction HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 138: Call to function '_bset' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 151: Call to function 'IF' with no prototype in function HB_FUN_CGETFILE
Warning W8065 .\VYTAS01.PRG 152: Call to function 'IF' with no prototype in function HB_FUN_CGETFILE
*** 1 errors in Compile ***

** error 1 ** deleting VYTAS01.OBJ

*RMK file
#Borland make sample, (c) FiveTech Software 2005

HBDIR=d:\harbour
BCDIR=d:\Borland\bcc55
FWDIR=d:\fwh

#change these paths as needed
.path.PRG = .\
.path.OBJ = .\obj
.path.CH = $(FWDIR)\include;$(HBDIR)\include
.path.C = .\
.path.rc = .\

#important: Use Uppercase for filenames extensions, in the next two rules!

PRG = \
VYTAS01.PRG \
# invdata.PRG \
# compile.PRG \
# reports.PRG \
# testit.PRG \
# param.PRG \
# xbrowse.PRG
# one.PRG

# C = \
# two.C

PROJECT : Vytas01.exe

Vytas01.exe : $(PRG:.PRG=.OBJ) $(C:.C=.OBJ) Vytas01.res
echo off
echo $(BCDIR)\bin\c0w32.obj + > b32.bc
echo obj\Vytas01.obj, + >> b32.bc
echo Vytas01.exe, + >> b32.bc
echo Vytas01.map, + >> b32.bc
echo $(FWDIR)\lib\FiveH.lib $(FWDIR)\lib\FiveHC.lib + >> b32.bc
echo $(HBDIR)\lib\rtl.lib + >> b32.bc
echo $(HBDIR)\lib\vm.lib + >> b32.bc
echo $(HBDIR)\lib\gtwin.lib + >> b32.bc
echo $(HBDIR)\lib\lang.lib + >> b32.bc
echo $(HBDIR)\lib\macro.lib + >> b32.bc
echo $(HBDIR)\lib\rdd.lib + >> b32.bc
echo $(HBDIR)\lib\dbfntx.lib + >> b32.bc
echo $(HBDIR)\lib\dbfcdx.lib + >> b32.bc
# echo $(HBDIR)\lib\dbfdbt.lib + >> b32.bc
echo $(HBDIR)\lib\debug.lib + >> b32.bc
echo $(HBDIR)\lib\common.lib + >> b32.bc
echo $(HBDIR)\lib\pp.lib + >> b32.bc
echo $(HBDIR)\lib\codepage.lib + >> b32.bc
# echo $(HBDIR)\lib\hbzip.lib + >> b32.bc

echo $(HBDIR)\lib\hbsix.lib + >> b32.bc
echo $(HBDIR)\lib\dbffpt.lib + >> b32.bc
# echo $(HBDIR)\lib\pcrepos.lib + >> b32.bc

rem Uncomment these two lines to use Advantage RDD
rem echo $(HBDIR)\lib\rddads.lib + >> b32.bc
rem echo $(HBDIR)\lib\Ace32.lib + >> b32.bc

echo $(BCDIR)\lib\cw32.lib + >> b32.bc
echo $(BCDIR)\lib\import32.lib + >> b32.bc
echo $(BCDIR)\lib\psdk\odbc32.lib + >> b32.bc
echo $(BCDIR)\lib\psdk\nddeapi.lib + >> b32.bc
echo $(BCDIR)\lib\psdk\iphlpapi.lib + >> b32.bc
echo $(BCDIR)\lib\psdk\rasapi32.lib, >> b32.bc

IF EXIST Vytas01.res echo Vytas01.res >> b32.bc
$(BCDIR)\bin\ilink32 -Gn -aa -Tpe -s @b32.bc
# del b32.bc

.PRG.OBJ:
$(HBDIR)\bin\harbour $< /N /W /Oobj\ /I$(FWDIR)\include;$(HBDIR)\include >> vjclip.log
$(BCDIR)\bin\bcc32 -c -tWM -I$(HBDIR)\include -oobj\$& obj\$&.c

.C.OBJ:
echo -c -tWM -D__HARBOUR__ -DHB_API_MACROS > tmp
echo -I$(HBDIR)\include;$(FWDIR)\include >> tmp
$(BCDIR)\bin\bcc32 -oobj\$& @tmp $&.c
# del tmp

Vytas01.res : Vytas01.rc
$(BCDIR)\bin\brc32.exe -r Vytas01.rc


# echo obj\CMX52.obj + >> b32.bc
# echo C:\comix\52\cmx52.lib + >> b32.bc

Posted: Fri May 05, 2006 4:20 pm
by Enrico Maria Giordano
Vytas wrote:Error E2209 .\VYTAS01.PRG 41: Unable to open include file 'ClipApi.h'
ClipApi.h is in your fwh\include directory. If not then you have a FWH installation problem.

EMG