Problème de message au survol du curseur

Signaler
Messages postés
40
Date d'inscription
mardi 16 mai 2006
Statut
Membre
Dernière intervention
27 octobre 2009
-
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
-
Bonjour à tous,

Je développe une application et j'ai besoin de savoir à un moment donné si le curseur de la souris survole la Form ou si au contraire il est en dehors de la fiche J'ai bien sûr rechercheé des infos à ce sujet sur les forums et j'en un trouvé quelques uns qui aborde ce sujet. Voilà le code que j'ai modifié et mis dans mon application :

Pour l'évènement OnMouseMove de la Form :

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

var
Tag : TagTrackMouseEvent;
b : Boolean;

begin
Tag.cbSize := sizeof(Tag);
Tag.dwFlags := TME_LEAVE;
Tag.hwndTrack := Self.Handle;
Tag.dwHoverTime := 10;
b := TrackMouseEvent(Tag);
// Vérifier que B est True si nécessaire. Indique que TrackMouseEvent à fonctionné.
end;

J'ai placé ce code dans Private?

procedure TForm1.WMMOUSELEAVE(var Message: TMessage);

begin
Label1.Caption := 'la souris a quitté la fiche';
end;

...et j'ai un Timer :

procedure TForm1.Timer1Timer(Sender: TObject);

begin
Label1.Caption := 'la souris est dans la fiche';
FormMouseMove(Self, [SSShift], 0, 0); //Pour rafraîchir la position de la souris
end;

Effectivement, cela fonctionne bien?sauf que sur ma forme j'ai un TEdit, plusieurs TCheckBox, etc. Quand la souris passe sur la form, cela m?indique bien « la souris est dans la fiche » mais le survole d'un des composants affiche le message «'la souris a quitté la fiche' » alors que le curseur est bien positionné sur la fiche. J'i essayé tout de sorte de manip mais je n'arrive à comprendre pourquoi ?

Je n'ai qu'une fiche dans mon application avec des composants : TEdit, TCheckBox et TGroupBox. Quand je passe sur un GroupBox par exemple, il me dit que je suis hors de la fiche, ce qui n'est pas le cas. Si le curseur survole la fiche entre les composants, il m'indique bien que je suis sur la fiche et non pas dehors.

En fait, j'ai besoin de cette information pour dire au Timer : je suis sur la forme dont tu bosses (Timer1.OnTimer := Timer1Timer) ou je ne suis pas sur la fiche alors tu ne travaille pas (Timer1.OnTimer := nil).

C'est pas aussi simple à résoudre, merci pour vos idées !

Merci pour votrer aide.

Cordialement

19 réponses

Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
jaune sur fond blanc ... grrr!
y'a une balise code vindious!
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Aaaah mes yeux !

Cordialement, Bacterius !
Messages postés
40
Date d'inscription
mardi 16 mai 2006
Statut
Membre
Dernière intervention
27 octobre 2009

Désolé Bactérius, j'ai du faire une fausse manipulation, je dépose la code en "jaune" pour qu"il ne fasse pas mal au yeux :


procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

var
Tag : TagTrackMouseEvent;
b : Boolean;

begin
Tag.cbSize := sizeof(Tag);
Tag.dwFlags := TME_LEAVE;
Tag.hwndTrack := Self.Handle;
Tag.dwHoverTime := 10;
b := TrackMouseEvent(Tag);
// Vérifier que B est True si nécessaire. Indique que TrackMouseEvent à fonctionné.
end;

Avez-vous une idée pour le problème que je rencontre ? Je ne dois pas être le seul !

Merci pour vos idées !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Hmm ... il doit exister une solution :

Dans un timer (réglé à 100 ms intervalle) :

procedure TForm1.Timer1Timer(Sender: TObject);
Var
 P: TPoint;
begin
 P := GetCursorPos;
 if PtInRect(P, ClientRect) then // souris dans la fiche else // souris en dehors
end;


Mais bon, c'est moche, et il doit exister une API ?

Cordialement, Bacterius !
Messages postés
40
Date d'inscription
mardi 16 mai 2006
Statut
Membre
Dernière intervention
27 octobre 2009

Bonjour Bactérius,

J'ai essayé ton code, j'avais oublié cette façon de faire mais cela donne toujours le même résultat. Si effectivement le
curseur est bien dans la fiche, quand je survole sur certains composants, il m'indique que je suis hors de la fiche
alors que ce n'est pas le cas. Donc, je ne peux pas être sûr m'appuyer sur cette information pour faire le traitement souhaité. J'ai même essayé ça :

if ((SourisX > Left) and (SourisX > Top)) and ((SourisY < ClientWidth) and (SourisY < ClientHeight))
then LOuEstSouris.Caption := 'la souris a quitté la fiche'
else LOuEstSouris.Caption := 'la souris est dans la fiche';

Même résultat !

Je dois penser autrement mais si vous avez une solution, je suis preneur.

Bonne journée à vous tous ..
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Ca n'a pas de sens ! A mon avis tes coordonnées de souris sont incorrectes, sinon même la solution avec le PtInRect devrait marcher ... et cela en dépit des composants dans la fiche !! Quels sont les composants fautifs, cite un exemple ?

Cordialement, Bacterius !
Messages postés
40
Date d'inscription
mardi 16 mai 2006
Statut
Membre
Dernière intervention
27 octobre 2009

Oui je sais bien que ça n'a pas de sens et j'essaye de comprendre. Par exemple le TCheckBox, le TGroupBox, le TButton, pratiquement tous.

Le survole entre deux composants fonctionne puisque je suis sur la forme mais dès que je passe dans la surface d'un composant (donc enfant de la forme) je suis en dehors de la fiche ! Impressionnnt alors que le cuseur est dasn la surface de la forme !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
T'es sûr que t'as pas gardé un morceau de code foireux dans le OnMouseLeave de la fiche ? Le code que je te propose se résume au test dans un Timer et toute autre configuration l'inhibe.

Cordialement, Bacterius !
Messages postés
40
Date d'inscription
mardi 16 mai 2006
Statut
Membre
Dernière intervention
27 octobre 2009

Non Bactérius, j'ai supprimé le code de OnMouseLeave qui faisait appel à WM_MESSAGE. Je suis parti sur ton code mais j'ai toujours le même résultat. Depuis, j'ai modifié mon programme pour qu'il réagisse comme je le souhaitais : sotin en mode loupe, soit en mode "appareil photo". Mais avoir la solution, ça m'intéresse beaucoup pour comprendre. Merci de t'y intéresser !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Peux-tu recopier l'intégralité de ton code fautif sur le forum ? (utiliser la balise, qui se trouve sur un des boutons de la textbox).

Cordialement, Bacterius !
Messages postés
4
Date d'inscription
lundi 17 avril 2006
Statut
Membre
Dernière intervention
5 octobre 2009

ton problème est très facile
seulement utilisez 1 timer
l'interval de ce timer = 1 pour qu'à chaque 1 milli-seconde vous pouvez connaitre si la souris est sur la fiche ou non

dans la procedure d'evennement du timer ecrivez le code suivant:

if (mouse.CursorPos.X >= Left) and (mouse.CursorPos.X <= Left+width) and (mouse.CursorPos.Y>=top) and (mouse.CursorPos.Y<=top+height) then
caption:= 'la souris et dans la fiche'
else
caption:= 'la souris et hors la fiche';
---------------------------------------------
c'est tout
que dieu vous aide
ton frère hichem
q_|_| | \)| q_| | \)
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Ca revient à un "PtInRect" comme j'avais proposé, mais il semble que ça ne marche pas ...

Cordialement, Bacterius !
Messages postés
40
Date d'inscription
mardi 16 mai 2006
Statut
Membre
Dernière intervention
27 octobre 2009

Bonjour Bactérius,

Pour simplifier, je me suis fait un tout petit projet avec juste un TGroupBox + un TCheckBox + un TBouton. J'ai placé ton code dans le timer (j'ai même essayé dans un les MouseMove de la forme et des composants). J'obtient toujours le même résultat !

Par contre, je me suis aperçu d'une anomalie : j'ai placé deux labels supplémentaires pour X et Y sur la fiche qui sont réactualisés par le OnMouseMove de la forme.

Alors qu'à un moment donné j'obtient X 432 et Y 186, je devrais être hors de la forme puisque celle ci à une dimension de Width = 425 et Height = 225. Donc normalement, ma souris étant au point 432.186, elle devrait être en dehors de la fiche !

Il ya un décalage entre les informations de position de la souris ? Les valeurs sont celles du bureau et non pas de la forme ,

Cordialement
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Dans ce cas-là joue avec ClientToScreen et ScreenToClient ... problème résolu je pense après ça.

Cordialement, Bacterius !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
@VoicedMirror : juste une petite chose dans ton code :

tform(childcontrol).onmousemove:= formmousemove;


Pourquoi transtyper en TForm et pas en TControl (la plus haute classe qui possède OnMouseMove) ?

Cordialement, Bacterius !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Euh oui la plus basse si tu veux. Moi je vois plutôt la hiérarchie de la VCL de haut en bas (TObject tout en haut, et des centaines de ramifications tout en bas). Mais d'autres peuvent la voir à l'envers, ou même sur le côté

Cordialement, Bacterius !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
...

Cordialement, Bacterius !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Je me demande d'ailleurs comment font les developpeurs chinois.


Eh ben ils la lisent de droite à gauche, culture oblige ... mais ça ne pose pas trop de problèmes puisqu'il suffit de se dire "objet avant hérite d'objet d'après" plutôt que le contraire chez nous autres occidentaux.

Cordialement, Bacterius !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Oui mais dans l'aide de Delphi, TObject est tout en haut ! Na !

Cordialement, Bacterius !