Programmer un hook dans un mdiform

Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 7 nov. 2016 à 08:59 - Dernière réponse :
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 15 nov. 2016 à 16:31
Bonjour,
c'est un plaisir de changer avec vous; en effet je suis nouveau dans la programmation csharp et pour mon petit projet test donc je suis entrain de travailler dessus , je rencontre un problème et sur ce j'aimerais que vous m'assistez si possible.
voici mon projet test:
j'ai créé un mdiparent avec plusieurs mdichild et je veux que lorsque j'ouvre un mdichild et que je fais 5mn sans faire un clic de la souris ou presser une touche du clavier; une fenêtre modale ayant un bouton s'affiche notifiant à l'utilisateur qu'il a fait 5mn d'inativité et que l'application va se fermer dans 10mn s'il ne clique pas sur le bouton .
voici mon problème:
je ne sais pas comment coder le hook clavier /souris dans la mdiparent afin d'intercepter tous les se produisant sur tous les mdichild activés.

merci d'avance.

"Que de faire semblant de connaitre, mieux vaut demander l'aide pour avoir les idées claire"
Afficher la suite 

Votre réponse

14 réponses

Messages postés
12267
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
18 novembre 2018
- 7 nov. 2016 à 09:39
0
Merci
Bonjour

il n'est pas utile de faire un hook pour ça.

Ce que tu peux faire:
  • dans le formulaire principal, il y a un timer qui régulièrement (toutes les secondes, par exemple) regarde la valeur d'un StopWatch (c'est un chronomètre), et affiche le message si la valeur est supérieure ou égale à 5min.
  • A l'initialisation de chaque mdiChild, tu passes le stopwatch en paramètre.
  • Tu mets le KeyPreview de ton mdiChild à true.
  • Pour les clicks tu fais une boucle qui abonne les événements Click de chaque contrôle une seule et même méthode.
  • Dans cette méthode, ainsi que dans celle abonnée au KeyPress de la form, tu remets le stopwath à zéro.

Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 8 nov. 2016 à 12:44
bonjour j'ai pensé à ce genre d'alternative mais je me suis rendu compte que si j'ai 30mdichild ou plus , ça devient un peu compliqué, et au net je suis tombé sur un document qui dit qu'avec le hook clavier/souris (si on programme le hook dans le mdiparent) il intercepte tous les événements des mdichild.
c'est ça que je savoir à partir d'un formulaire principal donné gerer le handle de toutes les autres formules de l'application sans que je ne programme le stopwatch dans ces formulaire là.
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 8 nov. 2016 à 12:55
car je veux qu'à partir de mon mdiparent, si un formulaire est ouvert :
- si l'utilisateur fait 5mn sans faire un mouvement de la souris ni du clavier, alors un formulaire modal s'affiche en indiquant le nombre de minute d'inactivité
- si l'utilisateur fait moins de 5mn et qu'il fait un mouvement clavier ou souris, alors le système initialise le timer

mon problème c'est de savoir comment je peux donc implémenter le bon code du hook dans le mdiparent pour gérer ce genre de cas.

merci d'avance pour votre assistance
Commenter la réponse de Whismeril
Messages postés
12267
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
18 novembre 2018
- 8 nov. 2016 à 13:06
0
Merci
Bonjour,

quand tu dis
je me suis rendu compte que si j'ai 30mdichild ou plus , ça devient un peu compliqué
c'est 30 form différents ou 30 instances du même form?
Commenter la réponse de Whismeril
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 8 nov. 2016 à 14:04
0
Merci
30 form différents
Commenter la réponse de VANDREAM
Messages postés
12267
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
18 novembre 2018
- Modifié par Whismeril le 8/11/2016 à 15:16
0
Merci
Et ben, je n'ai jamais eu de programme avec autant de forms.....

Je change un peu l'idée, avec une classe statique, c'est elle qui chronomètre (faut lancer la surveillance au début), puis on lui passe en paramètre chaque nouveau form à surveiller (mdi ou pas...), cette classe s'abonne aux évènements qui vont bien et affiche le form


using System;
using System.Diagnostics;
using System.Timers;
using System.Windows.Forms;


namespace test
{

    public static class SurveillanceInactivite
    {
        public delegate void TempsInactiviteAtteintEvent(TimeSpan DureePassee);

        /// <summary>
        /// Signale que la durée d'inactivité a été atteinte
        /// </summary>
        public static event TempsInactiviteAtteintEvent TempsInactiviteAtteint;

        /// <summary>
        /// Lance la surveillance
        /// </summary>
        /// <param name="Duree">Durée après laquelle on signalera l'inactivité</param>
        /// <param name="Sender">Formulaire qui demande la surveillance, et qui sera surveillé aussi</param>
        public static void DemarrerSurveillance(TimeSpan Duree, Form Sender)
        {
            AjouteASurveiller(Sender);
            duree = Duree;
            timer.Elapsed += timer_Elapsed;
            timer.Interval = 1000;
            timer.Start();
            chrono.Start();
        }

        /// <summary>
        /// Methode associée au timer qui vérifie régulièrement si on a atteint le temps d'inactivité
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (chrono.Elapsed >= duree)
            {
                TimeSpan dureePassee = chrono.Elapsed;
                chrono.Restart();

                if (SurveillanceInactivite.TempsInactiviteAtteint != null) SurveillanceInactivite.TempsInactiviteAtteint(dureePassee);//Déclenche l'évement pour signaler l'inactivité
                
                
            }
        }

        /// <summary>
        /// Methode qui remets le chronomètre à zéro
        /// </summary>
        public static void YaDeLaVie()
        {
            chrono.Restart();
        }

        /// <summary>
        /// S'abonne aux évènements du formulaire et ensuite l'affiche
        /// </summary>
        /// <param name="Formulaire"></param>
        public static void AjouteForumulaireASurveillerEtLaffiche(Form Formulaire)
        {
            AjouteASurveiller(Formulaire);
            Formulaire.Show();
        }


        /// <summary>
        /// S'abonne aux évènements du formulaire
        /// </summary>
        /// <param name="Formulaire"></param>
        private static void AjouteASurveiller(Form Formulaire)
        {
            Formulaire.MouseMove += Formulaire_MouseMove;
            Formulaire.KeyPreview = true;
            Formulaire.KeyPress += Formulaire_KeyPress;
            //to do: voir s'il est utile de s'abonner au MouseMove de chaque contrôle
        }


        private static void Formulaire_KeyPress(object sender, KeyPressEventArgs e)
        {
            YaDeLaVie();
        }

        private static void Formulaire_MouseMove(object sender, MouseEventArgs e)
        {
            YaDeLaVie();
        }

        private static System.Timers.Timer timer = new System.Timers.Timer();
        private static Stopwatch chrono = new Stopwatch();
        private static TimeSpan duree;
    }
}


Dans ton frmParent, il faut initialiser comme ça
            //pour le test, j'ai mis 10 secondes
            SurveillanceInactivite.DemarrerSurveillance(new TimeSpan(0, 0, 10), this);
            SurveillanceInactivite.TempsInactiviteAtteint += SurveillanceInactivite_TempsInactiviteAtteint;//on s'abonne à l'évènement qui dit que le temps est passé
            
            //Pour le test j'ai lancé 30 fois le même
            for (int i = 0; i < 30; i++)
            {
                Form6 frm = new Form6();
                SurveillanceInactivite.AjouteForumulaireASurveillerEtLaffiche(frm); //A la place de frm.Show()
            }


et la méthode abonnée à SurveillanceInactivite.TempsInactiviteAtteint
        void SurveillanceInactivite_TempsInactiviteAtteint(TimeSpan DureePassee)
        {
            MessageBox.Show(string.Format("T'as rien fait depuis {0} secondes", DureePassee.TotalSeconds));
        }


Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 9 nov. 2016 à 09:36
1) je voir que le deuxième code doit être dans le mdiparent
2) les 1er et le 3ème seront implémentés toujours dans le mdiparents?

j'essaie juste de comprendre ton code pour le tester,

car j'aimerais que tout le code soit impléménté dans le mdiparent et à partir de là si un mdichild est ouvert, le code implémenté dans le mdiparent recupère le handle du mdichild qui est ouvert afin d'intercepter d'abord tous les événements sur ce mdichild et les trait.



merci d'avance
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 11 nov. 2016 à 10:18
Bonjour,
j'ai testé le code.
j'ai créé un mdiparent avec 3 mdichild, mais quand je lance l'application il ne gère pas les événements de la souris et clavier même dans le mdiparent.

j'ai mis le timer à 2mn, mais après 1mn quand je clic sur la souris ou une touche de clavier ça ne réagit pas; après les 2mn le textbox suivant s'affiche: "T'as rien fait depuis 120 secondes",
Messages postés
12267
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
18 novembre 2018
>
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 11 nov. 2016 à 10:49
Bonjour,

Peux tu montrer comment tu l'as implémenté?
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 15 nov. 2016 à 13:11
Bonjour,

voici comment j'ai implémenté le code dans VS,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace MDIParents
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //pour le test, j'ai mis 10 secondes
            SurveillanceInactivite.DemarrerSurveillance(new TimeSpan(0, 2, 0), this);
            SurveillanceInactivite.TempsInactiviteAtteint += SurveillanceInactivite_TempsInactiviteAtteint;//on s'abonne à l'évènement qui dit que le temps est passé

            //Pour le test j'ai lancé 30 fois le même
            //for (int i = 0; i < 30; i++)
            //{
            //    FormFille1 frm = new FormFille1();
              
                SurveillanceInactivite.AjouteForumulaireASurveillerEtLaffiche(Formulaire); //A la place de frm.Show()
           // }
        }

        public static Form Formulaire = new Form();
        private void Form1_Load(object sender, EventArgs e)
        {

        }

        public static class SurveillanceInactivite
        {
            public delegate void TempsInactiviteAtteintEvent(TimeSpan DureePassee);

            /// <summary>
            /// Signale que la durée d'inactivité a été atteinte
            /// </summary>
            public static event TempsInactiviteAtteintEvent TempsInactiviteAtteint;

            /// <summary>
            /// Lance la surveillance
            /// </summary>
            /// <param name="Duree">Durée après laquelle on signalera l'inactivité</param>
            /// <param name="Sender">Formulaire qui demande la surveillance, et qui sera surveillé aussi</param>
            public static void DemarrerSurveillance(TimeSpan Duree, Form Sender)
            {
                AjouteASurveiller(Sender);
                duree = Duree;
                timer.Elapsed += timer_Elapsed;
                timer.Interval = 30000;
                timer.Start();
                chrono.Start();
            }

            /// <summary>
            /// Methode associée au timer qui vérifie régulièrement si on a atteint le temps d'inactivité
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private static void timer_Elapsed(object sender, ElapsedEventArgs e)
            {
                if (chrono.Elapsed >= duree)
                {
                    TimeSpan dureePassee = chrono.Elapsed;
                    chrono.Restart();

                    if (SurveillanceInactivite.TempsInactiviteAtteint != null) SurveillanceInactivite.TempsInactiviteAtteint(dureePassee);//Déclenche l'évement pour signaler l'inactivité
                
                
                }
            }

            /// <summary>
            /// Methode qui remets le chronomètre à zéro
            /// </summary>
            public static void YaDeLaVie()
            {
                chrono.Restart();
            }

            /// <summary>
            /// S'abonne aux évènements du formulaire et ensuite l'affiche
            /// </summary>
            /// <param name="Formulaire"></param>
            public static void AjouteForumulaireASurveillerEtLaffiche(Form Formulaire)
            {
                Formulaire = new Form();
                AjouteASurveiller(Formulaire);
                Formulaire.Show();
            }


            /// <summary>
            /// S'abonne aux évènements du formulaire
            /// </summary>
            /// <param name="Formulaire"></param>
            private static void AjouteASurveiller(Form Formulaire)
            {
               // Formulaire = new Form();
                Formulaire.MouseMove += Formulaire_MouseMove;
                Formulaire.KeyPreview = true;
                Formulaire.KeyPress += Formulaire_KeyPress;
                //to do: voir s'il est utile de s'abonner au MouseMove de chaque contrôle
            }

            private static void Formulaire_KeyPress(object sender, KeyPressEventArgs e)
            {
                YaDeLaVie();
            }

            private static void Formulaire_MouseMove(object sender, MouseEventArgs e)
            {
                YaDeLaVie();
            }

            private static System.Timers.Timer timer = new System.Timers.Timer();
            private static Stopwatch chrono = new Stopwatch();
            private static TimeSpan duree;
    }
        
        void SurveillanceInactivite_TempsInactiviteAtteint(TimeSpan DureePassee)
        {
            MessageBox.Show(string.Format("T'as rien fait depuis {0} secondes", DureePassee.TotalSeconds));
        }

        private void forme1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormFille1 ff1 = new FormFille1();
            ff1.MdiParent = this;
            ff1.Show();
        }

        private void forme2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormFille2 ff2 = new FormFille2();
            ff2.MdiParent = this;
            ff2.Show();
        }

        private void forme3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormFille3 ff3 = new FormFille3();
            ff3.MdiParent = this;
            ff3.Show();
        }

        private void Form1_MdiChildActivate(object sender, EventArgs e)
        {
            Formulaire = ActiveMdiChild;
        }

      
  }
}


EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ICI

Merci d'y penser dans tes prochains messages.
Commenter la réponse de Whismeril
Messages postés
12267
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
18 novembre 2018
- 9 nov. 2016 à 09:57
0
Merci
Bonjour

Le premier code est un classe à part entière, je te l'ai écrit et ça se voit dans le code dès le debut avec les using et en clair à la ligne 10.
C# est un langage (tout) objet, donc coder des classes est la base de la base (bien avant de savoir faire un hook...). Si cette notion n'est pas acquise, il est important que tu fasses une petite révision.
Voici un bon cours de débutant
http://tahe.developpez.com/dotnet/csharp/
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 9 nov. 2016 à 14:45
salut,
ok je vois , je vais tester et te faire un compte rendu



merci
Commenter la réponse de Whismeril
Messages postés
12267
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
18 novembre 2018
- 15 nov. 2016 à 16:20
0
Merci
Bonsoir,

SurveillanceActivite est une classe static, elle n'a rien à faire dans le code d'une form.
Je vais paraître lourd, mais pour coder en C#, il faut savoir quoi faire d'une classe.
Par soucis de lisibilité le plus simple est de la mettre dans son propre fichier, mais à minima pas dans une form.
Messages postés
24
Date d'inscription
mercredi 14 août 2013
Dernière intervention
15 novembre 2016
- 15 nov. 2016 à 16:31
Bonsoir,*

ok
Commenter la réponse de Whismeril

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.