AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi TThread: Wie eine Prodedure von Form1 in Thread bringen?
Thema durchsuchen
Ansicht
Themen-Optionen

TThread: Wie eine Prodedure von Form1 in Thread bringen?

Ein Thema von Helmi · begonnen am 14. Dez 2004 · letzter Beitrag vom 24. Mär 2005
Antwort Antwort
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.312 Beiträge
 
Delphi XE2 Professional
 
#1

TThread: Wie eine Prodedure von Form1 in Thread bringen?

  Alt 14. Dez 2004, 15:06
Hallo,

ich hab folgende Procedure, der in der Form1 liegt.

Diesen möchte ich nun in einen Thread bringen.

Nur wird in diese Procedure eine erzeugte Progressbar benutzt, Strings aus einer ListView gelesen, Dateien kopiert, etc.

Was muss ich beachten, wenn ich diese Procedure in einen Thread bringen will?

Code:
procedure TForm1.Updaten;
var
  Anzahl, i, DateiNr, Info_Code: Integer;
  QuellDatei, Speicherort, Bezeichnung, Datei_Name, SpeicherDatei: String;
  QuellDatei_vorhanden, QuellDatei_unbenutzt, Speicherort_vorhanden,
  Speicherort_Datum_gleich, Speicherort_Datum_aelter, Speicherort_ueberschreiben,
  Datei_kopieren: Boolean;
  PB_Rect: TRect;

begin
  //Variablen leeren
  Info_Code := 0;

  //Variablen beschreiben
  Speicherort_ueberschreiben := CheckBox_Speicherort_ueberschreiben.Checked;

  //Anzahl der ListView-Einträge
  Anzahl := ListView_Dateien.Items.Count;

  //erste Seite anzeigen
  PageControl.ActivePageIndex := 0;

  //Komponenten disablen
  EnDisableComponents(false);

  for i := 0 to Anzahl - 1 do
    with ListView_Dateien do
      begin
        //Wenn die Form beendet wird dann die Schleife unterbrechen
        If Form_schliessen then
          break;

        //Dateinummer angeben
        DateiNr := i + 1;

        //Quell-Datei, Speicherort und Bezeichnung aus ListView auslesen
        QuellDatei   := Items.Item[i].SubItems.Strings[0];
        Speicherort  := Items.Item[i].SubItems.Strings[1];
        Bezeichnung  := Items.Item[i].SubItems.Strings[2];

        //Speicherort mit einem Backslash enden lassen
        Speicherort          := IncludeTrailingPathDelimiter(Speicherort);

        //prüfen ob die Quell-Datei vorhanden ist
        QuellDatei_vorhanden := FileExists(QuellDatei);

        //prüfen ob die Quell-Datei nicht benutzt wird
        QuellDatei_unbenutzt := not IsFileInUse(QuellDatei);

        //prüfen ob der Speicherort vorhanden ist
        Speicherort_vorhanden := DirectoryExists(Speicherort);

        //Dateinamen für Speicherort auslesen
        Datei_Name           := ExtractFilename(QuellDatei);

        //Dateinamen an den Speicherort anhängen, sollte eine Bezeichnung vorhanden
        //sein, dann wird diese angehängt
        If Bezeichnung <> '' then
          SpeicherDatei  := Speicherort + Bezeichnung
        else
          SpeicherDatei  := Speicherort + Datei_Name;

        //Datum prüfen
        If QuellDatei_Vorhanden and FileExists(SpeicherDatei) then
          begin
            Speicherort_Datum_gleich := DateiDatum(QuellDatei) = DateiDatum(SpeicherDatei);
            Speicherort_Datum_aelter := FileAge(SpeicherDatei) > FileAge(QuellDatei);
          end
        else
         begin
            Speicherort_Datum_gleich := false;
            Speicherort_Datum_aelter := false;
          end;

        //prüfen ob der Speicherort überschrieben werder darf
        If Speicherort_ueberschreiben then
          Speicherort_Datum_aelter := false;

        //prüfen ob die Checkbox in der ListView angeklickt wurde
        Datei_kopieren   := Items.Item[i].Checked;

        If Datei_kopieren and QuellDatei_vorhanden and QuellDatei_unbenutzt and
        Speicherort_vorhanden and not Speicherort_Datum_gleich and
        not Speicherort_Datum_aelter then
          begin
            //ListView nach rechts scrollen
            SendMessage(Handle, WM_HSCROLL, SB_RIGHT, 0);

            //kurze Wartezeit
            sleep(500);

            //Progressbar in der jeweiligen Zeile in der Spalte fünf erzeugen
            PB_Rect := Items[i].DisplayRect(drBounds);

            with PB_Rect do
              begin
                Left   := Left + Columns[0].Width + Columns[1].Width +
                                  Columns[2].Width + Columns[3].Width;

                Right  := Left + Columns[4].Width - 1;
                Bottom := Bottom - 1;
              end;

            //ProgressBar beschreiben
            with PB_Status do
              begin
                BoundsRect := PB_Rect;
                Visible    := true;
                Position   := 0;
              end;

            //ProgressBar an die ListView übergeben
            Items[i].Data := PB_Status;

            try
              //
              Application.ProcessMessages;

              //Datei kopieren
              CopyFileWithProgressBar(QuellDatei, SpeicherDatei, PB_Status, true);

              //Code 1
              Info_Code := 1;

              //kurze Wartezeit
              sleep(1000);
            finally
              //Progressbar verstecken
              PB_Status.Visible := false;
            end;
          end
        else
          begin
            If not Datei_kopieren then
              //Code 6
              Info_Code := 6
            else
              If not QuellDatei_vorhanden and not Speicherort_vorhanden then
                //Code 4
                Info_Code := 4
              else
                If not QuellDatei_vorhanden and Speicherort_vorhanden then
                  //Code 3
                  Info_Code := 3
                else
                  If QuellDatei_vorhanden and not Speicherort_vorhanden then
                    //Code 2
                    Info_Code := 2
                  else
                    If Speicherort_Datum_gleich then
                      //Code 5
                      Info_Code := 5
                    else
                      If Speicherort_Datum_aelter then
                        //Code 7
                        Info_Code := 7
                      else
                        If not QuellDatei_unbenutzt then
                          //Code 8
                          Info_Code := 8;
          end;

        //
        ListViewInfos(ListView_Dateien, i, 3, Info_Code);

        try
          Application.ProcessMessages;
        except
          //Meldung anzeigen
          MessageDlg(Msg3, mtInformation, [mbOK], 0);
        end;
      end;

  //Komponenten enablen
  EnDisableComponents(true);
mfg
Helmi
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: TThread: Wie eine Prodedure von Form1 in Thread bringen?

  Alt 14. Dez 2004, 15:17
Du musst erst mal Daten und GUI trennen. Dann kannst du in der Delphi-Referenz durchsuchenSynchronize Methode deines Threads eine Methode deines Formulares aufrufen und den Listview aktualisieren.

PS: Eine einzelne Funktion mit 175 Zeilen hab eich noch nie gesehen. Ich würde mal gucken, ob du das nicht in sinnvole Routinen aufsplitten kannst, dann wird das ganze schon übersichtlicher.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.312 Beiträge
 
Delphi XE2 Professional
 
#3

Re: TThread: Wie eine Prodedure von Form1 in Thread bringen?

  Alt 14. Dez 2004, 15:23
oki

Diese Funktion ist leider sehr lange - ich weiss - eigentlich wär sie noch länger, aber ich hab schon einige Sachen in Functions ausquatiert.

Wenn du aber schaust, ist im oberen drittel reine Überprüfung und String-Beschreibung - nix weltbewegendes
  Mit Zitat antworten Zitat
fisherman_b

Registriert seit: 4. Mär 2005
Ort: Aachen
21 Beiträge
 
RAD-Studio 2009 Arc
 
#4

Re: TThread: Wie eine Prodedure von Form1 in Thread bringen?

  Alt 24. Mär 2005, 14:30
Ok, diese Sache ist schon etwas älter... aber bei der Suche nach Hinweisen, die mir bei der Lösug zu einem aktuellen Problem helfen könnten, kam das hier der Sache am nächsten.

Ich habe also ähnliches getan - eine Form, die mittels Button einen Thread startet, der Routinen ausführt (TIdTCPClient.ReadLn und Überprüfung der erhaltenen Daten) und eine ListBox in der TForm aktualisiert. Die Aktualisierung geschieht im Thread mittels Synchronize.
So weit, so gut, das klappt alles wunderbar. Aber: Nachdem der Thread abgearbeitet ist, muss man immer erst einmal auf die Form klicken, damit diese wieder aktiv ist. Wenn ich in der Listbox (alle im Thread eingetragenen Werte sind vorhanden und sichtbar) einen Eintrag per Mausklick markieren möchte,sieht man die Markierung sogar erst, nachdem man ein beliebiges anderes Programm aktiviert und dann wieder zu der Form zurückkehrt. Ich habe zu Testzwecken an unzähligen Stellen versucht, die Form im Code während und nach dem Thread zu aktivieren, jede Menge ProcessMessages eingefügt - nix. Wahrscheinlich nur eine winzige Kleinigkeit ? Leider sehe ich nach einigen Tagen Suchen und Testen den Wald vor lauter Bäumen nicht mehr... Daher wäre ich für jede Idee, wonach ich suchen könnte, dankbar.

Gruss,

Bernhard
  Mit Zitat antworten Zitat
Antwort Antwort


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 06:40 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