tpruett
asked on
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.
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
CDlg.ShowOpen
' 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
Else
directory = Mid(sFile, 1, charPos - 1) & "\"
sFile = Mid(sFile, charPos + 1) & nullChar
Do
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
Map1.Refresh
The open looks like this in my Delphi project right now, which will only open one map at a time:
procedure TfrmMain.AddLayer2Click(Se nder: TObject);
var
DataType: String;
idx: Integer;
sFile: String;
begin
if OpenDialog1.Execute then
begin
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
BMGeoMap1.Refresh;
if Layers(BMGeoMap1.Layers).C ount < 1 then
AddLayer2.Enabled := False;
DeleteLayer1.Enabled := False;
ClearOverlayLayer1.Enabled := False;
Print1.Enabled := False;
SaveasBitmap1.Enabled := False;
RefreshMap1.Enabled := False;
CopyMaptoClipboard1.Enable d := False;
end;
end;
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.
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
CDlg.ShowOpen
' 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
Else
directory = Mid(sFile, 1, charPos - 1) & "\"
sFile = Mid(sFile, charPos + 1) & nullChar
Do
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
Map1.Refresh
The open looks like this in my Delphi project right now, which will only open one map at a time:
procedure TfrmMain.AddLayer2Click(Se
var
DataType: String;
idx: Integer;
sFile: String;
begin
if OpenDialog1.Execute then
begin
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
BMGeoMap1.Refresh;
if Layers(BMGeoMap1.Layers).C
AddLayer2.Enabled := False;
DeleteLayer1.Enabled := False;
ClearOverlayLayer1.Enabled
Print1.Enabled := False;
SaveasBitmap1.Enabled := False;
RefreshMap1.Enabled := False;
CopyMaptoClipboard1.Enable
end;
end;
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.
I think I would use the files property & the multi select option, something like this:
var
maps : TStringList;
ix : integer;
begin
maps := TStringList.create;
if openDialog1.execute then
begin
maps.assign(openDialog1.fi les);
if maps.count > 1 then
for ix := 0 to maps.count-1 do
begin
maps.objects[ix] := TMap.create(...);
//Load map data from file maps[ix]to TMap(maps.objects[ix])
end;
//now all maps can be refrenced from the TStringList
end;
Just a thought.
GL
Mike
var
maps : TStringList;
ix : integer;
begin
maps := TStringList.create;
if openDialog1.execute then
begin
maps.assign(openDialog1.fi
if maps.count > 1 then
for ix := 0 to maps.count-1 do
begin
maps.objects[ix] := TMap.create(...);
//Load map data from file maps[ix]to TMap(maps.objects[ix])
end;
//now all maps can be refrenced from the TStringList
end;
Just a thought.
GL
Mike
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
BMGeoMap1.Refresh;
with:
for Counter := 0 to OpenDialog1.Files.Count -1 do begin
BMGeoMap.AddLayer(OpenDial og1.Files[ Counter],n il);
end;
BMGeoMap.Refresh;
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).
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
BMGeoMap1.Refresh;
with:
for Counter := 0 to OpenDialog1.Files.Count -1 do begin
BMGeoMap.AddLayer(OpenDial
end;
BMGeoMap.Refresh;
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).
ASKER
That works great. Thanks for the help.
Returns a list of the selected file names.
property Files: TStrings;
Description
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.)
GL
Mike