Threads vervielfältigen
-
Ich versuche mich gerade an der Threaderstellung...
Nun habe ich es zu meinem ersten Thread gebracht, jedoch frage ich mich jetzt, wie ich die Sache variabler gestalte, d.h. wie kann ich aus dem einen Thread beliebig viele machen, so das z.B. 10 Label->Captions unabhängig voneinander aktualisiert werden ?Eigentlich hatte ich mir gedacht, das ich einfach mehrere Objekte erstelle und diese dann halt zu verschiedenen Zeitpunkten oder so.
Aber da ich in meinem Thread direkt die Form1->Label1->Caption anspreche, frage ich mich, wie ich z.B. Form1->Label2->Caption dort hinkriege ?//--------------------------------------------------------------------------- void __fastcall scanthread::updatecaption() { Form1->Label1->Caption=AnsiString(Counter); } //--------------------------------------------------------------------------- void __fastcall scanthread::Execute() { int x=StrToInt(Form1->Label1->Caption); while(Terminated==false && x<10000) { Counter=x; Synchronize(updatecaption); x++; } FreeOnTerminate = true; } //--------------------------------------------------------------------------- scanthread* test; //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { test=new scanthread(false); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { test->Terminate(); } //---------------------------------------------------------------------------
Ich hoffe Ihr könnt wie immer helfen
-
Als erstes solltest Du in den Tag Eigenschaften der Labels die Du ändern willst einen Index setzen.
Den Tag übergibst Du dann an deinen Thread der danach suchst
Dann castes Du die Komponentenliste deiner Form nach den Labels
und frags die Eigenschaft Tag des Labels ab.Über Dynamic Cast gibt es einen Beitrag in der FAQ vom Board hier, sicher gibt es da auch ne Lösung für die Komponentenliste.
Dirk
-
Also das mit dem Index klingt gut, aber wie übergebe ich das an meinen Thread und wie kann ich
hab das hier unter Dynamic cast gefunden...
TEdit *xyz = dynamic_cast<TEdit*>(PopupMenu1->PopupComponent); if (xyz) xyz->Text = "bla, bla!";
aber ehrlich gesagt, verstehe ich nicht wirklich worum es dabei geht
--> was bewirkt diese Zeile eigentlich (konnte in der FAQ unn in der BCB Hilfe nix hilfreiches finden)?TEdit *xyz = dynamic_cast<TEdit*>(PopupMenu1->PopupComponent);
hier mal mein Versuch die Sache auf mein Programm zu übersetzen, funktioniert natürlich nicht
//--------------------------------------------------------------------------- void __fastcall scanthread::updatecaption() { TLabel *xyz = dynamic_cast<TLabel*>(Caption); if (xyz) xyz->Caption = AnsiString(Counter); } //---------------------------------------------------------------------------
Kannst du mir noch nen Tip geben oder vielleicht sagen, was ich falsch gemacht habe ?
-
Hallo ganz einfach.
Den Index kannst Du im Constructor deines Threads mit angeben.
In der Header Datei wo Du deinen von TThread abgeleitet hast
//im Header ! class scanthread : public TThread { private: protected: void __fastcall Execute(); public: __fastcall scanthread(bool CreateSuspended); int LabelIndex; }; //in der Code Datei __fastcall scanthread::scanthread(bool CreateSuspended, int Index) : TThread(CreateSuspended) { LabelIndex = Index; }
Und dann in deiner Funktion musst Du auf die Componenten Liste deiner Form zugreifen
void __fastcall scanthread::Execute() { int I; TLabel*Temp; while(Terminated==false && x<10000) { Counter=x; Synchronize(updatecaption); x++; } FreeOnTerminate = true; } void __fastcall scanthread::updatecaption() { for (I = Form1->ComponentCount - 1; I >= 0; I--) { Temp = Form1->Components[I]; if (dynamic_cast<TLabel *>(Temp)) { if(Temp->Tag== LabelIndex) { Teamp->caption = "was Du willst :) "; break; } } } }
Ich übernehme natürlich keine Garantie das es per Copy & Paste auf anhieb funktioniert, einwenig musste auch selbst machen. Aber der Ansatz stimmt schonmal.
Noch ein Tipp für Threads .
Benutze noch die Klasse TCriticalSection und davon die Methoden Enter() und Leave(),Das macht die ganze sache noch sicherer, dann musste auch nicht über Synchronize gehen.Ich hoffe dir einwenig geholfen zu haben
Dirk
-
erstmal vielen Dank für deine ausführliche Hilfe
so sieht es jetzt bei mir aus und es funktioniert.
Nur wenn ich auf Button1 klicke und gleich danach auf Button3 (um den zweiten Thread zu starten), wartet der zweite, bis der erste fertig ist und fängt dann an. Kann ich die irgendwie gleichzeitig ablaufen lassen ?CPP:
//--------------------------------------------------------------------------- __fastcall scanthread::scanthread(bool CreateSuspended, int Index) : TThread(CreateSuspended) { LabelIndex = Index; } //--------------------------------------------------------------------------- void __fastcall scanthread::updatecaption() { for (int I = Form1->ComponentCount - 1; I >= 0; I--) { if (Form1->Components[I]->ClassNameIs("TLabel")) { if (dynamic_cast<TLabel *>(Form1->Components[I])->Tag == LabelIndex) { dynamic_cast<TLabel*>(Form1->Components[I])->Caption = Counter; break; } } } } //--------------------------------------------------------------------------- void __fastcall scanthread::Execute() { int x=0; while(Terminated==false && x<10000) { Counter=x; Synchronize(updatecaption); x++; } FreeOnTerminate = true; } //---------------------------------------------------------------------------
Header:
class scanthread : public TThread { private: protected: void __fastcall Execute(); public: __fastcall scanthread(bool CreateSuspended, int Index); void __fastcall scanthread::updatecaption(); int Counter,LabelIndex; }; //---------------------------------------------------------------------------
HauptCPP (mit den Buttons):
scanthread* test1; scanthread* test2; //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { test1=new scanthread(false,1); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { test1->Terminate(); test2->Terminate(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { test2=new scanthread(false,2); } //---------------------------------------------------------------------------
-
hab die Execute Methode etwas verändert und nu klappt es.
//--------------------------------------------------------------------------- void __fastcall scanthread::Execute() { int x=0; while(Terminated==false && x<10000) { Counter=x; Synchronize(updatecaption); Application->ProcessMessages(); x++; } FreeOnTerminate = true; } //---------------------------------------------------------------------------
nochmals vielen dank