Aus einem Thread etwas in ein TForm Label schreiben



  • Hey Leute,
    Also ich wolle ein Programm schreiben das etwas ausliest und dann in einem Label anzeigt.
    Bisher hab ich das über den Return Wert geregelt
    damit beim ButtonClick das ausgelesene auf dem Label angezeigt wird.

    DWORD WINAPI entfernung(LPVOID param)
    {
    mining.trennzeichen();
    mining.abstand();
    return mining.berechnen();
    }

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    if(Button1->Caption == "Beenden")
    Close();
    Button1->Caption = "Beenden";

    int xspdif =6, yspdif =6;
    int xscan = 1046, yscan = 153;
    int xpunkt = xscan+xspdif, ypunkt = yscan+yspdif;
    mining.koordinaten(xpunkt,ypunkt,xscan,yscan);

    CreateThread(NULL,0,entfernung,0,CREATE_SUSPENDED, NULL);

    Label1->Caption = entfernung(0);
    }

    So da der Wert sich aber ständig ändert wollte ich in dem Thread eine Endlos schleifen laufen lassen der die Ausgabe in dem Label immer aktuell hält.
    Über den Return Wert kann ich das dann ja nichtmehr machen.
    Aber aus dem Thread kann ich das mit Label->Caption auch nicht realsieren da es ja nicht zur Klasse TForm1 gehört.

    Ich hatte mir dann überlegt immer eine Statische Statischen methode der Klasse TForm1 aufzurufen, die Statische methode durfte mit Label1->Caption aber auch nichtmehr draufzugreifen.

    Nun meine Frage ist es irgendwie möglich ist, die errechneten werte aus dem Thread auf das Label in TForm1 zu legen?
    Oder würde das dann auch die GUI blockieren obwohl das auslesen und berechnen in einem Thread abläuft?

    Hoffe ihr könnt mir bissl weiterhelfen und Vielen Dank schonmal
    mfg Death



  • Klingt nach BCB ???

    - speicher die Werte in LOKALER Variablen des Thread
    - mach ne Funktion (Thread- Member!) OHNE Parameter
    - rufe diese mit Synchronize auf.
    In der Funktion kannst Du auf das Label zugreifen.

    Du kannst dem Thread nach der Erzeugung auch die Adresse von dem TLabel übergeben. Solange Du mit Synchronize arbeitest, kannst Du auch darüber die Anzeige steuern.

    Gruss
    frank



  • viele dank schonmal 🙂
    aber hast mir vielleicht noch nen kurzes bsp wie du das meinst ^^
    danke
    mfg death



  • !!! ACHTUNG !!!
    Reins CBuilder C.

    Die entsprechenden Komponenten musst Du in der Form ablegen !!!
    (TButton, TLabel)
    und die Methoden ergänzen.

    OnThreadEnded der Form ist für Callback bei Beenden. Kann auch entfallen.
    (Dann beim Erzeugen des Thread NULL übergeben)

    //Header- Datei

    //---------------------------------------------------------------------------
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    typedef void __fastcall (__closure *TOnExecuteEnd)(int Count);
    //---------------------------------------------------------------------------
    class TLabelActThread : public TThread
    {
    private:
            int Count;
            TLabel *Label2Act;
            void __fastcall LabelAct(void);
            TOnExecuteEnd OnExecuteEnd;
    protected:
            virtual void __fastcall Execute(void);
    public:
            __fastcall TLabelActThread(bool CreateSuspended, TLabel *ALabel2Act, TOnExecuteEnd AExecuteEnd);
    
    };
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
            TButton *Button1;
            TLabel *Label1;
            void __fastcall Button1Click(TObject *Sender);
    private:	// Anwenderdeklarationen
            TLabelActThread *LAT;
            void __fastcall OnThreadEnded(int Count);
    public:		// Anwenderdeklarationen
            __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    

    // CPP- Datei

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    { LAT=NULL;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::OnThreadEnded(int Count)
    { LAT=NULL;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    { LAT=new TLabelActThread(true,Label1,&OnThreadEnded);
      LAT->FreeOnTerminate=true;
      //...
      //...
      //...
      LAT->Resume();
    }
    //---------------------------------------------------------------------------
    __fastcall TLabelActThread::TLabelActThread(bool CreateSuspended, TLabel *ALabel2Act, TOnExecuteEnd AExecuteEnd)
            : TThread(Suspended)
    { Label2Act=ALabel2Act;
      OnExecuteEnd=AExecuteEnd;
    }
    //---------------------------------------------------------------------------
    void __fastcall TLabelActThread::LabelAct(void)
    { Label2Act->Caption=Count;
    }
    //---------------------------------------------------------------------------
    void __fastcall TLabelActThread::Execute(void)
    { Count=0;
      while (!Terminated && (Count<1000))
      { Count++;
        Synchronize(LabelAct);
      }
      Label2Act=NULL;
      if (OnExecuteEnd!=NULL)
      { OnExecuteEnd(Count);
      }
    }
    //---------------------------------------------------------------------------
    

Anmelden zum Antworten