Adding Multiselection to TFileOpenDialogs
ADVANCED
Date: 7 February
1997
Author: Brice VIDAL
Platform: 32 bits environement
In memory of: Carcass
Overview
- As you have perhaps noticed when selecting
many files and then pressing the Open button, nothing happens.
Well this is due to the fact that the FileName has a size fixed to _MAX_PATH.
Changing this is not very difficult, much more can be done...
- Lost in the jungle of the flags? Perhaps
you want to limit the length of a file name to 64 without dropping the
multiselection capabilities. You can download the code here,
it is completely documented so do not hesitate.
Changing the size of the FileName member
- The TOpensSaveDialog::TData
constructor can take parameters. The size of FileName can be changed
via the constructor but you'll have to decide the amount you want to attribute
to FileName.
#include <owl/opensave.h>
TOpenSaveDialog::TData FileData(
(uint32)OFN_EXPLORER | OFN_ALLOWMULTISELECT,
// the FLAGS
(char*)"Your
App Files (*.app)|*.app| All Files (*.*)|*.*|",
// the Filter
(char*)"*.app",
// the Custom Filter
(char*)"C:\\BC5",
// the Initial Dir
(char*)"app",
// the Default Extension
(int)500,
// the Size of FileName
(int)0);
// the Filter Index
- If you prefer you
can acces the size diretly accessing the int MaxPath but remember
that the FileName MUST be resized, if not you will have to
face a GPF or worse... Personaly I do not recommend this method
but you are free to use it. Another danger appears when the TOpenSaveDialog::TData
destructor will try to delete FileName...
#include <owl/opensave.h>
TOpenSaveDialog::TData FileData;
FileData.Flags = OFN_EXPLORER | OFN_ALLOWMULTISELECT;
FileData.MaxPath = 500;
if(FileData.FileName)
delete[] FileData.FileName;
FileData.FileName = new char[FileData.MaxPath];
Most common flags
- OFN_ALLOWMULTISELECT: allows multiselection
in the dialog box. If the dialog box is created by using a private template,
the definition of the File Name list box must contain the LBS_EXTENDEDSEL
value. When this flag is set thFileName string is not always formatted
in the same way: when using the OFN_EXPLORER flag, as seen before,
each name is separated by a null terminator and the double null
terminator indicates the end of the string ; when this flag isn't set then
each name is separated by a space. Here's an example showing how
to deal with the space delimiter:
#include <cstring.h>
if(TFileOpenDialog(this, FileData).Execute()==ID_OK)
{
char* p;
p = strtok(FileData.FileName, '
');
string path(p);
while(p = strtok(NULL, '
'))
{
string openName(p);
openName = path + openName;
OpenFile(openName.c_str());
}
}
- OFN_CREATEPROMPT asks the user
if he or she wants to create the file if it does not exist.
- OFN_EXPLORER creates a dialog
box which looks like the one in the overview section. With this flag your
dialog box will look like the open dialog boxes from Win95, if you don't
set this flag your dialog box will look like a normal open dailog box (Win3.x).
- OFN_FILEMUSTEXIST,OFN_PATHMUSTEXIST
specifies that the user must type an existing file name, if this file does
not exists a warning dialog box is created.
- OFN_HIDEREADONLY hides the Read
Only check box.
- OFN_LONGNAMES, OFN_NOLONGNAMES
forces the dialog box to use or not long file names. Those flags are ignored
if OFN_EXPLORER is set.
- OFN_NOCHANGEDIR restores the current
directory to its original value if the user has moved to another directory.
- OFN_NODEREFERENCELINKS formats
the FileName string with the path to the *.lnk file and not with the path
of the file to which it points.
- OFN_NONETWORKBUTTON hides and
disables the Network button.
- OFN_NOVALIDATE does not check
for invalid characters in the file name nor adds the default extension
to the text.
- OFN_OVERWRITEPROMPT generates
a dialog box if the file alredy exists.
- OFN_READONLY sets the state of
the Read Only check box to checked.
- OFN_SHOWHELP shows the help button.
Going further
- If you want to go
further you have to step into the OWL code. You need to create your
own TOpenSaveDialog, TFileOpenDialog and TFileSaveDialog. For this
derive your class privately from TOpenSaveDialog and in your Init()
call thi Init member of TOpenSaveDialog and then add what ever you want.
See Microsoft's help file on ONPENFILENAME to know all what you
can do. You also need a copy constructor and an operator =,
have a look at opensave.h and at the advmulti.zip
archive for more details.
#include <owl/opensave.h>
class TYourOpenSaveDialog : private TOpenSaveDialog
{
// all you need
protected:
void Init(TResId templateID);
// all you need
};
void TYourOpenSaveDialog::Init(TResId templateId)
{
// call the usual Init
TOpenSaveDialog::Init(templateID);
// all you need
}
- For your open and save dialog you then
need your own TFileSaveDialog and TFileOpenDialog derived from your TOpenSaveDialog.
These classes need a DoExecute() which are similar to the ones of
TFileOpenDialog and TFileSaveDialog. Here to you'll need a copy constructor
and an operator =, and here too have a look at opensave.h and at
the advmulti.zip archive for more details.
class TYourFileOpenDialog : public
TYourOpenSaveDialog
{
// all you need
public:
int DoExecute();
// all you need
};
int TYourFileOpenDialog::DoExecute()
{
// have a look at opensave.h
}
That's all folks, have fun !