CM_MOUSELEAVE / CM_MOUSEENTER bei TImage



  • Hallo!

    Ich weiß, dies wurde ähnlich schonmal hier gefragt:
    http://www.c-plusplus.net/forum/viewtopic.php?t=61190&start=0

    Ich habe das 2. Beispiel von Andreas ausprobiert, und es funktioniert auch ohne Probleme. Wenn ich über ein Objekt auf der Form gehe, wird "CMMouseEnter" aufgerufen. Jetzt möchte ich jedoch, abhängig von der Komponente, die "CM_MOUSEENTER" auslöst, ein anderes Ereignis ausführen.
    Dabei kommt es zu einer Exception (EAccessViolation):

    void __fastcall TForm5::CMMouseEnter(TMessage* Message)
    {
    if(Message->LParam==(Longint)Image2) // Hier kommt der Fehler
    Application->MessageBoxA("Hallo","Test",MB_OK);
    Paint();
    }
    

    Ich habe mal nachgeguckt und festgestellt, das "Message->LParam=???" angezeigt wird (wenn ich Debugge).

    Weiß jemand weiter?



  • Problem gelöst!

    Wenn man Andreas' Beispiel ein wenig verändert klappt das ganze:
    Wichtig dabei war der Wechsel von "TMessage *" zu "TMessage &":

    in der .H:

    private:	// Anwender-Deklarationen
      void __fastcall CMMouseEnter(TMessage & Message); // Vorher:
      void __fastcall CMMouseLeave(TMessage & Message); // "TMessage * Message"
    public:		// Anwender-Deklarationen
    	__fastcall TForm5(TComponent* Owner);
    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(CM_MOUSEENTER, TMessage , CMMouseEnter); // Vorher
        MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage , CMMouseLeave); // "TMessage *"
    END_MESSAGE_MAP(TForm);
    


  • CM_MOUSEENTER und CM_MOUSELEAVE würde ich nicht verwenden, da bei sehr schnellen Mausbewegungen die Message nicht mehr an die Komponente gesendet wird, wenn sich die Maus ausserhalb des Hauptfensters befindet. Liegt daran, dass die Messages halt nur gesendet werden, wenn die Maus idle ist, was aber bei einer schnellen Bewegung nicht der Fall ist.

    Sauberer ist es allemal das Ganze mit TrackMouseEvent zu machen.



  • There is one weakness in this mechanism: if the user moves the mouse out
    of the control very fast and ends up outside the applications window the
    Idle method may not be called (since the app receives no mouse move
    messages) and so your control will not get a CM_MOUSELEAVE, until the
    mouse enters the applications window again. You can fix that by dropping
    a timer (say with an interval of 250 msecs) onto the form, with an empty
    OnTimer event. The generated timer messages will make sure Idle is called
    regularly.


Log in to reply