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.
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

Dann versteh ich wohl dein Problem nicht !?
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).
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