AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi programm friert ein, progress bar, leerzeichen ignorieren...
Thema durchsuchen
Ansicht
Themen-Optionen

programm friert ein, progress bar, leerzeichen ignorieren...

Ein Thema von Headi · begonnen am 24. Dez 2005 · letzter Beitrag vom 27. Dez 2005
Antwort Antwort
Seite 1 von 2  1 2      
Headi

Registriert seit: 17. Nov 2005
Ort: Weinfelden
101 Beiträge
 
Delphi 2007 Professional
 
#1

programm friert ein, progress bar, leerzeichen ignorieren...

  Alt 24. Dez 2005, 13:49
Hallo leute,

Also ich bin ja gerade drann, ein crc32 check programm zu schreiben,
jetzt habe ich aber noch ein paar probleme.
Also zuerst mal was ich schon hingekriegt habe:

  • sfv dateien laden
  • dateien prüfen ob verhanden
  • dateien auf crc32 überprüfen
  • sfv dateien erstellen


Und hier meine Probleme:

  • sfv dateien sind so aufgebaut: "datei crchash" beim leerzeichen trenne ich die zwei angaben, Allerdings gibs ein fehler wenn im Dateinamen auch leerzeichen sind (achja hash wert ist immer 8 zeichen lang, also müsste ich ja sagen können er muss immer beim achten zeichen von rechts trennen oder?)
  • in manchen sfv Dateien sind noch kommentare enthalten, welche er ignorieren soll. kommentare beginnen immer mit ";"
  • beim crc check friert das Programm ein
  • ich würde gerne während dem checken eine Fortschritts Anzeige haben



wäre wirklich nice wenn ihr mir bei diesen Problemen helfen könntet

hab mal meinen code angehängt,
interessant ist zurzeit eigentlich nur unit1

vielen dank schonmal

mfg headi
Angehängte Dateien
Dateityp: zip sfv_985.zip (826,6 KB, 10x aufgerufen)
Pascal
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 24. Dez 2005, 22:44
Hi,

Zitat von Headi:
Also zuerst mal was ich schon hingekriegt habe:

  • sfv dateien laden
  • dateien prüfen ob verhanden
  • dateien auf crc32 überprüfen
  • sfv dateien erstellen
Schon mal Gratulation für dein Programm so weit!

Zitat von Headi:
Und hier meine Probleme:

  • sfv dateien sind so aufgebaut: "datei crchash" beim leerzeichen trenne ich die zwei angaben, Allerdings gibs ein fehler wenn im Dateinamen auch leerzeichen sind (achja hash wert ist immer 8 zeichen lang, also müsste ich ja sagen können er muss immer beim achten zeichen von rechts trennen oder?)
  • in manchen sfv Dateien sind noch kommentare enthalten, welche er ignorieren soll. kommentare beginnen immer mit ";"
  • beim crc check friert das Programm ein
  • ich würde gerne während dem checken eine Fortschritts Anzeige haben
Wie trennst du denn im Moment? Du solltest dir die Funktionen für String-Verarbeitung anschauen, hier insbesondere RightStr und LastDelimitter.
Mittels RightStr kannst du dir den Teilstring rechts von einer Position zurückgeben lassen, mit LeftStr den Links von einer Position, copy ist auch eine Möglichkeit (gibt noch viele weitere). Hier könntest du absolut die 8 Zeichen benutzen oder um flexibler zu bleiben kannst du dir mit LastDelimitter die Position des letzten Auftrauchens eines Zeichens (bei dir also Space) zurückgeben lassen.
Eine weitere Alternative wäre es natürlich, dir durch ein TStringList Objekt und gesetztem Delimitter den String in alle Einzelteile zerlegen zu lassen und alle ausser dem letzten wieder zusammen zu setzen (hier aber vorher einen String anlegen, der alle anderen aufnehmen kann).

Um Kommentare zu filtern (sind doch Zeilenkommentare?), kannst du dir mittels Pos die Position eines ";" zurückgeben lassen. Der String der dich dann interessieren sollte geht von 1 bis Pos(';', geleseneZeile) - 1

Ja, warum bei crc das Programm einfriert kann ich jetzt natürlich nicht sagen (noch nicht deinen Code geladen).

Fortschrittsanzeige? Sollte eigentlich kein Problem sein. Musst dir nur überlegen, wann du die am sinnvollsten updatest (also nicht 100000 Schritte, wenn nur 100 verschiedene angezeigt werden). Am einfachsten denke ich kann man soetwas mit einer Methode machen, die bei einem Fortschritt aufgerufen wird.
Da gibt es dann mehrere Möglichkeiten, die einfachste wäre es einfach einen Fortschrittsbalken zu übergeben. Ist aber unschön, du wärst natürlich an diesen gebunden und es müsste für eine andere Komponente der Code geändert werden.
Eine weitere Möglichkeit bestünde darin, einfach einen Methodenzeiger (procedure(const progress : Cardinal) of Object) zu definieren und dann halt eine Methode zuzuweisen.
Alternativ (und etwas mehr OOP) einfach ein Interface definieren, dass eine solche Methode deklariert und dann in dein Objekt, in dem der Fortschritt stattfindet ein Listener-Modell einbauen (also registerListener, notifyListener und removeListener), dann kannst du beliebig viele Objekte über einen Fortschritt informieren (eben alle registrierten Listener).

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Headi

Registriert seit: 17. Nov 2005
Ort: Weinfelden
101 Beiträge
 
Delphi 2007 Professional
 
#3

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 25. Dez 2005, 19:14
hmmm... ich krieg das einfach nicht hin,

also zum ersten Problem:

Ich habe mir die tipps nochmals angeschaut, die du mir gegeben hast.
Ich habe es jetzt geschafft, jedes wort anzusprechen, aber irgendeine gute funktion konnte ich nicht basteln.
Ich möchte ja nicht den ganzen code den ich schon habe wieder umschreiben.

bis jetzt sieht dieser code so aus:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject); //sfv file öffnen
begin

  if OpenDialog1.Execute then
   begin
    SL := TStringList.Create;
    SL.LoadFromFile(OpenDialog1.FileName); //sfv daten in stringlist speichern
    SL.Delimiter :=' ';

    SLSub := TStringList.Create;
    StringGrid1.RowCount:=SL.Count+1; //stringgrid zeilen erstellen

    for I := 0 to SL.Count - 1 do
     begin
      SLSub.DelimitedText := SL[I];

      StringGrid1.Cells[0, (1+(I))]:=SlSub[0]; //dateiname in stringgrid einfügen
      StringGrid1.Cells[2, (1+(I))]:=SlSub[1]; //hash wert in stringgrid einfügen
      StringGrid1.Cells[1, (1+(I))]:='ready'; //status gleich ready
     end;
   end;
end;

dann zum zweiten Problem:

Ja es sind zeilenkommentare.
Mit dem pos bin ich irgendwie auch nicht weitergekommen,
irgendwie habe ich immer probleme mit den verschiedenen Formaten, also Strings, string, integer...

drittes Problem:

Also ich glaube, das ist ja sogar normal dass ein Programm bei längeren berechnungen einfriert,
aber ich glaube das kann man doch mit einem thread oder so umgehen?! Nur habe ich leider keine Ahnung davon.

viertes Problem:

Also das mit dem Fortschrittbalken krieg ich glaub nicht hin, da ich erstens zu wenig ahnung davon habe, und zweitens
habe ich durch die componente die mir das ganze berechnet irgendwie zu wenig informationen.
Ich werde dort jetzt einfach einen Fortschritsbalken anzeigen, der hin und her fahrt.


vielen dank schonmal,
Ich hoffe ihr könnt mir das noch ein bisschen genauer erklären

mfg headi
Pascal
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 25. Dez 2005, 19:41
Zitat von Headi:
dann zum zweiten Problem:

Ja es sind zeilenkommentare.
Mit dem pos bin ich irgendwie auch nicht weitergekommen,
irgendwie habe ich immer probleme mit den verschiedenen Formaten, also Strings, string, integer...
Mal eine einfache Lösung:

Delphi-Quellcode:
procedure extractComments(const ListWithComments, ListWithoutComments : TStringList);
var i : Integer;
begin
  // nachschauen, dass keine Referenz = nil ist
  if assigned(ListWithComments) and assigned(ListWithoutComments) then
    begin
      // löschen der Liste in die alle Zeilen ohne Kommentar kommen
      ListWithoutComments.Clear;
      // schauen ob es mindestens eine Zeile gibt
      if ListWithComments.Count > 0 then
        begin
          // übertragen der Einträge, dabei aber jeden Kommentar löschen
          for i := 0 to ListWithComments.Count - 1 do
            begin
              // wenn Zeile einen Kommentar enthält
              // > 1 -> keine Zeile die nur ein Kommentar ist wird kopiert
              if Pos(';', ListWithComments.Strings[i]) > 1 then
                begin
                  // kopieren des Teils der nicht zum Kommentar gehört
                  ListWithoutComments.Add(copy(ListWithComments.Strings[i], 1, Pos(';', ListWithComments.Strings[i]));
                end // if Pos(';', ListWithComments.Strings[i]) > 1
              // sonst die Zeile unverändert kopieren
              else
                begin
                  ListWithoutComments.Add(ListWithComments.Strings[i]);
                end;
            end; // for i := 0 to ListWithComments.Count - 1
        end; // if ListWithComments.Count > 0
    end; // if assigned(ListWithComments) and assigned(ListWithoutComments)
end;
Hier übergibst du einfach zwei StringListen. Die erste enthält den originalen Inhalt inklusive den Kommentaren. Die zweite kann ruhig leer sein (der Inhalt wird auf jeden Fall gelöscht). Es wird nun jede Zeile der ersten Liste genommen und immer der Teil in die zweite Liste kopiert, der vor einem Kommentar kommt. Statt Pos(';' ... ) solltest du lieber eine Konstante benutzen, falls du von ';' mal auf etwas anderes wechseln möchtest.

Zitat von Headi:
drittes Problem:

Also ich glaube, das ist ja sogar normal dass ein Programm bei längeren berechnungen einfriert,
aber ich glaube das kann man doch mit einem thread oder so umgehen?! Nur habe ich leider keine Ahnung davon.
Ja klar, du kannst einen Thread anlegen. Aber Nebenläufigkeit hat ein paar eigene Tücken. Ist nicht wirklich trivial da alles zu berücksichtigen. Du findest eine Menge Tutorials zu Threads und Delphi, aber hier dürfte es reichen, wenn du von Zeit zu Zeit etwas rechenzeit freigibst.
Wenn du eine große Schleife hast, die etwas berechnet und es nur lange dauert, da die Anzahl der Iterationen sehr groß ist, solltest du alle paar Durchläufe ein Application.ProcessMessages einbauen. Dieser Befehl lässt Windows auch andere Nachrichten verarbeiten, die sonst nicht zum Zuge kämen (betrifft dann u.A. neuzeichnen und verschieben von Fenstern).

So, jetzt guck ich doch nochmal in deinen Code. Ach Moment, du benutzt ein paar Komponenten, könntest du bitte angeben welche? (ist immer leichter sich Quellcode anzusehen, wenn man alle Komponenten kennt).

Ach und bitte nicht die .exe in ein zip, sondern nur die Files die man zum selber kompilieren braucht (hab nur einen ISDN Kanal zur Verfügung).

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 25. Dez 2005, 20:42
Zitat:
Ja klar, du kannst einen Thread anlegen. Aber Nebenläufigkeit hat ein paar eigene Tücken. Ist nicht wirklich trivial da alles zu berücksichtigen. Du findest eine Menge Tutorials zu Threads und Delphi, aber hier dürfte es reichen, wenn du von Zeit zu Zeit etwas rechenzeit freigibst.
Iwo, das ist mit Jedi (TJvThread) eigentlich kein grosses Geheimnis. Man darf nur nicht aus dem Thread schreibend direkt auf die Komponenten zugreifen (z.B. ProgressBar, Label, etc.).
Die einfachste Variante ist die Aktualisierung mit einem Timer zu lösen. Die Werte aus dem Thread schreibt man sich in eine globale Variable (oder auch Liste oder wie auch immer) und gibt diese dann mit dem Timer aus.

Es ist einfacher als man denkt und hilft ungemein
  Mit Zitat antworten Zitat
Headi

Registriert seit: 17. Nov 2005
Ort: Weinfelden
101 Beiträge
 
Delphi 2007 Professional
 
#6

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 25. Dez 2005, 21:10
so hab jetzt mal dein code ausprobiert, aber der funktioniert irgendwie nicht richtig.
Folgende Fehlermeldung:
Zitat:
Im Projekt Project1.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 00574807 in Modul 'Project1.exe'. Lesen von Adresse 00000000' aufgetreten.
mein code sieht so aus vielleicht hab ich ja was falsch gemacht

Delphi-Quellcode:
procedure extractComments(const ListWithComments, ListWithoutComments : TStringList);
var i : Integer;
begin
  // nachschauen, dass keine Referenz = nil ist
  if assigned(ListWithComments) and assigned(ListWithoutComments) then
    begin
      // löschen der Liste in die alle Zeilen ohne Kommentar kommen
      ListWithoutComments.Clear;
      // schauen ob es mindestens eine Zeile gibt
      if ListWithComments.Count > 0 then
        begin
          // übertragen der Einträge, dabei aber jeden Kommentar löschen
          for i := 0 to ListWithComments.Count - 1 do
            begin
              // wenn Zeile einen Kommentar enthält
              // > 1 -> keine Zeile die nur ein Kommentar ist wird kopiert
              if Pos(';', ListWithComments.Strings[i]) > 1 then
                begin
                  // kopieren des Teils der nicht zum Kommentar gehört
                  ListWithoutComments.Add(copy(ListWithComments.Strings[i], 1, Pos(';', ListWithComments.Strings[i])));
                end // if Pos(';', ListWithComments.Strings[i]) > 1
              // sonst die Zeile unverändert kopieren
              else
                begin
                  ListWithoutComments.Add(ListWithComments.Strings[i]);
                end;
            end; // for i := 0 to ListWithComments.Count - 1
        end; // if ListWithComments.Count > 0
    end; // if assigned(ListWithComments) and assigned(ListWithoutComments)
end;

procedure TForm1.Button1Click(Sender: TObject); //sfv file öffnen
var SLwithcomments: TStringList;
begin

  if OpenDialog1.Execute then
   begin
    SLwithcomments := TStringList.Create;
    SL.LoadFromFile(OpenDialog1.FileName); //sfv daten in stringlist speichern
    extractComments(SLwithcomments, SL);
    SL.Delimiter :=' ';

    SLSub := TStringList.Create;
    StringGrid1.RowCount:=SL.Count+1; //stringgrid zeilen erstellen

    for I := 0 to SL.Count - 1 do
     begin
      SLSub.DelimitedText := SL[I];

      StringGrid1.Cells[0, (1+(I))]:=SlSub[0]; //dateiname in stringgrid einfügen
      StringGrid1.Cells[2, (1+(I))]:=SlSub[1]; //hash wert in stringgrid einfügen
      StringGrid1.Cells[1, (1+(I))]:='ready'; //status gleich ready
     end;
   end;
end;



Zitat von Sir Rufo:
Zitat:
Ja klar, du kannst einen Thread anlegen. Aber Nebenläufigkeit hat ein paar eigene Tücken. Ist nicht wirklich trivial da alles zu berücksichtigen. Du findest eine Menge Tutorials zu Threads und Delphi, aber hier dürfte es reichen, wenn du von Zeit zu Zeit etwas rechenzeit freigibst.
Iwo, das ist mit Jedi (TJvThread) eigentlich kein grosses Geheimnis. Man darf nur nicht aus dem Thread schreibend direkt auf die Komponenten zugreifen (z.B. ProgressBar, Label, etc.).
Die einfachste Variante ist die Aktualisierung mit einem Timer zu lösen. Die Werte aus dem Thread schreibt man sich in eine globale Variable (oder auch Liste oder wie auch immer) und gibt diese dann mit dem Timer aus.

Es ist einfacher als man denkt und hilft ungemein
Könntest du das vielleicht ein bisschen genäuer erklären??
Ich habe wirklich noch nie einen thread erstellt.
Vorallem habe ich ja nur einen Befehl in meinem code, der rest überniehmt dann die componente!!
Achja der Befehl lautet so: SZCRC32File(FileName); Achja hab mal noch die componente angehängt und mein code ohne exe

Danke schon mal

mfg headi
Angehängte Dateien
Dateityp: zip sfv_937.zip (15,0 KB, 5x aufgerufen)
Dateityp: zip crc_133.zip (10,1 KB, 6x aufgerufen)
Pascal
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 26. Dez 2005, 23:39
Zitat:
Vorallem habe ich ja nur einen Befehl in meinem code, der rest überniehmt dann die componente!!
... und diese Komponente braucht aber sehr lange und friert dann das Fenster ein.

Einfach die Komp. TJvThread auf das Formular ziehen und den Aufruf der anderen Komponente in TJvThread.OnExecute reinschreiben.
Zum Starten rufst du dann TJvThread.Execute auf.
Der Event OnBegin informiert Dich, dass der Thread gestartet wurde.
OnFinish bzw. OnFinishAll informiert Dich (das Programm), dass der Thread beendet ist.

Eigentlich alles wie gehabt, nur das Fenster friert nicht mehr ein.

Aber du musst noch abfangen, wenn das Programm einfach so beendet wird, bevor der Thread fertig ist.
Entweder Du hast die Möglichkeit der Komp. das mitzuteilen (hallo, mach mal Schluss), oder du verhinderst das Beenden solange bis OnFinish/OnFinishAll gekommen ist.

Als weitere Möglichkeit bietet sich auch an (vor allem auf Mehr-CPU-Systemen) die Berechnung von mehreren Dateien parallel zu verarbeiten, dann nutzt du auch alle CPUs aus und nicht nur eine.

Ich werde morgen mal sehen und dort eine Thread-Version reinstellen ... alte Menschen müssen jetzt schlafen
  Mit Zitat antworten Zitat
Headi

Registriert seit: 17. Nov 2005
Ort: Weinfelden
101 Beiträge
 
Delphi 2007 Professional
 
#8

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 27. Dez 2005, 00:14
Zitat von Sir Rufo:
Einfach die Komp. TJvThread auf das Formular ziehen und den Aufruf der anderen Komponente in TJvThread.OnExecute reinschreiben.
Zum Starten rufst du dann TJvThread.Execute auf.
Hab das mal gemacht, bekomme jetzt allerdings

[Fehler] Unit1.pas(95): E2035 Nicht genügend wirkliche Parameter

die zeile lautet

Thread1.Execute;

Irgendwie müsste da noch ein pointer rein oder so glaube ich zumindest!??

Danke schon mal für deine hilfe

mfg headi
Pascal
  Mit Zitat antworten Zitat
Benutzerbild von Ultimator
Ultimator

Registriert seit: 17. Feb 2004
Ort: Coburg
1.860 Beiträge
 
FreePascal / Lazarus
 
#9

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 27. Dez 2005, 00:18
Ich vermute, die Create-Methode will noch eine Boolean-Variable, die angibt, ob der Thread angehalten erzeugt oder gestartet erzeugt wreden soll (true für angehalten, false damit er gleich das arbeiten anfängt, sobald er erschaffen ist)
Julian J. Pracht
  Mit Zitat antworten Zitat
Headi

Registriert seit: 17. Nov 2005
Ort: Weinfelden
101 Beiträge
 
Delphi 2007 Professional
 
#10

Re: programm friert ein, progress bar, leerzeichen ignoriere

  Alt 27. Dez 2005, 01:11
Zitat von Ultimator:
Ich vermute, die Create-Methode will noch eine Boolean-Variable, die angibt, ob der Thread angehalten erzeugt oder gestartet erzeugt wreden soll (true für angehalten, false damit er gleich das arbeiten anfängt, sobald er erschaffen ist)
[Fehler] Unit1.pas(95): E2010 Inkompatible Typen: 'Pointer' und 'Boolean'


hmmm... was muss ich da angeben??
Was ist ein pointer

Hilfeeee...
Pascal
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:37 Uhr.
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