Delphi-PRAXiS
Seite 2 von 7     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Gleiche Variablen-Namen (https://www.delphipraxis.net/192650-gleiche-variablen-namen.html)

Delbor 8. Mai 2017 19:51

AW: Gleiche Variablen-Namen
 
Hi DeddyH
Zitat:

Wenn der FileSearcher und am besten auch die ihm zugewiesenen EventHandler zum Frame gehören, würde ich die Stringliste auch als privates Feld (und ggf. Public ReadOnly-Property) des Frames deklarieren, dann ist alles schön beisammen und man kommt nicht durcheinander.
Die Sache mit dem Property habe ich mir auch überlegt. Einen Event müsste ich vom Frame aus aber so oder so abfeuern, da die Mainform ja nicht wissen kann, wann der PathfinderFrame die Liste (und damit das Listenproperty) neu bestückt. Das würde dann heissen, dass ich vom Frame aus einen TNotifierEvent abfeuere, den die Mainform empfängt und dabei dann das Listen-Property des Frames ausliest.
So, wie ich Uwe Raabe aber verstanden habe, kann ich den FPathlist-Parameter des Frames problemlos an das private Feld FPathlist der Mainform zuweisen.
Ein vorgehen, dass mich auch in späteren Zeiten beim lesen meines Codes wohl immer etwas irritieren wird. Von daher wäre die Lösung mit dem Property wohl etwas klarer.

Gruss
Delbor

DeddyH 8. Mai 2017 19:56

AW: Gleiche Variablen-Namen
 
Also gibt es auch im Mainform eine entsprechende Liste? Dann ist eine 2. Instanz vermutlich Quatsch, da Du mit einer Public (jetzt aber nicht mehr ReadOnly) Property dasselbe erreichen kannst. Ich tippe hier am Tablet, sonst hätte ich mal schnell etwas Beispielcode geschrieben, so ist mir das aber zu mühsam.

hoika 8. Mai 2017 19:57

AW: Gleiche Variablen-Namen
 
Hallo,
Zitat:

Weil ich dann jeweils von der Mainform aus mit der Framepathlist arbeiten müsste. Da FPathlist ein privates Feld ist, ist dies nicht möglich, ausser ich mache das Feld zu einer Public-Variable.
Klar, ich könnte so aus jeder Unit mit der Framevariable arbeiten. Aber sobald sich in einem Projekt keine PathfinderFrame befindet, muss ich in allen Units, die darauf zugreifen, dies unterbinden - das heisst, ich müsste alle diese Units bearbeiten.
Dann nimm eine Globals-Unit, pack dort Deine Variablen rein (von mir aus auch als class var,
dann bleiben wir beim OOP)
die sowohl Main als auch der Frame benutzt.

Ansonsten ist das hier mit Kanonen auf Spatzen schießen.

Zitat:

dass ich vom Frame aus einen TNotifierEvent abfeuere
Und schon sind wir beim Event-Listener

DeddyH 8. Mai 2017 20:15

AW: Gleiche Variablen-Namen
 
Das ist aber doch keine Raketentechnik.
Delphi-Quellcode:
type
  TDingensFrame = class(TFrame)
  private
    FPathList: TStrings;
    ...
  public
    property PathList: TStrings read FPathList write FPathList;

...

procedure TDingensFrame.SomeEvent(Param: string);
begin
  if Assigned(FPathList) then
    FPathList.Add(Param);
end;
Jetzt kann das Formular der Frame-Property eine TStrings-Instanz zuweisen, und der nutzt dann diese. Damit gibt es nur eine Instanz, aber beide haben Zugriff darauf.

Uwe Raabe 8. Mai 2017 21:01

AW: Gleiche Variablen-Namen
 
Zitat:

Zitat von Delbor (Beitrag 1370617)
So, wie ich Uwe Raabe aber verstanden habe, kann ich den FPathlist-Parameter des Frames problemlos an das private Feld FPathlist der Mainform zuweisen.

Das habe ich so nicht gesagt! Es muss dann schon geklärt werden, wer da dann was frei gibt.

Besser wäre es, du würdest immer nur die Inhalte von einer StringList in die andere kopieren. Dann hast du auch keine Probleme. Möglicherweise musst du dazu aber noch an deiner Programmstruktur basteln.

Delbor 8. Mai 2017 22:09

AW: Gleiche Variablen-Namen
 
Hi DeddyH

Zitat:

Jetzt kann das Formular der Frame-Property eine TStrings-Instanz zuweisen, und der nutzt dann diese. Damit gibt es nur eine Instanz, aber beide haben Zugriff darauf.
Da gibts jetzt aber ein gewaltiges Missverständnis: Die Mainform darf/muss dem Pathfinderframe keinen String zuweisen. Die Aufgabe des Frames ist es ja gerade, die von seiner Komponente TFilesearcher gefundenen Pfade in einer Liste zu sammeln und diese nach aussen zu senden/von aussen auszulesen zu lassen. dieser Liste einen String von der Mainform, aus zuzuweisen.

Diese Procedure wird ausgeführt, wenn der Filesearcher einen Pfad gefunden hat:
Delphi-Quellcode:
procedure TSearchThread.DoOnMatchFound;
begin
  if Assigned(FOnMatchFound) then
    begin
      Lock;
      try
        FOnMatchFound(self, FPath, FSearchRec);
      finally
        UnLock;
      end;
    end;
end;
Das da gefeuerte Event wird im PathfinderFrame abgefangen:
Delphi-Quellcode:
procedure TPathFinderFrame.FileSearcher1MatchFound(Sender: TObject;
  const Path: string; const FileInfo: TSearchRec);
  var Complettpath, J: String;
begin
  if Assigned(FCurrentNode) then
  begin
    Complettpath := IncludeTrailingPathDelimiter(Path) +  FileInfo.Name;
    AddNewNode(FCurrentNode, FileInfo.Name, Complettpath,TSearchRecAnalyzer.IsDirectory(FileInfo));
  end;
end;
Und AddNewNode fügt dem Treeview einen neuen Knoten hinzu sowie FPathlist einen neuen String:
Delphi-Quellcode:
procedure TPathFinderFrame.AddNewNode(ParentNode: TTreeNode; const aCaption,
  aRealName: string; CanGetChildren: Boolean);
var
  Node: TTreeNode;
  NameRec: PNameRec;
begin
  Node := TVPathExplorer.Items.AddChild(ParentNode, aCaption);
  if CanGetChildren then
    begin
      Node.ImageIndex := 1;
      Node.SelectedIndex := 1;
      (* Dummy-Knoten anlegen *)
      TVPathExplorer.Items.AddChild(Node, 'dummy');
    end
  else
    begin
      Node.ImageIndex := 2;
      Node.SelectedIndex := 2;
      FPathlist.Add(aRealName); // <<===
    end;
  New(NameRec);
  NameRec^.RealName := aRealName;
  Node.Data := NameRec;
end;
In FPathlist stehen abschliessend alle in einem bestimmten Ordner gefundenen Dateien. Ausgelöst wird dder Event, wenn der Filesearcher seine Suche beendet hat:
Delphi-Quellcode:
procedure TPathFinderFrame.FileSearcher1ExecuteComplete(Sender: TObject);
  var LPathlist: TStringlist; LOrdner: String;
begin
  if Assigned(FCurrentNode) then
    FCurrentNode.Expand(false);
  if Assigned(FOnPathListEvent) then
    FOnPathListEvent(Sender, FOrdner, FPathlist);
end;
Der Eventtyp:
Delphi-Quellcode:
TPathListEvent = procedure(Sender:TObject; const FOrdner: String; const FPathlist: TStringList) of Object;
Wenn ich das richtig verstanden habe, müsste ich diesen Event jedesmal, wenn ein Pfad gefunden wird, feuern:
Delphi-Quellcode:
procedure TDingensFrame.SomeEvent(Param: string);
begin
  if Assigned(FPathList) then
    FPathList.Add(Param);
end;
Dieser Beispielcode erinnert mich allerdings sehr an diese Diskussion.
Damals hatte ich MapRules für eine normale Stringliste gehalten; reichlich spät kam ich dahinter, dass MapRules ene TCollection-Object ist und Add ein TCollectionitem-Objekt zurückliefert.
Im Gegensatz dazu ist nun FPathlist wirklich ein TStringlist-Objekt und Add die Methode, die der Liste einen Eintrag hinzufügt. Die Procedur müsste also so ausehen:
Delphi-Quellcode:
procedure TDingensFrame.SomeEvent(Pfad: string);
begin
  if Assigned(FPfad) then
    FPfad(Pfad);
end;
Und in TDingensMainForm:
procedure TDingensMainForm.DoSomeEvent(Pfad: string);
begin
Self.FPathlist.Add(Pfad);
end;
Das Problem, das ich da sehe, ist: woher weiss ich nun, wann der TDingensframe keine Pfade mehr sendet? Einfach nur zuzuwarten, ob innerhab einer gewissen Zeit noch was kommt, scheint mir sehr zweifelhaft.

Gruss
Delbor

Delbor 8. Mai 2017 22:54

AW: Gleiche Variablen-Namen
 
Hi Uwe Raabe
Zitat:

Das habe ich so nicht gesagt! Es muss dann schon geklärt werden, wer da dann was frei gibt.
Hmm... Und wie wird, bzw. kann dies geklärt werden? Indem der Compiler darüber informiert wird, welche der Variablen zu was gehört?
Genau das hat aber meine Frage veranlasst.

Zur Erinnerung: Meine bisherige Prozedur gibt die Liste direkt aus, ohne sie in einem Feld zwischenzuspeichern:
Delphi-Quellcode:
procedure TSQLiteTestMain.DoPathListEvent(Sender: TObject;
  const FOrdner: String; const FPathlist: TStringList);
begin
  Self.EdiFolder.Clear;
  Self.EdiFolder.Text := FOrdner;
  Self.LBxPathlist.Clear;
  Self.LBxPathlist.Items.AddStrings(FPathlist);
end;
Stattdessen soll nun der übergebene KonstantenParameter FPathlist an das private Feld TSQLiteTestMain.FPathlist übergeben werden. Das würde nach meinen bisherigen Vorstellungen etwa so ausehen:
Delphi-Quellcode:
procedure TSQLiteTestMain.DoPathListEvent(Sender: TObject;
  const FOrdner: String; const FPathlist: TStringList);
begin
  FPathlist.AddStrings(FPathlist);
end;
Und genau das dürfte unmöglich sein. Es sei denn...:
Delphi-Quellcode:
procedure TSQLiteTestMain.DoPathListEvent(Sender: TObject;
  const FOrdner: String; const FPathlist: TStringList);
begin
  Self.FPathlist.AddStrings(PathFinderFrame.FPathlist);
end;
Allerdings müsste so auch der Eventtyp angepasst werden: Statt
Delphi-Quellcode:
TPathListEvent = procedure(Sender:TObject; const FOrdner: String; const FPathlist: TStringList) of Object;
müsste dies heissen:
Delphi-Quellcode:
TPathListEvent = procedure(Sender:TObject; const FOrdner: String; const PathFinderFrame.FPathlist: TStringList) of Object;
Allerdings - ob sowas überhaupt möglich ist, ist mir nicht bekannt; ich denke eher nicht.
Wobei dann tatsächlich mein erster ansatz übrig bliebe:
Delphi-Quellcode:
procedure TPathFinderFrame.FileSearcher1ExecuteComplete(Sender: TObject);
  var LPathlist: TStringlist; LOrdner: String;
begin
  if Assigned(FCurrentNode) then
    FCurrentNode.Expand(false);
  if Assigned(FOnPathListEvent) then
  begin
    LPathList := TStringlist.Create;
    try
    LPathList.AddStrings(FPathlist);
    LOrdner := FOrdner;
    FOnPathListEvent(Sender, FOrdner, LPathlist);
    finally
      LPathList.Free;
    end;
  end;
end;
und in der Mainform:
Delphi-Quellcode:
procedure TSQLiteTestMain.DoPathListEvent(Sender: TObject;
  const FOrdner: String; const LPathlist: TStringList);
begin
  FPathlist.AddStrings(LPathlist);
end;
Gruss
Delbor

Uwe Raabe 8. Mai 2017 23:57

AW: Gleiche Variablen-Namen
 
Und was spricht gegen dies?
Delphi-Quellcode:
procedure TSQLiteTestMain.DoPathListEvent(Sender: TObject;
  const FOrdner: String; const FPathlist: TStringList);
begin
  Self.FPathlist.Assign(FPathlist);
end;

DeddyH 9. Mai 2017 06:28

AW: Gleiche Variablen-Namen
 
Jetzt muss ich aber mal nachhaken: wo genau wird diese Liste benötigt/angezeigt?

Ghostwalker 9. Mai 2017 07:00

AW: Gleiche Variablen-Namen
 
So wie ich das verstehe, wird die Liste im Mainform angzeigt.

Ich würde das so lösen (Code frei getippt):
Delphi-Quellcode:
   TOnComplete = TNotifyEvent;

   TPathfinderframe = Class...
   private
      fpathlist : TStringlist;
      fonComplete : TOnComplete;
     :
   published
     Property Pathlist : TStringlist read fpathlist write fpathlist;
     Property onComplete: TOnComplete read fonComplete write foncomplete;
     :
   end;
Bei der Suche selbst, innerhalb des Frames, wird die Stringliste erweitert. Beim Complete wird einfach das Event gefeuert und so dem Hauptformular bescheid gegeben, das die Liste neu ist. Anhand der Liste kann dann der Treeview entsprechend angezeigt werden.

Eine Instanz der Stringliste und eine Übergabe ist nicht notwendig.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:24 Uhr.
Seite 2 von 7     12 34     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz