• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1065
  • Last Modified:

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.
  • 2
  • 2
  • 2
1 Solution
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.
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.
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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.

Featured Post

Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

  • 2
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now