Performclick, simuler les clic sur contrôles

Soyez le premier à donner votre avis sur cette source.

Vue 27 667 fois - Téléchargée 709 fois

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

Ajouter un commentaire Commentaires
Messages postés
21
Date d'inscription
jeudi 20 novembre 2008
Statut
Membre
Dernière intervention
13 mai 2011

Merci, très compréhensible ton code ;)
Messages postés
7
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
13 septembre 2013

Oui en fait tout fonctionne mais pas en debug, car il faut que l'écran soit au premier plan pour recevoir le clic simulé....
je me suis fait eu comme un débutant...
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
97
Salut,

C'est normal dans cet exemple le TextBox n'est que la cible des actions des boutons, aucun comportement n'est lié aux actions effectuées dessus.
Messages postés
7
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
13 septembre 2013

salut, je sais pas si c'est parce que je suis sous seven 64 mais çà fait rien du tout....
à part quand je clique sur les boutons..mais si je clique sur les textbox rien de rien.
Si vous savez pourquoi je suis preneur, car c'est exactement ce dont j'ai besoin.
Merci
Messages postés
27
Date d'inscription
samedi 19 juin 2004
Statut
Membre
Dernière intervention
14 octobre 2008
2
Salut,

moi aussi je cherche comme toi cyraile.
A mon avis c'est possible puisque ça peut se faire pour les touches claviers (avec sendKeys qui envoie un evenement clavier sur l'application active sur le bureau, j'ai essayé avec bloc note ça marche).
Donc si il ya des solutions pour le cas souris, je suis preneuse !

Babou
Afficher les 12 commentaires

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.