Performclick, simuler les clic sur contrôles

Description

Comme il s'agit d'un type de question qui a tendance à revenir régulièrement, voici une classe utilitaire exposant des méthodes permettant de simuler des clics sur les contrôles.
Les clics sont simulés via PostMessage et les notifications
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBLCLK
WM_RBUTTONDOWN
WM_RBUTTONUP
WM_RBUTTONDBLCLK
WM_MBUTTONDOWN
WM_MBUTTONUP
WM_MBUTTONDBLCLK
WM_XBUTTONDOWN
WM_XBUTTONUP
WM_XBUTTONDBLCLK

Source / Exemple :


/// <summary>
        /// Permet d'effectuer le clic.
        /// </summary>
        /// <param name="ctrl"><see cref="Control"/> visé.</param>
        /// <param name="pos"><see cref="Point"/> déterminant les coordonnées du clic. (Coordonnées relatives au point supérieur gauche du contrôle visé).</param>
        /// <param name="button">Valeur de <see cref="MouseButtons"/> indiquant quel bouton de la souris agit.</param>
        /// <returns><c>true</c> si l'opération est une réussite, sinon <c>false</c>.</returns>
        private static bool PerformClick(Control ctrl, Point pos, MouseButtons button)
        {
            uint downMsg = 0;
            IntPtr downWParam = IntPtr.Zero;
            uint upMsg = 0;
            IntPtr upWParam = IntPtr.Zero;

            // définition des valeurs suivant le bouton demandé
            switch ( button )
            {
                case MouseButtons.Left:
                    downMsg = WM_LBUTTONDOWN;
                    downWParam = MK_LBUTTON;
                    upMsg = WM_LBUTTONUP;
                    break;

                case MouseButtons.Right:
                    downMsg = WM_RBUTTONDOWN;
                    downWParam = MK_RBUTTON;
                    upMsg = WM_RBUTTONUP;
                    break;

                case MouseButtons.Middle:
                    downMsg = WM_MBUTTONDOWN;
                    downWParam = MK_MBUTTON;
                    upMsg = WM_MBUTTONUP;
                    break;

                case MouseButtons.XButton1:
                    downMsg = WM_XBUTTONDOWN;
                    downWParam = MK_XBUTTON1;
                    upMsg = WM_XBUTTONUP;
                    break;

                case MouseButtons.XButton2:
                    downMsg = WM_XBUTTONDOWN;
                    downWParam = MK_XBUTTON2;
                    upMsg = WM_XBUTTONUP;
                    break;

                default:
                    // bouton non géré
                    return false;
            }

            try
            {
                // position du clic
                IntPtr lParam = new IntPtr(pos.X | (pos.Y << 16));

                // envoi du clic (clic = down + up)
                bool downRet = NativeMethods.PostMessage(ctrl.Handle, downMsg, downWParam, lParam);
                bool upRet = NativeMethods.PostMessage(ctrl.Handle, upMsg, upWParam, lParam);

                // si un seul des appels a échoué, l'ensemble a échouer.
                return downRet & upRet;
            }
            catch
            {
                // si une exception a été levée, on considère que l'ensemble est un échec
                return false;
            }
        }

        /// <summary>
        /// Permet d'effectuer le double clic.
        /// </summary>
        /// <param name="ctrl"><see cref="Control"/> visé.</param>
        /// <param name="pos"><see cref="Point"/> déterminant les coordonnées du double clic. (Coordonnées relatives au point supérieur gauche du contrôle visé).</param>
        /// <param name="button">Valeur de <see cref="MouseButtons"/> indiquant quel bouton de la souris agit.</param>
        /// <returns><c>true</c> si l'opération est une réussite, sinon <c>false</c>.</returns>
        private static bool PerformDoubleClick(Control ctrl, Point pos, MouseButtons button)
        {
            uint msg = 0;
            IntPtr wParam = IntPtr.Zero;

            // définition des valeurs suivant le bouton demandé
            switch ( button )
            {
                case MouseButtons.Left:
                    msg = WM_LBUTTONDBLCLK;
                    wParam = MK_LBUTTON;
                    break;

                case MouseButtons.Right:
                    msg = WM_RBUTTONDBLCLK;
                    wParam = MK_RBUTTON;
                    break;

                case MouseButtons.Middle:
                    msg = WM_MBUTTONDBLCLK;
                    wParam = MK_MBUTTON;
                    break;

                case MouseButtons.XButton1:
                    msg = WM_XBUTTONDBLCLK;
                    wParam = MK_XBUTTON1;
                    break;

                case MouseButtons.XButton2:
                    msg = WM_XBUTTONDBLCLK;
                    wParam = MK_XBUTTON2;
                    break;

                default:
                    // bouton non géré
                    return false;
            }

            try
            {
                // position du double clic
                IntPtr lParam = new IntPtr(pos.X | (pos.Y << 16));

                // envoi du double clic
                return NativeMethods.PostMessage(ctrl.Handle, msg, wParam, lParam);
            }
            catch
            {
                // si une exception a été levée, on considère que l'ensemble est un échec
                return false;
            }
        }

        #region API: Constantes

        private const uint WM_LBUTTONDOWN            = 0x0201;
        private const uint WM_LBUTTONUP              = 0x0202;
        private const uint WM_LBUTTONDBLCLK          = 0x0203;
        private const uint WM_RBUTTONDOWN            = 0x0204;
        private const uint WM_RBUTTONUP              = 0x0205;
        private const uint WM_RBUTTONDBLCLK          = 0x0206;
        private const uint WM_MBUTTONDOWN            = 0x0207;
        private const uint WM_MBUTTONUP              = 0x0208;
        private const uint WM_MBUTTONDBLCLK          = 0x0209;
        private const uint WM_XBUTTONDOWN            = 0x020B;
        private const uint WM_XBUTTONUP              = 0x020C;
        private const uint WM_XBUTTONDBLCLK          = 0x020D;
        
        private static readonly IntPtr MK_LBUTTON  = new IntPtr(0x0001);
        private static readonly IntPtr MK_RBUTTON  = new IntPtr(0x0002);
        private static readonly IntPtr MK_MBUTTON  = new IntPtr(0x0010);
        private static readonly IntPtr MK_XBUTTON1 = new IntPtr(0x0020);
        private static readonly IntPtr MK_XBUTTON2 = new IntPtr(0x0040);

        #endregion API: Constantes

        #region API: Méthodes

        private class NativeMethods
        {
            [DllImport("user32.dll", SetLastError = false)]
            internal static extern bool PostMessage(
                IntPtr hWnd, 
                uint Msg, 
                IntPtr wParam,
                IntPtr lParam
                );
        }

        #endregion API: Méthodes
    }

// pour la suite, voir "PerformClickHelper.cs"

Conclusion :


Quelques liens pratiques :

PostMessage : http://msdn.microsoft.com/en-us/library/ms644944.aspx

WM_LBUTTONDOWN : http://msdn.microsoft.com/en-us/library/ms645607.aspx
WM_LBUTTONUP : http://msdn.microsoft.com/en-us/library/ms645608.aspx
WM_LBUTTONDBLCLK : http://msdn.microsoft.com/en-us/library/ms645606.aspx

WM_RBUTTONDOWN : http://msdn.microsoft.com/en-us/library/ms646242.aspx
WM_RBUTTONUP : http://msdn.microsoft.com/en-us/library/ms646243.aspx
WM_RBUTTONDBLCLK : http://msdn.microsoft.com/en-us/library/ms646241.aspx

WM_MBUTTONDOWN : http://msdn.microsoft.com/en-us/library/ms645610.aspx
WM_MBUTTONUP : http://msdn.microsoft.com/en-us/library/ms645611.aspx
WM_MBUTTONDBLCLK : http://msdn.microsoft.com/en-us/library/ms645609.aspx

WM_XBUTTONDOWN : http://msdn.microsoft.com/en-us/library/ms646245.aspx
WM_XBUTTONUP : http://msdn.microsoft.com/en-us/library/ms646246.aspx
WM_XBUTTONDBLCLK : http://msdn.microsoft.com/en-us/library/ms646244.aspx

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.