Récupérer position du curseur sur une Form tranparente

Résolu
Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022 - 31 mars 2016 à 18:18
Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022 - 4 avril 2016 à 17:49
Bonjour,
Récupérer la position du curseur dans une Form n'est pas vraiment un problème. Mais cela semble plus compliqué si le BackColor de cette Form est transparent. Autrement dit si la valeur de la propriété TransparencyKey de la Form est égale à Celle du BackColor.
Auriez-vous une solution? D'avance je vous fais part de mes sincères remerciements.

8 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 31/03/2016 à 20:21
Si (et seulement si), à la fois :
- l'évènement Mouse_Move "échappe" sous VB.Net à un Form Transparent
- VB.Net n'a pas de solution native (évènement autre)
Tu peux toujours utiliser un Timer et ce dont je t'ai parlé dans mon premier message...

________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
3
bonjour,
le souci ne viens du fait qu'il n'y ait pas de bordure mais plutôt du TransparencyKey identique au BackColor. Ayant déjà été confronté a ce problème je l'ai pallier en récupérant la position de la sourie a l'écran et en y soustrayant la position de la form.
Voici un petit exemple, qui détecte également les clic gauche et droit de la sourie en espèrent que cela t'aide.


Private Delegate Sub delegPositionChange(ByVal PositionSourie As Point)
Private Position As Point

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Timer1.start()
End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

If Me.InvokeRequired Then
Me.Invoke(New delegPositionChange(AddressOf AffichePosition), Position)
End If

AffichePosition(Control.MousePosition)

If Control.MouseButtons = Windows.Forms.MouseButtons.Left Then
'clic gauche
End If

If Control.MouseButtons = Windows.Forms.MouseButtons.Right Then
'clic droit
End If

End Sub

Private Sub AffichePosition(ByVal PositionSourie As Point)

Dim PositionForm As Point = New Point(Me.Location.X, Me.Location.Y)

Dim PositionSourieForm As Point = New Point(PositionSourie.X - PositionForm.X, PositionSourie.Y - PositionForm.Y)

If PositionSourieForm.X > 0 And PositionSourieForm.Y > 0 And PositionSourieForm.X < Me.Width And PositionSourieForm.Y < Me.Height Then
Label1.Text = PositionSourieForm.X
Label2.Text = PositionSourieForm.Y
Else
Label1.Text = "Hors Form"
Label2.Text = "Hors Form"
End If

End Sub

3
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 1/04/2016 à 13:22
Bonjour, Rykudos,
Je pense que tu n'as pas tout lu ....
Et tant qu'à utiliser un timer (lourd, lourd, comme je l'ai dit plus haut), autant le faire plus "proprement"
0
Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022 1
2 avril 2016 à 12:21
Bonjour,
Merci encore pour toutes vos critiques. L'utilisation du timer malgré sa lourdeur, fonctionne mais avec quelques imperfections:
Si à la position du curseur (par rapport à l'écran), on retranche celle du Form et que l'on espionne la valeur obtenue que lorsqu'il est strictement à l'intérieur du dit Form, on doit avoir des valeurs comprises entre 1 et la (largeur -1) ou la (hauteur - 1) du Form. Mais du fait que l'on utilise un timer, ces valeurs ne sont imprécises lors des franchissements des bordures du Form et varient.
C'est un réel plaisir de vous lire ...
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211 > Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022
2 avril 2016 à 12:45
Pas lorsque l'on a défini le rectangle normalement (avant "transparence") occupé par le form, que l'intervalle du timer est à son minimum, et que l'on subordonne le tout à des conditions arithmétiques précises (et au besoin "rectificatives"). Je sais faire la chose sous VB6 "depuis kala kala ."..
Ce procédé n'est à mon sens toutefois nullement à conseiller.
0
Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022 1
4 avril 2016 à 17:49
Merci encore à vous tous, grâce à votre aide j'ai pu terminer mon petit projet dont voici les grandes lignes.
Mon Pc étant sous Wind 10. Pour quitter Windows ou faire un redémarrage ou le mettre en veille prolongée il me faut:
1 - Cliquer sur l’icône de Windows (à gauche dans la barre de tâches)
2 - Cliquer sur le bouton Marche/Arrêt.
3 - Cliquer une dernière fois pour faire mon choix
Projet:
3 boutons inclus dans un Form transparent (pour le fun), après avoir épinglé l’icône de l'appli dans la barre de tâches, j'obtiens quelque chose de plus léger et de plus court que la démarche standard pour quitter Windows, Il suffit de:
1 - cliquer sur l’icône appropriée de la barre de tâche qui fera apparaitre les 3 boutons (le Form les contenant étant déplaçable où bon nous semble grâce à une poignée qui apparait quand le curseur passe au dessus) et il n'y a plus se cortège de tuiles et autres menus accompagnants. si l'on clique en dehors du Form, l'appli se termine les boutons disparaissent.
2 - On clique sur l'un des boutons, Windows se ferme ou redémarre ...
Il ne reste plus qu'à faire en sorte que l'utilisateur puisse choisir les icônes des boutons.
Remarque:
Avec 3 raccourcis programmés sur le bureau de Windows on obtiendrait le même résultat mais avec 2 inconvénients, les raccourcis sont toujours visibles et il faut faire des doubles cliques pour exécuter leurs codes.
Ce fut un plaisir ...
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
31 mars 2016 à 19:13
Bonjour,
Dès lors que tu ne précises pas si cette "récupération de position du curseur" doit se faire dans un évènement Mouse_Move, je vais te répondre ainsi :
- on peut toujours extraire la position du curseur par rapport à l'écran
- on peut toujours extraire les coordonnées (Left et Top) du form actif
- le reste n'est qu'arithmétique.
Si, maintenant, tu souhaites faire cela dans l'évènement de déplacement sur ton Form (au Mouse_Move, donc), c'est autre chose... Mais comme tu n'en as rien dit, ma foi ... tu as ta réponse.
2
Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022 1
31 mars 2016 à 19:39
Merci pour ta réponse, je croyais avoir été clair en disant "dans mon Form", mais il semble que non ... Alors je précise, cette récupération se fait lors d'un Mouse_Mouve avec le BackColor du Form transparent: c'est avec la valeur de la propriété TransparencyKey du Form = BackColor du Form que plus rien ne fonctionne. Voici le code que j'utilise:

Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
Label1.Text = CStr(e.X)
Label2.Text = e.Y.ToString
End Sub
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211 > Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022
31 mars 2016 à 19:55
Ben non : récupérer une position sur un Form ne dit en rien si dans évènement ou à la demande !
Mais je laisse le soin de te répondre à un spécialiste VB.Net (qui n'est pas mon langage de développement).
Essaye simplement dorénavant d'être extrêmement précis dans l'exposé d'une difficulté. Cela évitera des pertes de temps.
0
Whismeril Messages postés 19035 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 1 mai 2024 656
31 mars 2016 à 21:06
Bonsoir,

cela vient du fait que la Form n'est pas transparente, mais évidée.
Si tu as un raccourci sur ton bureau, tu verras que tu peux cliquer dessus au travers de ta form.

Est ce que jouer sur l'opacité répondrait à ton besoin?
2
Whismeril Messages postés 19035 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 1 mai 2024 656
31 mars 2016 à 21:24
0
Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022 1 > Whismeril Messages postés 19035 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 1 mai 2024
31 mars 2016 à 22:50
J'utilise vb express 2013, j'ai essayé le code trouvé à cette adresse et j’obtiens un BackColor blanc et non transparent, le résultat est surprenant
Merci pour ton aide.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 1/04/2016 à 07:06
Je ne comprends pas vraiment l'utilité de tout cela, mais voici quelques réflexions :
1) un form "évidé" (pour reprendre l'expression utilisée par Whismeril), n'est "présent" que là où il "est" (les "évidements" n'en sont pas des parties) et ne subit donc des évènements que là où il est.
2) un form translucide (opacité réduite) occupe toute son aire (rectangle) et laisse entrevoir ce qui se trouve sous lui, mais on ne peut évidemment intervenir sur les objets qu'il "recouvre". Il conserve, lui, la totalité de ses évènements.
3) vouloir le beurre et l'argent du beurre étant une démarche utopique, il va falloir choisir entre ce que l'on veut (1) ou 2))
4) si l'on choisit le 1) : plusieurs possibilités, qui relèvent toutes de l'ingéniosité, mais ajoutent des lourdeurs inévitables :
J'ai cité par exemple plus haut l'utilisation d'un timer pour relever en son "tick" la position du curseur sur l'écran et agir conditionnellement sur le form.
Il y en a d'autres (plus lourdes encore)
5) si l'on choisit le 2) : ===>> j'"ai lu dans vos messages que des difficultés étaient rencontrées pour donner au form une translucidité.
Qu'à cela ne tienne. Si VB.Net présente une carence, elle peut être contournée en utilisant directement les fonctions de l'A1pi de Windows.
Voilà ce que je ferais, par exemple, sous VB6 :
a) les déclarations des fonctions
Private Declare Function SetWindowLong Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function SetLayeredWindowAttributes Lib "USER32" (ByVal hWnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long

Ces déclarations sont à modifier légèrement sous VB.Net (les types Long)
b) deux exemples de leur utilisation :
exemple 1 :
SetWindowLong Me.hWnd, (-20), &H80000
SetLayeredWindowAttributes Me.hWnd, 0, 155, &H2

exemple 2 :
SetWindowLong Me.hWnd, (-20), &H81000
SetLayeredWindowAttributes Me.hWnd, 0, 100, &H3

(ou Me.hwnd est le handle du form)
6) une autre démarche (mais elle dépend considérablement du but recherché) serait de ne toucher ni à la transparence ni à la translucidité du form et de lui attribuer (s'il a, comme sous VB6, une propriété Picture) l'image de la partie de l'écran qu'il recouvre. On voit tout de suite la lenteur induite puisqu'il faudra modifier cette image tout au long des déplacements éventuels du Form. Et là également, il faudrait (c'est du moins une nécessité sous VB6) utiliser des fonctions de l'Api de Windows pour extraire l'image occupée par le rectangle correspondant de l'écran...
Voilà ... ce n'étaient qu'une partie de mes réflexions à ce sujet. Je vous laisse maintenant "voir" ...

----

________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
2
Whismeril Messages postés 19035 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 1 mai 2024 656
1 avril 2016 à 07:09
Bonjour,

donc comme tu le dis Uc tu cherches à avoir le beurre et l'argent du beurre?

Oriente toi alors sur le "hook de souris", https://support.microsoft.com/fr-fr/kb/319524
qui fait intervenir user32, comme Uc te l'as proposé.
2
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
1 avril 2016 à 07:17
Salut, Whism,
Le harponnage de la souris est également une solution possible.
Mais comme tout harponnage, elle nécessite l'absence totale (et donc une parfaite maîtrise) de tout défaut dans son application (pas uniquement dans cette partie-là de l'application). (gaffe, surtout, aux sorties intempestives).
Amitiés
0
Magentha Messages postés 28 Date d'inscription jeudi 1 septembre 2005 Statut Membre Dernière intervention 14 avril 2022 1
31 mars 2016 à 22:17
Merci pour vos réponses.
Mon projet est de créer des contrôles Boutons dans un Form et du fait que celui-ci soit transparent et que sa propriété BorderStyle soit sur "None"; d'avoir à l’exécution du code l'impression de boutons volants ou appartenants au fond d'écran du PC.
Il serait intéressant de pouvoir positionner cet ensemble de boutons sur l'écran selon son bon vouloir, pour cela il me semble nécessaire de pouvoir déterminer la position du curseur ainsi que l'évènement MouseDown pour pouvoir draguer le Form sur l'écran.
Si vous avez une idée du code nécessaire merci pour votre aide ...
1
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
1 avril 2016 à 07:39
Les problèmes rencontrés résultent du fait que son form est sans sans bordure (raison pour laquelle il cherche à utiliser son évènement Mouse_move pour pouvoir le déplacer).
Il serait dans ce cas nettement moins "onéreux" de prévoir un bouton (un contrôle quelconque, en fait) ajouté à son form là où le veut. Il suffirait alors, dans l'évènement Mouse_move de CE contrôle, de provoquer le déplacement du Form (et non du contrôle dans le form).
1
Whismeril Messages postés 19035 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 1 mai 2024 656
1 avril 2016 à 11:50
Bonjour,

Pas bête du tout ça!
0
Rejoignez-nous