BindGadgetEvent und 2. Fenster

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
TheCube
Beiträge: 154
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

BindGadgetEvent und 2. Fenster

Beitrag von TheCube »

Purebasic 6.04 LTS (X64)
Hallo,
auch wenn das Thema vielleicht viele ermüdet, finde ich keine schlanke Lösung und "riskier" mal zu fragen.
Ich möchte als simples Beispiel per BindEvent & Co ein für sich gekapseltes Fenster öffnen (Eine Art "About-Splashwindow"),
das sich nach Zeit (z.B. 10sek.), Window-Klick oder Button-Klick schliesst. Wollte das in ein Include-File auslagern und ggf. wiederverwenden.
Die folgenden Diskussionen (und ein wenig im englischen Forum) habe ich bereits gelesen:
https://www.purebasic.fr/german/viewtop ... =bindevent
https://www.purebasic.fr/german/viewtop ... nt#p355537

Mein Kernproblem ist also wohl, wie ich elegant (und Hauptprogramm-unabhängig) Events im AboutWindow verarbeiten kann.
Hier das lauffähige Einstiegsgerippe, vielleicht hat ja jemand Lust das passend zu ergänzen/ändern,
natürlich würde auch ein Link zu einer ähnlichen Losung völlig reichen.

Code: Alles auswählen

Enumeration
  #MainWindow
  #AboutWindow
EndEnumeration

Enumeration
  #Button_About
  #Button_Send
  #Button_Ok
EndEnumeration

; ----------------------------------------------------------------------------------------
Procedure DoAbout()
  If (OpenWindow(#AboutWindow, 233, 81, 410, 234, ".....", #PB_Window_BorderLess | #PB_Window_ScreenCentered ) )
    ButtonGadget(#Button_Ok, 190, 200, 50, 25, "OK")
    SetWindowColor(#AboutWindow, RGB(50,100,220)) : StickyWindow(#AboutWindow, 1)
    ;
    ; Die Anzeige des #AboutWindow nach 10sek, klick ins Fenster (blauer Bereich) oder OK-Buttton beenden
    ;
    ;CloseWindow(#AboutWindow)
  EndIf  
EndProcedure
; ----------------------------------------------------------------------------------------

OpenWindow(#MainWindow, 0, 0, 600, 400, "Programm-Hauptfenster", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
ButtonGadget(#Button_Send, 350, 370, 80, 25, "Send")
ButtonGadget(#Button_About, 550, 370, 40, 25, "?")
BindGadgetEvent(#Button_About, @DoAbout())

Repeat  ; Hauptschleife "klassisch"
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button_Send : Debug "Send angeklickt!"
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow
Benutzeravatar
jacdelad
Beiträge: 348
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: BindGadgetEvent und 2. Fenster

Beitrag von jacdelad »

Hi,
Fenster öffnen, Timer für dieses Fenster erzeugen und mit BindEvent an eine zweite Funktion binden, die bei Aufruf das Fenster schließt (und den Timer gleich mit). Ich liege allerdings schon im Bett und kann dir das jetzt nicht umsetzen. Mach ich morgen, wenn ich kurz Zeit habe und hier keiner antwortet oder du das schon selbst gemacht hast.

Übrigens beendet dein "Until" das Programm auch, wenn du das About-Fenster schließt. Bau lieber noch ne Abfrage ein, welches Fenster geschlossen werden soll.
Zuletzt geändert von jacdelad am 08.04.2024 20:54, insgesamt 1-mal geändert.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: BindGadgetEvent und 2. Fenster

Beitrag von STARGÅTE »

Solange du im Hauptprogramm eine aktive Event-Schleife hast (was ja der Fall sein sollte), kannst du unabhängig von diesem Hauptprogramm mittels BindGadgetEvent() deinem About-Fenster Ereigniss-Callbacks zuweisen.

Wenn dein DoAbout() kann komplett auf Konstanten verzichtet und das Fenster, alle Gadgets usw. mit #PB_Any erzeugt werden und darauf das Event gebunden wird, gibt es auch keine Kollision mit dem Hauptprogramm.

Alle möglichen Events schreibst du dann einfach als kleine Mini-Prozeduren die dann als Callback aufgerufen werden, wenn das Event ausgelöst wird.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
TheCube
Beiträge: 154
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

Re: BindGadgetEvent und 2. Fenster

Beitrag von TheCube »

Hey danke, ohne Zweifel gute Ideen/Tipps die ich mir morgen noch versuche auch umzusetzen.
Die Erkenntnis das diese vielen kleinen zusätzlichen Callback-Proceduren "normal" sind (und keine Unfähigkeit meinerseits)
ist allein schon was wert.
Ein kleines griffiges Beispiel für ein ggf. kurzlebiges simples Nebenfester, das quasi im komplett in einem Inlude.pbi gehandled wird,
fehlt aber echt noch, besonders wo einige Profis hier gerne über die Vorteile schreiben. <)
Benutzeravatar
jacdelad
Beiträge: 348
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: BindGadgetEvent und 2. Fenster

Beitrag von jacdelad »

Code: Alles auswählen

Enumeration
  #MainWindow
  #AboutWindow
EndEnumeration

Enumeration
  #Button_About
  #Button_Send
  #Button_Ok
EndEnumeration

; ----------------------------------------------------------------------------------------
Procedure CloseDoAbout()
  CloseWindow(#AboutWindow)
EndProcedure

Procedure DoAbout()
  If (OpenWindow(#AboutWindow, 233, 81, 410, 234, ".....", #PB_Window_BorderLess | #PB_Window_ScreenCentered ) )
    ButtonGadget(#Button_Ok, 190, 200, 50, 25, "OK")
    SetWindowColor(#AboutWindow, RGB(50,100,220)) : StickyWindow(#AboutWindow, 1)
    ;
    ; Die Anzeige des #AboutWindow nach 10sek, klick ins Fenster (blauer Bereich) oder OK-Buttton beenden
    ;
    ;CloseWindow(#AboutWindow)
  EndIf
  AddWindowTimer(#AboutWindow,999,10000)
  BindEvent(#PB_Event_Timer,@CloseDoAbout(),#AboutWindow)
  BindGadgetEvent(#Button_OK,@CloseDoAbout(),#PB_EventType_LeftClick)
EndProcedure
; ----------------------------------------------------------------------------------------

OpenWindow(#MainWindow, 0, 0, 600, 400, "Programm-Hauptfenster", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
ButtonGadget(#Button_Send, 350, 370, 80, 25, "Send")
ButtonGadget(#Button_About, 550, 370, 40, 25, "?")
BindGadgetEvent(#Button_About, @DoAbout())

Repeat  ; Hauptschleife "klassisch"
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button_Send : Debug "Send angeklickt!"
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow And EventWindow()=0
Noch ein Hinweis: Wenn dein AboutWindow in mehreren Projekten zum Einsatz kommen soll, dann nutze keine Konstanten als IDs für Fenster und OK-Button (und was sonst noch darin erscheinen soll), sondern dynamisch erzeugte IDs (per #PB_All), sonst kommst du früher oder später in Teufels Küche!
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: BindGadgetEvent und 2. Fenster

Beitrag von mk-soft »

Dafür gibt es Named Enumeration um weiter mit Konstanten zu arbeiten

Beispiel etwas angepasst

Code: Alles auswählen


; ----------------------------------------------------------------------------------------

Enumeration Windows
  #AboutWindow
EndEnumeration

Enumeration Gadgets
  #About_Button_Ok
EndEnumeration

Procedure CloseDoAbout()
  CloseWindow(#AboutWindow)
EndProcedure

Procedure DoAbout()
  If (OpenWindow(#AboutWindow, 233, 81, 410, 234, ".....", #PB_Window_BorderLess | #PB_Window_ScreenCentered ) )
    ButtonGadget(#About_Button_Ok, 190, 200, 50, 25, "OK")
    SetWindowColor(#AboutWindow, RGB(50,100,220)) : StickyWindow(#AboutWindow, 1)
    ;
    ; Die Anzeige des #AboutWindow nach 10sek, klick ins Fenster (blauer Bereich) oder OK-Buttton beenden
    ;
    ;CloseWindow(#AboutWindow)
  EndIf
  AddWindowTimer(#AboutWindow,999,10000)
  BindEvent(#PB_Event_Timer,@CloseDoAbout(),#AboutWindow)
  BindGadgetEvent(#About_Button_OK,@CloseDoAbout(),#PB_EventType_LeftClick)
EndProcedure

; ----------------------------------------------------------------------------------------

Enumeration Windows
  #MainWindow
EndEnumeration

Enumeration Gadgets
  #Main_Button_About
  #Main_Button_Send
EndEnumeration

OpenWindow(#MainWindow, 0, 0, 600, 400, "Programm-Hauptfenster", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
ButtonGadget(#Main_Button_Send, 350, 370, 80, 25, "Send")
ButtonGadget(#Main_Button_About, 550, 370, 40, 25, "?")
BindGadgetEvent(#Main_Button_About, @DoAbout())

Repeat  ; Hauptschleife "klassisch"
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #MainWindow
          Break
      EndSelect
      
    Case #PB_Event_Menu
      Select EventMenu()
          ;
      EndSelect
        
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Main_Button_Send : Debug "Send angeklickt!"
      EndSelect
  EndSelect
  
ForEver
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
TheCube
Beiträge: 154
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

Re: BindGadgetEvent und 2. Fenster

Beitrag von TheCube »

@jacdelad:
Vielen Dank, mit diesem Beispiel (auf eigene Aufgabestellung bezogen) ist endlich der Groschen gefallen.
Habe direkt noch das "klicken" ins blaue Event nachgerüstet. Klappt.
Dann (entsprechend deinem Hinweis) noch auf #PB-Any umgestellt. Scheitert noch an Procedure CloseDoAbout(), siehe Code unten.
@mk-soft:
Named Enumeration ist auch Alternative, wenn es mal nicht total gekapselt sein soll ... schön.

Code: Alles auswählen

Enumeration
  #MainWindow
EndEnumeration

Enumeration
  #Button_About
  #Button_Send
EndEnumeration

; ----------------------------------------------------------------------------------------
Procedure CloseDoAbout()                           ; Einen Parameter kann ich dem Callback ja nicht mitgeben.
  CloseWindow(xxxxx)                   ; !!!!      ; Wie bekomme ich die Window Nr hierhin ? Nur per Global ?
EndProcedure

Procedure DoAbout()
  windownr = OpenWindow(#PB_Any, 233, 81, 410, 234, ".....", #PB_Window_BorderLess | #PB_Window_ScreenCentered )
  If (windownr)  
    butnr = ButtonGadget(#PB_Any, 190, 200, 50, 25, "OK")
    SetWindowColor(windownr, RGB(50,100,220)) : StickyWindow(windownr, 1)
    ; #
    ; #  Hier ggf. noch allerlei anzeigen (Text, Grafik, usw.) ... 
    ; #
  EndIf
  AddWindowTimer(windownr,999,10000)
  BindEvent(#PB_Event_Timer,@CloseDoAbout(),windownr)
  BindGadgetEvent(butnr,@CloseDoAbout(),#PB_EventType_LeftClick)
  BindEvent(#PB_Event_LeftClick, @CloseDoAbout(), windownr)
EndProcedure
; ----------------------------------------------------------------------------------------

OpenWindow(#MainWindow, 0, 0, 600, 400, "Programm-Hauptfenster", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
ButtonGadget(#Button_Send, 350, 370, 80, 25, "Send")
ButtonGadget(#Button_About, 550, 370, 40, 25, "?")
BindGadgetEvent(#Button_About, @DoAbout())

Repeat  ; Hauptschleife "klassisch"
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button_Send : Debug "Send angeklickt!"
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow And EventWindow()=0
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: BindGadgetEvent und 2. Fenster

Beitrag von STARGÅTE »

In der Callback Prozedur kannst du EventWindow() und EventGadget(), etc. nutzen um die jeweiligen Nummer zu erhalten.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
TheCube
Beiträge: 154
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

[Gelöst] BindGadgetEvent und 2. Fenster

Beitrag von TheCube »

Ach danke für den Schubs, na klar. WindowEvent() im Callback "böse", EventWindow() (und Verwandte) "gut".
War mir glatt durchgegangen. :oops:
Für die stillen Mitlesenden: Im letzten Code hier drüber in der Procedure CloseDoAbout() das xxxxx durch EventWindow() ersetzen, fertig.
Antworten