Comment savoir si la souris se trouve sur une fenêtre de niveau supérieur? Par "over", je veux dire que le pointeur de la souris est dans le rectangle client de la fenêtre de premier niveau et il n'y a pas d'autre fenêtre de haut niveau sur ma fenêtre à l'emplacement du pointeur de la souris. En d'autres termes, si l'utilisateur cliquait sur l'événement, celui-ci serait envoyé à ma fenêtre de niveau supérieur (ou à l'une de ses fenêtres filles). J'écris en C# en utilisant Windows Forms, mais ça ne me dérange pas d'utiliser p/invoke pour faire des appels Win32.Comment puis-je savoir si la souris se trouve sur une fenêtre de niveau supérieur?
Répondre
Vous pouvez utiliser la fonction WinAPI WindowFromPoint
. Sa signature C# est:
[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(POINT Point);
Notez que POINT
ici ne sont pas les mêmes que System.Drawing.Point
, mais PInvoke fournit a declaration for POINT
that includes an implicit conversion between the two.
Si vous ne connaissez pas encore la position du curseur de la souris, GetCursorPos
le trouve:
[DllImport("user32.dll")]
static extern bool GetCursorPos(out POINT lpPoint);
Cependant, le WinAPI appelle beaucoup de choses « fenêtres »: contrôles à l'intérieur d'une fenêtre sont également des « fenêtres ». Par conséquent, vous ne pouvez pas obtenir une fenêtre de niveau supérieur dans le sens intuitif (vous pouvez obtenir un bouton radio, panneau ou autre chose). Vous pouvez appliquer itérativement la fonction GetParent
à marcher dans la hiérarchie GUI:
[DllImport("user32.dll", ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
Une fois que vous trouverez une fenêtre sans parent, cette fenêtre sera une fenêtre de niveau supérieur. Puisque le point que vous avez passé à l'origine appartient à un contrôle qui n'est pas couvert par une autre fenêtre, la fenêtre de niveau supérieur est nécessairement celle à laquelle le point appartient.
Après avoir obtenu le handle de fenêtre, vous pouvez utiliser Control.FromHandle() pour obtenir une référence au contrôle. Ensuite, vérifiez la position relative de la souris pour voir si c'est la zone cliente du formulaire ou du contrôle. Comme ceci:
private void timer1_Tick(object sender, EventArgs e) {
var hdl = WindowFromPoint(Control.MousePosition);
var ctl = Control.FromHandle(hdl);
if (ctl != null) {
var rel = ctl.PointToClient(Control.MousePosition);
if (ctl.ClientRectangle.Contains(rel)) {
Console.WriteLine("Found {0}", ctl.Name);
return;
}
}
Console.WriteLine("No match");
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr WindowFromPoint(Point loc);
Dans quelles circonstances la souris ne sera-t-elle pas dans la fenêtre retournée par WindowFromPoint? –
@Daniel - à la demande de l'OP, lorsque la souris se trouve dans la zone non-client de la fenêtre. Comme la frontière et la légende d'un formulaire. –
@Daniel, juste un supplément supplémentaire, vous pouvez utiliser 'GetWindowLongPtr()' directement pour vérifier s'il s'agit d'une fenêtre de niveau supérieur. Passez le paramètre 'GWL_EXSTYLE' au paramètre' nIndex', puis utilisez l'opération au niveau du bit sur le résultat de la fonction pour vérifier si elle contient la valeur 'WS_EX_TOPMOST'. – Vantomex
- 1. Comment savoir dans quel moniteur une fenêtre WPF se trouve
- 2. Comment savoir si un pointeur de la souris se trouve sur un élément particulier de la page?
- 3. Rechercher si QTreeWidgetItem est de niveau supérieur
- 4. Coin arrondi non pixélisé pour la fenêtre de niveau supérieur
- 5. Comment puis-je trouver ou enregistrer la fenêtre de niveau supérieur X11 à partir de laquelle une fenêtre de niveau supérieur a été ouverte?
- 6. pour savoir si la souris se déplace sur le contrôle ou un point sur l'écran
- 7. GTK/GDK Comment savoir si une fenêtre est superposée par une autre fenêtre?
- 8. Comment savoir si mon composant Java se trouve dans une applet?
- 9. Comment savoir si une instance nommée se trouve dans le conteneur dans StructureMap 2.6?
- 10. trouver le widget de niveau supérieur sur une fenêtre non active en qt
- 11. Comment vérifier si mon itérateur ne se trouve sur rien
- 12. Comment savoir si une souris survole un élément
- 13. Firefox: Obtenir les coordonnées de la souris du coin supérieur gauche de la fenêtre
- 14. Comment savoir si une fenêtre est active? (Win32 API)
- 15. Comment puis-je savoir si un fichier javascript a déjà été inclus dans une page de niveau supérieur?
- 16. comment savoir si la fenêtre est ouverte - PHP/Javascript?
- 17. comment puis-je contrôler l'opacité et l'ordre z de la fenêtre de niveau supérieur dans WPF?
- 18. Comment savoir si un noeud jQuery se trouve au début de son noeud parent?
- 19. Comment savoir si deux CGRect se croisent?
- 20. Implémenter une fenêtre de niveau supérieur à partir d'un récepteur de diffusion
- 21. Comment un QToolBar peut-il savoir où il se trouve?
- 22. comment savoir si le clic de souris a été fait sur la barre de titre
- 23. Comment tester si une coordonnée se trouve dans une zone de diamant?
- 24. Comment obtenir le conteneur de niveau supérieur d'un composant JComponent?
- 25. WPF CommandBinding PAS sur l'élément de niveau supérieur/Window/this
- 26. Où se trouve la fenêtre Debug -> Exceptions?
- 27. Comment savoir si une fenêtre est une fenêtre modale ou mdi?
- 28. Windows: Souris sur la décoration de la fenêtre
- 29. Comment vérifier si la souris est sur une instance de symbole avec ActionScript 3 dans Flash
- 30. AutoIt3 - Comment se ramifier si une fenêtre apparaît?
La position du curseur peut être obtenue par 'Control.MousePosition'; La fenêtre parente peut être trouvée par un seul appel 'GetAncestor (hwnd, 2)' de 'user32.dll' (' GetParent' vérifie non seulement les parents mais aussi les propriétaires de fenêtres, ce qui peut ne pas être bon). – max
Coredll.dll est uniquement approprié sur Windows Mobile. –
@Hans: Merci, choisi le mauvais je suppose. Actualisé. – Timwi