OpenDialog Files property

Map1 is a map control that displays vector map files. Map1.SpatialDataName is a Widestring that is a path to a particular map file, in that it is the map that is currently being displayed in Map1.

From the OpenDialog component, how can I get a string of "Files..." that were multiselected into the SpatialDataName string so that I can open and view several layers that "overlay".

I have tried several examples from the help, though with little success. Most likely the same solution that performs this functionality will allow me add and remove individual layers from the control.

I would greatly appreciate any feedback.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

is this what you are looking for?:

Returns a list of the selected file names.

property Files: TStrings;


FileName is a TStrings instance that contains each selected file name with its full directory path. (To let users select multiple file names, set the ofAllowMultiSelect flag in Options.)

Assuming the Map1 is a member of the TMap class, and that you want to create one of these map controls for each of the files that get selected, you could try this:

Set the ofAllowMultiSelect flag in the OpenDialog in the designer.

Your code could look something like this:

if OpenDialog1.Execute then
  for Counter := 0 to OpenDialog1.Files.Count -1 do
  with TMap.Create(Self) do
    SpatialDataName := OpenDialog1.Files[Count];

You'll then get one TMap object for each file.

If you want to put all of the files into one TMap, then this might not be possible with a widestring.

You could try:
Map1.SpatialDataName := OpenDialog1.Files.CommaText;

This will put a comma in between each of the file names for you and put them all in one string.

Failing that, you're going to need to provide more information on this mapping component.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
tpruettAuthor Commented:
The comma text solution doesn't seem to work. I have an example of the same process in VB:

Private Sub mnuMap_ConnectLayer_Click()
  Dim DataType As String
  Dim directory As String
  Dim filenames As String
  Dim nullChar As String
  Dim charPos As Long
  Dim idx As Integer
  Dim sFile As String
  Dim fld As Field
  nullChar = Chr(0)
  On Error GoTo OpenFileError:
    ' Open dialog box to get the primary layer file name
    CDlg.filename = ""
    ' Build the open filter
    CDlg.Filter = "AutoCAD (DWG DXF)|*.dwg;*.dxf|MapInfo (TAB)|*.tab|ESRI Shape (SHP)|*.shp|AtlasGIS (AGF)|*.agf||"
    CDlg.FilterIndex = 3 ' Choose ArcView Shape files as the default filter
    CDlg.DialogTitle = "Connect a Data Layer to the Map"
    CDlg.Flags = cdlOFNHideReadOnly Or cdlOFNFileMustExist Or cdlOFNAllowMultiselect Or cdlOFNExplorer Or cdlOFNLongNames
    CDlg.CancelError = 1 ' Exit subroutine if cancel is hit
    ' The filter index determines what type of map data is displayed
    idx = CDlg.FilterIndex
      Select Case idx <> 0
        Case idx = 1
          DataType = "AutoCAD"
        Case idx = 2
          DataType = "MapInfo"
        Case idx = 3
          DataType = "ArcView"
        Case idx = 4
          DataType = "AtlasGIS"
      End Select
    sFile = CDlg.filename
    ' This parsing of the CommonDialog.filename is based on the VB 5
    ' Open file common dialog, with the preceeding Flag values set
    charPos = InStr(sFile, nullChar)
    If charPos = 0 Then
        filenames = sFile
        directory = Mid(sFile, 1, charPos - 1) & "\"
        sFile = Mid(sFile, charPos + 1) & nullChar
            charPos = InStr(sFile, nullChar)
            filenames = filenames & Chr(34) & directory & Mid(sFile, 1, charPos - 1) & Chr(34) & Chr(32)
            sFile = Mid(sFile, charPos + 1) /* What you are looking for and, start, length */
        Loop Until Len(sFile) = 0
    End If
    ' Set the map data type and file names
    Map1.SpatialDataType = DataType
    Map1.SpatialDataName = filenames
    Map1.KeepAspect = True
    Map1.BackColor = RGB(255, 255, 255)
    Map1.Visible = True

The open looks like this in my Delphi project right now, which will only open one map at a time:

procedure TfrmMain.AddLayer2Click(Sender: TObject);
  DataType: String;
  idx: Integer;
  sFile: String;
  if OpenDialog1.Execute then
    BMGeoMap1.SpatialDataName := OpenDialog1.Filename;
    if OpenDialog1.FilterIndex = 1 then
      BMGeoMap1.SpatialDataType := 'MapInfo';
    if OpenDialog1.FilterIndex = 2 then
      BMGeoMap1.SpatialDataType := 'AutoCAD';
    if OpenDialog1.FilterIndex = 3 then
      BMGeoMap1.SpatialDataType := 'AutoCAD';
    if OpenDialog1.FilterIndex = 4 then
      BMGeoMap1.SpatialDataType := 'ArcView';
    if OpenDialog1.FilterIndex = 5 then
      BMGeoMap1.SpatialDataType := 'AtlasGIS';

      OpenDialog1.FileName := '';
      OpenDialog1.FilterIndex := 0;    {Choose All Layer Types as the default filter}
      OpenDialog1.Title := 'Add a Data Layer to the Map';
      sFile := OpenDialog1.FileName;
    if BMGeoMap1.AddLayer(sFile, nil) then
    if Layers(BMGeoMap1.Layers).Count < 1 then
      AddLayer2.Enabled := False;
      DeleteLayer1.Enabled := False;
      ClearOverlayLayer1.Enabled := False;
      Print1.Enabled := False;
      SaveasBitmap1.Enabled := False;
      RefreshMap1.Enabled := False;
      CopyMaptoClipboard1.Enabled := False;

I will keep trying. If you or anyone else has any more feedback, I would be happy to receive this. Map1 is an OCX.

The MDI idea is interesting, though Map1 is drawn on a form. I am not sure how to refer to it without dropping it on a form, otherwise the compiler tells me that "Map1 already exists", and if I remove it an just refer to the _TLB.pas file, then it will not regognize my reference to it (Map1) in the procedure.

Thanks again.
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

I think I would use the files property & the multi select option, something like this:

 maps : TStringList;
 ix : integer;
 maps := TStringList.create;
 if openDialog1.execute then
  if maps.count > 1 then
   for ix := 0 to maps.count-1 do
    maps.objects[ix] := TMap.create(...);
//Load map data from file maps[ix]to TMap(maps.objects[ix])
//now all maps can be refrenced from the TStringList

Just a thought.
A couple of points:

These lines belong before the Opendialog1.Execute, not after:

      OpenDialog1.FileName := '';
      OpenDialog1.FilterIndex := 0;    {Choose All Layer Types as the default filter}
      OpenDialog1.Title := 'Add a Data Layer to the Map';

Secondly, if you replace this:
      sFile := OpenDialog1.FileName;
    if BMGeoMap1.AddLayer(sFile, nil) then


  for Counter := 0 to OpenDialog1.Files.Count -1 do begin

Then you should get the results you are looking for.  Note that there will always be at least one filename, so long as you set you OpenDialog options correctly, and make sure that the value returned by Execute is true (which you are already doing).
tpruettAuthor Commented:
That works great. Thanks for the help.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.