Wie baut man einen Programmablauf in Pure Basic richtig auf?

Anfängerfragen zum Programmieren mit PureBasic.
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Vielleicht ist es so schöner:

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 Ausgabe()
    
    SetGadgetText(0,Str(Zahl1))
    SetGadgetText(1,Str(Zahl2))
    SetGadgetText(2,Str(Zahl3))
    
EndProcedure

Procedure Berechnung ()
    Zahl1 = Zahl1 + Berechnung1
    Zahl2 = Zahl2 + Berechnung2
    Zahl3 = Zahl3 + Berechnung3
    
    Ausgabe()
EndProcedure

;SetTimer_(WindowID(0),0,10,@Berechnung())

Repeat
    
    Berechnung()   
    ; Proceduren aufrufen
    
    Delay(2)
    EventID =WindowEvent()
    While EventID
        ;Events abarbeiten, mit Callback wärs vielliecht schöner
        Select EventID
            Case #PB_Event_CloseWindow
                End
        EndSelect
        EventID =WindowEvent()
    Wend
ForEver
Optimismus ist ein Mangel an Information.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

yo.

oder mit dem delay im WaitWindowEvent() (s.o.),
das sollte man neuerdings einem delay vorziehen.

um mal zu interpretieren:
durch den counter lässt du nur jeden 4ten durchlauf die aktion durchführen,
damit stellst du sicher, dass 3 refresh-events korrekt ausgeführt werden.



> aber wie lässt er das jetzt unter Linux laufen?

wäre noch zu prüfen, ob das problem unter Linux überhaupt auftritt,
denn die unterschiede sind doch größer, als man auf den ersten blick denkt.


[edit]
wir posten zu schnell

yo, mit callbacks wärs gewiß schöner. aber die gehen halt nur mit winAPI
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

edel hat geschrieben:

Code: Alles auswählen

Until event = #WM_CLOSE
dafür gibt es eine PB-Konstante.

WinAPI zu beherrschen schön und gut.

aber hier im anfänger-bereich bitte nicht unnötig Win-Abhängig coden.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Myrddin
Beiträge: 7
Registriert: 10.09.2006 15:44
Wohnort: Immenstadt im Allgäu

Beitrag von Myrddin »

Vielen vielen Dank für die turboschnelle Hilfe. Das ganze Spiel geht nun auch ohne weiteres mit doppelt so viele Gadget. Damit habe ich ein gutes Grundgerüst.

Jetzt sollte ich den Code-Teil noch verstehen. Mag mir noch jemand erklären was da passiert? Diese ganze Event-Geschichte sind für mich noch böhmische Dörfer.

Code: Alles auswählen


    EventID =WindowEvent() 
    While EventID 
        ;Events abarbeiten, mit Callback wärs vielliecht schöner 
        Select EventID 
            Case #PB_Event_CloseWindow 
                End 
        EndSelect 
        EventID =WindowEvent() 
    Wend 

Gruß
Michael
Pure Basic 4.0
Benutzeravatar
vonTurnundTaxis
Beiträge: 2130
Registriert: 06.10.2004 20:38
Wohnort: Bayreuth
Kontaktdaten:

Beitrag von vonTurnundTaxis »

Wenn in einem Fenster etwas passiert, dann wird das als sog. "Event" zurückgegeben.
Ein Beispiel dafür ist #PB_Event_CloseWindow:

Code: Alles auswählen

Repeat
  Event = WaitWindowEvent() ;Das aufgetretene Event wird in der Variable "Event" gespeichert
Until  Event = #PB_Event_CloseWindow; Wenn das Event "#PB_Event_CloseWindow" (Fenster schließen) aufgetreten ist, wird die Schleife beendet.
//Nachtrag:
Die PureBasic-Hilfe ist wirklich hilfreich. Du kannst sie im Editor per [F1] öffnen.
Nicht durch Zorn, sondern durch Lachen tötet man
ClipGrab | Pastor - jetzt mit kurzen URLs!
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Ganz kurz gesagt:

Unter Windows läuft alles über Events (Ereignisse). Wenn du den Inhalt des Stringgadgets änderst, dann wird hier durch dein Programm ein Event ausgelöst. Das muss aber auch noch von deinem Fenster verarbeitet werden. Wenn du jetzt (wait)windowevent() aufrufst, dann wird 1 (!) Event aus der Liste abgearbeitet. Wenn du aber in einem Intervall (min.) 3 Events erzeugst, aber nur eins ababrbeitest, dann kann das nicht funktionieren. Deshalb hab ich da eine Schleife gemacht, die pro Intervall alle Events abarbeitet. Da kannst du selber auch die für dich wichtigen Events abarbeiten (#WM_CLOSE, z.B., bzw. das PB-Äquivalent)

Fragen?
Optimismus ist ein Mangel an Information.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

in dieser zweite lösung hat Hell das warten direkt in die hauptschleife gesetzt.
(vorher hatte es das mit der zählvariablen drin)

der GAG war halt, dass jedes SetGadgetText() ein event zurück gibt.
also muss man 3 events bearbeiten, ohne anzuzeigen,
damit alle angezeigt werden.

in dieser schleife (in dem neuesten post) wird darauf gewartet, dass alle events abgearbeitet sind.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Diesen Schnipsel brauchst du dir gar nicht erst aufschreiben, merken
oder wie auch immer.

Das mit SetTimer_ events verschluckt werden ist mir zwar noch nicht
aufgefallen, aber ich schieb es mal auf die interne eventschleife.
Mit timeSetEvent_ laeuft es wie gewollt, Auch wenn es etwas komplexer
ist.

Beispiel :

Code: Alles auswählen

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 Ausgabe()
  
  SetGadgetText(0,Str(Zahl1))
  SetGadgetText(1,Str(Zahl2))
  SetGadgetText(2,Str(Zahl3))
 
EndProcedure

Procedure Berechnung(uId,msg,dwUser,dw1,dw2 )
  
  Zahl1 = Zahl1 + Berechnung1
  Zahl2 = Zahl2 + Berechnung2
  Zahl3 = Zahl3 + Berechnung3
  
  Ausgabe()
EndProcedure

#millisec = 200

TimerID = timeSetEvent_(#millisec,0,@Berechnung(),0,#TIME_PERIODIC)

Repeat
  
  EventID = WaitWindowEvent()

  If EventID = #PB_Event_Gadget
    Select EventGadget()
      Case 0 : Debug "1"
      Case 1 : Debug "2"
      Case 2 : Debug "3"
    EndSelect
  EndIf
  
Until EventID = #PB_Event_CloseWindow

timeKillEvent_(TimerID)
http://msdn.microsoft.com/library/defau ... tevent.asp
http://msdn.microsoft.com/library/defau ... meproc.asp
http://msdn.microsoft.com/library/defau ... levent.asp
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ja schön...

hast du auch eine adäquate API-freie lösung parat?
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Myrddin
Beiträge: 7
Registriert: 10.09.2006 15:44
Wohnort: Immenstadt im Allgäu

Beitrag von Myrddin »

Danke Leute, glaube jetzt ist der Groschen so langsamm gefallen.

Nochmal allgemein, für andere Anfänger und das ichs auch recht verstanden habe:
1. Also jede Aktion die entweder ich ausführe (Knopf drücken, Taste drücken, etc) oder das Programm (Text in ein Gadget schreiben, etc) lösst ein Event aus.
2. Die Events müssen vom Programm abgearbeitet werden. Ohne das passiert nichts. Also wenn ich ein Text in ein Gaget schreibe erzeugt das ein Event das ein Anzeigen/Auffrischen auslöst.
3. Ich kann die Events abfragen und ggF weitere Aktionen auslösen.

Ich kann jetzt also über weitere Case-Abfragen z.B. Tastatureingaben verarbeiten, oder?

Ja die F1-Hilfte ist gut aber bei weitem nicht perfekt. Mein Problem, ich habe da noch keine Liste der Events-Konstanten gefunden. Nur einzelne Konstanten tauchen hier und da mal auf. Gibt es da eine Liste?

Gruß
Michael
Pure Basic 4.0
Antworten