|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1255 Wohnort: Ruhrpott
|
Verfasst am: 08.09.2013, 19:31 Titel: Programm mit GUI |
|
|
Hallo Leute, ich brauche eure Hilfe!
Ich schreibe jetzt schon seit etlichen Jahren Programme, habe mich im Laufe des letzten Jahres einigermaßen erfolgreich in die WinAPI - Programmierung eingearbeitet und befasse mich gerade mit der (Windows-) GUI - Programmierung. Ich habe verschiedene Editoren ausprobiert und mich durch etliche Tutorials gearbeitet und bekomme inzwischen auch einigermaßen ansehnliche Oberflächen hin.
Nur für eines bin ich offenbar zu blöd: Ein Programm (das irgendetwas berechnet) und eine GUI (die hübsch aussieht) ZUSAMMEN in ein Programm zu bekommen, und zwar so, daß das Programm auch dann weiterläuft, wenn ein Fenster geöffnet ist. Aber ganz gleich, an welcher Stelle ich das Programm bis jetzt in den Quelltext engefügt habe, sobald ein Fenster geöffnet ist, steht alles still und kümmert sich nur noch um eben jenes Fenster.
Nur wenn ich entweder das Programm oder die GUI in einem eigenen Thread laufen lasse, funktioniert alles problemlos, aber das kann doch eigentlich nicht im Sinne des Erfinders sein - oder doch?
Gruß
grindstone |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 955 Wohnort: Austria
|
Verfasst am: 08.09.2013, 20:47 Titel: Re: Programm mit GUI |
|
|
grindstone hat Folgendes geschrieben: | Nur wenn ich entweder das Programm oder die GUI in einem eigenen Thread laufen lasse, funktioniert alles problemlos, aber das kann doch eigentlich nicht im Sinne des Erfinders sein - oder doch? |
In der Tat lagert man Rechenzeitintensive Vorgänge in einen eigenen Thread aus. Insbesondere darf man im GUI-Thread keine solchen Aufgaben ausführen, weil sonst natürlich die GUI hängt, wie du bereits bemerkt hast.
Moderne Programmiersprachen und Frameworks, wie z.B. C#/.NET bieten diverse Funktionen, um Synchronisation zwischen Threads bzw. allgemein parallele Programmierung zu vereinfachen .. trotzdem muss man sich noch immer darum kümmern, dass solche Aufgaben in einem eigenen Thread ausgeführt werden bzw. zumindest bestimmte Regeln beachten, wenn man von anderen Threads auf den GUI-Thread zugreifen will. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1255 Wohnort: Ruhrpott
|
Verfasst am: 08.09.2013, 21:51 Titel: |
|
|
Vielen Dank für die schnelle Antwort!
Da bin ich ja scheinbar doch auf dem richtigen Weg. Ist ja auch irgendwie logisch, das Arbeiten mit Threads ist für mich halt noch relativ neu.
Der Hintergrund für meine Frage ist folgender: Ich bastele gerade an einem in freeBasic geschriebenen Winamp - DSP-Plugin, und da wollte ich als kleines Anwendungsbeispiel eine Funktion einbauen, die laufend den durchschnittlichen RMS-Pegel des abgespielten Stückes in einem eigens dafür geöffneten kleinen Fenster (ähnlich einer MessageBox) anzeigt. Soweit funktioniert das alles schon, nur ist das Anzeigefenster bis jetzt ein eigenständiges Programm mit eigener .exe, und das möchte ich gerne in das Plugin integrieren.
Nochmals vielen Dank für die Antwort!
Gruß
grindstone |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1255 Wohnort: Ruhrpott
|
Verfasst am: 11.09.2013, 23:29 Titel: |
|
|
@St_W: Vielen Dank noch mal, das war der richtige Denkanstoß.
@alle, die es interessiert:
Ich habe mir jetzt, nachdem ich die Sache (endlich) zum Laufen gekriegt habe, einmal den Spass gemacht, mir die Funktionsweise einer GUI genau anzusehen und ein wenig herumzuprobieren, um insbesondere zu verstehen, warum die GUI quasi neben dem Hauptprogramm herlaufen muß statt wie gewohnt mittendrin zu stecken. Und da ich mir gut vorstellen kann, daß der eine oder andere sich diese Frage auch gerade stellt, möchte ich meine neu gewonnenen Erkenntnisse zum Thema "einbinden einer GUI ins Programm" hier in einem kleinen "Mini-Tuorial" weitergeben.
Als Basis dient das Code-Beispiel TrackBar (Slider) von Volta, weil es schön kurz, klar und übersichtlich ist.
Jede GUI hat eine "Message loop" genannte Endlosschleife,
Code: | ...
Do Until( GetMessage( @wMsg, null, 0, 0 ) = FALSE ) 'messages loop
TranslateMessage( @wMsg )
DispatchMessage ( @wMsg )
Loop
...
|
und so liegt für den naiven Anfänger der Gedanke nahe, dort seinen Programmcode hineinzuschreiben, damit dieser kontinuierlich und periodisch abgearbeitet wird.
Das funktioniert aber nicht, weil die API-Funktion GetMessage sich so ähnlich verhält wie der Sleep-Befehl. So wie Sleep auf einen Tastendruck wartet, wartet GetMessage auf ein Ereignis, das mit dem betreffenden Fenster zusammenhängt, etwa eine Mausbewegung, einen Mausklick oder eine mit SendMessage übermittelte Nachricht.
Wer sehen möchte, welchen Effekt das hat, kann die Message loop im Code-Beispiel wie folgt abändern...
Code: | ...
Dim As Integer x
Do Until( GetMessage( @wMsg, null, 0, 0 ) = FALSE ) 'messages loop
x += 1
Print x
TranslateMessage( @wMsg )
DispatchMessage ( @wMsg )
Loop
...
|
...und das Ganze dann mit dem Parameter -s console kompilieren und starten. In dem sich zusammen mit dem Trackbar öffneden DOS-Fenster kann man dann sehen, wie bei jedem Durchlauf der Message loop der aktuelle Wert von x ausgegeben wird, sobald man den Mauszeiger über dem Trackbar-Fenster bewegt. Wird der Mauszeiger nicht bewegt, steht das Programm still.
Ein (Haupt-)Programm, das kontinuierlich laufen soll, benötigt daher einen eigenen Thread - oder man verwendet statt GetMessage die PeekMessage-Funktion:
Code: | ...
Dim As Integer x
Do
If (PeekMessage( @wMsg, null, 0, 0, PM_REMOVE )= 0 ) Then
x += 1
Print x;" ";FALSE;" ";TRUE
'Sleep 3000
Else
x += 1
Print x;"**************************"
TranslateMessage( @wMsg )
DispatchMessage ( @wMsg )
EndIf
Loop
...
|
Es geht also doch, allerdings hat diese Vorgehensweise ihre Tücken.
Zum einen muß man dafür sorgen, daß die Message loop häufig genug durchlaufen wird. Was passiert, wenn das Programm sekunden- oder vielleicht minutenlang mit Berechnungen beschäftigt ist, kann man sehen, wenn man das Kommentarzeichen vor dem Sleep-Befehl entfernt: solange PeekMessage nicht aufgerufen wird, reagiert das Fenster weder auf die Maus noch auf die Tastatur.
Des weiteren muß man dafür sorgen, daß das Programm beim Schließen des Fensters auch wirklich beendet wird. Wenn man in unserem Beispiel das Trackbar-Fenster schließt (Klick auf das Kreuz rechts oben), läuft das Programm - wie man sieht - trotzdem weiter. Ohne das DOS-Fenster ließe sich der Prozess jetzt nur noch beenden, indem man ihn im Taskmanager abschießt. |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|