Seite 1 von 3

ButtonGadget automatisch umschalten, aber wie?

Verfasst: 18.12.2005 14:01
von PB42
Hallo, ich schreibe gerade ein Programm, das mit Musiknoten zu tun hat. Konkret: Klicke ich Tasten auf der virtuellen Klaviatur, erscheinen die Noten auf dem Bildschirm. Da es in der Musik bekanntlich #- und b-Vorzeichen gibt, wird der Programmblock, der Kreuze vor die Noten schreibt, über Case 0 angesteuert und der Programmblock, der b-Vorzeichen vor die Noten schreibt, mit Case 1. Soviel zur Vorgeschichte. Nun sollen weitere ButtonGadgets in das Programm eingefügt werden, also z.B. ein Clear-Button, damit im Bedarfsfall alle Noten auf einmal vom Bildschirm wieder entfernt werden können. Das läuft dann über Case 2. So, und jetzt ist das Problem dabei, daß ich nach dem Löschen aller Noten erst dann wieder neue Noten eingeben kann, wenn ich vorher entweder erstmal erneut den #-Button klicke oder den b-Button, weil ja sonst weiterhin der Clear-Button aktiv ist (nämlich Case 2). Ich will aber SOFORT nach dem Löschen aller Noten wiederum die Tasten auf der Klaviatur anklicken können, also ohne den Umweg über Button # oder Button b. Wie geht das? Der Code ist zu lang zum Einfügen, das sind schonwieder ca. 2000 Zeilen, aber meine Frage läßt sich sicher auch allgemein beantworten. Danke.

PB42

Verfasst: 18.12.2005 14:22
von PAMKKKKK
Das was du brachst ist ein so genanntes Flag (zu deutsch eine Flagge, oder ein Zustandsanzeiger).
Dieses fragst du dann ab.
(Flags sind eine der wenigen aussnahmen, wo Globale Variablen sinnvoll sind.)

Wenn dein Programm startet dann ist das Flag = NULL, weil ja noch keine Noten eingegeben worden sind.

Code: Alles auswählen

Global displayNotes.b
displayNotes.b = 0
Wenn Noten angezeigt werden setz du das Flag immer auf z.B. 1

Code: Alles auswählen

Procedure Show_Notes()
.......
displayNotes.b = 1
EndProcedure
Mit dem Clear Button kannst du dann das Flag abfragen und damit Arbeiten

Code: Alles auswählen

case #Button3
  if displayNotes.b = 1
    Clear_all()
    displayNotes.b = 0 ; wieder auf NULL setzen !!!
  endif
hoffe das hilft....

Verfasst: 18.12.2005 14:52
von PB42
Danke, PAMKKKKK, aber das Problem ist ja, daß das Programm nach dem Drücken des Clear-Buttons IMMER in Case 2 reinrammelt und dadurch Case 0 und Case 1 überspringt. Was mich so stört, ist der Umstand, daß man zwar abfragen kann "If EventGadgetID()=2", aber nicht einfach sagen kann "GadgetID() =0". Jetzt mach ich mir erstmal Mittag. Mahlzeit.

PB42

Verfasst: 18.12.2005 15:50
von PAMKKKKK
:? :roll: Dann versteh ich wohl dein Problem nicht !? :oops:

Poste doch mal deine Event schleife!
Warscheinlich sind wir dann schlauer.......

Ich geh nun auf´n Weihnachtsmarkt ....Prost!

Verfasst: 18.12.2005 16:37
von PB42
Ok, ich gebe in folgendem Code mal einen kleinen Ausschnitt des Programms und erkläre dann nochmal, worum es mir geht:

Code: Alles auswählen

InitSprite()
InitKeyboard()
InitMouse()
InitSound()
OpenWindow(0,0,0,800,600,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget,"")
OpenWindowedScreen(WindowID(0), 0, 50, 800, 400, 0, 0, 0)
CreateGadgetList(WindowID(0))


;den Teil, wo die virtuelle Klaviatur erzeugt wird, lasse ich hier weg


ButtonGadget(0,680,5,40,40,"#")
ButtonGadget(1,730,5,40,40,"b")
ButtonGadget(2,630,5,40,40,"Clear")

eventID = WindowEvent()
GadgetID = EventGadgetID()
Select GadgetID
  
Case 0
  
  ;Taste cis'
  If eventID = #WM_LBUTTONDOWN And WindowMouseX() > 380 And WindowMouseX() < 397 And WindowMouseY() > 350 And WindowMouseY() < 415
  cis1 = 1
  cis2 = 1
  cis3 = 1
  x = x + 31
  DisplaySprite(7,x,1)
  PlaySound(18)
  EndIf
  
Case 1

  ;Taste des'
  If eventID = #WM_LBUTTONDOWN And WindowMouseX() > 380 And WindowMouseX() < 397 And WindowMouseY() > 350 And WindowMouseY() < 415
  des1 = 1
  des2 = 1
  des3 = 1
  x = x + 31
  DisplaySprite(35,x,0)
  PlaySound(18)
  EndIf  

Case 2 

  DisplaySprite(118,31,0)
  DisplaySprite(118,31,85)
  x = 0
  EndSelect
  
usw..................   
1) Mit ButtonGadget(0) wird der Programmteil angesteuert, welcher Töne mit #-Vorzeichen auf den Bildschirm bringt.
2) Mit ButtonGadget(1) wird der Programmteil angesteuert, welcher Töne mit b-Vorzeichen auf den Bildschirm bringt.
3) Nach dem Drücken von ButtonGadget(2) werden alle Noten vom Bildschirm entfernt.

Das Problem: Nach dem Löschen der Noten sind Case 0 oder Case 1 deaktiviert, je nachdem, was von beiden vorher aktiviert war, sodaß es nicht möglich ist, neue Noten eingeben zu können, es sei denn, man klickt erst wieder auf ButtonGadget(0) oder ButtonGadget(1). Genau diesen Umstand will ich aber nach Möglichkeit vermeiden. Mit anderen Worten muß innerhalb des Zustands Case 2 dafür gesorgt werden, daß Case 0 oder Case 1 wieder aktiviert werden und Case 2 natürlich zugleich deaktiviert, OHNE daß man dafür erst Button 0 oder Button 1 klicken muß.

PB42

Verfasst: 20.12.2005 14:07
von PAMKKKKK
Hmmm kratz am Kopf......

Ich kann in dem hier geposteten Code immer noch nicht deine event Schleife erkennen (For...ever oder While....Until/wend). :roll:

Schick mir doch mal deine Coder per PN. Wenn du schon eine *.exe Kompeliert hast, dann schick die auch mit.

Verfasst: 21.12.2005 13:38
von PB42
Vielen Dank, PAMKKKKK, aber tatsächlich habe ich das Problem bereits gelöst. Meines Erachtens gibt es dafür nur die eine Lösung, daß der "Clear"-Button zum Statisten gemacht wird, sodaß dessen "Auswertung" eben nicht mehr durch CASE stattfindet, sondern über WindowMouseX() und WindowMouseY() in Kombination mit #WM_LBUTTONDOWN, es sei denn, es gibt in PB eine Möglichkeit, auch das Loslassen eines Buttons auswerten zu können: Falls nicht, wäre das eine unschöne Lücke in PB.

PB42

Verfasst: 21.12.2005 15:07
von Batze
PB42 hat geschrieben: usw..................
Zeig doch erstmal deine Eventschleife!

PB42 hat geschrieben:[...] es sei denn, es gibt in PB eine Möglichkeit, auch das Loslassen eines Buttons auswerten zu können

Code: Alles auswählen

OpenWindow(0,  0,  0,  200, 60, #PB_Window_MinimizeGadget, "Fenster")
CreateGadgetList(WindowID(0))
ButtonGadget(0, 10, 15, 180, 30, "Klick mich (aber lass nicht los)")

Repeat
  Event = WaitWindowEvent()
  If Event = #PB_Event_Gadget
    MessageRequester("Button:", "Das Event kommt jetzt erst an !!!")
  EndIf  
Until Event = #PB_Event_CloseWindow

Verfasst: 21.12.2005 15:29
von PAMKKKKK
Ne...Ne...Näh...

So leicht kommst du mir nicht davon....

Ich habe immer den verdacht, das du dein Eventschleife auf deine eigene Art Bastels ......

Schick mir doch mal wenigstens eine Test Kompelation von Programm deinem.

Dann kann ich mir besser vorstellen wie du das alles meinst....

schickmirpost AT web.de

Verfasst: 21.12.2005 16:18
von PB42
Da Du nochmals fragst wegen Event usw., hier der Aufbau im Groben für den speziellen Bereich, den Du meinst:

Code: Alles auswählen

Repeat

   select GadgetID

   Case 1

   ...

   Case 2

   ...

   Case 3

   ...

   Endselect


Until eventID = #PB_EventCloseWindow
So macht man das doch und gegen basteln sperrt sich PB beharrlich, ist ja auch richtig so. Ist zwar gut gemeint, aber ich brauche da nicht meinen Code oder Teile davon zu verschicken. Das Problem, von dem ich gesprochen hatte, kann man bildlich umgesetzt auch so formulieren: Vor mir steht ein altes Röhrenradio mit mehreren Tasten da dran. Dann drücke ich die Taste KW, dann MW, dann UKW. Fazit: Die Taste, die gedrückt wurde, bleibt unten und alle anderen gehen hoch. Und genauso verhält sich das mit Select GadgetID und den anschließenden CASE-Befehlen: Einmal geschaltet, immer geschaltet, bis man den nächsten CASE-Befehl mit einem anderen Button aktiviert. Was ich jedoch ausnahmsweise gebraucht hätte, wäre die Möglichkeit gewesen, daß CASE 2 sofort wieder ausklinkt, nachdem ich den CLEAR-Button gedrückt hatte und dafür CASE 1 wieder einklinkt, ohne dafür extra wieder Button 1 klicken zu müssen. Das kann ich vergesen und das weiß ich nun.

PB42