J'ai une fenêtre WPF et je souhaite déterminer lorsqu'un utilisateur finit de déplacer une fenêtre autour du bureau. Je me suis connecté à l'événement de l'emplacement de l'emplacement et c'est bien, mais je ne peux pas comprendre comment déterminer lorsque l'utilisateur cesse de déplacer la fenêtre (en libérant le bouton gauche de la souris). P>
Il n'y a aucun événement pour m'aider à déterminer cela, quelque chose comme un événement de l'emplacement de l'emplacement. J'ai essayé de connecter à Mouseleftbuttonup, mais cet événement n'est jamais tiré. p>
Quelqu'un a des idées? p>
4 Réponses :
Deux approches possibles seraient: p>
Vous ne savez pas vraiment lorsque le bouton de la souris est levé. Au lieu de cela, vous attendez que la fenêtre cesse d'envoyer ces événements de déplacement. Configurez une courte teneur à vécue qui commence à cocher chaque fois que vous recevez un événement de déplacement de la fenêtre. Réinitialisez la minuterie si c'est déjà sur. Lorsque vous recevez l'événement de la minuterie, par exemple. Après quelques centaines de millisecs, vous pouvez supposer que l'utilisateur a cessé de déplacer la fenêtre. Même avec une souris haute résolution, lorsque vous maintenez le bouton gauche de la souris gauche et essayez de rester immobile, la gigue continuera à envoyer des événements de déménagement. Cette approche est documentée ici a>. p> li>
tentative de capturer les notifications de la souris de la zone non client de la fenêtre. Vous pouvez configurer un Crochet de message de fenêtre pour capturer la fenêtre messages. Une fois que le premier événement de déplacement de la fenêtre est vu, le crochet pourrait commencer à rechercher des événements WM_NclbuttonUp. Cette approche évite la minuterie et la supposition. Cependant, cela rend les hypothèses sur les voies Windows permet à l'utilisateur de positionner les fenêtres et peut échouer dans certains cas, par ex. Si l'utilisateur déplace l'utilisateur uniquement avec le clavier uniquement (alt + espace, m, touches fléchées). p> li>
ol>
Vous voulez obtenir le message WM_WindowEfposchanged, ajoutez ceci à la classe de votre fenêtre:
internal enum WM
{
WINDOWPOSCHANGING = 0x0047,
}
[StructLayout(LayoutKind.Sequential)]
internal struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public int flags;
}
private override void OnSourceInitialized(EventArgs ea)
{
HwndSource hwndSource = (HwndSource)HwndSource.FromVisual((Window)this);
hwndSource.AddHook(DragHook);
}
private static IntPtr DragHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handeled)
{
switch ((WM)msg)
{
case WM.WINDOWPOSCHANGED:
{
WINDOWPOS pos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS));
if ((pos.flags & (int)SWP.NOMOVE) != 0)
{
return IntPtr.Zero;
}
Window wnd = (Window)HwndSource.FromHwnd(hwnd).RootVisual;
if (wnd == null)
{
return IntPtr.Zero;
}
// ** do whatever you need here **
// the new window position is in the pos variable
// just note that those are in Win32 "screen coordinates" not WPF device independent pixels
}
break;
}
return IntPtr.Zero;
}
Vous pouvez écouter pour le WM_ENTERSIZEMOVE événement, qui ne devrait tirer que lorsque le mouvement est démarré. Bien que l'utilisateur glisse, vous pouvez recevoir des événements WM_MOVING et WM_MOVE. Ce dernier dépend des paramètres de son système (par exemple, la fenêtre se déplace au fur et à mesure de la traînée, par rapport à un contour). Enfin, wm_exitsizemove indiquerait quand ils sont terminés. P>
Vous pouvez être intéressé par la réponse que j'ai postée ici: p>
Comment désactivez-vous Aero Snap dans une application? P >
La réponse contient un moyen fiable de détecter le démarrage / extrémité des mouvements de la fenêtre dans le but de désactiver Aero Snap. P>