Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Dateien einlesen (https://www.delphipraxis.net/167486-dateien-einlesen.html)

schöni 1. Apr 2012 19:23

Dateien einlesen
 
Hallo,

ich habe folgenden Quelltext erstellt:

Delphi-Quellcode:
var StillFiles: Integer;
begin
  Image.Proportional := true;
  Image.Stretch := true;
  FFileList := TStringList.Create;
  while (FindFirst(FFilename,faAnyFile,FSearch)=0) and (StillFiles=0) do
  begin
    FFileList.Add(FSearch.Name);
    StillFiles := FindNext(FSearch);
  end;
  FindClose(FSearch);
  ListBox1.Items.Assign(FFileList); //Die soll zum Testen sein, ob die Dateien gelesen wurden
end;
Ich will damit eine Diashow erzeugen, indem ich die Dateinamen (Bilder) meines Verzeichnisses in eine Stringliste einlese um später per Timerereignis einen Stringlistenindex zu inkrementieren und so die einzelnen Dateien in eine TImage Komponente lade mit Image.Picture.LoadFromFile(FFileList.Strings[Index].

Leider wird mit dem obigen Quelltext keine Datei eingelesen und so bleibt die Listbox auch leer. Warum? Was mache ich falsch? Ich habe mir auch diesen Quelltext aus http://forum.delphi-treff.de/showthr...-einer-Diashow

Delphi-Quellcode:
procedure TFHaupt.SBDiaClick(Sender: TObject);
var
  sr : TSearchRec;
  start : Cardinal;
begin
  extension := extractfileext(OpenPictureDialog1.FileName);
  if FindFirst(extractFilepath(OpenPictureDialog1.FileName)+'*'+extension,
     faAnyFile, sr) = 0 then
  begin
    repeat
      image1.Picture.LoadFromFile(sr.Name);
      image1.Update;
      Label1.Caption:=sr.Name;
      start := GetTickCount;
      repeat
        application.ProcessMessages;
      until GetTickCount > (start + warten);
      repeat
        application.ProcessMessages;
        if Bruch then break;
      until weiter;
      if Bruch then break;
    until FindNext(sr) <> 0;
    FindClose(sr);
  end;
end;
Hieraus habe ich mir meinen Quelltext darüber gebaut.

Weil es so leider nicht funktioniert:

Delphi-Quellcode:
procedure TBildbetrachter.SpTBXItem2Click(Sender: TObject);
var
  space: String;
begin
  //
  space := ' ';
  if FFilename='' then
  begin
    if PicsDialog.Execute then
    begin
      FFilename := PicsDialog.FileName;
      Image.Picture.LoadFromFile(FFilename);
      Bildbetrachter.Caption := Bildbetrachter.Caption + space + FFileName;
      Image.Update;
    end;
    if FindFirst(FFilename,faAnyFile,FSearch) = 0 then
    Timer.Enabled := true;
  end;
end;

procedure TBildbetrachter.TimerTimer(Sender: TObject);
var space: String;
begin
  space := ' ';
  if FindNext(FSearch) = 0 then
  begin
    Bildbetrachter.Caption := Bildbetrachter.Caption + space + FSearch.Name;
    Image.Picture.LoadFromFile(FSearch.Name);
    Image.Update;
  end;
  //Als ich vorher ShowMessage('Timer ausgelöst") testweise hier stehen hatte, wurde der Timer ausgelöst.
end;
Nach dem ButtonClick sehe ich nur das erste Bild. Ich habe das Timer Intervall auf 10 Sekunden eingestellt.

Nachdem das erste Bild angezeigt wurde, kann ich den Dialog zur Dateiauswahl nicht mehr aufrufen.



Was ist hier falsch. Ich werde ein weiteres Thema eröffnen "Mediaplayer verstehen. Denn diesen wollte ich zuvor einsetzen aber der hat nur ein OnClick Ereignis, das wohl ausschliesslich zur Auswertung in Frage kommt. Die Fragen hierzu folgen dort.
.
.
.
.

DeddyH 1. Apr 2012 19:28

AW: Dateien einlesen
 
Obwohl ich ja sonst eher nicht so der "Komponentenschubser" bin, möchte ich hier sagen: spar Dir den Aufwand und schau Dir diese Komponente einmal an: http://www.delphiarea.com/products/d...nents/picshow/

schöni 1. Apr 2012 19:42

AW: Dateien einlesen
 
Danke @DeddyH, werde ich machen. Sieht vielversprechend aus.

himitsu 1. Apr 2012 21:44

AW: Dateien einlesen
 
Zitat:

Delphi-Quellcode:
var StillFiles: Integer;
begin
  Image.Proportional := true;
  Image.Stretch := true;
  FFileList := TStringList.Create;
  while (FindFirst(FFilename,faAnyFile,FSearch)=0) and (StillFiles=0) do
  begin
    FFileList.Add(FSearch.Name);
    StillFiles := FindNext(FSearch);
  end;

Warnt dich denn nicht der Compiler vor dem nicht initialisierten StillFiles?

Ich könnte fast wetten diese Variable ist nicht 0 und deswegen wird auch nicht in die Schleife gesprungen.
Du kannst aber froh sein, denn wäre dort reingesprungen wurden, dann hättest du dir vermutlich eine Endlosschleife gebastelt.

Denn wer kommt schon auf die Idee FindFirst ebenfalls mit in die Schleife aufzunehmen?
Da wird der Suchvorgann immer wieder von neu vorne gestartet. :stupid:

PS: In der DP und vorallem in der CL gibt es schon mehrere Codes ala "find all files".
Hier im Forum suchenFindAllFiles
FindAllFilesFindAllFiles
...

Ansonsten steht in deiner Delphi-OH sogar ein Beispielcode für FindFiles.
Delphi-Referenz durchsuchenFindFirst (auch zu Erreichen über die geheime F1-Funktion)

Tipp für neuere Delphis: Delphi-Referenz durchsuchenTDirectory.GetFiles

DeddyH 2. Apr 2012 07:02

AW: Dateien einlesen
 
Oder mein TFileSearcher, aber das ist in diesem Fall wohl mit Kanonen auf Spatzen geschossen.

ConnorMcLeod 2. Apr 2012 17:52

AW: Dateien einlesen
 
Geht das nicht üblicherweise mit
Delphi-Quellcode:
FindFirst...
while FindNext do
begin
end;

DeddyH 2. Apr 2012 18:10

AW: Dateien einlesen
 
Oder mit
Delphi-Quellcode:
if FindFirst... then
  repeat
  until FindNext... <> 0;

ConnorMcLeod 2. Apr 2012 18:20

AW: Dateien einlesen
 
Genau, aber
Delphi-Quellcode:
while FindFirst...
finde ich ziemlich exotisch ;-)

himitsu 2. Apr 2012 18:23

AW: Dateien einlesen
 
Nicht nur ODER oder EXOTISCH,

denn sonst würde man den ersten Fund überspringen.
Zitat:

Delphi-Quellcode:
FindFirst...
while FindNext do
begin
  // verarbeiten
end;

Delphi-Quellcode:
if FindFirst... then
begin
  // verarbeiten ;)
  while FindNext... do
  begin
    // verarbeiten
  end;
  FindClose...;
end;
Wobei am Ende natürlich Beides ginge.
Delphi-Quellcode:
if FindFirst... then
begin
  repeat
    // verarbeiten
  until FindNext... <> 0;
  FindClose...;
end;

schöni 4. Apr 2012 10:20

AW: Dateien einlesen
 
Danke @Himitsu, @ConnorMcLeod, DeddyH....

@Himitsu:

Danke für den Hinweis, werde mir meinen Quelltext noch mal bezüglich der Variablen "stillfiles" ansehen.

Aber:

Ich wollte allerdings eigentlich eine selber erstellte Lösung schaffen. :wink: Der Filesearcher von DeddyH sieht gut aus, aber damit nutze ich wieder eine Lösung, die jemand anderes geschrieben hat. Wenn ich aber programmieren will, muss ich auch fähig sein, selber eine Lösung zu erarbeiten. Außerdem muss ich mich in eine von anderen Programmierern erstellte Lösung auch hineinarbeiten, bevor ich sie nutzen kann.

Werd mir deshalb die anderen Lösungen für findallfiles auch anschauen. Werde auch den FileSearcher-Quelltext von DeddyH studieren und bei Verständnisproblemen hier fragen. Die pichshow Komponente(n) schaue ich mir auch an.

Und schließlich habe ich genug Ehrgeiz, aus all diesen Anregungen meine persönliche Lösung zu schaffen. :wink:

.

schöni 4. Apr 2012 10:53

AW: Dateien einlesen
 
Aaaaaaber eine Frage habe ich schon jetzt an DeddyH:

Die Picshow Demos nutzen ja die zu installierende PicShow-Komponente. Nun habe ich jedoch nur D7 Personal und die kostenlose Turbo Delphi Version. In letzterer kann ich keine Fremdkomponenten installieren. Erstere enthält keine Datenbank Komponenten. Ich muss also die Komponenten komplett per Hand instantiieren. Deshalb die Frage:

Was ist Picture.Data in Splash.dfm im Ordner DBDemo?

Was ist PgPicture.Data in Main.dfm im Ordner Demo?

Im Ordner Demo gibt es den Unternordner Photos. Ich vermute Picture.Data bzw. PgPicture.Data enthält eines der Fotos aus diesem Ordner? Richtig?

Allerdings habe ich die Funktion noch nicht gefunden, die mir das Foto dorthin lädt, wenn ich die PicShow Komponente aud der .dfm Datei entferne, um die Demos wegen der vorausgesetzten DB Komponenten mit Turbo Delphi zu übersetzen.


.

mkinzler 4. Apr 2012 11:14

AW: Dateien einlesen
 
Die Klasse TGraphic kennt die Methoden LoadFromFile()/LoadFromStream()

schöni 4. Apr 2012 18:46

AW: Dateien einlesen
 
Asche auf mein Haupt. Sorry, ich hatte den Pfadnamen falsch.

FindFirst(FFileName)... und nicht, wie es richtig gewesen wäre:

Delphi-Quellcode:
FindFirst(
   ExtractFilePath(FFileName)+'*'+ExtractFileExt(FFileName),...
Die FileSearch-Komponente von DeddyH schau ich mir dennoch an. Und jetzt, wo meine eigene (wenn auch) Quick and Dirty Lösung für die Diashow läuft, auch die PicShow Komponente und die anderen Tipps.

DeddyH 4. Apr 2012 18:55

AW: Dateien einlesen
 
Zitat:

Zitat von schöni (Beitrag 1160249)
Die FileSearch-Komponente von DeddyH schau ich mir dennoch an.

Ich möchte Dir nur kurz warnen: als Anschauungsobjekt ist die eigentlich eher schlecht geeignet, da sehr umfangreich. Wenn Du es trotzdem versuchen möchtest, kannst Du Dich mit Fragen aber gerne an mich wenden.

schöni 4. Apr 2012 19:43

AW: Dateien einlesen
 
Zitat:

Zitat von mkinzler (Beitrag 1160123)
Die Klasse TGraphic kennt die Methoden LoadFromFile()/LoadFromStream()

Das weiß ich. Was ich aber nicht weiß, ist, wie wird in der Eigenschaft Picture.Data in der .dfm Datei das Bild abgelegt?

Die reinen Bilddaten ohne Headerinfo oder die komplette Datei?

@DeddyH hat, wie hier auch zu lesen ist, eine PicShow-Komponente feilgeboten. In den mitgelieferten Demos gibt es in den Formulardateien die Felder

Picture.Data und

PgPicture.Data

Ich wollte halt das Original auch dann wiederherstellen, wenn DeddyH nicht noch mal antwortet. Dazu muss ich entweder wissen, welches der mitgelieferten Fotos er als Hintergrund im Objektinspektor gesetzt hat oder ich muss die Daten als Binärdatei speichern und an (Pg)Picture.Data zuweisen, da ich in Turbo Delphi keine Fremdkompos installieren kann. In D7 Personal fehlen die leider auch vorausgesetzten DB-Komponenten. Werde das deshalb selber ausprobieren. Wenn in Data die reinen Bilddaten stehen, sollte ich diese in binform in ein Array laden können und im Quellcode an Data zuweisen können.

Zitat:

Zitat von DeddyH
Ich möchte Dir nur kurz warnen: als Anschauungsobjekt ist die eigentlich eher schlecht geeignet, da sehr umfangreich. Wenn Du es trotzdem versuchen möchtest, kannst Du Dich mit Fragen aber gerne an mich wenden.

Danke für das Angebot. Ich werde bei Bedarf darauf zurück kommen. Ich versuche es trotz der Warnung.

DeddyH 5. Apr 2012 07:11

AW: Dateien einlesen
 
Pack mal spaßhalber ein TImage auf ein Formular, lade dort zur Entwurfszeit eine Grafik hinein und schau Dir die DFM als Text an. Dann wirst Du sehen, dass dort die kodierten Pixeldaten unter Data stehen. Das muss also keine Grafik aus dem Unterverzeichnis, sondern kann auch eine ganz andere sein. Für Dich spielt das aber keine Rolle, wenn Du die Komponente zur Laufzeit erzeugst, da Du "Data" eh nicht angreifst, sondern per LoadFromFile/LoadFromStream eine Grafik hineinladen kannst (Picture- bzw. BgPicture-Eigenschaft). Um die Komponente unter D7 Personal zu installieren, müsste es meiner Ansicht nach genügen, in der Hauptunit die DB-Variante samt aller Verweise auf DB-Packages komplett auszukommentieren. Die DB-Packages sind die, die der Compiler als fehlend monieren wird. Zu guter Letzt wirft man aus der Registrierungsunit noch die DB-Komponente raus, und es sollte gehen.

schöni 5. Apr 2012 11:35

AW: Dateien einlesen
 
Zitat:

Zitat von DeddyH (Beitrag 1160297)
Pack mal spaßhalber ein TImage auf ein Formular, lade dort zur Entwurfszeit eine Grafik hinein und schau Dir die DFM als Text an. Dann wirst Du sehen, dass dort die kodierten Pixeldaten unter Data stehen. Das muss also keine Grafik aus dem Unterverzeichnis, sondern kann auch eine ganz andere sein. Für Dich spielt das aber keine Rolle, wenn Du die Komponente zur Laufzeit erzeugst, da Du "Data" eh nicht angreifst, sondern per LoadFromFile/LoadFromStream eine Grafik hineinladen kannst (Picture- bzw. BgPicture-Eigenschaft). Um die Komponente unter D7 Personal zu installieren, müsste es meiner Ansicht nach genügen, in der Hauptunit die DB-Variante samt aller Verweise auf DB-Packages komplett auszukommentieren. Die DB-Packages sind die, die der Compiler als fehlend monieren wird. Zu guter Letzt wirft man aus der Registrierungsunit noch die DB-Komponente raus, und es sollte gehen.

Ok, danke, das funktioniert. Ich konnte die Komponente ohne die Datenbankteile (auskommentiert) installieren und das Demo starten.

Die Überblendeffekte funktionieren mit den kleineren mitgelieferten Bildern einwandfrei. Ich habe jedoch eigene Bilder von meiner DigiCam, die ein ganzes Stück größer sind. Da klappt das Überblenden nicht mehr so schön flüssig. Habe eienen Athlon mit 1GHz. 512 MByte RAM. Habe noch 1 Laptop mit 0,99 GByte RAM, Prozessor 1,73GHz Pentium.

Kann das optimiert werden? Wenn ja, wo?

DeddyH 5. Apr 2012 11:37

AW: Dateien einlesen
 
Vermutlich hast Du die originalen Riesenbilder der Webcam benutzt und lediglich die Anzeige gestrecht. Das ist eher kontraproduktiv, besser wäre es, die Bilder zu verkleinern, abzuspeichern und diese Dateien dann zu verwenden.

schöni 6. Apr 2012 10:05

AW: Dateien einlesen
 
Zitat:

Zitat von DeddyH (Beitrag 1160348)
Vermutlich hast Du die originalen Riesenbilder der Webcam benutzt und lediglich die Anzeige gestrecht. Das ist eher kontraproduktiv, besser wäre es, die Bilder zu verkleinern, abzuspeichern und diese Dateien dann zu verwenden.

Nein, ich hatte Bilder von meiner Digitalkamera verwendet. Aber wenn ich die verkleinere, funktioniert das Überblenden wie gewünscht.

Interessanterweise funktioniert das Programm mit D7 Personal übersetzt wunderbar, aber nicht so mit Turbo Delphi übersetzt, wo ich die Komponente nicht installieren kann. Dort erhalte ich eine

EAccessViolation in Modul PSDemo.exe bei Adresse 000A62A9, Zugriffsverletzung bei Adresse 004A62A9 in Modul PSDemo.exe. Lesen von Adresse 0000260.

Das kann eigentlich nur mit dem Problem der nicht installierten Komponente zusammen hängen, sonst würde es mit D7 Personal und dort korrekt installierter Komponente ja auch nicht funktionieren.

PsPicture.Data enthält also die Pixeldaten des Hintergrundes. Die PicShow Kompo hat einen Hintergrund, der jedoch im Objektinsprktor festgelegt wurde und wahrscheinlich in der Ressourcendatei versteckt ist. Enthält Data die reinen Bilddaten oder die komplette Datei einschließlich Headerinformation. Im letzteren Fall könnte ich probeweise die Hexstings in Binärziffern umwandeln und als .jpg Datei abspeichern und wegen der in Turbo Delphi nötigen Instantiierung zur Laufzeit mit LoadFromFile laden. Wenn Data aner nur die reine Pixelinformation umfasst???


Wegen der Problematik mit Turbo Delphi habe ich mir auch DfmToPas beschafft. Leider ist die Oberfläche dort für mich nicht verwendbar. Diese verlangt ein leeres Verzeichnis für die Zielunit aber erlaubt nicht, dieses Verzeichnis vor der Konvertierung festzulegen. Und wie benennt dieses Programm dann die neue Pascal Datei? Heißt also Sourcen studieren und auch verstehen oder doch eigene Lösung zu finden. Die sollte so aussehen, das ich eine Include Datei erhalte, die dann im Interface Teil meines Formular Quelltextes so eigefügt ist, das sich die Unit danach so verhält, als wäre sie mit der Original .dfm Datei übersetzt worden.

Doch dann muss ich wissen, welchen Quelltext diese Software dann für PgPicture.Data = {...} erzeugen müsste.

.

mkinzler 6. Apr 2012 11:43

AW: Dateien einlesen
 
Der Hintergrund wird in BgPicture.Data stecken

DeddyH 6. Apr 2012 12:10

AW: Dateien einlesen
 
Den braucht man nun auch nicht unbedingt. Testhalber habe ich gerade mit Delphi 2007 die Demo leicht modifiziert, ohne die Komponente zu installieren (die Nachfrage von Delphi beim Laden des Projekts, ob die Komponente entfernt werden soll, muss man dabei verneinen). Dazu muss man lediglich die Deklaration von PicShow in den private-Abschnitt verschieben und im OnCreate ein paar Zeilen hinzufügen.
Delphi-Quellcode:
procedure TMainForm.FormCreate(Sender: TObject);
begin
  PicShow := TPicShow.Create(self);
  PicShow.Left := ClientWidth;
  PicShow.Align := alClient;
  PicShow.Parent := self;
  PicShow.Center := true;
  PicShow.Stretch := true;
  PicShow.Proportional := true;
  PicShow.OnStart := PicShowStart;
  PicShow.OnStop := PicShowStop;
  PicShow.OnProgress := PicShowProgress;
  PicShow.OnDblClick := PicShowDblClick;
  //Ab hier Originalcode der Demo
  Randomize;
  //usw.

schöni 6. Apr 2012 13:23

AW: Dateien einlesen
 
Super! Mit dieser Modifikation funktioniert es. :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:30 Uhr.

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