Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Search result to Tstrings(problem) 1

Status
Not open for further replies.

JanChlpik

Technical User
May 10, 2008
10
CZ
Code:
var Filelist: TStrings;//List of files
var Path : string;//file directory
var searchResult : TSearchRec;//search result

Everything is working for me except getting the file path to file list. I can run it, but this line always causes error.

Code:
Filelist.Add(Path +'\'+searchResult.name);
 
Are you creating the TStrings? e.g.

Code:
FileList := TStrings.Create;

----------
Those who work hard are rewarded with more work and remembered come time to downsize. Those who hardly work are given a paycheck and ignored completely.
 
Filelist is defined as private variable. If I define it in procedure itself it does not work same if I create it. However it works find with memo. Possibly tstrings are conflicting somehow.
Code:
procedure TForm1.Open1(Sender: TObject);
var Path : string;
var searchResult : TSearchRec;
begin
if Radiobutton1.Checked then if OpenDialog1.Execute then
 begin
 Filelist := OpenDialog1.Files;
 Memo1.Clear;
 Memo1.Lines.AddStrings(Filelist);
 Button1.Enabled := true;
 Button2.Enabled := false;
     end;
  if Radiobutton2.Checked then if SelectDirectory('Select a directory','',Path) then
  begin
  Memo1.Clear;
  if FindFirst(Path +'\'+ '*.ddj', faAnyFile-faDirectory, searchResult)= 0 then begin
  Memo1.lines.append(Path +'\'+ searchResult.name);
  While FindNext(searchResult)=0 do
  begin
  Memo1.lines.append(Path +'\'+ searchResult.name);
  end;
  end;
  Button1.Enabled := true;
  Button2.Enabled := false;
  FindClose(searchResult);
  end;
end;
 
Where in your code is the line Glenn asked about?
Code:
Filelist:= TStrings.Create;
Filelist is defined as private variable.
If this is true, then you should have something like this or it will not work:
Code:
procedure TForm1.Create(Sender: TObject);
begin
  Filelist:= TStringList.Create;
end;

procedure TForm1.Destroy(Sender: TObject);
begin
  Filelist.Free;
end;
This will apply to ANY object type variable you place in the private or public section of your form definition, unlike components that you drop on the form from the palette, which are owned by, created by and freed by the parent form. You need to understand this to program in any OOP language.

Also, you code indentions make your code very difficult to read. You will have more success if you look at some other programmers code indention technique. No two programmers use the exact same format, but yours needs improvement, no offense.

Hope this helps and good luck!


Roo
Delphi Rules!
 

also, slightly off topic, shouldn't there be an
Code:
OpenDialog1.Free
at the end of that procedure for good measure?


Steve (Delphi 2007 & XP)
 
No, not if it was dropped on the form from the palette, as I explained.

Roo
Delphi Rules!
 
Thanks. Now I got it working.

Well the problem was the filelist was declared in private. I moved it to var(Where Tform is)

Code:
 private
    { Private declarations }

  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Filelist: TStrings;
  implementation


Sorry but Delphi does not intend automatically, I would use text editor, but I do not know the code, just some basics. I usually search for what I want and keep trying until have the right code.

Next is that this forum has poor options for text formating.(But have great people)
 
Thanks CADTenchy isnt here full article about freeing objects? It works fine as it is little program
Btw isnt if freed automatically by closing form?
 
Delphi IDE does not auto-indent per-say, but if configured to do so, it will follow you indention as you create new lines. If you hit back-space at the beginning of a new line, it will auto un-indent back to the previous code block. It is something will develop a feel for. After a while, you won't have to even think about it, it becomes natural.

Making Filelist global is not going to solve your problem. You still need to put "Filelist:= TStringList.Create;" somewhere before you can reference it.

Typically, I init global objects like this, at the end of the unit where they are declared:
Code:
initialization
begin
  Filelist:= TStringList.Create;
end;

finalization
begin
  Filelist.Free;
end;

end.
Note that the begin/end statements are not required in
initialization/finalization. I do it anyway for clarification.

And THANKS for the *. :)



Roo
Delphi Rules!
 
TOpenDialog.Files is a read-only TStrings property.

If the OP says:
Code:
FileList := TStringList.Create;
FileList := OpenDialog1.Files;
then he has a memory leak. So don't do it.

The reason that:
Code:
FileList.Add( ... );
does not work is because TOpenDialog.Files is read-only --hence, FileList is read-only. You don't own it anyway.

You'll have to use the TStrings.Assign method or the TStrings.AddStrings method:
Code:
// As already noted, this belongs in FormCreate
FileList := TStringList.Create;

// Replace all the strings in FileList
// with the ones returned by the TOpenDialog.
FileList.Assign( OpenDialog1.Files );

// Or

// Add the strings from the TOpenDialog
// to the ones we already have (if any).
FileList.AddStrings( OpenDialog1.Files );

// As already noted, this belongs in FormDestroy
FileList.Free;

Hope this helps.
 
I can't figure out how to edit posts...

I forgot to mention that by using Assign or AddStrings you are copying data from the read-only TOpenDialog.Files property into your own, personal, edit-if-you-like string list.

Enjoy!
 
Thanks for usefull tips.

Indent options are in Tools>options>editor options>source options(I have default options and not sure what to change)

I have finished subdirectory search part today and everything works fine.
 
Please don't interpret this as an argument. BUT...

IF truly a global object variable, there are reasons that it should not be created by the form:
[ul]
[li]Objects (classes) should not control object it does not own, because, runtime errors can occur if the object is referenced and the form has not been created.[/li]
[li]Global variables belong to the unit, not the form within that unit.[/li]
[/ul]
This is the purpose of the initialization/finalization sections (optional) and why I suggested it.

Regarding Jan's usage of his FileList, you are absolutely correct. My "argument" was only of the creation of globals.

Furthermore, TString is rather abstract. TStringList is a more appropriate object. While testing, FileList.Assign() failed. It works if FileList is TStringList.

As tested (with MyFilelist as TStringList owned by the form):
Code:
procedure TTestForm.Open1(Sender: TObject);
var
  //i: integer;
  Path : string;
  searchResult : TSearchRec;
begin
  if Radiobutton1.Checked then
    if OpenDialog1.Execute then begin
      MyFilelist.Assign(OpenDialog1.Files);
      (* alternate method *)
      //for i:= 0 to OpenDialog1.Files.Count -1 do
       //MyFilelist.Add(OpenDialog1.Files[i]);
      Memo1.Clear;
      Memo1.Lines.AddStrings(MyFilelist);
      Button1.Enabled := true;
      Button2.Enabled := false;
    end;

  if Radiobutton2.Checked then
    if SelectDirectory('Select a directory','',Path) then
    begin
      Memo1.Clear;
      if FindFirst(Path +'\'+ '*.ddj', faAnyFile-faDirectory, searchResult)= 0 then
      begin
        Memo1.lines.append(Path +'\'+ searchResult.name);
        While FindNext(searchResult)=0 do begin
          Memo1.lines.append(Path +'\'+ searchResult.name);
        end;
      end;
      Button1.Enabled := true;
      Button2.Enabled := false;
      FindClose(searchResult);
    end;
end;

procedure TTestForm.FormCreate(Sender: TObject);
begin
  MyFilelist:= TStringList.Create
end;

procedure TTestForm.FormDestroy(Sender: TObject);
begin
  MyFilelist.Destroy
end;

I did not test the "Radiobutton2.Checked" option.

Roo
Delphi Rules!
 
Roo, why are you so combative? When did I call you an idiot? Do you even read my posts before complaining? Your "corrected" example is exactly what I advised!

Please take less offense.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top