Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 07.10.2015, 10:32 Titel: ScreenEvent-Funktion fehlerhaft? |
|
|
Beim Auswerten der x,y-Koordinaten nach einem Mouse-Button-Event wird nur die y-Koordinate angegeben, die x-Koordinate bleibt immer auf 1. Ist das ein Fehler?
Festgestellt bei den Versionen: 1.01.0-1.04.0 |
|
Nach oben |
|
|
Lothar Schirm
Anmeldungsdatum: 24.04.2006 Beiträge: 64 Wohnort: Bayern
|
Verfasst am: 07.10.2015, 17:02 Titel: |
|
|
Noch viel schlimmer (getestet mit 1.04, 32 Bit): Hier wird immer x = 1 und y = 640 ausgegeben
Code: |
#Include "fbgfx.bi"
Dim evt As FB.EVENT
Function x_Button(x As Integer) As Integer 'welcher Button
If x = FB.BUTTON_LEFT Then
Print "Die Linke";
ElseIf x = FB.BUTTON_RIGHT Then
Print "Die rechte";
ElseIf x = FB.BUTTON_MIDDLE Then
Print "Die mittlere";
ElseIf x = FB.BUTTON_X1 Then
Print "Die X1";
ElseIf x = FB.BUTTON_X2 Then
Print "Die X2";
End If
Return 0
End Function
ScreenRes 640, 480
Width 640\8, 480\16
Do
If ScreenEvent(@evt) Then
Select Case evt.type
Case FB.EVENT_KEY_PRESS
If evt.scancode = FB.SC_ESCAPE Then End
If evt.ascii > 0 Then
Print "'" & evt.ascii & "'";
Else
Print "eine unbekannte Taste";
End If
Print " wurde gedrueckt (Scancode " & evt.scancode & ")"
Case FB.EVENT_KEY_RELEASE
If evt.ascii > 0 Then
Print "'" & evt.ascii & "'";
Else
Print "eine unbekannte Taste";
End If
Print " wurde losgelassen (Scancode " & evt.scancode & ")"
Case FB.EVENT_KEY_REPEAT
If evt.ascii > 0 Then
Print "'" & evt.ascii & "'";
Else
Print "eine unbekannte Taste";
End If
Print " wird gehalten (Scancode " & evt.scancode & ")"
Case FB.EVENT_MOUSE_MOVE
Print "Maus wurde bewegt nach " & evt.x & ", " & evt.y & _
" (delta " & evt.dx & ", " & evt.dy & ")"
Case FB.EVENT_MOUSE_DOUBLE_CLICK
Locate CsrLin -2,1
x_Button(evt.button)
Print " Maustaste wurde doppelt gedrueckt"
Case FB.EVENT_MOUSE_BUTTON_PRESS
x_Button(evt.button)
Print " Maustaste wurde gedrueckt"
Print "x = " & evt.x '<------- Es wird immer x = 1 angezeigt!
Print "y = " & evt.y '<------- Es wird immer y = 640 angezeigt!
Case FB.EVENT_MOUSE_BUTTON_RELEASE
x_Button(evt.button)
Print " Maustaste wurde losgelassen"
Case FB.EVENT_MOUSE_WHEEL
Print "Das Mausrad wurde verstellt auf " & evt.z
Case FB.EVENT_MOUSE_ENTER
Print "Die Maus wurde in das Programmfenster bewegt"
Case FB.EVENT_MOUSE_EXIT
Print "Die Maus wurde aus dem Programmfenster bewegt"
Case FB.EVENT_WINDOW_GOT_FOCUS
Print "Das Programmfenster hat den Fokus erhalten"
Case FB.EVENT_WINDOW_LOST_FOCUS
Print "Das Programmfenster hat den Fokus verloren"
Case FB.EVENT_WINDOW_CLOSE
End
End Select
End If
Sleep 10
Loop
|
|
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4603 Wohnort: ~/
|
Verfasst am: 07.10.2015, 17:25 Titel: |
|
|
Code: | TYPE EVENT FIELD = 1
type AS INTEGER
UNION
TYPE
scancode AS INTEGER
ascii AS INTEGER
END TYPE
TYPE
x AS INTEGER
y AS INTEGER
dx AS INTEGER
dy AS INTEGER
END TYPE
button AS INTEGER
z AS INTEGER
w AS INTEGER
END UNION
END TYPE |
button bildet zusammen mit anderen Werten (z. B. dem Block x, y, dx, dy) eine UNION; es ist also gar nicht möglich, dass sowohl der Button-Zustand als auch die Mauskoordinaten gleichzeitig gespeichert werden. SCREENEVENT liefert nicht generell den "Systemzustand", sondern nur spezielle Informationen zum speziellen Ereignis. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Lothar Schirm
Anmeldungsdatum: 24.04.2006 Beiträge: 64 Wohnort: Bayern
|
Verfasst am: 07.10.2015, 17:30 Titel: |
|
|
Und wieso funktioniert das dann im Code-Beispiel mit "Case FB.EVENT_MOUSE_MOVE"? - Ich verwende ScreenEvent sowieso nicht, ist mir viel zu kompliziert. Inkey und GetMouse tun es auch. |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4603 Wohnort: ~/
|
Verfasst am: 07.10.2015, 17:51 Titel: |
|
|
Bei FB.EVENT_MOUSE_MOVE wird x, y, dx und dy gesetzt (dafür z. B. nicht button). Bei FB.EVENT_MOUSE_BUTTON_PRESS wird button belegt (das ist ja das Event), die aktuelle Position x, y sowie dx und dy aber nicht (das gehört nicht zum Mausdruck-Event). Bei FB.EVENT_KEY_PRESS wird scancode und ascii belegt, usw. Halt immer das, was direkt zum Event gehört.
Ob SCREENEVENT eine praktische Funktion ist, ist dann nochmal eine andere Frage, die jeder selbst entscheiden muss. Ein paar Funktionen sind vielleicht damit einfacher, wie Doppelklick oder das Verlassen des Fensters - oder wenn dich generell nur interessiert, ob bzw. wie stark die Maus bewegt wurde (erspart den Vergleich mit den vorherigen Werten). Wenn einfach nur die Mausposition abgefragt werden soll, ist GETMOUSE deutlich praktischer (und funktioniert auch ohne Mausbewegung ). _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Lothar Schirm
Anmeldungsdatum: 24.04.2006 Beiträge: 64 Wohnort: Bayern
|
Verfasst am: 07.10.2015, 17:56 Titel: |
|
|
Danke, ich hoffe, Elor ist auch zufrieden (mit wahrscheinlicher Verunsicherung?). |
|
Nach oben |
|
|
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 08.10.2015, 10:52 Titel: |
|
|
@Lothar Schirm: Bei mir wird bei einem Button-Ereigniss in x die Tastennummer und in y die Koordinate zurueck gegeben.
Mit den Antworten bin ich schon zufrieden, mit der Funktionsweise von ScreenEvent aber nicht.
Normalerweise Arbeite ich auch lieber mit InKey und GetMouse, der Grund, weshalb ich ScreenEvent einsetzen wollte, liegt darin, dass ich die easySDL-Unit von den Delphi-OpenGL-Tutorials nach FreeBASIC Portiert habe und diese wollte ich jetzt komplett von SDL trennen (was ja auch kein Problem ist).
@nemored: Das mit der UNION ist schon klar, aber wenn ich ein Button-Event abfrage, will ich doch auch wissen wo das war. Es ist mir ein Raetzel wieso man Mousebutton und Koordinaten getrennt hat.
Bei einer normalen Grafik-Anwendung ist es egal ob man zusaetzlich noch GetMouse() aufrufen muss, in einer OpenGL-Anwendung ist das aber unnoetige Zeit die da verbraucht wird.
Danke fuer die Antworten. |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4603 Wohnort: ~/
|
Verfasst am: 08.10.2015, 14:17 Titel: |
|
|
Zitat: | Es ist mir ein Raetzel wieso man Mousebutton und Koordinaten getrennt hat. |
Weil das Ereignis "Eine (Maus-)Taste wird gedrückt/losgelassen" etwas anderes ist als der Zustand "Die Maus befindet sich an der Position x/y". Umgekehrt gibt ein Mausbewegungs-Ereignis auch nicht den Zustand des Mausbuttons zurück. So gesehen ist das ein durchaus logisches Verhalten. Das man sich noch weitere Informationen wünschen könnte, kann ich selbstverständlich gut verstehen. Aber streng genommen ist das dann eine Mischung von zwei Konzepten.
Wenn man rein nur mit SCREENEVENT arbeitet, wird man wohl jede Mausbewegung registrieren und die aktuelle Mausposition gesondert speichern (analog auch den Zustand der Mausbuttons). Ich könnte mir sogar vorstellen, dass GETMOUSE oder entsprechende API-Funktionen genau so etwas machen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 08.10.2015, 19:33 Titel: |
|
|
Ich kenn das eben von Turbo- b.z.w. Free Pascal, da wird eben alles geliefert was man braucht, ich dachte halt das waehr in FB auch so. Ok, muss ich mir die Info's halt mit GetMouse() holen. |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 08.10.2015, 20:47 Titel: |
|
|
Wenn du unbedingt eventbasiert arbeiten möchtest, könntest du dir auch einfach die Mauskoordinaten aus einem vorherigen Screen-Event merken, was ist daran so kompliziert? Wenn du GetMouse verwendest, brauchst du eigentlich auch nicht mehr ScreenEvent für Mausklicks zu verwenden. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 09.10.2015, 12:05 Titel: |
|
|
@Jojo: Es ist nicht kompliziert, sondern nur nicht so wie ich mir das vorgestellt hatte. Das ganze sollte wie folgt aussehen:
Code: |
/' Include : bglEvents.bi '/
#pragma Once
#include Once "fbgfx.bi"
#define __BGLEVENTS_H__
#if __FB_VERSION__ < "1.04.0"
Type Boolean As Integer ' ?
Const False = 0
Const True = Not False
#endif
' Der NameSpace FB wird hier nicht verwendet
' ----- Typen -----
Type TEvent As FB.EVENT
' ----- Records -----
' ----- Objects -----
Type PHandleEvents As THandleEvents Ptr
Type _
THandleEvents Extends Object
Public :
Declare Constructor ()
Declare Sub MainLoop ()
Protected :
Declare Abstract Sub IdleProc ()
Declare Virtual Sub HandleKeyPress (ByRef Event As TEvent)
Declare Virtual Sub HandleKeyRelease (ByRef Event As TEvent)
Declare Virtual Sub HandleKeyRepeat (ByRef Event As TEvent)
Declare Virtual Sub HandleMouseMove (ByRef Event As TEvent)
Declare Virtual Sub HandleButtonPress (ByRef Event As TEvent)
Declare Virtual Sub HandleButtonRelease (ByRef Event As TEvent)
Declare Virtual Sub HandleDoubleClick (ByRef Event As TEvent)
Declare Virtual Sub HandleMouseWheel (ByRef Event As TEvent)
Declare Virtual Sub HandleMouseHWheel (ByRef Event As TEvent)
Declare Virtual Sub HandleMouseEnter (ByRef Event As TEvent)
Declare Virtual Sub HandleMouseExit (ByRef Event As TEvent)
Declare Virtual Sub HandleGotFocus (ByRef Event As TEvent)
Declare Virtual Sub HandleLostFocus (ByRef Event As TEvent)
Declare Virtual Sub HandleWindowClose (ByRef Event As TEvent)
Private :
Event As TEvent
Done As Boolean
Declare Sub HandleEvent ()
End Type
' --------------------------------------------------------------------
' PUBLIC
' --------------------------------------------------------------------
' --- THandleEvents --------------------------------------------------
' Constructor ()
' --------------------------------------------------------------------
Constructor THandleEvents ()
Done= False
End Constructor
' --- THandleEvents --------------------------------------------------
' MainLoop ()
' --------------------------------------------------------------------
Sub THandleEvents.MainLoop ()
Do
If ScreenEvent() Then
HandleEvent ()
End If
IdleProc ()
Loop Until Done
End Sub
' --------------------------------------------------------------------
' PROTETED
' --------------------------------------------------------------------
' --- THandleEvents --------------------------------------------------
' HandleKeyPress () - Muss vom Nachfolger Aufgerufen werden
' --------------------------------------------------------------------
Sub THandleEvents.HandleKeyPress (ByRef Event As TEvent)
If(Event.ScanCode = FB.SC_ESCAPE) Then Done= True
End Sub
' und hier alle anderen Methoden, hab ich jetzt nur raus genommen damit's nicht zu lang wird.
' --- THandleEvents --------------------------------------------------
' HandleWindowClose () - Muss vom Nachfolger Aufgerufen werden.
' --------------------------------------------------------------------
Sub THandleEvents.HandleWindowClose (ByRef Event As TEvent)
Done= True
End Sub
' --------------------------------------------------------------------
' PRIVATE
' --------------------------------------------------------------------
' --- THandleEvents --------------------------------------------------
' HandleEvent ()
' --------------------------------------------------------------------
Sub THandleEvents.HandleEvent ()
ScreenEvent(@Event)
Select Case Event.Type
Case FB.EVENT_KEY_PRESS : HandleKeyPress (Event)
Case FB.EVENT_KEY_RELEASE : HandleKeyRelease (Event)
Case FB.EVENT_KEY_REPEAT : HandleKeyRepeat (Event)
Case FB.EVENT_MOUSE_MOVE : HandleMouseMove (Event)
Case FB.EVENT_MOUSE_BUTTON_PRESS : HandleButtonPress (Event)
Case FB.EVENT_MOUSE_BUTTON_RELEASE: HandleButtonRelease (Event)
Case FB.EVENT_MOUSE_DOUBLE_CLICK : HandleDoubleClick (Event)
Case FB.EVENT_MOUSE_WHEEL : HandleMouseWheel (Event)
Case FB.EVENT_MOUSE_HWHEEL : HandleMouseHWheel (Event)
Case FB.EVENT_MOUSE_ENTER : HandleMouseEnter (Event)
Case FB.EVENT_MOUSE_EXIT : HandleMouseExit (Event)
Case FB.EVENT_WINDOW_GOT_FOCUS : HandleGotFocus (Event)
Case FB.EVENT_WINDOW_LOST_FOCUS : HandleLostFocus (Event)
Case FB.EVENT_WINDOW_CLOSE : HandleWindowClose (Event)
End Select
End Sub
|
Bei verwendung einer MouseButtonEvent-Methode (gleich welcher art) wars halt praktisch gewessen wenn im Event alle Info's stehen, jetzt muss ich's halt etwas ab aendern. |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 09.10.2015, 13:18 Titel: |
|
|
Ein paar statische Variablen in HandleEvent und ein entsprechender (eigener; größerer) UDT für TEvent sollts großteils lösen.
Was anderes find ich aber interessanter und zwar das hier (sorry, off topic):
Elor hat Folgendes geschrieben: | Code: | #if __FB_VERSION__ < "1.04.0"
Type Boolean As Integer ' ?
Const False = 0
Const True = Not False
#endif |
|
Laut Doku kann man das zwar anscheinend so verwenden, aber ich frage mich wie das zuverlässig funktionieren kann, da ja Strings verglichen werden - oder etwa nicht? Ich würde da eher auf __FB_MIN_VERSION__ setzen. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4603 Wohnort: ~/
|
Verfasst am: 09.10.2015, 14:09 Titel: |
|
|
Wenn die Versionsnummern konsequent (stringmäßig) aufsteigend erfolgen - also nicht z. B. auf ein __FB_VERSION__ "1.99.0" dann doch noch ein "1.100.0" folgt oder auch nur auf die Patchversion "1.04.9" die Version "1.04.10", funktioniert das mit den String-Vergleichen. Im Sinne von "man weiß nie, was irgendwann mal kommt" hätte ich auch eher mit __FB_MIN_VERSION__ verglichen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 09.10.2015, 17:04 Titel: |
|
|
Was den vergleich der Versionsnummer angeht hab ich gar nicht drueber nachgedacht, stimmt, __FB_MIN_VERSION ist sicherer.
@St_W: Ich hab mir ueberlegt gar kein Event-Type an die Methoden zu uebergeben sondern nur noch das was zum Ereigniss gehoert.
Also hol ich mit GetMouse() die x,y-Koordinate bei einem MsButtonEvent und Ruf dann Methodenname(Event.button, x, y) auf, dass sollte ja kein Problem sein. |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2509 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 09.10.2015, 19:33 Titel: |
|
|
Vorhin auch einmal einen kleinen Test für ScreenEvent geschrieben, hat aber gleich zu einem
Code: | C:\Program Files (x86)\FreeBASIC\fbc -s gui "MausEreignis.bas"
MausEreignis.asm: Assembler messages:
MausEreignis.asm:260: Internal error!
Assertion failure in stringer at ../../../src/binutils-2.25/gas/read.c line 5323.
Please report this bug.
Make done |
geführt. Passiert übrigens auch bei der aktuellsten FBC-Version (1.04.0 / 10-01-2015).
Bug im internationalen Forum bereits gemeldet. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 09.10.2015, 21:04 Titel: |
|
|
@dreael: Das liegt aber nicht an ScreenEvent sondern an den Ausrufezeichen in den Print-Zeilen.
Diese z.B.:
Code: |
Print "Taste " + Str(e.scancode) + " (ASCII=" + Str(e.ascii) + !" gedr\ückt"
|
|
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4603 Wohnort: ~/
|
Verfasst am: 09.10.2015, 23:28 Titel: |
|
|
Es liegt wohl weder an SCREENEVENT noch am Ausrufezeichen, sondern an der unbekannten Escape-Sequenz \ü. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2509 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 10.10.2015, 18:06 Titel: |
|
|
nemored hat Folgendes geschrieben: | Es liegt wohl weder an SCREENEVENT noch am Ausrufezeichen, sondern an der unbekannten Escape-Sequenz \ü. |
Danke für den Hinweis, sollte natürlich "\129" sein... ;-) Nach dieser Korrektur funktioniert das Beispiel auch wie gewünscht.
Im internationalen Forum denselben Hinweis erhalten. => Bug hat somit nichts mit ScreenEvent() zu tun, sondern kommt bei erweiterten String-Literalen zum Tragen: Das "ü" hätte ganz einfach einen Syntaxfehler generieren müssen (Ziffer erwartet, ungültiges Zeichen in Escape-Sequenz o.ä.), stattdessen wird auf Stufe Assemblercode vom FBC irgend ein Müll generiert (=dies stellt der wirkliche Bug beim aktuellen FBC dar). => bereits auch so im internationalen Forum als Ergänzung mitgeteilt. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
Elor
Anmeldungsdatum: 12.07.2013 Beiträge: 205 Wohnort: Konstanz
|
Verfasst am: 12.10.2015, 11:46 Titel: |
|
|
Beim Beispiel von dreael erzeugt SLEEP, zusammen mit ScreenEvent, nicht immer das was man erwartet. ScreenEvent kann zwar erkennen das eine Taste gedrueckt wurde,
aber nur selten welche (FBC-1.04.0-linux-x86). Gibt man eine Zeit an, Funktionierts wieder,
Mausereignisse sind dann auch wieder verfuegbar. |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2509 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 13.10.2015, 20:09 Titel: |
|
|
Inzwischen noch unter
http://beilagen.dreael.ch/QB/MausEreignis.bas
eine komplettierte Version hochgeladen.
Elor hat Folgendes geschrieben: | Beim Beispiel von dreael erzeugt SLEEP, zusammen mit ScreenEvent, nicht immer das was man erwartet. |
Inzwischen die Sache mit SLEEP verbessert. Was jetzt natürlich noch schön wäre, wäre ein SLEEP, welches erst beim Auftreten eines solchen ScreenEvents "aufwacht" oder alternativ für ScreenEvent() ein Boolean-Parameter für blocking/non-blocking-Verhalten (aktuell ist nur non-blocking unterstützt). -> Müsste ich im internationalen Forum direkt als kleiner Feature Request vorschlagen.
Ich weiss mittlerweilen nur von Python mit der tkinter-Bibliothek, dass sich dort die Events auf einem Canvas-Element sehr ähnlich wie ScreenEvent() aus FB verhalten. Allerdings kann man dort den Prozess echt "schlafen legen" (macht dort alles der mainloop()-Aufruf), bis von der Maus und Tastatur etwas hineinkommt. Typischerweise wird das Ereignis dann als Callback-Prozedur verarbeitet. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
|