1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2009
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2009
    Messages : 231
    Points : 125
    Points
    125

    Par défaut Implémenter via API un évènement au niveau application

    Bonjour à tous les fans de VB6,

    Le titre n'est pas trop explicite mais je vais tenter de vous expliquer au mieux mon problème.

    J'ai une application VB6 lourde (90 projets, plusieurs centaines de form...) et j'aimerais y intégrer un timeout de session. Le fonctionnement serait simple, quand l'utilisateur ne se sert plus du logiciel eu bout de x minutes, je lance une procédure permettant de fermer sa session, s'il clique dans l'application (n'importe où), le timer présent dans la fenêtre principale est remis à zéro.

    Mon problème est que je ne peux pas ajouter du code dans tous les projets pour la remise à zéro du timer. La solution la plus simple serait que dès que l'utilisateur bouge la souris (et que l'appli est lancée bien sur), le timer est réinitialisé.

    J'aimerais donc savoir s'il est possible de :
    - Récupérer via un API de windows le bon évènement (comme quand l'utilisateur bouge la souris et que son ordi sort de veille)
    - Ou bien implémenter un évènement global au niveau de l'objet "App" qui se déclencherais à chaque mouvement de souris (ou clic clavier)
    - une autre solution ...

    Merci à tous pour vos conseils
    La Solution AGILE de Cartographie et d'Urbanisation des Systèmes d'Information éditée et développée par la société AB+ SOFTWARE
    http://www.soluqiq.fr/

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    mai 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2007
    Messages : 107
    Points : 115
    Points
    115

    Par défaut

    Bonjour,

    Il te faut donc "travailler" sur les moments d'inaction du système (en anglais on dit idle time).

    Une API pourrait t'aider: GetLastInputInfo()

    Mais je ne l'ai jamais utilisé et ne sais pas ce qui est considéré ou non comme étant de l'activité.

  3. #3
    Modérateur
    Avatar de l_autodidacte
    Homme Profil pro
    Retraité : Directeur de lycée/Professeur de sciences physiques
    Inscrit en
    juillet 2009
    Messages
    1 943
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Retraité : Directeur de lycée/Professeur de sciences physiques
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2009
    Messages : 1 943
    Points : 4 417
    Points
    4 417

    Par défaut

    Un petit exemple pour GetLastInputInfo en plaçant un bouton de commande appelé cmdAction sur l'objet Form1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    Option Explicit
     
    Private Type PLASTINPUTINFO
       cbSize As Long
       dwTime As Long
    End Type
     
    Private Declare Function GetLastInputInfo Lib "user32.dll" (pLII As PLASTINPUTINFO) As Long
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    '
    '
     
    Private Sub Form_Load()
       cmdAction.Caption = "Arrêter"
       Timer1.Interval = 5
       Timer1.Enabled = True
    End Sub
     
    Private Sub cmdAction_Click()
     
       Timer1.Enabled = Not Timer1.Enabled
     
       Select Case Timer1.Enabled
          Case True
             cmdAction.Caption = "Arrêter"
          Case False
             cmdAction.Caption = "Démarrer"
       End Select
     
    End Sub
     
    Private Sub Form_Unload(Cancel As Integer)
       Timer1.Enabled = False
    End Sub
     
    Private Sub Timer1_Timer()
     
       Dim pLII As PLASTINPUTINFO
     
       pLII.cbSize = Len(pLII)
       GetLastInputInfo pLII
       Me.Caption = "Temps d'inactivité(souris et clavier) : " & FormatNumber((GetTickCount() - pLII.dwTime) / 1000, 3) & " secondes"
    End Sub
    Le temps d'inactivité de la souris et/ou du clavier est mis à jour dans le titre de la fenêtre Form1 et ce quelle que soit la position de la souris
    Ne pas oublier le tag si satisfait.
    Voter pour toute réponse satisfaisante avec pour encourager les intervenants.
    Toujours utiliser la clause Option Explicit(VBx, VBS ou VBA)
    Vous pouvez consulter mes contributions
    Consultez les différentes FAQs et les Cours/Tutoriels VB6/VBScript
    Ne pas oublier L'Aide VBScript et MSDN VB6 Fr

  4. #4
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2009
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2009
    Messages : 231
    Points : 125
    Points
    125

    Par défaut

    Merci pour ces infos mais ce n'est pas le fonctionnement que je recherche.

    Cette solution utilise un timer qui, une fois le délai écoulé, va récupérer le temps d'inactivité de la souris.

    La partie timer est OK pour moi, quand le timer est écoulé, le programme déconnecte l'utilisateur et ferme la session.

    Ce que je cherche c'est comment réinitialiser le timer quand la souris bouge et non l'inverse c'est à dire quand le timer arrive au bout, aller voir si la souris a bougé. Cette solution serait envisageable mais pas forcement optimisée. Je m'explique :

    On prend un timer de 10 mn. Au bout de 10 mn, on récupère le temps depuis la dernière action de l'utilisateur.

    Dans un premier temps cette dernière action a pu être sur un autre logiciel, ou sur Windows directement donc même si l'utilisateur a le programme réduit dans la barre de tache et qu'il bosse sur autre chose sa session ne sera jamais fermée.

    Dans un deuxième temps, il faut faire un calcul pour remettre un délai correct au timer en cas d'action. Si la dernière action s'est passée il y a 5 mn, il faut remettre le délai du timer à 5 mn et non a 10, bref cette solution n'est pas optimisée. (oui je sais ce n'est qu'une simple soustraction )

    Pour l'instant j'ai utilisé la fonction SetTimer de l'API user32 pour créer un timer dynamique et l'affecter à la fenêtre principale. Puis j'utilise un activeX pour "attraper" les messages Windows et, suivant le type de message et le handle de la fenêtre, je sais que je suis dans mon application et je peux tout simplement tuer le timer (avec la fonction KillTimer) et en recréer un autre.

    Pour l'instant je galère un peu avec les messages windows mais c'est cool d'avoir une fonction dans laquelle le programme passe à chaque message de Windows (et il y en a un paquet).

    Je mettrai un exemple de code quand tout marchera correctement
    La Solution AGILE de Cartographie et d'Urbanisation des Systèmes d'Information éditée et développée par la société AB+ SOFTWARE
    http://www.soluqiq.fr/

  5. #5
    Modérateur
    Avatar de l_autodidacte
    Homme Profil pro
    Retraité : Directeur de lycée/Professeur de sciences physiques
    Inscrit en
    juillet 2009
    Messages
    1 943
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Retraité : Directeur de lycée/Professeur de sciences physiques
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2009
    Messages : 1 943
    Points : 4 417
    Points
    4 417

    Par défaut

    Ce que je cherche c'est comment réinitialiser le timer quand la souris bouge et non l'inverse
    Justement, lorsque la souris bouge ou qu'on actionne une touche du clavier, le temps d'inactivité est remis à zéro(comme si le timer est réinitialisé).
    C'est ce temps-là qu'on utilisera pour décider de la fermeture ou non de la session. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Option Explicit
     
    Private Type PLASTINPUTINFO
       cbSize As Long
       dwTime As Long
    End Type
     
    Private Declare Function GetLastInputInfo Lib "user32.dll" (pLII As PLASTINPUTINFO) As Long
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    '
    '
     
    Private Sub Form_Load()
       cmdAction.Caption = "Arrêter"
       Timer1.Interval = 5
       Timer1.Enabled = True
    End Sub
     
    Private Sub cmdAction_Click()
     
       Timer1.Enabled = Not Timer1.Enabled
     
       Select Case Timer1.Enabled
          Case True
             cmdAction.Caption = "Arrêter"
          Case False
             cmdAction.Caption = "Démarrer"
       End Select
     
    End Sub
     
    Private Sub Form_Unload(Cancel As Integer)
       Timer1.Enabled = False
    End Sub
     
    Private Sub Timer1_Timer()
     
       Dim pLII As PLASTINPUTINFO, TM
     
       pLII.cbSize = Len(pLII)
       GetLastInputInfo pLII
       Me.Caption = "Temps d'inactivité(souris et clavier) : " & FormatNumber((GetTickCount() - pLII.dwTime) / 1000, 3) & " secondes"
       TM = (GetTickCount() - pLII.dwTime) / 1000
       If TM >= 10 Then Unload Me
    End Sub
    une condition a été ajoutée dans la procédure Timer1_Timer() qui ferme le programme par exemple.
    Sauf si le timer ne doit être actif que si l'une des fenêtres du programme est active, là cela devient autre chose, car le temps calculé ne dépend d'aucun programme actif ou non.
    Ne pas oublier le tag si satisfait.
    Voter pour toute réponse satisfaisante avec pour encourager les intervenants.
    Toujours utiliser la clause Option Explicit(VBx, VBS ou VBA)
    Vous pouvez consulter mes contributions
    Consultez les différentes FAQs et les Cours/Tutoriels VB6/VBScript
    Ne pas oublier L'Aide VBScript et MSDN VB6 Fr

  6. #6
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2009
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2009
    Messages : 231
    Points : 125
    Points
    125

    Par défaut

    Sauf si le timer ne doit être actif que si l'une des fenêtres du programme est active
    C'est le cas
    La Solution AGILE de Cartographie et d'Urbanisation des Systèmes d'Information éditée et développée par la société AB+ SOFTWARE
    http://www.soluqiq.fr/

  7. #7
    Modérateur
    Avatar de l_autodidacte
    Homme Profil pro
    Retraité : Directeur de lycée/Professeur de sciences physiques
    Inscrit en
    juillet 2009
    Messages
    1 943
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Retraité : Directeur de lycée/Professeur de sciences physiques
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2009
    Messages : 1 943
    Points : 4 417
    Points
    4 417

    Par défaut

    Alors un petit test avec le code en PJ. A adapter selon ton besoin
    Fichiers attachés Fichiers attachés
    Ne pas oublier le tag si satisfait.
    Voter pour toute réponse satisfaisante avec pour encourager les intervenants.
    Toujours utiliser la clause Option Explicit(VBx, VBS ou VBA)
    Vous pouvez consulter mes contributions
    Consultez les différentes FAQs et les Cours/Tutoriels VB6/VBScript
    Ne pas oublier L'Aide VBScript et MSDN VB6 Fr

  8. #8
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2009
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2009
    Messages : 231
    Points : 125
    Points
    125

    Par défaut

    Merci pour vos réponses.

    En fait j'ai utilisé un ocx qui était déjà présent dans mes projets et qui permet de gérer les MDI Form. Cet ocx contient des fonctions permettant d'écouter les messages de Windows et de les re-dispatcher.

    J'ai donc pu récupérer les messages de clic de souris et de changement d’icône (qui se produit très souvent en fonction de ce que l’icône survole).

    A la fin du démarrage du logiciel, je crée dynamiquement un timer avec la fonction SetTimer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SetTimer(F_MDIParent.hwnd, 10, 10000, AddressOf FermerSession)
    J'ai mis 10 pour l'ID du timer car je n'ai pas trouvé comment récupérer le dernier ID possible. Vu que j'ai d'autres timer sur la fenêtre, en mettant 0 il aurait modifié le premier timer crée.

    En récupérant dans la fonction "WndProc" de l'OCX l'ID des bons messages (on trouve les ID et valeurs Hexa sur MSDN), je peux en cas de clic de souris ou de changement de curseur de souris tuer le timer avec la fonction "KillTimer" et le recréer.

    Pour garder les bonnes valeurs, notamment le handle de la fenêtre et l'adresse mémoire de la fonction appelée par le timer, j'ai crée dans l'OCX des variables pour stocker ces valeurs et les retrouver facilement.

    Si quelqu'un s'y connait sur ce fonctionnement j'aimerais bien trouver de la doc, j'ai cherché je n'ai trouvé que ce site qui explique comment attraper les messages Windows :
    http://www.exaflop.org/docs/vbsubclass/index.html

    Je ne comprend pas trop comment une fonction peu attraper les messages Windows sans être appelée (ou cette fonction a un nom générique et elle est appelée par un thread...)

    Voilà, en tout cas merci pour votre aide
    La Solution AGILE de Cartographie et d'Urbanisation des Systèmes d'Information éditée et développée par la société AB+ SOFTWARE
    http://www.soluqiq.fr/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 18/08/2006, 11h22
  2. [Maj pb] Propagation d'évènement au niveau supérieur
    Par seiryujay dans le forum AWT/SWING
    Réponses: 6
    Dernier message: 26/06/2006, 16h05
  3. Implémenter une API
    Par pier* dans le forum APIs
    Réponses: 4
    Dernier message: 02/05/2006, 19h40
  4. [API][Système] Appel d'une application externe via java
    Par Tasslekender dans le forum Général Java
    Réponses: 2
    Dernier message: 17/03/2006, 15h13
  5. Imprimer 2 pages ( 2*A5 ) , comment via API ?
    Par Thomad dans le forum Windows
    Réponses: 5
    Dernier message: 29/09/2005, 15h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo