Eventbearbeitung für on-the-fly erzeugte Fenster - wie?
Eventbearbeitung für on-the-fly erzeugte Fenster - wie?
Hallo,
ich möchte aus einem chat-ähnlichen Programm heraus eine theoretisch beliebige Anzahl an "Kommunikationsfenstern" öffnen.
Im Prinzip ähnlich wie bei Skype, wo man zeitgleich mit mehreren Leuten chatten kann und für jeden Kontakt ein eigenes Fenster hat.
Ich bin mir jetzt nicht ganz sicher wie ich das mit der Eventbearbeitung regle.
Die Fenster sehen prinzipiell gleich aus und haben auch Buttons etc. die Eventmäßig bearbeitet werden müssen.
Das ganze soll aber völlig losgelöst vom Hauptprogramm ablaufen, das ein eigenes Fenster hat, welches die Kontakte als Liste anzeigt (Skype läßt wieder grüßen).
Am liebsten wäre es mir, wenn jedes der Kommunikationsfenster in einem eigenen Thread liefe und darüber auch die Verbindung zum entfernten Kommunikationspartner (Server) hergstellt wird. Dadurch würde das Hauptprogramm nicht stocken, wenn es mal zu Verbindungsproblemen kommen sollte.
Die einzelnen Netzwerkverbindung zu den Kommunikationspartnern sollen auf jeden Fall in einem Thread laufen. Wenn dazu noch die Fenster im selben Thread erzeugt und destroyed werden könnten, dann würde das die ganze Sache verwaltungstechnisch vereinfachen.
Soweit ich weiß kann/sollte man die Eventbearbeitung aller Fenster aber immer nur in einem Loop des Hauptprogramms bearbeiten.
Das würde die Sache nach erster Näherung aber wieder verkomplizieren.
Hat jemand eine Idee wie man das am besten angeht?
ich möchte aus einem chat-ähnlichen Programm heraus eine theoretisch beliebige Anzahl an "Kommunikationsfenstern" öffnen.
Im Prinzip ähnlich wie bei Skype, wo man zeitgleich mit mehreren Leuten chatten kann und für jeden Kontakt ein eigenes Fenster hat.
Ich bin mir jetzt nicht ganz sicher wie ich das mit der Eventbearbeitung regle.
Die Fenster sehen prinzipiell gleich aus und haben auch Buttons etc. die Eventmäßig bearbeitet werden müssen.
Das ganze soll aber völlig losgelöst vom Hauptprogramm ablaufen, das ein eigenes Fenster hat, welches die Kontakte als Liste anzeigt (Skype läßt wieder grüßen).
Am liebsten wäre es mir, wenn jedes der Kommunikationsfenster in einem eigenen Thread liefe und darüber auch die Verbindung zum entfernten Kommunikationspartner (Server) hergstellt wird. Dadurch würde das Hauptprogramm nicht stocken, wenn es mal zu Verbindungsproblemen kommen sollte.
Die einzelnen Netzwerkverbindung zu den Kommunikationspartnern sollen auf jeden Fall in einem Thread laufen. Wenn dazu noch die Fenster im selben Thread erzeugt und destroyed werden könnten, dann würde das die ganze Sache verwaltungstechnisch vereinfachen.
Soweit ich weiß kann/sollte man die Eventbearbeitung aller Fenster aber immer nur in einem Loop des Hauptprogramms bearbeiten.
Das würde die Sache nach erster Näherung aber wieder verkomplizieren.
Hat jemand eine Idee wie man das am besten angeht?
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
-
Little John
Wie mir in dieser Diskussion erklärt wurde, sollte jeder Thread seine Ereignisse selbst behandeln.
Wie man das innerhalb der einzelnen Threads macht, hängt von den eigenen Präferenzen ab. Das wurde ja hier recht ausführlich diskutiert.
Gruß, Little John
Wie man das innerhalb der einzelnen Threads macht, hängt von den eigenen Präferenzen ab. Das wurde ja hier recht ausführlich diskutiert.
Gruß, Little John
Oh, da steht doch tatsächlich:Little John hat geschrieben:Wie mir in dieser Diskussion erklärt wurde, sollte jeder Thread seine Ereignisse selbst behandeln.
Cool, das ist ja genau das, was ich brauche. Irgendwie hab ich bisher was falsches verinnerlicht ("Niemals eine Eventschleife in einem Thread benutzen!"PMV hat geschrieben:Für jeden Thread, der Fenster erstellt wird eine Eventschleife benötigt.
Werde ich zuhause gleich mal ausprobieren. Danke Little John.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
-
Kaeru Gaman
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
> "Niemals eine Eventschleife in einem Thread benutzen!"
das ist zu kurz gemerkt gewesen:
"Niemals Event-Bezogene Befehle in einem Thread benutzen, dem das Fenster nicht gehört"
oder
"Immer alle Fenster- und Event-Befehle in den selben Thread packen"
... aber du kannst auch alle Fenster mit PB_Any erzeugen und alle Events in der selben Eventschleife bearbeiten.
das ist zu kurz gemerkt gewesen:
"Niemals Event-Bezogene Befehle in einem Thread benutzen, dem das Fenster nicht gehört"
oder
"Immer alle Fenster- und Event-Befehle in den selben Thread packen"
... aber du kannst auch alle Fenster mit PB_Any erzeugen und alle Events in der selben Eventschleife bearbeiten.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Der Weise weiß, dass er ein Narr ist.
Es muss ja irgendeine Kommunikation zwischen dem Hauptfenster und dem
"Clientfenster" existieren. Ich wuerde den Netzwerkteil in einem eigenem
Thread unterbringen, dieser sendet dann, was auch immer, an das
Hauptfenster. Das Hauptfenster wertet es aus und schickt es an die einzelnen
Clienten weiter.
"Clientfenster" existieren. Ich wuerde den Netzwerkteil in einem eigenem
Thread unterbringen, dieser sendet dann, was auch immer, an das
Hauptfenster. Das Hauptfenster wertet es aus und schickt es an die einzelnen
Clienten weiter.
Leider bin ich heute Abend noch nicht so weit, um das zu prüfen. Bin gerade erst an den Rechner gekommen.
Nach dem, was ihr geschrieben habt, gehe ich eigentlich davon aus, daß jeder Thread nur die Events der Fenster bekommt, die unter ihm auch erzeugt worden sind.
Der Plan ist:
Ich habe ein Mainwindow mit fester "Nummer" (#Wnd_Main) und einen Eventloop im "Hauptthread". Dann starte ich einen zweiten Thread, der eigentständig ein Chat-Window öffnet (mittels #PB_Any, weil es ja theoretisch beliebig viele Fenster werden können). Wenn der zweite Thread in seinem Eventloop die Events abruft, wäre es ziemlich blöd, wenn dort auch die Events des #Wnd_Main ankämen.
Ich hoffe, daß ist nicht so... na ich setze mich jetzt besser mal ran, statt hier so viel rumzutippern.
@Edel: Erst dachte ich ja, das ginge nur so wie von Dir vorgeschlagen, aber mir scheint die vollständige Verlagerung der Eventbearbeitung in den jeweiligen Thread als am einfachsten.
So kann ich jedes Chatfenster fast als eigenständiges Programm ansehen und behandeln. Der Datenaustausch mit dem Mainwindow ist sehr gering und geschiet eh über gemeinsame Strukturen, so wie auch schon beim empfangenden Server, der bereits als Thread läuft (aber eben keine GUI benötigt).
Das verwirrt mich jetzt wieder. Heißt das, daß ich Fenster, die ich in einem Thread erzeuge nicht mit #PB_Any erzeugen darf?Kaeru Gaman hat geschrieben:> "... aber du kannst auch alle Fenster mit PB_Any erzeugen und alle Events in der selben Eventschleife bearbeiten.
Nach dem, was ihr geschrieben habt, gehe ich eigentlich davon aus, daß jeder Thread nur die Events der Fenster bekommt, die unter ihm auch erzeugt worden sind.
Der Plan ist:
Ich habe ein Mainwindow mit fester "Nummer" (#Wnd_Main) und einen Eventloop im "Hauptthread". Dann starte ich einen zweiten Thread, der eigentständig ein Chat-Window öffnet (mittels #PB_Any, weil es ja theoretisch beliebig viele Fenster werden können). Wenn der zweite Thread in seinem Eventloop die Events abruft, wäre es ziemlich blöd, wenn dort auch die Events des #Wnd_Main ankämen.
Ich hoffe, daß ist nicht so... na ich setze mich jetzt besser mal ran, statt hier so viel rumzutippern.
@Edel: Erst dachte ich ja, das ginge nur so wie von Dir vorgeschlagen, aber mir scheint die vollständige Verlagerung der Eventbearbeitung in den jeweiligen Thread als am einfachsten.
So kann ich jedes Chatfenster fast als eigenständiges Programm ansehen und behandeln. Der Datenaustausch mit dem Mainwindow ist sehr gering und geschiet eh über gemeinsame Strukturen, so wie auch schon beim empfangenden Server, der bereits als Thread läuft (aber eben keine GUI benötigt).
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
-
Little John
Nein. #PB_Any geht in jedem Fall ( in any caseKurzer hat geschrieben:Das verwirrt mich jetzt wieder. Heißt das, daß ich Fenster, die ich in einem Thread erzeuge nicht mit #PB_Any erzeugen darf?Kaeru Gaman hat geschrieben:> "... aber du kannst auch alle Fenster mit PB_Any erzeugen und alle Events in der selben Eventschleife bearbeiten.
Gruß, Little John
hier mal ein kleines beispiel wie ich das meinte
Code: Alles auswählen
Structure threadinfo
client.l
hWnd.i
EndStructure
Procedure TestThread(*thi.threadinfo)
Delay(200)
PostMessage_(*thi\hWnd,#WM_USER,*thi\client,Random(3))
FreeMemory(*thi)
EndProcedure
Procedure Main()
Protected hWnd
Protected event
Protected i
Protected *thi.threadinfo
hWnd = OpenWindow(0,#PB_Ignore,#PB_Ignore,200,200,"Test")
If hWnd
ListViewGadget(0,0,0,200,200)
For i = 0 To 10
*thi = AllocateMemory(SizeOf(threadinfo))
If *thi
*thi\hWnd = hWnd
*thi\client = i
CreateThread(@TestThread(),*thi)
EndIf
Next
EndIf
Repeat
event = WaitWindowEvent()
If event = #WM_USER
Select EventlParam()
Case 0
AddGadgetItem(0,-1,"Message 0 an client = " + Str(EventwParam()))
Case 1
AddGadgetItem(0,-1,"Message 1 an client = " + Str(EventwParam()))
Case 2
AddGadgetItem(0,-1,"Message 2 an client = " + Str(EventwParam()))
Case 3
AddGadgetItem(0,-1,"Message 3 an client = " + Str(EventwParam()))
EndSelect
EndIf
Until event = #PB_Event_CloseWindow
EndProcedure:Main()
Guter Vorschlag Edel, die Kommunikation zwischen Main(), den Clientthreads und dem Serverthread per PostMessage zu regeln.
Ist sicher einfacher als über Statusflags innerhalb der globalen Struktur. Zumal fast jeder der Threads eine eigene Eventroutine hat.
PS: Kann der Server-Thread eine Windows-Eventroutine enthalten, auch wenn er kein eigenes Fenster besitzt?
Ist sicher einfacher als über Statusflags innerhalb der globalen Struktur. Zumal fast jeder der Threads eine eigene Eventroutine hat.
PS: Kann der Server-Thread eine Windows-Eventroutine enthalten, auch wenn er kein eigenes Fenster besitzt?
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Hinweis:
Nur bei Windows haben Threads mit erzeugten Fenster ein eigenes Eventhandling. Bei Linux kommt alles am Hauptfenster an.
Nur bei Windows haben Threads mit erzeugten Fenster ein eigenes Eventhandling. Bei Linux kommt alles am Hauptfenster an.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive