WPF: Dessiner son propre curseur - problème non-trivial
-
12-09-2020 - |
Question
Je dois mettre en œuvre un curseur avec des caractéristiques très spécifiques:
- il doit être animé
- car après n secondes, il clique automatiquement - de sorte que l'animation est la rétroaction de l'utilisateur lorsque le clic se produira
- Il doit casser à certaines de nos commandes
- Il doit travailler en dehors de notre application
Les approches jusqu'à présent:
- Rendez ma commande WPF dans un bitmap, créez un curseur en dehors de celui-ci et utilisez user32.dll / SetSystemcursor pour la définir.
-
pro
-
- Le curseur n'a aucun délai après la souris puisqu'il s'agit d'un vrai curseur
-
con - CLASTAPAPPAT est assez difficile, d'autant plus que nous avons des entrées d'entrée absolues et relatives et je devrais réinitialiser la mouseposition tout le temps ou utiliser user32.dll / clipcursor (system.windows.forms.cursor.clip fait la même chose) mais le Le curseur claqué secoue toujours autour de la position cassée (essaie de s'échapper, de réinitialiser à nouveau ....)
- Le code que j'utilise jette des exceptions étranges après une durée aléatoire - mon code actuel semble donc assez instable
-
pro
Pour résoudre la deuxième approche, mon curseur devrait avoir au moins un pixel transparent Dans le hotspot, de sorte que la souris puisse cliquer sur ... qui ne semble pas être une solution réelle pour moi ...
N'importe qui est n'importe qui?
EDIT: Quelques exemples de source pour montrer les problèmes ...:
Exemple d'application et source Pour afficher le problème avec la souris à une position fixe: clipit.rar
Exemple d'application et source qui échoue après le temps aléatoire - Réglage d'un curseur auto-dessiné: ESGYCUR.RAR
peut être trouvé sous: http://sourcemonk.com/cursor
La solution
Merci à HTTP: //social.msdn.microsoft.com/forums/en-us/wpf/thread/a3cb7db6-5014-430f-A5C2-C9746B077D4F
Je peux cliquer sur mon curseur auto-tiré qui suit la position de la souris par Réglage du style de la fenêtre: Aucun, et AutoryTransparent comme je l'ai déjà fait et alors
public const int WS_EX_TRANSPARENT = 0x00000020;
public const int GWL_EXSTYLE = (-20);
[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hwnd,
int index);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hwnd,
int index, int newStyle);
public static void makeTransparent(IntPtr hwnd) {
int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
}
et appeler MakeTransparent de OnsourceInitialisé ...