OnMouseOver

Hi,

gibt es irgendeine Möglichkeit, eine ‚echte‘ OnMouseOver-Ereignisbehandlung (ähnlich wie in JavaScript) zu schreiben? Das normale OnMouseMove von Delphi reicht nicht; ich brauche irgendwas, womit ich auf das VERLASSEN des Bereiches reagieren kann.

Gruß, Steffen

Wenn du beispielsweise Buttons farblich hervorheben willst, wenn die Maus darüber steht, dann schreib noch einen OnMouseMove-Handler auf der Parent-Form, der die Farbe der Buttons prüft:

if Button1.Font.Color = clRed then
Button1.Font.Color := clWindowText;

(wenn diese mit Rot geflasht werden)

Danke. So mache ich das bisher. Leider funktionierts nicht immer 100pro, da bei sehr schnellen Mausbewegungen manchmal das OnMouseMove-Ereignis des Formulars ausgelöst wird. In dem Fall würde der Button Rot bleiben.

Gruß, Steffen

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Steffen,

da mußt das MouseMove-Ereignis der Parent-Form wie folgt behandeln

var q:boolean; //in der ParentForm definieren

wenn nicht MausAufBereich(X,Y) und q then (MausHatBereichVerlassen)
q:=MausAufBereich(X,Y)

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Manfred,

ist ja so ähnlich, wie Roger vorgeschlagen hat. Leider kann der Mauszeiger das Parent-Formular auch mit einer so schnellen Bewegung verlassen, daß das OnMouseMove-Ereignis des Formulars nicht ausgelöst wird. Und was dann?

Gruß, Steffen

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Tach alle miteinander,

Interessantes Posting!
Was ich machen würde (die Idee hatte ich gerade), ist einen
den Maus-Event global zu hooken (hä?), und zwar über die
WINAPI-Funktion

SetWindowsHookEx(WH_MOUSE, MouseHookCallBack, HInstance, 0);

Leider brauch man dazu eine DLL, was ich nicht mag, aber egal.
Wenn man das richtig aufsetzt, wird für ALLE Mausbewegungen,
egal, welche Applikation gerade den Fokus hat, die MousHookCallBack routine, die sich in der DLL befinden muss,
aufgerufen. Die kann dann an deine Applikation eine Message
schicken, das die Maus sich bewegt hat (und natürlich wohin)
und Du kannst dann entscheiden, ob der Button rot oder blau ist.

Auf Anfrage versende ich meinen globalhooker gerne (aber er nuked das system, wenn man was falsch macht!)

mfg
Mark

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Steffen,

wenn die Maus so schnell bewegt wird, das vor dem MausVerlässtBereich kein MausIstImBereich erkannt wird, ist m.E. diese Information auch in Windows nicht vorhanden und kann dann auch nicht von Delphi verarbeitet werden. Ein Hook hilft dann auch nicht weiter.

Mich würde interesssieren, ob dieses Problem von Javascript zuverlässig gelöst wird; wenn ja, muß die Information ja in Windows vorhanden sein.

Manfred

Hallo Manfred,

ist ja so ähnlich, wie Roger vorgeschlagen hat. Leider kann
der Mauszeiger das Parent-Formular auch mit einer so schnellen
Bewegung verlassen, daß das OnMouseMove-Ereignis des Formulars
nicht ausgelöst wird. Und was dann?

Hi Mark,

kannst Du mir ein Beispiel über die verwendung eines Hooks geben? ich hab´ das vor längerer Zeit schon mal probiert, hat aber nicht geklappt.

Manfred

Hallo, an alle!

Hab ein vergleichbares Problem:
Ich arbeite mit einem TabbedNotebook; leider gibt es hier keinen OnMouseMove Befehl wie etwa in der Parent Form, um den Button den Befehl zu geben, dass dieser wieder in der Ursprungsfarbe erscheint.

Gibts da doch eine einfache Möglichkeit?

Hi Mark,

klingt gut. Ich denke, das ist es, wonach ich gesucht habe.
Soweit ich den Befehl begriffen habe, braucht man für die Callback-Funktion keine DLL, eine ganz normale function (keine Methode) sollte es auch tun.

Gruß, Steffen

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Steffen,
Leider falsch. Ohne DLL geht das eben nicht systemweit. Der Grund ist folgender: Wenn Du eine Callback-routine, die sich in Deiner Applikation befindet, systemweit einklinksen würdst, wird
diese Adresse ab jetzt (bis zum UnHook) immer aufgerufen, EGAL, ob deine Applikation noch läuft, oder nicht. Was ist wenn sie nicht mehr im Speicher ist und der Hook ist immer noch aktiv?
PENG Windows wech!

Damit Windows da nicht in die Pampa läuft, verbiedet es einfach einen systemweiten Hook, wenn die Callbackroutine sich in einer EXE-Datei befindet.
Ist die Callbackroutine dagegen in einer DLL, kann sie ja immer aufgerufen werden, da Windows kontrolliert, wann die DLL rausfliegt.

Eine Methode braucht das wirklich nicht zu sein, Methoden unterscheiden sich ja eigentlich nicht von Funktionen. Es ist eine Sprung-Adresse, nicht mehr- und nicht weniger

Viel spass beim knobeln

mark

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Manfred,
Beispiel wofür?
WIE man es macht, oder WOZU man es braucht?
WIE:
function MouseHookCallBack(Code: integer; Msg: WPARAM; MouseHook: LPARAM): LRESULT; stdcall;
begin

if Msg=WM_MOUSEMOVE then
With MouseHookStruct^ Do Begin PostMessage(MonitorWnd, WM_MONITORMOUSEMOVE, pt.x, pt.y);

Result := CallNextHookEx(hkMouse, Code, Msg, MouseHook);
end;

MonitorHwnd ist das Window-Handle deiner TForm.
Const WM_MONITORMOUSEMOVE = WM_USER + 1;
In TForm:
OnCreate = SetWindowsHookEx(WH_MOUSE, MouseHookCallBack, HInstance, 0);

OnDestroy = UnhookWindowsHookEx(hkMouse);

Und dann noch eine
private Procedure TForm1.cmMouseMoved (Var Msg : TMessage); message WM_MONITORMOUSEMOVE;

WOZU? z.B. um Buttons rot/blau zu färben. Oder Passwörter auszuspähen. Oder festzustellen, ob jemand am PC sitzt und was macht etc. Oder als Maus/Keyboard-Recorder für Windows-Skripte oder so.
Andere Hooks dienen z.B. zur Speicherüberwachung oder allgemein zur Überwachung wer wann welche WinApi-Aufrufe benutzt. Will man die blocken? etc etc etc

mfg

Mark

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Mark,

Danke für Deine Hilfe,
Meine Frage war nach dem Wie
Leider weiß ich bei Deinem Code noch folgendes nicht

Definition MouseHookStruct^´

Die Function MouseHookCallBack wird aber nur aufgerufen wenn ich mich mit der Maus auf dem Formular befinde.

Manfred

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

mh…is ein hook net etwas überdimensioniert?

ih denke auf cm_Mouseenter und cm_Mouseleave reagieren sollte reichen…

gruss

rq

Hi Rüdiger,

klingt interessant. Hast Du irgendwelche genaueren Infos? Ich konnte in der Win32help keine Angaben über CM_Mouseenter oder sonstige CM_-Messages finden.

Gruß, Steffen

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

kleines Beispiel

uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TURLLAbel = class(TLabel)
private
{ Private-Deklarationen }
protected
{ Protected-Deklarationen }
procedure cmMouseenter(var Msg: TMessage); message cm_MouseEnter;
procedure cmMouseLeave(var Msg: TMessage); message cm_MouseLeave;
public
{ Public-Deklarationen }
published
{ Published-Deklarationen }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents(‚Beispiele‘, [TURLLAbel]);
end;

{ TURLLAbel }

procedure TURLLAbel.cmMouseenter(var Msg: TMessage);
begin
Cursor:=crHandPoint;
Font.Color:=clBlue;
end;

procedure TURLLAbel.cmMouseLeave(var Msg: TMessage);
begin
Cursor:=crdefault;
Font.Color:=clWindowText;
end;

Gruss RQ

Hallo Rüdiger,

Danke für das Beispiel; die Messages sind also in Control definiert. Schade, daß ich nur mit der Std-Version fahre…
Geht aber trotzdem nicht so ganz: wie mir scheint, reagiert CM_MouseLeave auch nicht 100pro auf extrem schnelle Mausbewegungen.

Gruß, Steffen

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]