Maus loslassen wird null erkannt

Anfängerfragen zum Programmieren mit PureBasic.
Re42
Beiträge: 91
Registriert: 08.11.2020 23:41

Re: Maus loslassen wird null erkannt

Beitrag von Re42 »

Danke, aber Zitat "Das geht so nicht mehr" kann so nicht stimmen, denn genau so geht das ja in meinem ursprünglichen Code, das ist ja das Verrückte. Wie kann das in einem Code gehen und im anderen nicht?

Ich weiß, daß die Maus erst dann den Event erzeugt, wenn man die wieder losläßt, aber trotzdem ist da ein Riesenunterschied zwischen

#PB_Event_LeflClick und #WM_LBUTTONUP

An den Programmstellen, wo "schalt = 2" oder "schalt = 0" steht, ist #PB_Event_LeflClick unbrauchbar, denn in dem Fall darf der Mausklick nur in Programmzeile 79 ausgewertet werden, und nicht zugleich auch weiter oben, der Mauszeiger ist ja dann immernoch auf demselben Schalter! Wenn man an den besagten Stellen #PB_Event_LeflClick statt #WM_LBUTTONUP einsetzt, funktioniert das also nicht mit den Schalterwechseln. Mit #WM_LBUTTONUP funktioniert es, aber eben nur in meinem ersten Code, den ich ändern will.

Beleidigt habe ich PureBasic nirgendwo, oder stimmt es etwa nicht, daß PureBasic bis zum heutigen Tag keinen eigenen Befehl für #WM_LBUTTONUP anbietet? Auch ich finde aber ansonsten PureBasic wirklich super gut gelungen.

Ratschläge nicht annehmen? Wo soll ich das lernen? Dazu müßte ich erstmal genau die richtige Fachliteratur finden.

Eventuell gelingt mir ja eine völlig neue Steuerung für die Schalter, oder ich muß mich eben damit abfinden, daß ich jetzt nur noch umschalten kann zwischen grün-rot, und rot-grün. Danke nochmals an alle.
Zuletzt geändert von Re42 am 27.12.2020 12:28, insgesamt 1-mal geändert.
DarkDragon
Beiträge: 6267
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: Maus loslassen wird null erkannt

Beitrag von DarkDragon »

Wenn du InitMouse aufrufst und einen Screen verwendest, solltest du auch die Mouse Befehle verwenden:

https://www.purebasic.com/documentation ... index.html
https://www.purebasic.com/documentation ... utton.html

Einfach die Änderungen beobachten:

Code: Alles auswählen

ExamineMouse()
LastButtonState = ButtonState
ButtonState = MouseButton(...)

If LastButtonState <> 0 And ButtonState = 0
    ; Released
EndIf
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Re42
Beiträge: 91
Registriert: 08.11.2020 23:41

Re: Maus loslassen wird null erkannt

Beitrag von Re42 »

Danke, davon weiß ich und das könnte ich auch mal ausprobieren, aber soviel ich weiß, hat man dann die Arbeit, erstmal einen eigenen Mauszeiger erzeugen zu müssen. Bleibt aber im Hinterkopf.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Maus loslassen wird null erkannt

Beitrag von ccode_new »

Code: Alles auswählen

If GetAsyncKeyState_(#VK_LBUTTON) & 1
  Debug "linke Maustaste gedrückt."
EndIf 
If Not GetAsyncKeyState_(#VK_LBUTTON) & 1
  Debug "linke Maustaste losgelassen"
EndIf
Das & 1 kann auch weg gelassen werden und dient hier nur für Überprüfungen auf 0 oder 1.
Außerdem ist GetAsyncKeyState_() gängige Praxis.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Maus loslassen wird null erkannt

Beitrag von Mijikai »

Re42 hat geschrieben:...
Ziel der Übung soll sein, daß die Schalter entweder grün oder rot werden, aber niemals beide rot. Im Fall beide grün nehmen dann programmseitig beide Schalter einen Blauton an.
...
Hier mal etwas Code:

Code: Alles auswählen

;Schalter AN = GRÜN
;Schalter AUS = ROT
;Beide Schalter AN = (beide) BLAU
;Beide Schalter AUS = NICHT ERLAUBT -> vertausche AN/AUS

EnableExplicit

Structure BUTTON
  x.f
  y.f
  w.f
  h.f
  ox.f
  oy.f
  state.b[2]
  color.l[4]
EndStructure

Macro InitButton(_btn_,_x_,_y_,_w_,_h_,_s_,_c1_,_c2_,_c3_)
  _btn_\x = _x_
  _btn_\y = _y_
  _btn_\w = _w_
  _btn_\h = _h_
  _btn_\ox = _x_ + _w_
  _btn_\oy = _y_ + _h_
  _btn_\state[0] = _s_
  _btn_\color[0] = _c1_
  _btn_\color[1] = _c2_
  _btn_\color[2] = _c2_
  _btn_\color[3] = _c3_
EndMacro

Macro DrawButton(_btn_,_key_,_x_,_y_)
  _btn_\state[1] = 0
  If _key_
    If _x_ > _btn_\x And _x_ < _btn_\ox And _y_ > _btn_\y And _y_ < _btn_\oy
      _btn_\state[0] ! 1
      _btn_\state[1] = 1
    EndIf
  EndIf
  DrawingMode(#PB_2DDrawing_Default)
  Box(_btn_\x,_btn_\y,_btn_\w,_btn_\h,_btn_\color[_btn_\state[0]])
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(_btn_\x,_btn_\y,_btn_\w,_btn_\h,$666666)
EndMacro

Macro UpdateButtons(_btn1_,_btn2_)
  If _btn1_\state[0] + _btn2_\state[0] = 2
    _btn1_\color[1] = _btn1_\color[3]
    _btn2_\color[1] = _btn1_\color[3]
  Else
    If _btn1_\state[0] + _btn2_\state[0] = 0
      If _btn1_\state[1]
        _btn2_\state[0] ! 1
      Else
        _btn1_\state[0] ! 1
      EndIf
    Else
      _btn1_\color[1] = _btn1_\color[2]
      _btn2_\color[1] = _btn1_\color[2]
    EndIf
  EndIf
EndMacro

Procedure.i Main()
  Protected Dim btn.BUTTON(1)
  Protected up.i
  Protected mx.i
  Protected my.i
  If InitSprite()
    If OpenWindow(0,0,0,600,400,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
      If OpenWindowedScreen(WindowID(0),0,0,600,400)
        SetFrameRate(60)
        InitButton(btn(0),100,100,100,30,#False,$333388,$338833,$883333)
        InitButton(btn(1),100,200,100,30,#True,$333388,$338833,$883333)
        Repeat
          Repeat
            Select WindowEvent()
              Case #PB_Event_LeftClick
                up = 1
              Case #PB_Event_CloseWindow
                Break 2
              Case #Null
                Break
            EndSelect
          ForEver
          mx = WindowMouseX(0)
          my = WindowMouseY(0)
          ClearScreen($0)
          If StartDrawing(ScreenOutput())   
            DrawButton(btn(0),up,mx,my)
            DrawButton(btn(1),up,mx,my)
            UpdateButtons(btn(0),btn(1))
            StopDrawing()
          EndIf
          FlipBuffers()
          up = 0
        ForEver
      EndIf
      CloseWindow(0)  
    EndIf  
  EndIf
  ProcedureReturn
EndProcedure

Main()

End
Benutzeravatar
HeX0R
Beiträge: 2960
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: Maus loslassen wird null erkannt

Beitrag von HeX0R »

ccode_new hat geschrieben:

Code: Alles auswählen

If GetAsyncKeyState_(#VK_LBUTTON) & 1
  Debug "linke Maustaste gedrückt."
EndIf 
If Not GetAsyncKeyState_(#VK_LBUTTON) & 1
  Debug "linke Maustaste losgelassen"
EndIf
& $8000 wäre eigentlich richtig, um den aktuellen Status zu ermitteln.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Maus loslassen wird null erkannt

Beitrag von STARGÅTE »

Das hier wird meine letzte Antwort sein, weil ich das Gefühl habe, dass der Thread im Sande verläuft.

Um den Thread mal (aus meiner Sicht) auf die Ursprungsfrage zusammenzufassen:
Re42 hat geschrieben:Der Debugger liefert nur nach Endif einen Wert (13112), also wird die Abfrage „Maus loslassen“ erst gar nicht erkannt.
13112 ist das Event #PB_Event_LeftClick und bedeutet das die Maus losgelassen wurde.
Re42 hat geschrieben:Beleidigt habe ich PureBasic nirgendwo, oder stimmt es etwa nicht, daß PureBasic bis zum heutigen Tag keinen eigenen Befehl für #WM_LBUTTONUP anbietet?
Das Event #WM_LBUTTONUP wird (under Windows) gesendet wenn die Maus losgelassen wird. Das gleiche (OS-übergreifende Event) signalisiert #PB_Event_LeftClick.
Re42 hat geschrieben:Ich weiß, daß die Maus erst dann den Event erzeugt, wenn man die wieder losläßt, aber trotzdem ist da ein Riesenunterschied zwischen #PB_Event_LeftClick und #WM_LBUTTONUP
Das ist richtig. #PB_Event_LeflClick ist offiziell als WindowEvent() dokumentiert. #WM_LBUTTONUP wird an dieser Stelle ist nicht offiziell dokumentiert.

Ansonsten hat Mijikai dir am ende ja einen Beispielcode für das "Ziel der Übung" gegeben.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Maus loslassen wird null erkannt

Beitrag von ccode_new »

HeX0R hat geschrieben:& $8000 wäre eigentlich richtig, um den aktuellen Status zu ermitteln.
Warum?

Eigentlich brauch man gar kein & dahinter schreiben.
Es sei denn man benutzt noch ein 16 Bit - Windows mit short int, ansonsten ist es doch automatisch ein int.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Re42
Beiträge: 91
Registriert: 08.11.2020 23:41

Re: Maus loslassen wird null erkannt

Beitrag von Re42 »

Danke Mijilai für den Code. Werde ich mir morgen ansehen, heute bin ich zu müde.

@Stargate
Wieso gibt es denn dann auch noch extra #WM_LBUTTONDOWN? Das wertet den Event aus, wenn die Maus gedrückt wurde und #WM_LBUTTONUP wertet den Event aus, wenn sie losgelassen wurde. Wie Windows das intern macht, weiß ich nicht. Auf jeden Fall kann #WM_LBUTTONUP nicht mit #PB_Event_LeftClick ersetzt werden, sonst wäre mein Problem ja gelöst. #PB_Event_LeftClick wertet aus, daß die Maus gedrückt wurde und nicht auch noch das Gegenteil.
DarkDragon
Beiträge: 6267
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: Maus loslassen wird null erkannt

Beitrag von DarkDragon »

ccode_new hat geschrieben:
HeX0R hat geschrieben:& $8000 wäre eigentlich richtig, um den aktuellen Status zu ermitteln.
Warum?

Eigentlich brauch man gar kein & dahinter schreiben.
Es sei denn man benutzt noch ein 16 Bit - Windows mit short int, ansonsten ist es doch automatisch ein int.
https://docs.microsoft.com/en-us/window ... nckeystate
If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState
GetKeyState ist vllt. auch gut, denn bei GetAsyncKeyState sind es roh abfragen:
GetAsyncKeyState(VK_LBUTTON) always returns the state of the left physical mouse button, regardless of whether it is mapped to the left or right logical mouse button. You can determine the system's current mapping of physical mouse buttons to logical mouse buttons by calling GetSystemMetrics(SM_SWAPBUTTON).
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Antworten