Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 8 sur 8
  1. #1
    Membre régulier
    Homme Profil pro Alex
    Ingénieur développement logiciels
    Inscrit en
    juin 2009
    Messages
    230
    Détails du profil
    Informations personnelles :
    Nom : Homme Alex
    Localisation : France

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

    Informations forums :
    Inscription : juin 2009
    Messages : 230
    Points : 92
    Points
    92

    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

  2. #2
    Membre du Club
    Inscrit en
    mai 2007
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : mai 2007
    Messages : 56
    Points : 54
    Points
    54

    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 Moncef Ben Othman
    Directeur de lycée
    Inscrit en
    juillet 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Nom : Homme Moncef Ben Othman
    Âge : 59
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Directeur de lycée
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2009
    Messages : 1 460
    Points : 2 900
    Points
    2 900

    Par défaut

    Un petit exemple pour GetLastInputInfo en plaçant un bouton de commande appelé cmdAction sur l'objet Form1 :
    Code :
    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
    A cœur vaillant rien d'impossible
    Ne pas oublier le tag si satisfait.
    Voter pour toute réponse satisfaisante avec
    Vous pouvez voir Mes contributions

  4. #4
    Membre régulier
    Homme Profil pro Alex
    Ingénieur développement logiciels
    Inscrit en
    juin 2009
    Messages
    230
    Détails du profil
    Informations personnelles :
    Nom : Homme Alex
    Localisation : France

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

    Informations forums :
    Inscription : juin 2009
    Messages : 230
    Points : 92
    Points
    92

    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

  5. #5
    Modérateur
    Avatar de l_autodidacte
    Homme Profil pro Moncef Ben Othman
    Directeur de lycée
    Inscrit en
    juillet 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Nom : Homme Moncef Ben Othman
    Âge : 59
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Directeur de lycée
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2009
    Messages : 1 460
    Points : 2 900
    Points
    2 900

    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 :
    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.
    A cœur vaillant rien d'impossible
    Ne pas oublier le tag si satisfait.
    Voter pour toute réponse satisfaisante avec
    Vous pouvez voir Mes contributions

  6. #6
    Membre régulier
    Homme Profil pro Alex
    Ingénieur développement logiciels
    Inscrit en
    juin 2009
    Messages
    230
    Détails du profil
    Informations personnelles :
    Nom : Homme Alex
    Localisation : France

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

    Informations forums :
    Inscription : juin 2009
    Messages : 230
    Points : 92
    Points
    92

    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

  7. #7
    Modérateur
    Avatar de l_autodidacte
    Homme Profil pro Moncef Ben Othman
    Directeur de lycée
    Inscrit en
    juillet 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Nom : Homme Moncef Ben Othman
    Âge : 59
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Directeur de lycée
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2009
    Messages : 1 460
    Points : 2 900
    Points
    2 900

    Par défaut

    Alors un petit test avec le code en PJ. A adapter selon ton besoin
    Fichiers attachés Fichiers attachés
    A cœur vaillant rien d'impossible
    Ne pas oublier le tag si satisfait.
    Voter pour toute réponse satisfaisante avec
    Vous pouvez voir Mes contributions

  8. #8
    Membre régulier
    Homme Profil pro Alex
    Ingénieur développement logiciels
    Inscrit en
    juin 2009
    Messages
    230
    Détails du profil
    Informations personnelles :
    Nom : Homme Alex
    Localisation : France

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

    Informations forums :
    Inscription : juin 2009
    Messages : 230
    Points : 92
    Points
    92

    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 :
    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

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •