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=0Ich 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.