Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TThread: Wie eine Prodedure von Form1 in Thread bringen? (https://www.delphipraxis.net/35996-tthread-wie-eine-prodedure-von-form1-thread-bringen.html)

Helmi 14. Dez 2004 15:06


TThread: Wie eine Prodedure von Form1 in Thread bringen?
 
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

Luckie 14. Dez 2004 15:17

Re: TThread: Wie eine Prodedure von Form1 in Thread bringen?
 
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.

Helmi 14. Dez 2004 15:23

Re: TThread: Wie eine Prodedure von Form1 in Thread bringen?
 
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

fisherman_b 24. Mär 2005 14:30

Re: TThread: Wie eine Prodedure von Form1 in Thread bringen?
 
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


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:51 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