[fpc-pascal] Getting multiple files from GetOpenFileNameA
James Richters
james at productionautomation.net
Fri May 24 02:17:03 CEST 2019
Thank you very much for explaining all this!! I really don’t know what I would do without the helpful people here!
I didn’t know there was something like IncludeTrailingPathDelimiter, wow that sure is useful! I have a LOT of places I need to make sure I stick in the trailing \ and this function will really help clean up a lot of that mess!
I did not realize Open_File.lpstrFile was working like a pointer to Ret… knowing that makes things make more sense! I thought setting Open_File.lpstrFile:=Ret was just a way to initialize it, not that it was actually a pointer to Ret.
Should I just never use Open_File.lpstrFile except to set it to Ret (which I will probably rename to make it more clear that THAT is the real location of all my file name data)
So in other words do
Repeat
String_List.add(StrPas(Ret[Position_of_Filename]));
inc(Position_of_Filename,length(String_List[String_List.Count-1])+1);
Until Ret[Position_of_Filename]=#0;
The reason I made those variables global is because I set the initial ones in the main program loop… no real reason for doing that other than I thought it might help my crash issues if I wasn’t constantly creating and destroying those variables. It does seem like a good idea to initialize every time so I’ll move all that into the function.
I’ve incorporated the recommended changes and still have a few problems.
Here is my updated sample program. I renamed Ret to Open_File_Buffer and I am only using that variable after Open_File.lpstrFile:=Open_File_Buffer; my problems still show up only if I try to set a default file with Open_File_Buffer:=Pchar(Target_File+#0+#0); I’m not sure if I am doing this right. It seems to put it in there but then if I select more than one file, it returns a False, and I also get crashes occasionally as well. Open_File.lpstrInitialDir seems to work better but it only works if I do not try to set a default file name. sometimes want a default file name, sometimes I do not, but I always want to set the initial directory, so I would like to learn the proper way to achieve both of these.
Thank you again for the help and the great suggestions! It’s very much appreciated.
James
{$mode objfpc}{$H+}
// https://docs.microsoft.com/en-us/windows/desktop/api/commdlg/nf-commdlg-getopenfilenamea
// https://docs.microsoft.com/en-us/windows/desktop/api/commdlg/ns-commdlg-tagofna
Uses
sysutils,Windows,Commdlg,Classes,CRT;
Var
File_Num : Word;
Target_File : AnsiString;
File_Stringlist : tstringList;
{=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=}
Procedure Display_File_StringList(Var Display_String_List:tStringList);
Var
SL_Loop : Word;
Begin
If Display_String_List.Count=0 then
Begin
Textcolor(12);
Writeln('0 Files Selected')
End
Else
If Display_String_List.Count=1 then
Begin
TextColor(10);
Writeln(Display_String_List[0]);
Textcolor(14);
Writeln('1 Files Selected');
End
Else
Begin
TextColor(13);
Writeln('Path for all files: ',Display_String_List[0]);
TextColor(10);
For SL_Loop:= 1 to Display_String_List.Count-1 Do
Writeln('File #',SL_Loop,': ',Display_String_List[SL_Loop]);
Textcolor(14);
Writeln(Display_String_List.Count-1,' Files Selected');
End;
End;
{=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=}
Function Get_Files_Into_Stringlist(Var String_List:tStringList):Boolean;
Var
Open_File_Result : Boolean;
Position_of_Filename : Word;
Open_File : TOpenFileNameA;
Open_File_Buffer : array[0..100000] of char;
Begin
String_List.Clear;
fillchar(Open_File, sizeof(Open_File), 0);
fillchar(Open_File_Buffer, sizeof(Open_File_Buffer), 0);
Open_File.lStructSize:=sizeof(Open_File);
Open_File.lpstrFile:=Open_File_Buffer;
Open_File.nMaxFile:=SizeOf(Open_File_Buffer);
Open_File.hwndOwner:=0;
Open_File.Flags := OFN_EXPLORER or OFN_FILEMUSTEXIST or OFN_ALLOWMULTISELECT;
Open_File.lpstrDefExt:='.txt';
Open_File.lpstrTitle:='My Program - Open File';
Open_File.lpstrFilter:='All Files (*.*)'+#0+'*.*'+#0;
If Target_File<>'' then
Begin
// The line below makes GetOpenFileNameA return with False if I select more than one file.
// It also causes the following occasionally:
// An unhandled exception occurred at $00401B5A:
// EAccessViolation: Access violation
// $00401B5A GET_FILES_INTO_STRINGLIST, line 66 of i:/programming/gcode/test/getfilenamea to stringlist.pas
// $00401E60 main, line 99 of i:/programming/gcode/test/getfilenamea to stringlist.pas
Open_File_Buffer:=Pchar(Target_File+#0+#0);
//If the line below is un commmented, it selects multiple files from the correct directory, but only if the line above is commented out
//Open_File.lpstrInitialDir:=Pchar(ExtractFilePath(Paramstr(1))+#0+#0);
End;
Open_File_Result:=GetOpenFileNameA(@Open_File);
If Open_File_Result then
Begin
Position_of_Filename:=0;
Repeat
String_List.add(StrPas(@Open_File_Buffer[Position_of_Filename]));
inc(Position_of_Filename,length(String_List[String_List.Count-1])+1);
Until Open_File_Buffer[Position_of_Filename]=#0;
End;
Writeln(Open_File_Result);
Get_Files_Into_Stringlist:=Open_File_Result;
End;
{=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=}
Procedure Process_File(Some_File: AnsiString);
Begin
TextColor(11);
Writeln('Processing File: ',Some_File);
End;
{=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=}
Begin {Main Program}
File_Stringlist:=TStringlist.Create;
If paramstr(1)<>'' then
Begin
Target_File:=paramstr(1);
Process_File(Target_File);
End
else
Target_File:='';
Repeat
Get_Files_Into_Stringlist(File_Stringlist);
Display_File_StringList(File_Stringlist);
If (File_Stringlist.Count=1) and FileExists(File_Stringlist[0]) Then
Begin
Target_File:=File_Stringlist[0];
Process_File(Target_File);
End
Else
If (File_Stringlist.Count>1) Then
Begin
Target_File:=IncludeTrailingPathDelimiter(File_Stringlist[0]);
for file_num:=1 to File_Stringlist.count-1 do
Process_File(Target_File+File_Stringlist[File_Num]);
End;
Until File_Stringlist.count=0;
File_Stringlist.Free;
end.
{=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20190523/8e8fb19b/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Getfilenamea to Stringlist.pas
Type: application/octet-stream
Size: 4534 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20190523/8e8fb19b/attachment.obj>
More information about the fpc-pascal
mailing list