Eventbearbeitung für on-the-fly erzeugte Fenster - wie?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Kurzer
Beiträge: 1618
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Eventbearbeitung für on-the-fly erzeugte Fenster - wie?

Beitrag von Kurzer »

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?
"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.
Little John

Beitrag von 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
Benutzeravatar
Kurzer
Beiträge: 1618
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Little John hat geschrieben:Wie mir in dieser Diskussion erklärt wurde, sollte jeder Thread seine Ereignisse selbst behandeln.
Oh, da steht doch tatsächlich:
PMV hat geschrieben:Für jeden Thread, der Fenster erstellt wird eine Eventschleife benötigt.
Cool, das ist ja genau das, was ich brauche. Irgendwie hab ich bisher was falsches verinnerlicht ("Niemals eine Eventschleife in einem Thread benutzen!" :shock: ).

Werde ich zuhause gleich mal ausprobieren. Danke Little John. :allright:
"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.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> "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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

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.
Benutzeravatar
Kurzer
Beiträge: 1618
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Leider bin ich heute Abend noch nicht so weit, um das zu prüfen. Bin gerade erst an den Rechner gekommen.
Kaeru Gaman hat geschrieben:> "... aber du kannst auch alle Fenster mit PB_Any erzeugen und alle Events in der selben Eventschleife bearbeiten.
Das verwirrt mich jetzt wieder. Heißt das, daß ich Fenster, die ich in einem Thread erzeuge nicht mit #PB_Any erzeugen darf?

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.
Little John

Beitrag von Little John »

Kurzer hat geschrieben:
Kaeru Gaman hat geschrieben:> "... aber du kannst auch alle Fenster mit PB_Any erzeugen und alle Events in der selben Eventschleife bearbeiten.
Das verwirrt mich jetzt wieder. Heißt das, daß ich Fenster, die ich in einem Thread erzeuge nicht mit #PB_Any erzeugen darf?
Nein. #PB_Any geht in jedem Fall ( in any case ;-) ).

Gruß, Little John
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

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()
Benutzeravatar
Kurzer
Beiträge: 1618
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

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?
"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.
Benutzeravatar
mk-soft
Beiträge: 3857
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Hinweis:

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
Antworten