Label-Zugriff von Thread
-
hallo,
ist ganz gut das du dieses frage gestellt hast, denn da gibt es etwas wichtiges zu beachten, das wenn man es nicht beachtet nicht unbedingt sofort zu einem fehler führt, früher oder später aber zu ganz bösen dingen führen kann. angenommen du hast eine form auf der dein label sitzt (es gibt im CBuilder übrigens auch einen TStaticText). in einer anderen unit ist dein TThread-Object (ich nehme hier jetzt an, das du das TThread-Object der VCL verwendest und nicht die api-funktionen). nun ist es so, das hauptformular mit den vcl-kompos läuft in einem anderen prozess wie das thread objekt. damit du aber dennoch vom thread aus auf die kompos des formulars zugreifen kannst ohne gefahr zu laufen, gibt es eine methode namens Synchronize(...), dieser Methode übergibst die routine in der der zugriff auf die form-kompos stattfindet, denn die methode die du synchronize übergibst wird im selben kontext wie der vcl hauptthread ausgeführt, ein beispiel:
void __fastcall TMyThread::Execute() { FCount = 1; do { Synchronize(GuiElements); //Aufruf von synchonize. FCount++; } while (FCount <= 200000); } void __fastcall TMyThread::GuiElements() { //läuft im kontext des vcl-hauptthreads. Form1->DisplayLabel->Caption = IntToStr(FCount); }
mfg
murph
-
q15: Ob "1ntrud0r" den Text gelesen hat spielt keine Rolle. Er hat ihn einfach nicht verstanden
1ntrud0r: Lesen lernen und üben. Sätze möglichst bis zum Ende durchlesen, usw.
-
Besten Dank an murphy, der Hinweis, dass es auch StaticText Komponenten gibt war sehr hilfreich. Hier kann ich den Handle (z.B. hWndStatic) vom StaticText an den Thread übergeben und da mit folgendem Code den StaticText beeinflussen.
AnsiString StaticText = "Irgend ein Text"; SendMessage(hWndStatic, WM_SETTEXT, 0, (LPARAM)(LPCSTR)&LabelText)
Übrigens, ich arbeite nicht mit 'TThread' sondern mit '_beginthreadNT'. Was das mit TThread auf sich hat, werde ich mir später einmal zu Gemüte ziehen.
Grüße aus Regensburg
-
q150022 schrieb:
Übrigens, ich arbeite nicht mit 'TThread' sondern mit '_beginthreadNT'. Was das mit TThread auf sich hat, werde ich mir später einmal zu Gemüte ziehen.
Abgesehen davon, dass du dieses Detail vielleicht hättst früher erwähnen sollen, würde ich dir empfehlen, die Informationen über TThread besser jetzt als später einzuziehen...
-junix
-
Ups, funktioniert doch nicht
Auch nachdem ich 'LabelText' in 'StaticText' umgetauscht habe...
AnsiString StaticText = "Irgend ein Text"; SendMessage(hWndStatic, WM_SETTEXT, 0, (LPARAM)(LPCSTR)&StaticText)
Beim Probieren wird der Text nicht "richtig" angezeigt, sondern es sind nur irgendwelche Ascii-Zeichen zu sehen...
-
Kleines Rätsel für dich:
(LPARAM)(LPCSTR)&StaticText
Was bedeutet die obige Zeile?
-
Bevor Du Dich totsuchst. AnsiString auf char*: AnsiString::c_str()
Junix hat Recht: lieber gleich TThread, sparst Dir ne Menge Stress.
Kurzeinweisung:
Datei->Neu->Weiter, dann "Thread-Objekt" auswählen. Klassenname nach Geschmack eingeben, und hallelujah!- eine neue Unit, mit einer neuen von TThread abgeleiteten Klasse, mit den wichtigsten Funktionsrümpfen schon drin.
Die wichtigsten Hinweise stehen dann schon als Kommentare im Code.
Der Thread-Code kommt in die Execute()-Methode.
Um auf der Haupt-Form an den VCL-Komponenten rumzufummeln, dazu jeweils eigene Threadklasse-Memberfunktion schreiben und aus Execute() heraus mit Synchronize() arbeiten, wie oben schon mal erwähnt.
Steht in den generierten Kommentaren aber auch schon sehr schön drin, für die meisten Zwecke alles ziemlich Idiotensicher.
-
Leser schrieb:
q15: Ob "1ntrud0r" den Text gelesen hat spielt keine Rolle. Er hat ihn einfach nicht verstanden
1ntrud0r: Lesen lernen und üben. Sätze möglichst bis zum Ende durchlesen, usw.mach jmd andren dumm von der seite an ...
Ich hab ihn nur druff hingewiesen das er die Memberfunktionen von TLabel benutzen kann und nicht die Räder neu erfinden brauch .. mehr net
-
Ach ja, und aus Deinem Hauptcode heraus (#includes nicht vergessen!) einfach eine (oder mehrere!) Instanz Deiner TThread-basierten Klasse erzeugen, etwa:
meinThread = new MeineThreadKlasse (true); // fasle, um gleich zu starten
Dann nach Belieben über meinThread->Resume() und ->Suspend() das Ding starten und anhalten.
Viel Spaß!!
-
Genau die Methode 'c_str()' von AnsiString habe ich gesucht - Danke!
Das Thema TThread scheint wirklich easy zu sein - ich weiss garnicht warum ich nicht früher mit Borland angefangen habe...
-
Leser schrieb:
Bevor Du Dich totsuchst. AnsiString auf char*: AnsiString::c_str()
Danke für diese äusserst effektive Zerstörung des Lerneffekts.
Er hätte sich nicht todgesucht, sondern hätte einfach mal antworten sollen. Ich hätte ihn dann schon in die richtige Richtung geschubst. Alleine schon die konstellation des Codes den er da geschrieben hat, verrät nämlich dass er gar nicht genau wusste, was er da eigentlich tat. Viel mehr weiss er nun auch nicht.
Wie dem auch sei, die "konvertierung" von AnsiString nach char-Pointer ist eigentlich auch schon in der FAQ vermerkt und mit einigen wichtigen Hinweisen versehen, die man unbedingt lesen sollte!
-junix