PureBasic: Event-Handler
Dieses Kapitel geht näher auf verschiedenen Arten von Ereignissen (Event) ein und zeigt deren sinnvollen Einsatz
WindowEvent() / WaitWindowEvent()
BearbeitenEs 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
BearbeitenEine 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
BearbeitenUm 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
BearbeitenManchmal 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
BearbeitenSizeWindow 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.