Wie baut man einen Programmablauf in Pure Basic richtig auf?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Das Auge nimmt ja eh nicht alle Änderungen sofort wahr ...
Also ist es blödsinn, bei jedem Durchlauf die Gadgets neu zu füllen.
Und PB bietet ja einen hübschen Timer ... also kann man es auch damit
lösen *gg*

Und für deine Tastatur gibs auch was in PB :wink:
Also das wäre mein Vorschlag :mrgreen:

Code: Alles auswählen

; Konstanten definieren
#AnzahlRechnungen = 3

Enumeration
  #Summand0Down
  #Summand0Up
  #Summand1Down
  #Summand1Up
  #Summand2Down
  #Summand2Up
EndEnumeration
; ---------------------------
; Variablen definieren 
Global Dim Zahl.d(#AnzahlRechnungen - 1) ;die gespeicherten Zahlen
Zahl(0) = 0
Zahl(1) = 0
Zahl(2) = 0

Global Dim Summand.d(#AnzahlRechnungen - 1) ;die zu addierende Zahl
Summand(0) = 10 ;Angaben in Zehntel!
Summand(1) = -1
Summand(2) = 8 

;Gadgets des Fensters
Global Dim ZahlGadget(#AnzahlRechnungen - 1) ;StringGadget mit der Zahl
Global Dim SummandGadget(#AnzahlRechnungen - 1) ;SpinGadget mit dem Summanden
; ---------------------------

; Prozeduren
;aktualisiert die StringGadgets alle 100 ms
Procedure Ausgabe()
  Protected i.l
  Static Timer.l
  If Timer = #False : Timer = ElapsedMilliseconds() - 100 : EndIf
  If Timer + 100 <= ElapsedMilliseconds()
    For i = 0 To #AnzahlRechnungen - 1
      SetGadgetText(ZahlGadget(i) ,Str(Zahl(i))) 
    Next
    Timer + 100 ; -> Timer = Timer + 100
    ;Hinweiß: in PB kann man in solchen Fällen das Gleichzeichen 
    ;weg lassen. Somit sparrt man sich einwenig Schreibarbeit
  EndIf
EndProcedure 

; Addiert nach 75 ms zu jeder Zahl den Summanden
Procedure Berechnung() 
  Protected i.l
  Static Timer.l
  If Timer = #False : Timer = ElapsedMilliseconds() - 100 : EndIf
  If Timer + 75 <= ElapsedMilliseconds()
    For i = 0 To #AnzahlRechnungen - 1
      Zahl(i) + Summand(i) 
    Next
    Timer + 75
  EndIf
EndProcedure 
; ---------------------------

; Fenster Öffnen; 
OpenWindow(0,350,150,200,200,"Zahlen") 
CreateGadgetList(WindowID(0)) 
For i = 0 To #AnzahlRechnungen - 1
  ;erstellt zu jeder Zahl ein StringGadget
  ZahlGadget(i) = StringGadget(#PB_Any, 10, 10 + i * 30, 50, 20, Str(Zahl(i))) 
  ;und zu jedem Summanden ein SpinGadget
  SummandGadget(i) = SpinGadget(#PB_Any, 60, 10 + i * 30, 50, 20, -1000, 10000)
  ;SpinGadgets müssen selber aktualisiert werden (siehe Hilfe)
  ;da die Summanden Zehntel anzeigen, muss eine Stelle nach dem
  ;komma angezeigt werden
  SetGadgetState(SummandGadget(i), Summand(i)) 
  SetGadgetText(SummandGadget(i), StrD(Summand(i)/10, 1))
Next
; ---------------------------

; hiermit kann man sich zu jeder Taste ein entsprechendes
; Menüereignis definieren (weiteres siehe Hilfe)
AddKeyboardShortcut(0, #PB_Shortcut_A, #Summand0Down)
AddKeyboardShortcut(0, #PB_Shortcut_S, #Summand0Up)
AddKeyboardShortcut(0, #PB_Shortcut_Left, #Summand1Down)
AddKeyboardShortcut(0, #PB_Shortcut_Right, #Summand1Up)
AddKeyboardShortcut(0, #PB_Shortcut_D, #Summand2Down)
AddKeyboardShortcut(0, #PB_Shortcut_F, #Summand2Up)
; ---------------------------

; Hauptschleife
Repeat  
    Select WaitWindowEvent(50) ;wartet maximal 50 ms auf ein Event
      Case #PB_Event_CloseWindow
        End
      
      ;wenn ein SpinGadget gedrückt wird, den Summanden aktualisieren
      Case #PB_Event_Gadget
        For i = 0 To #AnzahlRechnungen - 1
          ;vergleicht das Gadget, welches das Event ausgelöst hat
          ;mit allen vorhandenen SpinGadgets
          If EventGadget() = SummandGadget(i)
            ;die Word-Variable ist nötig, da sonnst keine
            ;negativen Werte übermittelt werden können
            ;der Rückgabewert ist 'unsignet' (ohne Vorzeichen)
            ;wir wollen aber 'signet' (mit Vorzeichen), Variablen
            ;in PureBasic sind bis heute immer mit Vorzeichen, so
            ;wandelt PureBasic für uns den Rückgabewert richtig um.
            State.w = GetGadgetState(SummandGadget(i))
            Summand(i) = State
            SetGadgetText(SummandGadget(i), StrD(Summand(i)/10, 1))
            Break
          EndIf
        Next
      
      ;für die Tasten ist das Event-Handling von Menüs zu benutzten
      ;siehe Hilfe zu den KeyboardShortcuts
      Case #PB_Event_Menu
        EventMenu = EventMenu()
        For i = 0 To #AnzahlRechnungen - 1
          ; ein bischen Logick, ich hoffe du kommst damit klar :-)
          If Int(EventMenu / 2) = i
            ; % bedeutet Modulo (Rest), EventMenu wird also durch 2
            ;geteilt und dann der Rest zurück gegeben. Kann also
            ;nur 0 bei geraden und 1 bei ungeraden Zahlen sein.
            If EventMenu % 2 = #False 
              Summand(i) - 1
            Else
              Summand(i) + 1
            EndIf
            SetGadgetState(SummandGadget(i), Summand(i)) 
            SetGadgetText(SummandGadget(i), StrD(Summand(i)/10, 1))
            Break
          EndIf
        Next
    EndSelect 
    
    ; Proceduren aufrufen 
    Berechnung()    
    Ausgabe() 
ForEver
^^hoffe das ist verständlich für dich <) ... musste ja auch nicht genau so
machen, wir haben ja im prinzip überhaupt keine Ahnung, was das fertige
Programm machen soll.

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Myrddin
Beiträge: 7
Registriert: 10.09.2006 15:44
Wohnort: Immenstadt im Allgäu

Beitrag von Myrddin »

Hallo PMV,

danke noch für den Quellcode. Werde mir das die Tage mal ansehen. Mit der anderen Variante bin ich nun erstmal klar gekommen wenn ich Knöpfe (Gadgets)verwende für Eingabe statt direkte Tastatureingabe.

Gruß
Michael
Pure Basic 4.0
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Hallo,

so geht es für diesen Anwendungsfall auch und ist ggf. einfacher/verständlicher:

Code: Alles auswählen

; Variablen definieren

Global Zahl1.d=0
Global Zahl2.d=0
Global Zahl3.d=0

Global Berechnung1.d=-1
Global Berechnung2.d=0.1
Global Berechnung3.d=0.8

; Fenster Öffnen;
OpenWindow(0,350,150,200,200,"Zahlen")
CreateGadgetList(WindowID(0))
StringGadget(0,10,10,50,20,Str(Zahl1))
StringGadget(1,10,40,50,20,Str(Zahl2))
StringGadget(2,10,70,50,20,Str(Zahl3))

Procedure Berechnung ()

  Zahl1 = Zahl1 + Berechnung1
  Zahl2 = Zahl2 + Berechnung2
  Zahl3 = Zahl3 + Berechnung3
 
EndProcedure

Procedure Ausgabe()

  SetGadgetText(0,Str(Zahl1))
  SetGadgetText(1,Str(Zahl2))
  SetGadgetText(2,Str(Zahl3))

EndProcedure

Repeat

  EventID = WaitWindowEvent(1)

  ; Proceduren aufrufen
  If Ticks = 10 ; alle 10ms die Proceduren aufrufen...
    Berechnung()
    Ausgabe()
    Ticks = 0
  EndIf
  Ticks = Ticks + 1

Until EventID = #PB_Event_CloseWindow
Gruß Markus
"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
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ich will mich auch mal einmischen! :mrgreen:

Bei funktioniert dieser Code super!

Code: Alles auswählen

; Variablen definieren

Global Zahl1.d=0
Global Zahl2.d=0
Global Zahl3.d=0

Global Berechnung1.d=-1
Global Berechnung2.d=0.1
Global Berechnung3.d=0.8

; Fenster Öffnen;
OpenWindow(0,350,150,200,200,"Zahlen")
CreateGadgetList(WindowID(0))
StringGadget(0,10,10,50,20,StrD(Zahl1, 1))
StringGadget(1,10,40,50,20,StrD(Zahl2, 1))
StringGadget(2,10,70,50,20,StrD(Zahl3, 1))

Procedure Berechnung ()

  Zahl1 + Berechnung1
  Zahl2 + Berechnung2
  Zahl3 + Berechnung3
 
EndProcedure

Procedure Ausgabe()

  SetGadgetText(0,StrD(Zahl1, 1))
  SetGadgetText(1,StrD(Zahl2, 1))
  SetGadgetText(2,StrD(Zahl3, 1))

EndProcedure

Repeat

  Select WaitWindowEvent(1)
    Case #PB_Event_CloseWindow
      Break
    
    Case #WM_KEYUP
      Select EventwParam()
        Case #VK_LEFT
          Berechnung1 - 1
        Case #VK_RIGHT
          Berechnung1 + 1
      EndSelect
    Case 0
      ; Proceduren aufrufen
      
      Ausgabe()
  EndSelect
  
  Berechnung()
Until EventID = #PB_Event_CloseWindow
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

NicTheQuick, irgendwas passt in Deinem Eventloop nicht:

Code: Alles auswählen

Repeat

  Select WaitWindowEvent(1)
    Case #PB_Event_CloseWindow
      Break
   
    Case #WM_KEYUP
      Select EventwParam()
        Case #VK_LEFT
          Berechnung1 - 1
        Case #VK_RIGHT
          Berechnung1 + 1
      EndSelect
    Case 0
      ; Proceduren aufrufen
     
      Ausgabe()
  EndSelect
 
  Berechnung()
Until EventID = #PB_Event_CloseWindow
Oben machste: Select WaitWindowEvent(1)
und unten: Until EventID = #PB_Event_CloseWindow

EventID wird nirgendwo gesetzt. Es geht zufällig in diesem Fall, weil beim Fensterschliessen wohl das ganze Programm automatisch beendet wird.
Aber richtiger wäre wohl:

Code: Alles auswählen

EventID = WaitWindowEvent(1)
Select EventID
...
Gruß Markus
"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
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Achso, ja, dann muss die "Until"-Zeile einfach in "ForEver" umbenannt
werden, dann passt hat. Das "Break" ist ja da. Funktionieren tut der Code nur
deswegen, weil 'EventID' immer 0 ist und 'PB_Event_CloseWindow' ungleich 0
ist.
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

Immer diese Leichenschänder :mrgreen:
Antworten