OnMouseMove MouseMove



  • OnMouseMove MouseMove wird ständig aufgerufen obwohl die Maus nicht bewegt wird.

    Ich bin etwas verwirrt, ich nutze das Ereignis MouseMove auf meinem Formular um bei Bewegung der Maus etwas auszulösen. Leider wird das Ereignis ständig ausgelöst sobald der Mauszeiger auf dem Formular ist, egal ob die Maus bewegt wird oder nicht. Hab ich das Ereignis falsch verstanden oder was mache ich falsch? Liegt es an der optischen Maus?

    Ich nutze die c++ Builder community edition 10.4 von Embacadero

    void __fastcall TDMForm::MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
    {
    DMTLV();
    }

    Kennt jemand das Problem?

    LG



  • @Skator123 sagte in OnMouseMove MouseMove:

    Leider wird das Ereignis ständig ausgelöst sobald der Mauszeiger auf dem Formular ist, egal ob die Maus bewegt wird oder nicht.

    Was heisst ständig? Alle paar Sekunden? Mehrmals in der Sekunde? 10x, 100x, 1000x, öfter?

    Hab ich das Ereignis falsch verstanden oder was mache ich falsch?

    Nö, ich würde sagen das hast du schon richtig verstanden. Ob du was falsch machst kann ich nicht sagen.

    Liegt es an der optischen Maus?

    Möglich, aber dann müsstest du eigentlich auch den Mauszeiger zittern sehen.



  • Hallo hustbaer, ich konnte das Problem weiter eingrenzen. Beim MouseMove Ereignis rufe ich eine Methode auf in der ich ein Objekt auf dem Bildschirm verschiebe mit

    ButtonDM->Left = random (ClientWidth- ButtonDM->Width - 20);
    ButtonDM->Top = random (ClientHeight- ButtonDM->Height - 100);
    

    dadurch wird offensichtlich das MouseMove ereignis neu ausgelöst. Wenn ich die beiden Befehle auskommentiere funktioniert MouseMove korrekt. Hast du eine Idee warum das so ist?

    Gruß Skator



  • Ich denke, es ist, wenn sich das Objekt unter dem Mauszeiger verändert, daß dann MouseMove dafür aufgerufen wird.

    Du kannst aber einfach ein boolsches Flag benutzen, um diese Rekursion im MouseMove zu unterbinden.



  • @Th69 Ich glaube nicht dass da etwas rekursiv aufgerufen wird. Normalerweise gibt's nen Message-Loop, und den nächsten Mouse-Move bekommt man erst wenn der aktuelle Handler verlassen wurde.



  • @Skator123: Hast du es mal ausprobiert?



  • Ich hab ähnliche Probleme mit dem MouseMoveEvent, das feuert bei einer Komponente auch ständig. Ich hab´s dadurch gelöst, dass ich mir die Mauskoordinaten lokal merke und nur bei echten Änderungen auf das Event reagiere:

    void __fastcall MyForm::OnMouseMove( TObject* Sender, MouseButton Button, TShiftState Shift, int X, int Y )
    {
       static TPoint last = TPoint( -1,-1 );
    
       TPoint curr = TPoint( X, Y );
       if( curr != last )
       {
          last = curr;
          // tu was
       }
    }
    


  • @DocShoe sagte in OnMouseMove MouseMove:

    static TPoint last = TPoint( -1,-1 );
    

    *Schmerzen*



  • @hustbaer sagte in OnMouseMove MouseMove:

    @DocShoe sagte in OnMouseMove MouseMove:

    static TPoint last = TPoint( -1,-1 );
    

    *Schmerzen*

    Alternative?



  • Membervariable?



  • @hustbaer

    Dann schlepp ich das ja da mit, wo ich es überhaupt nicht brauche. Mit meiner Lösung ist der "Schaden" auf die einzige Funktion begrenzt, wo er gebraucht wird. Race conditions können nicht auftreten, da der Aufruf immer aus dem GUI Thread kommt, ich sehe also nix, was dagegen spricht. Außer persönlicher Präferenz.



  • @hustbaer

    Was hältst du denn von solchen Konstrukten?

    void f()
    {
       static bool PreventReentrance = false;
    
       if( !PreventReentrance ) 
       {
          PreventReentrance = true;
          ...
          PreventReentrance = false;
       }
    }
    

  • Mod

    Ist das nicht eine Race Condition, die nur darauf wartet, dass sie explodiert?



  • Jo, denke auch. Hab sowas mal in ´nem Snippet gesehen, hängt vermutlich vom Einsatzbereich ab, wo das eingesetzt wird.


  • Mod

    @DocShoe sagte in OnMouseMove MouseMove:

    Jo, denke auch. Hab sowas mal in ´nem Snippet gesehen, hängt vermutlich vom Einsatzbereich ab, wo das eingesetzt wird.

    Nein, das ist einfach immer falsch, aber viele Leute haben halt einfach kein Bewusstsein für Race Conditions. Fehler dieser Art wirst du tausendfach in Codebeispielen finden, besonders oft sieht man dies bei Dateihandling.



  • @SeppJ

    Du gehst von Multithreading aus, das kann man auch zum Verhindern von endloser Rekursion benutzen. Wenn man seinen Programmablauf nicht im Griff hat.


  • Mod

    @DocShoe sagte in OnMouseMove MouseMove:

    @SeppJ

    Du gehst von Multithreading aus, das kann man auch zum Verhindern von endloser Rekursion benutzen. Wenn man seinen Programmablauf nicht im Griff hat.

    Naja, der gezeigte Code ist ganz eindeutig auf Multithreading bezogen, wo er falsch ist. Ansonsten bist du bei "Leute benutzen if mit globalen Variablen", was natürlich auch oft richtig eingesetzt wird 😉



  • @SeppJ

    Ich weiß zufällig, dass er nicht in Multithreading eingesetzt wird 😉


  • Mod

    @DocShoe sagte in OnMouseMove MouseMove:

    @SeppJ

    Ich weiß zufällig, dass er nicht in Multithreading eingesetzt wird 😉

    Häh? Wieso dann Reentrance (falsch) verhindern?

    das kann man auch zum Verhindern von endloser Rekursion benutzen

    Beziehst du dich darauf? Nutzt hier jemand statische Variablen in einer Rekursion? Das spricht ja noch mehr dafür, dass viele Leute einfach keine Ahnung haben.



  • @SeppJ

    Jetzt muss ich aufpassen, was ich sage. Da könnte jemand sauer auf mich werden. Aber ja, damit wird Rekursion verhindert.


Log in to reply