PureBasic: Event-Handler

Aus Wikibooks

Dieses Kapitel geht näher auf verschiedenen Arten von Ereignissen (Event) ein und zeigt deren sinnvollen Einsatz

WindowEvent() / WaitWindowEvent()[Bearbeiten]

Es gibt zwei Funktionen, mit welchen ein Ereignis abgefragt werden kann. Diese sind WindowEvent() und WaitWindowEvent(), wobei der einzige Unterschied darin besteht, das WaitWindowEvent() darauf wartet bis etwas geschieht und erst dann einen Wert ausgibt, während WindowEvent() bei jedem Aufruf entweder das Event, oder solange nichts passiert ist, den Wert '0' zurück gibt. WindowEvent() sollte vermieden werden, da das Programm auch wenn es nicht benutzt wird die CPU stark belastet. Die Funktion WaitWindowEvent() unterstützt den optionalen Parameter 'timeout' welcher zulässt das das Programm mit geringer CPU Auslastung Berechnungen durchführen kann.

; Listing 39: WindowEvent

OpenWindow(0,0,0,400,200,"Uhr",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
TextGadget(0,0,100,400,20,"",#PB_Text_Center)
Repeat
  
  Select WaitWindowEvent(20)
    Case #PB_Event_CloseWindow
      End
  EndSelect
  
  SetGadgetText(0,FormatDate("%hh:%ii:%ss",Date()))

ForEver


Der Timeout wurde hier auf 20 Millisekunden gesetzt, das heißt wenn das Programm 20ms gewartet hat gibt es wie WindowEvent() eine 0 zurück. Diese Variante hat gegenüber einer Kombination aus WindowEvent() und Delay(20) den Vorteil, das sollte vor Ablauf der 20ms etwas passieren, z.B. es wird ein Button gedrückt, kann das Programm sofort reagieren und muss nicht erst noch die 20ms abwarten bis es wieder etwas machen kann. FormatDate wird verwendet, um auf einfache Weise ein Datumswert in verständlicher Weise als String darzustellen.

Timer[Bearbeiten]

Eine Möglichkeit regelmäßig wiederkehrende Aufgaben zu erledigen sind Timer.

; Listing 40: Timer

OpenWindow(0,0,0,400,100,"Timer",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

TextGadget(0,0, 0,400,20,"Dieses Programm ist nun seit")
TextGadget(1,0,20,400,20,"")
TextGadget(2,0,40,400,20,"Sekunden aktiv")

AddWindowTimer(0,0,1000)

Repeat
  
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Timer
      sekunden+1
      SetGadgetText(1,Str(sekunden))
  EndSelect
  
ForEver

Durch AddWindowTimer wird im Abstand von 1000ms einmal das Event #PB_Event_Timer aufgerufen.

; Listing 41: Timer vs WaitWindowEvent

OpenWindow(0,0,0,400,100,"Timer",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

TextGadget(0,0, 0,400,40,"Fahre mit der Maus über das Fenster um den unterschied zwischen Timer und WaitWindowEvent mit timeout zu sehen")
TextGadget(1,0,40,400,20,"")

Repeat
  
  Select WaitWindowEvent(1000)
    Case #PB_Event_CloseWindow
      End
  EndSelect
  counter+1
  SetGadgetText(1,Str(counter))
  
ForEver

In diesem Beispiel steigt der Counter einmal pro Sekunde, solange das Fenster inaktiv ist. Sobald etwas mit dem Fenster gemacht wird liefert WaitWindowEvent einen Rückgabewert und muss nicht mehr auf den Ablauf der 1000ms warten. Daher wird der Counter schon vor Ablauf der Sekunde um eins erhöht werden.

EventGadget[Bearbeiten]

Um mehrere verschiedene Gadgets benutzen zu können benötigt man wie schon in GUI-Programmierung beschrieben EventGadget(). Sollte man wie es in größeren Programmen üblich ist mehrere Gadgets auf einem Fenster haben bietet es sich an diese auch über ein Select/Case zu verwalten.

; Listing 42: EventGadget

OpenWindow(0, 0, 0, 200, 200, "EventType", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
StringGadget(0, 0, 0, 200, 20, "Schreibe irgendwas")
TextGadget(1, 0, 20, 200, 20, "Der Text hat 18 Zeichen")
TextGadget(2, 0, 50, 200, 20, "Lösche durch Klicken:")
ListViewGadget(3, 0, 70, 200, 130)
For x=0 To 20
  AddGadgetItem(3,x,"Element "+Str(x))
Next

Repeat
  Select WindowEvent()
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Gadget
      
      Select EventGadget()
        Case 0
          SetGadgetText(1,"Der Text hat "+Str(Len(GetGadgetText(0)))+" Zeichen")
          
        Case 3
          RemoveGadgetItem(3,GetGadgetState(3))
          
      EndSelect
      
  EndSelect
ForEver

Das ListViewGadget ist eine Art Container in dem eine beliebige Anzahl an Strings gespeichert werden kann. Durch die Funktion AddGadgetItem kann ein neues Element hinzugefügt und der RemoveGadgetItem wieder gelöscht werden. Wenn ein Element ausgewählt ist kann wie beim StringGadget der Text des Elementes über GetGadgetText ausgelesen werden.

EventType[Bearbeiten]

Manchmal ist es nützlich verschiedene Aktionen des Benutzers unterscheiden zu können. So kann es durchaus vorkommen das bei einem Rechtsklick oder einem Doppelklick etwas anderes geschehen soll als bei einem normalen Links klick. Hierfür kann man EventType benutzen.

Hinweis: EventType ist nicht für alle Gadgets verfügbar, welche das sind entnehmen Sie bitte aus dem Referenz Handbuch.

; Listing 43: EventType

OpenWindow(0, 0, 0, 200, 200, "EventType", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
StringGadget(0, 0, 0, 200, 20, "Schreibe irgendwas")
TextGadget(1, 0, 20, 200, 20, "Der Text hat 18 Zeichen")
TextGadget(2, 0, 50, 200, 20, "Lösche nur duch Doppelklick:")
ListViewGadget(3, 0, 70, 200, 130)
For x=0 To 20
  AddGadgetItem(3,x,"Element "+Str(x))
Next

Repeat
  Select WindowEvent()
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Gadget
      
      Select EventGadget()
        Case 0
          Select EventType()
            Case #PB_EventType_Change
              SetGadgetText(1,"Der Text hat "+Str(Len(GetGadgetText(0)))+" Zeichen")
              
            Case #PB_EventType_Focus
              SetGadgetText(0,"")
              SetGadgetText(1,"Der Text hat "+Str(Len(GetGadgetText(0)))+" Zeichen")
              
          EndSelect
          
        Case 3
          Select EventType()
            Case #PB_EventType_LeftDoubleClick
              RemoveGadgetItem(3,GetGadgetState(3))
          EndSelect
          
      EndSelect
      
  EndSelect
ForEver

In diesem Beispiel wird gegenüber Listing 42 unterschieden was genau der Benutzer mit dem Gadget macht. So wird im StringGadget nicht nur gezählt wie viele Zeichen in dem StringGadget enthalten sind, sondern es wird beim anklicken der vorherige Inhalt gelöscht.

EventMenu[Bearbeiten]

; Listing 44: EventMenu

OpenWindow(0, 0, 0, 200, 200, "EventMenu", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateMenu(0,WindowID(0))
MenuTitle("Datei")
MenuItem(0,"Neu")
MenuItem(2,"Einstellungen")
MenuItem(3,"Beenden")
MenuTitle("?")
MenuItem(4,"Hilfe")

CreateToolBar(0,WindowID(0))
ToolBarStandardButton(0,#PB_ToolBarIcon_New)
ToolBarStandardButton(1,#PB_ToolBarIcon_Help)
ToolBarStandardButton(3,#PB_ToolBarIcon_Delete)

Repeat
  Select WindowEvent()
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Menu
      
      Select EventMenu()
        Case 0
          MessageRequester("Neu","Es wurde 'Neu' angeklickt!")
        Case 1
          MessageRequester("Hilfe","Es wurde 'Hilfe' angeklickt!")
        Case 2
          MessageRequester("Einstellungen","Es wurde 'Einstellungen' angeklickt!")
        Case 3
          MessageRequester("Beenden","Es wurde 'Beenden' angeklickt!")
        Case 4
          MessageRequester("Hilfe","Es wurde 'Hilfe' angeklickt!")
      EndSelect
      
  EndSelect
ForEver

Durch CreateMenu wird eine neue Menüleiste im durch WindowID bestimmten Fenster erstellt. Diese Werden durch den Befehl MenuTitle in einzelne Gruppen untergliedert, welche einzelne Elemente (MenuItem) enthalten. Ähnlich wie bei den Gadgets werden hier Konstanten verwendet mit denen die einzelnen Elemente später über EventMenu identifiziert werden können. Jedoch unterscheiden sich MenuItems von Gadgets in zwei Punkten. Erstens darf hier nicht der Wert #PB_Any verwendet werden, und zweitens können die Konstanten hier mehrfach vorkommen. Es muss aber beachtet werden, dass die MenuID für alle Elemente dieselbe Funktion hat, da nicht unterschieden wird ob ein Menü über die Menüleiste oder über die Toolbar aktiviert worden ist.

SizeWindow[Bearbeiten]

SizeWindow ist nützlich wenn das Fenster in der Größe verändert wurde, z.B. Maximiert, und der Inhalt automatisch angepasst werden soll.

; Listing 45: SizeWindow

OpenWindow(0, 0, 0, 200, 200, "SizeWindow", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
WindowBounds(0, 200, 200, #PB_Ignore, #PB_Ignore)
ListViewGadget(0, 0, 0, 200, 180)
ButtonGadget(1, 0, 180, 200, 20, "Beenden")
For x=0 To 50
  AddGadgetItem(0,x,"Element "+Str(x))
Next

Repeat
  Select WindowEvent()
    Case #PB_Event_CloseWindow
      End
      
    Case #PB_Event_SizeWindow
      ResizeGadget(0,0,0,WindowWidth(0),WindowHeight(0)-20)
      ResizeGadget(1,WindowWidth(0)/2-100,WindowHeight(0)-20,200,20)
      
    Case #PB_Event_Gadget
      
      Select EventGadget()
        Case 0
          End
          
      EndSelect
      
  EndSelect
ForEver

Die Parameter #PB_Window_MaximizeGadget und #PB_Window_SizeGadget werden benötigt um dem Benutzer das Ändern der Fenstergröße zu erlauben. Mit WindowBounds wird sichergestellt, das der Benutzer das Fenster nicht kleiner als 200x200 Pixel verkleinern kann, da der Inhalt dann nicht mehr übersichtlich dargestellt werden kann. Durch ResizeGadget kann die Größe und Position des Gadgets verändert werden. Die Position zu verändern kann in solchen Fällen nützlich sein, wenn ein Button an der Unterseite des Fensters fixiert, aber nicht die Größe verändert werden soll.