Ereignisorientiertes Programmieren

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Ereignisorientiertes Programmieren

Beitrag von remi_meier »

Zuerst zum Titel: Wenn jemand mit dem Begriff "eventorientiert" nicht
einverstanden ist, bitte per PN! Ich will keine Diskussion hier.

Jetzt zum Code:
Nun, was geht damit: Man registriert seine Fenster, Gadgets und MenuItems
mit diesen Prozeduren. Nun kann man jedem Event, welches zu irgendeinem
Fenster/Gadget/MenuItem gehört, eine Prozedur zuordnen, welche auf-
gerufen wird, wenn das Event eintritt.
Also man registriert zu Events Prozeduren, die bei deren Auftreten aufge-
rufen werden...

Ich glaube, die, welche sich dafür interessieren, verstehen es. :)

Code: Alles auswählen

Structure EOP_MENU 
  *ParentWindow.EOP_WINDOW 
  
  *NextMenu.EOP_MENU 
  *PreviousMenu.EOP_MENU 
  
  MenuItemID.l 
  *fChosen 
EndStructure 

Structure EOP_GADGET_FUNCS 
  *fLeftClick 
  *fRightClick 
  *fLeftDoubleClick 
  *fRightDoubleClick 
  *fFocus 
  *fLostFocus 
  *fChange 
EndStructure 

Structure EOP_GADGET Extends EOP_GADGET_FUNCS 
  *ParentWindow.EOP_WINDOW 
  
  *NextGadget.EOP_GADGET 
  *PreviousGadget.EOP_GADGET 
  
  GadgetID.l 
EndStructure 

Structure EOP_WINDOW_FUNCS 
  *fMenu 
  *fGadget 
  *fCloseWindow 
  *fRepaint 
  *fSizeWindow 
  *fMoveWindow 
EndStructure 

Structure EOP_WINDOW Extends EOP_WINDOW_FUNCS 
  *NextWindow.EOP_WINDOW 
  *PreviousWindow.EOP_WINDOW 
  *CurrentWindow.EOP_WINDOW 
  
  *Gadget.EOP_GADGET 
  *CurrentGadget.EOP_GADGET 
  
  *Menu.EOP_MENU 
  *CurrentMenu.EOP_MENU 
  
  WindowID.l 
EndStructure 




Procedure _EOP_NewGadget() 
  ProcedureReturn AllocateMemory(SizeOf(EOP_GADGET)) 
EndProcedure 

Procedure _EOP_NewMenu() 
  ProcedureReturn AllocateMemory(SizeOf(EOP_MENU)) 
EndProcedure 

Procedure _EOP_NewWindow() 
  ProcedureReturn AllocateMemory(SizeOf(EOP_WINDOW)) 
EndProcedure 


Procedure EOP_AddWindow(*EOP.EOP_WINDOW, Window.l) 
  Protected *p.EOP_WINDOW, *n.EOP_WINDOW 
  
  *p = *EOP\CurrentWindow 
  
  If *p\NextWindow = #Null 
    ; Add 
    *p\NextWindow                 = _EOP_NewWindow() 
    *EOP\CurrentWindow            = *p\NextWindow 
    *p\NextWindow\PreviousWindow  = *p 
    *p\NextWindow\WindowID        = Window 
  Else 
    ; Insert 
    *n = _EOP_NewWindow() 
    *n\PreviousWindow             = *p 
    *n\NextWindow                 = *p\NextWindow 
    *n\WindowID                   = Window 
    
    *p\NextWindow\PreviousWindow  = *n 
    *p\NextWindow                 = *n 
    *EOP\CurrentWindow            = *n 
  EndIf 
  
  ProcedureReturn *p\NextWindow 
EndProcedure 

Procedure EOP_RemoveWindow(*EOP.EOP_WINDOW, Window.l) 
  Protected *Win.EOP_WINDOW, *Gad.EOP_GADGET, *Men.EOP_MENU 
  
  If *EOP\WindowID = Window 
    Debug "Error: You are not allowed to remove the EOP-Window!" 
    ProcedureReturn #False 
  EndIf 
  
  ; Window suchen 
  If *EOP\NextWindow = #Null 
    Debug "Error: This window does not exist!" 
    ProcedureReturn #False 
  EndIf 
  *Win = *EOP\NextWindow 
  While *Win\WindowID <> Window And *Win\NextWindow <> #Null 
    *Win = *Win\NextWindow 
  Wend 
  
  If *Win\WindowID = Window 
    If *EOP\CurrentWindow = *Win\WindowID 
      *EOP\CurrentWindow = *Win\PreviousWindow 
    EndIf 
    
    If *Win\NextWindow <> #Null 
      *Win\NextWindow\PreviousWindow = *Win\PreviousWindow 
    EndIf 
    *Win\PreviousWindow\NextWindow = *Win\NextWindow 
    
    ; Gadget-Liste dieses Fensters löschen 
    If *Win\Gadget 
      *Gad = *Win\Gadget 
      While *Gad\NextGadget 
        *Gad = *Gad\NextGadget 
        If *Gad\PreviousGadget <> #Null 
          FreeMemory(*Gad\PreviousGadget) 
        EndIf 
      Wend 
      FreeMemory(*Gad) 
    EndIf 
    
    ; Menu-Liste dieses Fensters löschen 
    If *Win\Menu 
      *Men = *Win\Menu 
      While *Men\NextMenu 
        *Men = *Men\NextMenu 
        If *Men\PreviousMenu <> #Null 
          FreeMemory(*Men\PreviousMenu) 
        EndIf 
      Wend 
      FreeMemory(*Men) 
    EndIf 
    
    FreeMemory(*Win) 
  Else 
    Debug "Warning: Could not find this window." 
    ProcedureReturn #False 
  EndIf 
  
  ProcedureReturn #True 
EndProcedure 

Procedure EOP_SetCurrentWindow(*EOP.EOP_WINDOW, Window.l) 
  Protected *Win.EOP_WINDOW 
  
  If *EOP\WindowID = Window 
    *EOP\CurrentWindow = *EOP 
    
    ProcedureReturn #True 
  Else 
    
    ; Window suchen 
    If *EOP\NextWindow = #Null 
      ProcedureReturn #False 
    EndIf 
    
    *Win = *EOP\NextWindow 
    While *Win\WindowID <> Window And *Win\NextWindow <> #Null 
      *Win = *Win\NextWindow 
    Wend 
    
    If *Win\WindowID = Window 
      *EOP\CurrentWindow = *Win 
      
      ProcedureReturn #True 
    EndIf 
  EndIf 
  
  ProcedureReturn #False 
EndProcedure 

Procedure EOP_AddGadget(*EOP.EOP_WINDOW, Gadget.l) 
  Protected *p.EOP_WINDOW, *g.EOP_GADGET, *n.EOP_GADGET 
  
  *p = *EOP\CurrentWindow 
  
  *g = *p\CurrentGadget 
  If *g = #Null 
    *p\Gadget         = _EOP_NewGadget() 
    *p\CurrentGadget  = *p\Gadget 
    *g                = *p\Gadget 
    *g\PreviousGadget = #Null 
  Else 
    If *g\NextGadget = #Null 
      ; Adden 
      *g\NextGadget                 = _EOP_NewGadget() 
      *p\CurrentGadget              = *g\NextGadget 
      *g\NextGadget\PreviousGadget  = *g 
      *g                            = *g\NextGadget 
    Else 
      ; Inserten 
      *n                            = *g\NextGadget 
      *g\NextGadget                 = _EOP_NewGadget() 
      *p\CurrentGadget              = *g\NextGadget 
      *g\NextGadget\PreviousGadget  = *g 
      *g                            = *g\NextGadget 
      *g\NextGadget                 = *n 
      *n\PreviousGadget             = *g 
    EndIf 
  EndIf 
  
  *g\ParentWindow = *p 
  *g\GadgetID     = Gadget 
  
  ProcedureReturn *g 
EndProcedure 

Procedure EOP_RemoveGadget(*EOP.EOP_WINDOW, Gadget.l) 
  Protected *Win.EOP_WINDOW, *Gad.EOP_GADGET 
  
  If *EOP <> #Null 
    *Win = *EOP 
    While *Win\NextWindow <> #Null 
      If *Win\Gadget <> #Null 
        ; Gadget in der Liste suchen 
        *Gad = *Win\Gadget 
        While *Gad\GadgetID <> Gadget And *Gad\NextGadget <> #Null 
          *Gad = *Gad\NextGadget 
        Wend 
        
        If *Gad\GadgetID = Gadget 
          If *Gad\NextGadget <> #Null 
            *Gad\NextGadget\PreviousGadget = *Gad\PreviousGadget 
          EndIf 
          If *Gad\PreviousGadget <> #Null 
            *Gad\PreviousGadget\NextGadget = *Gad\NextGadget 
          EndIf 
          If *Win\CurrentGadget = *Gad 
            If *Gad\PreviousGadget <> #Null 
              *Win\CurrentGadget = *Gad\PreviousGadget 
            ElseIf *Gad\NextGadget <> #Null 
              *Win\CurrentGadget = *Gad\NextGadget 
            Else 
              *Win\CurrentGadget = #Null 
            EndIf 
          EndIf 
          
          FreeMemory(*Gad) 
          Break 
        EndIf 
      EndIf 
      
      *Win = *Win\NextWindow 
    Wend 
    
  Else 
    Debug "Error: *EOP - Pointer ist NULL!" 
    ProcedureReturn #False 
  EndIf 
  
  ProcedureReturn #True 
EndProcedure 

Procedure EOP_SetCurrentGadget(*EOP.EOP_WINDOW, Gadget.l) 
  Protected *Win.EOP_WINDOW, *Gad.EOP_GADGET 
  
  If *EOP <> #Null 
    *Win = *EOP 
    While *Win\NextWindow <> #Null 
      If *Win\Gadget <> #Null 
        ; Gadget in der Liste suchen 
        *Gad = *Win\Gadget 
        While *Gad\GadgetID <> Gadget And *Gad\NextGadget <> #Null 
          *Gad = *Gad\NextGadget 
        Wend 
        
        If *Gad\GadgetID = Gadget 
          *EOP\CurrentWindow = *Win 
          *Win\CurrentGadget = *Gad 
          Break 
        EndIf 
      EndIf 
      
      *Win = *Win\NextWindow 
    Wend 
    
  Else 
    Debug "Error: *EOP - Pointer ist NULL!" 
    ProcedureReturn #False 
  EndIf 
EndProcedure 

Procedure EOP_AddMenuItem(*EOP.EOP_WINDOW, MenuItem.l, *CallProcAddress) 
  Protected *p.EOP_WINDOW, *m.EOP_MENU, *n.EOP_MENU 
  
  *p = *EOP\CurrentWindow 
  
  *m = *p\CurrentMenu 
  If *m = #Null 
    *p\Menu         = _EOP_NewMenu() 
    *p\CurrentMenu  = *p\Menu 
    *m              = *p\Menu 
    *m\PreviousMenu = #Null 
  Else 
    If *m\NextMenu = #Null 
      ; Adden 
      *m\NextMenu               = _EOP_NewMenu() 
      *p\CurrentMenu            = *m\NextMenu 
      *m\NextMenu\PreviousMenu  = *m 
      *m                        = *m\NextMenu 
    Else 
      ; Inserten 
      *n                        = *m\NextMenu 
      *m\NextMenu               = _EOP_NewMenu() 
      *p\CurrentMenu            = *m\NextMenu 
      *m\NextMenu\PreviousMenu  = *m 
      *m                        = *m\NextMenu 
      *m\NextMenu               = *n 
      *n\PreviousMenu           = *m 
    EndIf 
  EndIf 
  
  *m\ParentWindow = *p 
  *m\MenuItemID   = MenuItem 
  *m\fChosen      = *CallProcAddress 
  
  ProcedureReturn *m 
EndProcedure 

Procedure EOP_RemoveMenuItem(*EOP.EOP_WINDOW, MenuItem.l) 
  Protected *Win.EOP_WINDOW, *Men.EOP_MENU 
  
  If *EOP <> #Null 
    *Win = *EOP 
    While *Win\NextWindow <> #Null 
      If *Win\Menu <> #Null 
        ; Menu in der Liste suchen 
        *Men = *Win\Menu 
        While *Men\MenuItemID <> MenuItem And *Men\NextMenu <> #Null 
          *Men = *Men\NextMenu 
        Wend 
        
        If *Men\MenuItemID = MenuItem 
          If *Men\NextMenu <> #Null 
            *Men\NextMenu\PreviousMenu = *Men\PreviousMenu 
          EndIf 
          If *Men\PreviousMenu <> #Null 
            *Men\PreviousMenu\NextMenu = *Men\NextMenu 
          EndIf 
          If *Win\CurrentMenu = *Men 
            If *Men\PreviousMenu <> #Null 
              *Win\CurrentMenu = *Men\PreviousMenu 
            ElseIf *Men\NextMenu <> #Null 
              *Win\CurrentMenu = *Men\NextMenu 
            Else 
              *Win\CurrentMenu = #Null 
            EndIf 
          EndIf 
          
          FreeMemory(*Men) 
          Break 
        EndIf 
      EndIf 
      
      *Win = *Win\NextWindow 
    Wend 
    
  Else 
    Debug "Error: *EOP - Pointer ist NULL!" 
    ProcedureReturn #False 
  EndIf 
  
  ProcedureReturn #True 
EndProcedure 

Procedure EOP_SetCurrentMenuItem(*EOP.EOP_WINDOW, MenuItem.l) 
  Protected *Win.EOP_WINDOW, *Men.EOP_MENU 
  
  If *EOP <> #Null 
    *Win = *EOP 
    While *Win\NextWindow <> #Null 
      If *Win\Menu <> #Null 
        ; Menu in der Liste suchen 
        *Men = *Win\Menu 
        While *Men\MenuItemID <> MenuItem And *Men\NextMenu <> #Null 
          *Men = *Men\NextMenu 
        Wend 
        
        If *Men\MenuItemID = MenuItem 
          *EOP\CurrentWindow = *Win 
          *Win\CurrentMenu   = *Men 
          Break 
        EndIf 
      EndIf 
      
      *Win = *Win\NextWindow 
    Wend 
    
  Else 
    Debug "Error: *EOP - Pointer ist NULL!" 
    ProcedureReturn #False 
  EndIf 
EndProcedure 

Procedure EOP_RegisterMenuItemFunction(*EOP.EOP_WINDOW, *CallProcAddress) 
  *EOP\CurrentMenu\fChosen = *CallProcAddress 
EndProcedure 

Procedure EOP_RegisterGadgetFunctions(*EOP.EOP_WINDOW, *Funcs.EOP_GADGET_FUNCS) 
  *EOP\CurrentGadget\fLeftClick         = *Funcs\fLeftClick 
  *EOP\CurrentGadget\fRightClick        = *Funcs\fRightClick 
  *EOP\CurrentGadget\fLeftDoubleClick   = *Funcs\fLeftDoubleClick 
  *EOP\CurrentGadget\fRightDoubleClick  = *Funcs\fRightDoubleClick 
  *EOP\CurrentGadget\fFocus             = *Funcs\fFocus 
  *EOP\CurrentGadget\fLostFocus         = *Funcs\fLostFocus 
  *EOP\CurrentGadget\fChange            = *Funcs\fChange 
EndProcedure 

Procedure EOP_RegisterWindowFunctions(*EOP.EOP_WINDOW, *Funcs.EOP_WINDOW_FUNCS) 
  *EOP\CurrentWindow\fMenu        = *Funcs\fMenu 
  *EOP\CurrentWindow\fGadget      = *Funcs\fGadget 
  *EOP\CurrentWindow\fCloseWindow = *Funcs\fCloseWindow 
  *EOP\CurrentWindow\fRepaint     = *Funcs\fRepaint 
  *EOP\CurrentWindow\fSizeWindow  = *Funcs\fSizeWindow 
  *EOP\CurrentWindow\fMoveWindow  = *Funcs\fMoveWindow 
EndProcedure 


; Returns Pointer to EOP_WINDOW -> *EOP 
Procedure EOP_Create(Window.l) 
  Protected *p.EOP_WINDOW 
  
  *p = _EOP_NewWindow() 
  *p\NextWindow     = #Null 
  *p\PreviousWindow = #Null 
  *p\CurrentWindow  = *p 
  *p\Gadget         = #Null 
  *p\CurrentGadget  = #Null 
  *p\Menu           = #Null 
  *p\WindowID       = Window 
  
  ProcedureReturn *p 
EndProcedure 

Procedure EOP_Delete(*EOP.EOP_WINDOW) 
  Protected *Win.EOP_WINDOW, *Gad.EOP_GADGET, *Men.EOP_MENU 
  
  If *EOP\NextWindow <> #Null 
    
    *Win = *EOP\NextWindow 
    While *Win\NextWindow <> #Null 
      
      ; Gadget-Liste dieses Fensters löschen 
      If *Win\Gadget 
        *Gad = *Win\Gadget 
        While *Gad\NextGadget 
          *Gad = *Gad\NextGadget 
          If *Gad\PreviousGadget <> #Null 
            FreeMemory(*Gad\PreviousGadget) 
          EndIf 
        Wend 
        FreeMemory(*Gad) 
      EndIf 
      
      ; Menu-Liste dieses Fensters löschen 
      If *Win\Menu 
        *Men = *Win\Menu 
        While *Men\NextMenu 
          *Men = *Men\NextMenu 
          If *Men\PreviousMenu <> #Null 
            FreeMemory(*Men\PreviousMenu) 
          EndIf 
        Wend 
        FreeMemory(*Men) 
      EndIf 
      
      *Win = *Win\NextWindow 
      FreeMemory(*Win\PreviousWindow) 
    Wend 
    FreeMemory(*Win\PreviousWindow) 
  Else 
    FreeMemory(*EOP) 
  EndIf 
  
EndProcedure 

Procedure EOP_ProcessEvents(*EOP.EOP_WINDOW, WindowEvent.l, WindowID.l, GadgetID.l, MenuItemID.l, EventType.l) 
  Protected *Win.EOP_WINDOW, *Gad.EOP_GADGET, *Men.EOP_MENU 
  
  ; Fenster finden 
  If *EOP = #Null 
    ProcedureReturn WindowEvent 
  EndIf 
  
  *Win = *EOP 
  While *Win\WindowID <> WindowID And *Win\NextWindow <> #Null 
    *Win = *Win\NextWindow 
  Wend 
  
  If *Win\WindowID = WindowID 
    Select WindowEvent 
      Case #PB_Event_Menu 
        If *Win\fMenu <> #Null 
          CallFunctionFast(*Win\fMenu) 
        EndIf 
      Case #PB_Event_Gadget 
        If *Win\fGadget <> #Null 
          CallFunctionFast(*Win\fGadget) 
        EndIf 
      Case #PB_Event_CloseWindow 
        If *Win\fCloseWindow <> #Null 
          CallFunctionFast(*Win\fCloseWindow) 
        EndIf 
      Case #PB_Event_Repaint 
        If *Win\fRepaint <> #Null 
          CallFunctionFast(*Win\fRepaint) 
        EndIf 
      Case #PB_Event_SizeWindow 
        If *Win\fSizeWindow <> #Null 
          CallFunctionFast(*Win\fSizeWindow) 
        EndIf 
      Case #PB_Event_MoveWindow 
        If *Win\fMoveWindow <> #Null 
          CallFunctionFast(*Win\fMoveWindow) 
        EndIf 
    EndSelect 
    
    ; Gadget finden 
    If *Win\Gadget = #Null 
      ProcedureReturn WindowEvent 
    EndIf 
    
    *Gad = *Win\Gadget 
    While *Gad\GadgetID <> GadgetID And *Gad\NextGadget <> #Null 
      *Gad = *Gad\NextGadget 
    Wend 
    
    If *Gad\GadgetID = GadgetID 
      Select EventType 
        Case #PB_EventType_LeftClick 
          If *Gad\fLeftClick <> #Null 
            CallFunctionFast(*Gad\fLeftClick) 
          EndIf 
        Case #PB_EventType_RightClick 
          If *Gad\fRightClick <> #Null 
            CallFunctionFast(*Gad\fRightClick) 
          EndIf 
        Case #PB_EventType_LeftDoubleClick 
          If *Gad\fLeftDoubleClick <> #Null 
            CallFunctionFast(*Gad\fLeftDoubleClick) 
          EndIf 
        Case #PB_EventType_RightDoubleClick 
          If *Gad\fRightDoubleClick <> #Null 
            CallFunctionFast(*Gad\fRightDoubleClick) 
          EndIf 
        Case #PB_EventType_Focus 
          If *Gad\fFocus <> #Null 
            CallFunctionFast(*Gad\fFocus) 
          EndIf 
        Case #PB_EventType_LostFocus 
          If *Gad\fLostFocus <> #Null 
            CallFunctionFast(*Gad\fLostFocus) 
          EndIf 
        Case #PB_EventType_Change 
          If *Gad\fChange <> #Null 
            CallFunctionFast(*Gad\fChange) 
          EndIf 
      EndSelect 
    EndIf 
    
    ; Menu finden 
    If *Win\Menu = #Null 
      ProcedureReturn WindowEvent 
    EndIf 
    
    *Men = *Win\Menu 
    While *Men\MenuItemID <> MenuItemID And *Men\NextMenu <> #Null 
      *Men = *Men\NextMenu 
    Wend 
    
    If *Men\MenuItemID = MenuItemID 
      If *Men\fChosen <> #Null 
        CallFunctionFast(*Men\fChosen) 
      EndIf 
    EndIf 
  EndIf 
  
  
  ProcedureReturn WindowEvent 
EndProcedure 

Procedure EOP_WindowEvent(*EOP.EOP_WINDOW) 
  Protected WindowEvent.l, WindowID.l, GadgetID.l, MenuItemID.l, EventType.l 
  
  WindowEvent = WindowEvent() 
  WindowID    = EventWindowID() 
  GadgetID    = EventGadgetID() 
  MenuItemID  = EventMenuID() 
  EventType   = EventType() 
  ProcedureReturn EOP_ProcessEvents(*EOP.EOP_WINDOW, WindowEvent, WindowID.l, GadgetID.l, MenuItemID.l, EventType.l) 
EndProcedure 

Procedure EOP_WaitWindowEvent(*EOP.EOP_WINDOW) 
  Protected Res.l 
  
  Repeat 
    Delay(2) 
    Res = EOP_WindowEvent(*EOP.EOP_WINDOW) 
  Until Res 
  
  ProcedureReturn Res 
EndProcedure 


; Die Datenstruktur: 
; Kleine Zeichnung: 
; Ich nenne diese Struktur später einfach EOP-Tree 
; 
; Window0-----------------Window1-----------------Window2----------. . . . 
;   |    \               /    \                      | 
; Menu1   Gadget1     Menu3   Gadget3             Gadget4 
;   |        |          | 
; Menu2   Gadget2     Menu4 
;   |        | 
;   .        . 
;   .        . 
;   .        . 
; 
; 
; Funktionsreferenz: 
; 
; *EOP.EOP_WINDOW = EOP_Create(Window.l) 
; Diese Funktion erstellt das erste Objekt "Window0" und 
; verknüpft es mit dem 1. Fenster, dem Hauptfenster, 
; welches über Window identifiziert wird. 
; Sie gibt den Pointer zum 1. Element des EOP-Trees zurück, 
; von diesem 1. Element an wird alles koordiniert, jede 
; EOP-Funktion verlangt diesen Pointer, ausser EOP_Create 
; und die intern benutzen _EOP_New***(). Dieser Pointer wird 
; auch von keiner Funktion verändert! 

; EOP_Delete(*EOP.EOP_WINDOW) 
; Diese Funktion löscht den ganzen EOP-Tree, identifiziert 
; durch den Pointer *EOP auf das 1. Element. 

; EOP_SetCurrentWindow(*EOP.EOP_WINDOW, Window.l) 
; Setzt das Fenster "Window.l" als aktuelles Fenster. D.h. 
; alle EOP_Add***() werden auf dieses Fenster angewendet und 
; bei z.B. EOP_AddWindow() wird das neue Fenster hinter dem 
; aktuellen eingesetzt. 

; EOP_SetCurrentMenuItem/Gadget() 
; bewirken das gleiche wie EOP_SetCurrentWindow() einfach für 
; die Gadgets und MenuItems! So können nachträglich die Event- 
; Funktionen eines Gadgets/MenuItems geändert werden. 

; EOP_AddWindow(*EOP.EOP_WINDOW, Window.l) 
; Diese Funktion funktioniert etwa gleich wie EOP_Create(), 
; nur dass sie nicht einen neuen EOP-Tree generiert, sondern 
; einfach ein neues Fenster dem Baum hinzufügt, EOP_AddGadget() 
; und EOP_AddMenu() sind dieser Funktion untergeordnet! Diese 
; Funktion setzt das aktuelle Fenster auf das neu hinzugefügte 
; und die beiden Funktionen für Menu und Gadget fügen dann die 
; Gadgets dort hinzu. 

; EOP_AddGadget(*EOP.EOP_WINDOW, Gadget.l) 
; Diese Funktion fügt ein neues Gadget zum aktuellen Fenster hinzu. 
; Gadget.l ist das PB-Handle für ein Gadget, z.B. #Button_0 

; EOP_AddMenuItem(*EOP.EOP_WINDOW, MenuItem.l, *CallProcAddress) 
; Diese Funktion fügt ein neues MenuItem zum aktuellen Fenster 
; hinzu. 
; MenuItem.l ist das PB-Handle für einen Menu-Eintrag 
; *CallProcAddress ist die Adresse der Prozedur, die aufgerufen 
; werden soll, wenn dieser Menu-Eintrag ausgewählt wurde. 

; EOP_Remove***(*EOP.EOP_WINDOW, ***.l) 
; Diese Funktionen entfernen das Gadget/MenuItem/Window aus 
; dem EOP-Tree. Bei Window werden alle dazugehörigen Gadgets 
; und MenuItems auch entfernt. 

; EOP_RegisterGadgetFunctions(*EOP.EOP_WINDOW, *Funcs.EOP_GADGET_FUNCS) 
; Diese Funktion registriert zum aktuellen Gadget (das zuletzt 
; hinzugefügte) die Funktionen, die bei den verschiedenen Events 
; aufgerufen werden sollen. 
; Dazu muss die folgende Sturktur EOP_GADGET_FUNCS übergeben werden: 
; Structure EOP_GADGET_FUNCS 
;   *fLeftClick 
;   *fRightClick 
;   *fLeftDoubleClick 
;   *fRightDoubleClick 
;   *fFocus 
;   *fLostFocus 
;   *fChange 
; EndStructure 
; 
; Diese Pointer müssen mit den Adressen zu Funktionen gefüllt werden. 
; Wenn zu einem Event keine Funktion gewählt werden soll, muss der 
; Pointer auf #NULL gestellt werden. 
; ACHTUNG! Diese Funktionen dürfen keine Parameter erwarten! 

; EOP_RegisterWindowFunctions(*EOP.EOP_WINDOW, *Funcs.EOP_WINDOW_FUNCS) 
; Dies ist die analoge Funktion zu den Window-Events. 
; Und EOP_RegisterMenuItemFunction() setzt auch die Aufruffunktion für 
; den aktuellen Menu-Eintrag. 

; EOP_WaitWindowEvent(*EOP.EOP_WINDOW) 
; und EOP_WindowEvent(*EOP.EOP_WINDOW) 
; sind die Funktionen, die die gleichen Aufgaben erfüllen, wie die von 
; PB, mit dem Unterschied, dass sie, bevor sie das Event zurückgeben, 
; noch die dazugehörige, registrierte Funktion aufrufen. 

; EOP_ProcessEvents(*EOP.EOP_WINDOW, WindowEvent.l, WindowID.l, GadgetID.l, 
;                                                MenuItemID.l, EventType.l) 
; Hier kann man das Event direkt übergeben, anstatt z.B. EOP_WindowEvent() 
; zu benutzen. Z.B. wenn man mehrere EOP-Trees hat oder man ein Event 
; auslösen will. 

; #################################################################### 
; Was muss also gemacht werden: 
; 
; 1.) Window erstellen (mit OpenWindow) 
; 2.) Neuer EOP-Tree erstellen (beliebig viele) 
;     *EOP = EOP_Create(Window.l) 
; 3.) CreateGadgetList() 
; 4.) Gadgets erstellen (z.B. ButtonGadget(1, ...)) 
; 4.) Gadget zum EOP-Tree hinzufügen EOP_AddGadget(*EOP, 1) 
; 5.) Die Struktur für die Funktion EOP_RegisterGadgetFunctions() 
;     mit Pointern auf Funktionen füllen. 
; 6.) EOP_RegisterGadgetFunctions() 
; 7.) Die Schleife, z.B.: 
;     Repeat 
;     Until EOP_WaitWindowEvent(*EOP) = #PB_Event_CloseWindow 
; 8.) EOP_Delete(*EOP) 

; Man kann auch beliebig viele EOP-Trees erstellen. Dazu muss dann 
; aber die Event-Schleife geändert werden, z.B.: 
; Repeat 
;   Event = EOP_WaitWindowEvent(*EOP1) 
;   EOP_ProcessEvents(*EOP2, Event, 0, 0, 0, 0) 
;   EOP_ProcessEvents(*EOP3, Event, 0, 0, 0, 0) 
; Until Event = #PB_Event_CloseWindow
Beispiel:

Code: Alles auswählen

XIncludeFile "EOPInclude.pbi" 

Global *EOP.EOP_WINDOW 

Procedure.s StrRep(s.s, Anz.l) 
  Protected z.l, n.s 
  
  For z = 1 To Anz 
    n + s 
  Next 
  
  ProcedureReturn n 
EndProcedure 

Procedure O_o() 
  Static s.l 
  If s = 0 
    v.s = "O_o hast du auf OK geklickt!?" 
  ElseIf s = 1 
    v.s = "Schooon wieder? Was willste denn von mir?" 
  ElseIf s = 2 
    v.s = "Du nervst! Geh sterben!" 
  ElseIf s = 3 
    v.s = "-_-*" 
  ElseIf s < 9 
    v.s = "Nag" + StrRep("o", s*3) + "t, ich mach dir nen neuen Dummy!" 
    ButtonGadget(s, (s - 3) * 55 + 5, (s - 3) * 55 + 5, 50, 50, "OK") 
    EOP_AddGadget(*EOP, s) 
    b.EOP_GADGET_FUNCS\fLeftClick = @O_o() 
    EOP_RegisterGadgetFunctions(*EOP, @b) 
  Else 
    v.s = "Vergiss es..." 
  EndIf 
  MessageRequester("°_°", v) 
  
  s + 1 
EndProcedure 

OpenWindow(0, 200,200, 500,500, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "EOP") 
CreateGadgetList(WindowID()) 
ButtonGadget(1, 5,5, 50,50, "OK") 

*EOP = EOP_Create(0) 

Button1.EOP_GADGET_FUNCS\fLeftClick = @O_o() 
EOP_AddGadget(*EOP, 1) 
EOP_RegisterGadgetFunctions(*EOP, @Button1) 

Repeat 
  
Until EOP_WaitWindowEvent(*EOP) = #PB_Event_CloseWindow 

EOP_Delete(*EOP)
AdvancedGadgetEvents(#True) nicht vergessen, wenn man z.B. beim
Buttongadget den Rechtsklick abfangen will!

Das alles ist noch relativ wenig getestet, also bitte nicht gleich ausrasten :wink:

greetz
Remi :)
Zuletzt geändert von remi_meier am 10.08.2005 14:46, insgesamt 1-mal geändert.
Benutzeravatar
freedimension
Admin
Beiträge: 1987
Registriert: 08.09.2004 13:19
Wohnort: Ludwigsburg
Kontaktdaten:

Re: Eventorientiertes Programmieren

Beitrag von freedimension »

Was soll ich sagen, genial :allright:
remi_meier hat geschrieben:Zuerst zum Titel: Wenn jemand mit dem Begriff "eventorientiert" nicht
einverstanden ist, bitte per PN! Ich will keine Diskussion hier.
Du glaubst doch nicht wirklich, dass du so billig davon kommst.
Ich hätte ja "event driven" dazu gesagt ... ;)


... aber eventorientiert bzw. ereignisorientiert geht latürnich auch in Ordnung :)
Beginne jeden Tag als ob es Absicht wäre!
Bild
BILDblog
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Du glaubst doch nicht wirklich, dass du so billig davon kommst.
Ich hätte ja "event driven" dazu gesagt ...
... aber eventorientiert bzw. ereignisorientiert geht latürnich auch in Ordnung
^^
Naja, mindestens hab ich jetzt noch kurz von Eventorientiert nach Ereignis-
orientiert gewechselt, da so Deutsch-Englisch-Mischungen nicht gerade
gut für mein Auge sind :roll:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

BildSehr interessante Sache
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
bluejoke
Beiträge: 1244
Registriert: 08.09.2004 16:33
Kontaktdaten:

Beitrag von bluejoke »

:allright: Danke für diese Arbeit
Ich bin Ausländer - fast überall
Windows XP Pro SP2 - PB 4.00
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

cool ... vielen dank für den Gedankenanstoß ... da wäre ich wohl selber nicht drauf gekommen ... :allright: ... hab ich mir mal gleich notiert :D

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
fsw
Beiträge: 74
Registriert: 12.09.2004 03:31
Wohnort: North by Northwest

Beitrag von fsw »

Endlich jemand der versteht das event-driven gui's besser sind. :allright:

Auf PureArea ist seit jahren eine library von mir die auch event-driven coding moeglich macht.

Hier das prinzip:

http://forums.purebasic.com/english/vie ... 0&start=15

Es zeigt wie event-driven coding mit wenig code moeglich ist.
Antworten