none
Comment détecter le déplacement de la souris en dehors d'une Form ? RRS feed

Réponses

  • Bonsoir Fred,

    J'ai repris ce projet, j'ai enlevé le code inutile concernant la gestion du clavier ainsi que les constantes non utilisées et j'ai commenté certaines parties.

    Le programme indique la position courante de la souris en temps réel, il ajoute à la suite dans une ListBox le bouton de la souris qui est appuyé et si la souris ne bouge pas pendant 5 secondes un message s'affiche.

    Voici le lien de téléchargement : https://skydrive.live.com/#cid=A3A27364F4EF38D8&id=A3A27364F4EF38D8!148

    Bonne soirée.


    N'hésitez pas à poser des questions si un problème subsiste ou quelque chose n'est pas clair. Dans l'autre cas, veuillez indiquer que le problème est résolu. Cordialement - Best Regards. Contact
    • Marqué comme réponse fred75 lundi 30 janvier 2012 18:38
    lundi 30 janvier 2012 16:39

Toutes les réponses

  • Bonjour,

    Voir http://msdn.microsoft.com/fr-fr/library/ms171545(v=vs.80).aspx ("Capture" de la souris). Eventuellement, il peut être utile de préciser l'objectif exact (si c'est un screensaver je ne crois pas que ce soit exactement la même technique, car le screensaver est l'application active et est donc bien la destination des messages de souris sans avoir besoin de la capturer).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    dimanche 29 janvier 2012 18:52
    Modérateur
  • Bonjour Patrice,

    Merci pour la référence mais cela s'applique à un contrôle dans une application

    J'aimerais savoir comment un screensaver se déclenche sachant qu'il peut y avoir plusieurs applications qui tournent ?

    Comment Windows déclenche le screensaver quand la souris ou le clavier n'ont pas reçu d’événement depuis X minutes ?

     


    fred on youTube
    PHP MySQL Web Site Creator
    fred
    lundi 30 janvier 2012 00:37
  • Bonjour Fred,

    Il faut pour cela utiliser un hook global de la souris.

    Le message WM_MOUSEMOVE est envoyé lorsque la souris bouge. Ainsi il devient possible de determiner si elle a bougé ou non durant les X dernières minutes.

    De nombreux articles parlent de ce sujet, en voici un : http://humann.developpez.com/hook/

    Je posterai un exemple en rentrant si vous avez des soucis pour le mettre en place.

    Bonne journée.


    N'hésitez pas à poser des questions si un problème subsiste ou quelque chose n'est pas clair. Dans l'autre cas, veuillez indiquer que le problème est résolu. Cordialement - Best Regards. Contact
    lundi 30 janvier 2012 08:15
  • Au temps pour moi. J'avais compris que l'on voulait diriger les évènements de déplacement de la souris vers Form1 même si ils ont lieu en dehors et non pas que l'on voulait juste savoir si il y a une activité sans l'intercepter. Ce n'est pas le screen saver qui voit que la souris n'est pas utilisée car il est lancé suite à ce constat. Donc là aussi je croyais comprendre que l'on parlait de la façon dont le screen saver sort de veille et non pas entre en veille... D'où l'intérêt d'être précis ;-)

    Cf la réponse de Michel. Là encore selon l'objectif final il serait aussi possible d'écrire un screensaver ? (ce n'est pas ce que l'on veut faire ?)


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    lundi 30 janvier 2012 09:54
    Modérateur
  • Bonjour,

    Merci Michel pour cette URL

    J'ai copié/collé le code mais j'ai des erreurs

    J'ai essayé de debugger mais il y a des choses qui m'échappent.

    Je veux bien un exemple

    Voici mon projet si tu veux y jeter un oeil

    sinon voici le code:

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Reflection;
    
    namespace HookMouse
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
        }
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int SetWindowsHookEx(
                    int idHook,
                    HookProc lpfn,
                    IntPtr hMod,
                    int dwThreadId);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto,
                    CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int UnhookWindowsHookEx(int idHook);
    
    
        [DllImport("user32.dll", CharSet = CharSet.Auto,
          CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int CallNextHookEx(
            int idHook,
            int nCode,
            int wParam,
            IntPtr lParam);
    
        [DllImport("user32")]
        private static extern int ToAscii(
            int uVirtKey,
            int uScanCode,
            byte[] lpbKeyState,
            byte[] lpwTransKey,
            int fuState);
    
        [DllImport("user32")]
        private static extern int GetKeyboardState(byte[] pbKeyState);
    
    
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern short GetKeyState(int vKey);
    
    
        private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
    
    
        [StructLayout(LayoutKind.Sequential)]
        private class POINT
        {
          /// <summary>
          /// Coordonnée X. 
          /// </summary>
          public int x;
          /// <summary>
          /// Coordonnée Y.
          /// </summary>
          public int y;
        }
    
    
        [StructLayout(LayoutKind.Sequential)]
        private class MouseHookStruct
        {
          /// <summary>
          /// Structure POINT pour les coordonnée 
          /// </summary>
          public POINT pt;
          /// <summary>
          /// Handle de la window
          /// </summary>
          public int hwnd;
          /// <summary>
          /// Specifies the hit-test value. For a list of hit-test values, see the description of the WM_NCHITTEST message. 
          /// </summary>
          public int wHitTestCode;
          /// <summary>
          /// Specifies extra information associated with the message. 
          /// </summary>
          public int dwExtraInfo;
        }
    
    
        [StructLayout(LayoutKind.Sequential)]
        private class MouseLLHookStruct
        {
          /// <summary>
          /// Structure POINT.
          /// </summary>
          public POINT pt;
          public int mouseData;
          public int flags;
          public int time;
          public int dwExtraInfo;
        }
    
    
        [StructLayout(LayoutKind.Sequential)]
        private class KeyboardHookStruct
        {
          /// <summary>
          /// Key code virtuel, la valeur doit etre entre 1 et 254. 
          /// </summary>
          public int vkCode;
          public int scanCode;
          public int flags;
          public int time;
          public int dwExtraInfo;
        }
    
        //Valeurs issues de Winuser.h du SDK de Microsoft.
        /// <summary>
        /// Windows NT/2000/XP: Installe un hook pour la souris
        /// </summary>
        private const int WH_MOUSE_LL = 14;
        /// <summary>
        /// Windows NT/2000/XP: Installe un hook pour le clavier
        /// </summary>
        private const int WH_KEYBOARD_LL = 13;
    
        private const int WH_MOUSE = 7;
    
        private const int WH_KEYBOARD = 2;
    
        /// <summary>
        /// Le message WM_MOUSEMOVE est envoyé quand la souris bouge
        /// </summary>
        private const int WM_MOUSEMOVE = 0x200;
        /// <summary>
        /// Le message WM_LBUTTONDOWN est envoyé lorsque le bouton gauche est pressé
        /// </summary>
        private const int WM_LBUTTONDOWN = 0x201;
        /// <summary>
        /// Le message WM_RBUTTONDOWN est envoyé lorsque le bouton droit est pressé
        /// </summary>
        private const int WM_RBUTTONDOWN = 0x204;
        /// <summary>
        /// Le message WM_MBUTTONDOWN est envoyé lorsque le bouton central est pressé
        /// </summary>
        private const int WM_MBUTTONDOWN = 0x207;
        /// <summary>
        /// Le message WM_LBUTTONUP est envoyé lorsque le bouton gauche est relevé
        /// </summary>
        private const int WM_LBUTTONUP = 0x202;
        /// <summary>
        /// Le message WM_RBUTTONUP est envoyé lorsque le bouton droit est relevé 
        /// </summary>
        private const int WM_RBUTTONUP = 0x205;
    
        private const int WM_MBUTTONUP = 0x208;
    
        private const int WM_LBUTTONDBLCLK = 0x203;
    
        private const int WM_RBUTTONDBLCLK = 0x206;
    
        private const int WM_MBUTTONDBLCLK = 0x209;
    
        private const int WM_MOUSEWHEEL = 0x020A;
    
    
        private const int WM_KEYDOWN = 0x100;
    
        private const int WM_KEYUP = 0x101;
    
        private const int WM_SYSKEYDOWN = 0x104;
    
        private const int WM_SYSKEYUP = 0x105;
    
        private const byte VK_SHIFT = 0x10;
        private const byte VK_CAPITAL = 0x14;
        private const byte VK_NUMLOCK = 0x90;
    
        public void StartMouseHook()
        {
          // Faire une instance de HookProc.
          MouseHookProcedure = new HookProc(MouseHookProc);
          //installer le hook
          int hook = SetWindowsHookEx(
                 WH_MOUSE_LL,
                  MouseHookProcedure,
                  Marshal.GetHINSTANCE(
                   Assembly.GetExecutingAssembly().GetModules()[0]),
                  0);
          //Si hook est a 0, donc la fonction SetWindowsHookEx a échoué
          if (hook == 0)
          {
            //Retourn le code d'erreur 
            int errorCode = Marshal.GetLastWin32Error();
            //Lance une exception du type Win32 
            throw new Win32Exception(errorCode);
          }
        }
    
        private MouseEventHandler _onMouseClick;
    
        public event MouseEventHandler OnMouseClick // error
        {
          add
          {
            _onMouseClick += value;
          }
          remove
          {
            _onMouseClick -= value;
          }
        }
    
        private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
        {
          bool processNextHook = true;
          // Verifions si nCode est different de 0 et que nos evenements sont bien attachés
          if ((nCode >= 0) && (_onMouseClick != null))
          {
            //Remplissage de la structure MouseLLHookStruct a partir d'un pointeur
            MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));
            //Detection du bouton clicker
            MouseButtons button = MouseButtons.None;
            switch (wParam)
            {
              case WM_LBUTTONDOWN:
                button = MouseButtons.Left;
                break;
              case WM_RBUTTONDOWN:
                button = MouseButtons.Right;
                break;
            }
            //parametre de notre event 
            MouseEventArgs e = new MouseEventArgs(button, 1, mouseHookStruct.pt.x, mouseHookStruct.pt.y, 0);
            //On appelle notre event
            OnMouseClick(e); // was OnMouseClick(this, e); // error OnMouseClick ne peut apparaitre qu'à gauche de += ou -=
          }
          //Si processNextHook == true alors on transmet le click au destinataire, sinon, on le garde pour nous (
          if (processNextHook == true)
          {
            return CallNextHookEx(0, nCode, wParam, lParam); // was return CallNextHookEx(hMouseHook, nCode, wParam, lParam);//error: hMouseHook doesn't exist
          }
          else
            return 1;
        }
    
        public void StartKeyHook()
        {
          KeyboardHookProcedure = new HookProc(this.KeyboardHookProc);//was KeyboardHookProcedure = new HookProc(KeyHookProc); // error: KeyHookProc doesn't exist
          //Installer le hook
          int hook = SetWindowsHookEx(
              WH_KEYBOARD_LL,
              KeyboardHookProcedure,
              Marshal.GetHINSTANCE(
              Assembly.GetExecutingAssembly().GetModules()[0]),
              0);
          //Si SetWindowsHookEx echoue
          if (hook == 0)
          {
            int errorCode = Marshal.GetLastWin32Error();
            throw new Win32Exception(errorCode);
          }
        }
    
        private KeyPressEventHandler _onKeyPress;
    
        //public event KeyPressEventHandler OnKeyPress // error surcharge hidding mother method
        //{
        //  add
        //  {
        //    _onKeyPress += value;
        //  }
        //  remove
        //  {
        //    _onKeyPress -= value;
        //  }
        //}
    
        private KeyEventHandler _onKeyUp;
    
        //public event KeyEventHandler OnKeyUp // error surcharge hidding mother method
        //{
        //  add
        //  {
        //    _onKeyUp += value;
        //  }
        //  remove
        //  {
        //    _onKeyUp -= value;
        //  }
        //}
    
        private KeyEventHandler _onKeyDown;
    
        //public event KeyEventHandler OnKeyDown // error surcharge hidding mother method
        //{
        //  add
        //  {
        //    _onKeyDown += value;
        //  }
        //  remove
        //  {
        //    _onKeyDown -= value;
        //  }
        //}
    
        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
          bool handled = false;
          //On verifie si tous est ok
          if ((nCode >= 0) && (_onKeyDown != null || _onKeyUp != null || _onKeyPress != null))
          {
            //Remplissage de la structure KeyboardHookStruct a partir d'un pointeur
            KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
            //KeyDown
            if (_onKeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
            {
              Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
              KeyEventArgs e = new KeyEventArgs(keyData);
              _onKeyDown(this, e);
              handled = handled || e.Handled;
            }
    
            // KeyPress
            if (_onKeyPress != null && wParam == WM_KEYDOWN)
            {
              // Si la touche Shift est appuyée
              bool isShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false);
              // Si la touche CapsLock est appuyée
              bool isCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);
    
              byte[] keyState = new byte[256];
              GetKeyboardState(keyState);
              byte[] inBuffer = new byte[2];
              if (ToAscii(MyKeyboardHookStruct.vkCode,
                        MyKeyboardHookStruct.scanCode,
                        keyState,
                        inBuffer,
                        MyKeyboardHookStruct.flags) == 1)
              {
                char key = (char)inBuffer[0];
                if ((isCapslock ^ isShift) && Char.IsLetter(key))
                  key = Char.ToUpper(key);
                KeyPressEventArgs e = new KeyPressEventArgs(key);
                _onKeyPress(this, e);
                handled = handled || e.Handled;
              }
            }
    
            // KeyUp
            if (_onKeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
            {
              Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
              KeyEventArgs e = new KeyEventArgs(keyData);
              _onKeyUp(this, e);
              handled = handled || e.Handled;
            }
          }
    
          // si handled est a true, on ne transmet pas le message au destinataire
          if (handled)
            return 1;
          else
            return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
        }
    
        private HookProc MouseHookProcedure { get; set; }
    
        private HookProc KeyboardHookProcedure { get; set; }
    
        public int hKeyboardHook { get; set; }
    
        private void Form1_Load(object sender, EventArgs e)
        {
          label1.Text = "la souris n'a pas encore été bougée";
          label2.Text = "Aucune touche n'a été appuyée";
        }
    
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
          label1.Text = "la souris a été bougée";
        }
    
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
          label2.Text = "Une touche a été appuyée";
        }
      }
    }
    



    fred on youTube
    PHP MySQL Web Site Creator
    fred
    lundi 30 janvier 2012 14:10
  • Bonsoir Fred,

    J'ai repris ce projet, j'ai enlevé le code inutile concernant la gestion du clavier ainsi que les constantes non utilisées et j'ai commenté certaines parties.

    Le programme indique la position courante de la souris en temps réel, il ajoute à la suite dans une ListBox le bouton de la souris qui est appuyé et si la souris ne bouge pas pendant 5 secondes un message s'affiche.

    Voici le lien de téléchargement : https://skydrive.live.com/#cid=A3A27364F4EF38D8&id=A3A27364F4EF38D8!148

    Bonne soirée.


    N'hésitez pas à poser des questions si un problème subsiste ou quelque chose n'est pas clair. Dans l'autre cas, veuillez indiquer que le problème est résolu. Cordialement - Best Regards. Contact
    • Marqué comme réponse fred75 lundi 30 janvier 2012 18:38
    lundi 30 janvier 2012 16:39
  • Merci Michel

    C'est génial, ça marche nickel

     


    fred on youTube
    PHP MySQL Web Site Creator
    fred
    lundi 30 janvier 2012 18:38