Button und ProgressBar in einer Liste



  • Ich möchte mehrere NC-Programme in jeweils eigenen Threads "übersetzen". Um den Vorgang übersichtlich zu gestalten, soll in einer Liste zeilenweise folgendes angezeigt werden:

    - Name der NC-Datei (und weitere AnsiStrings)
    - Fortschrittsbalken
    - Button zum Pausieren, Abbrechen, ...

    Die Anzahl der Threads variiert und somit soll die Liste zur Programmlaufzeit gefüllt werden.
    Die Fortschrittsbalken will ich über Messages "ansprechen".

    Kann mir jemand einen entscheidenden Tipp für die Umsetzung der Liste geben?
    Gibt es Probleme (Threads, Messages, ...), die man schon frühzeitig abfangen könnte?



  • Hallo,

    mit den Standard VCL Komponenten wird das etwas Fummelarbeit, sollte aber gehen.
    Ich würde einen Frame (von TFrame abgeleitet) bauen, und darin von links nach rechts die benötigten GUI Komponenten anordnen (TLabel für Name, TProgressBar für Fortschritt, TButtons für Pause/Abbrechen, etc). Anschließend erzeugst du für jeden deiner Threads einen solchen Frame und fügst ihn in eine TScrollBox ein.
    Da alle GUI Aktualisierungen im VCL Hauptthread stattfinden müssen musst du dann noch irgendwie die Synchronisation zwischen den WorkerThreads und dem VCL Hauptthread realisieren (z.B. mit TThread::Synchronize() oder SendMessage() der Win32 API).



  • Hey DocShoe, vielen Dank für den Tipp!

    Hab mir für den Moment ne Struktur definiert, die Zeiger auf die Komponenten enthält und für jeden neuen Thread erzeuge ich einen weitere Struktur und trage den Zeiger in eine TList ein. Funktioniert auch soweit ganz gut, werds aber wohl nochmal umbauen. Das mit der fertigen ScrollBox erspart jede Menge Arbeit.

    Was mir jetzt aufgefallen ist:
    Ich habe eine Funktion "myButtonClick" die von jedem Button beim OnClick-Ereignis aufgerufen wird.
    Wie kann ich herausfinden welcher Button geklickt wurde? Entweder hab ich´s übersehen oder ich bekomme über TObject *Sender ja keinen Händler oder Zeiger auf den aufrufenden Button.

    Die Messages, die die Aktualisierung der ProgressBars bewirken, will ich über ein Mutex "schützen". Siehst du da Probleme?



  • Doch, über den 'Sender' erhältst du den Button. Du mußt ihn nur entsprechend casten:

    TButton *button = (TButton*)Sender;
    


  • CreepingDeath schrieb:

    Die Messages, die die Aktualisierung der ProgressBars bewirken, will ich über ein Mutex "schützen". Siehst du da Probleme?

    Ja, ein Mutex ist nicht das Mittel der Wahl. Die VCL ist nicht threadsafe, wenn du aus einem Thread (nicht dem VCL Hauptthread) auf GUI Komponenten zugreifst erzeugst du undefiniertes Verhalten. Das kann eine Weile gut gehen und plötzlich zu seltsamsten Effekten führen. Du musst GUI Aktualisierungen aus dem Workerthread im Kontext des VCL Hauptthreads durchführen. Wie ich schon geschrieben habe geht das mittels der TThread::Synchronize Methode oder per SendMessage aus der Win32 API.

    Edit:
    Der cast sollte so aussehen (kein C-Style cast)

    TButton* Button = dynamic_cast<TButton*>( Sender );
    if( Button )
    {
       ...
    }
    

Anmelden zum Antworten