IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Téléchargez Python Discussion :

Injection de touches clavier (sans utiliser de lib externe comme win32api)


Sujet :

Téléchargez Python

  1. #1
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut Injection de touches clavier (sans utiliser de lib externe comme win32api)
    [EDIT] à vous les modérateurs : j'ai essayé de poster un script python, mais je suis tombé sur l'erreur "jeton de sécurité manquant" et maintenant je constate que ma description se retrouve sous la forme d'un post dans le forum...
    [EDIT2] une page a bien été crée à l'url indiquée plus bas, mais le source est inaccessible... du coup je le rajoute ici. Si j'ai raté quelque chose, excusez-moi para avance.


    Bonjour,

    Je vous propose un nouvel élément à utiliser : Injection de touches clavier (sans utiliser de lib externe comme win32api)

    Un script minimaliste qui permet de simuler l'appui de touches du clavier.

    Son intérêt sur l'existant est qu'il se contente de la libraire ctype, et ne nécessite pas l'installation de libraires externes (telles que win32api ou win32con).

    Il peut simuler l'appui des combinaisons de touches avec Shift, Control ou Alt.



    Quelques limitations :

    - Les caractères nécessitant l'appui de 2 touches successives (avec un tréma ou un accent circonflexe) ne sont pas accessibles.

    - Les combinaisons Shift + Flêche ne semblent pas fonctionner... (si quelqu'un a une idée)


    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
    # coding:cp1252
     
    class Win32 :
        import ctypes
        KeyTable = {}
        def __init__(self):
            self.buffer = None
        def BuildKeyTable (self):
            VkToScan   = lambda vk : self.ctypes.windll.user32.MapVirtualKeyA( vk,0 )
            ScanToVk   = lambda sc : self.ctypes.windll.user32.MapVirtualKeyA( sc,1 )
            AsciiToVk  = self.ctypes.windll.user32.VkKeyScanA
            GetKeyName = self.ctypes.windll.user32.GetKeyNameTextA
            if not self.buffer :
                self.buffer = self.ctypes.create_string_buffer( 300 )
            res = {} # dict[char/key name] = ( scan code , virtual key , shift , ctrl , alt ) 
            for sc in xrange( 128 ):
                GetKeyName( sc << 16,self.buffer,self.ctypes.sizeof( self.buffer ))
                if len( self.buffer.value ) == 1 :
                    res[self.buffer.value] = (sc,ScanToVk( sc ),0,0,0)
            for ascii in xrange( 32,256 ):
                vk = AsciiToVk( ascii )
                vk,shift,ctrl,alt = vk&0xff,(vk>>8)&1,(vk>>9)&1,(vk>>10)&1
                res[chr(ascii)] = ( VkToScan( vk ),vk,shift,ctrl,alt )
            # http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731
            specials = 'back,tab,,,,enter,,,shift,ctrl,alt,pause,capital,,,,,,,escape,,,,,space,prior,next,end,home,left,up,right,down,,,,,insert,delete'
            for name,vk in filter( lambda a : a[0] ,zip( specials.split(','),xrange( 8,1000 ))) :
                res[name] = (VkToScan( vk ),vk,0,0,0)
            return res
        def GetForegroundWindowTitle (self):
            if not self.buffer :
                self.buffer = self.ctypes.create_string_buffer( 300 )
            hwnd = self.ctypes.windll.user32.GetForegroundWindow()
            self.ctypes.windll.user32.GetWindowTextA( hwnd,self.buffer,self.ctypes.sizeof( self.buffer ))
            return self.buffer.value
        def PressKey ( self,key ):
            SubKeyPress = lambda sc,vk,down : self.ctypes.windll.user32.keybd_event( vk,sc,(3,1)[down],0 )
            if not self.KeyTable :
                self.KeyTable = self.BuildKeyTable()
            down,up = True,True
            if len( key ) > 1 :
                if key.startswith('+') : key,up   = key[1:],False
                if key.startswith('-') : key,down = key[1:],False
            if key in self.KeyTable :
                scan,vk,shift,ctrl,alt = self.KeyTable[key]
                print key,scan,vk,shift,ctrl,alt,down,up
                if alt   : self.PressKey('+alt')
                if ctrl  : self.PressKey('+ctrl')
                if shift : self.PressKey('+shift')
                if down  : SubKeyPress( scan,vk,True )
                if up    : SubKeyPress( scan,vk,False )
                if shift : self.PressKey('-shift')
                if ctrl  : self.PressKey('-ctrl')
                if alt   : self.PressKey('-alt')
     
    def PressKeys ( *keys ):
        w = Win32()
        import time
        for k in keys :
            if k.startswith('sleep'):
                time.sleep( float( k[5:] ))
            elif len( k ) > 1 and k.startswith('='):
                for c in k[1:]:
                    w.PressKey( c )
            else:
                w.PressKey( k )
     
    def WaitForegroundWindow ( name_pattern,timeout=5 ):
        w = Win32()
        import time,re
        for i in xrange( int( timeout/0.1 )):
            name = w.GetForegroundWindowTitle()
            if re.match( name_pattern,name ):
                return name
            time.sleep( 0.1 )
     
     
    # on attend qu'une fenêtre de bloc note (notepad.exe) ait le focus 
    if WaitForegroundWindow('.*Bloc-note.*'):
        # et on lui envoie plein de caractères !
        PressKeys( '+ctrl','home','-ctrl',r'''=# Bonjour le monde ! Voici plein de caractères bizarres : \/"'`:;.?@#$%<>(){}[] €éèàç °¤µ§¨^£''','enter')

    Qu'en pensez-vous ?
    Captain'Flam
    anciennement Sopsag, aka Hadrien
    Win seven x64 & Win 10 / Visual 2017 / Python 2.7 / Eclipse

  2. #2
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Bonjour,

    Intéressant! J'ai fait un petit test concluant. Cependant il y a des fois où la première lettre ne s'écrit pas. Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import time    
    # on attend qu'une fenêtre de bloc note (notepad.exe) ait le focus 
    if WaitForegroundWindow('.*Bloc-note.*'):
        # et on lui envoie plein de caractères !
        text = 'Test de frappe au clavier'
        for c in text:
            PressKeys(c)
            time.sleep(0.5)
    Si je lance le script et ensuite sélectionne la fenêtre notepad, la lettre 'T' n'est pas écrite.

    J

  3. #3
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    peut-être vaudrait-il mieux faire le time.sleep avant le PressKey...
    (c'est une réponse qui me semble logique, mais je n'ai pas fait l'essai)

    Hadrien
    Captain'Flam
    anciennement Sopsag, aka Hadrien
    Win seven x64 & Win 10 / Visual 2017 / Python 2.7 / Eclipse

Discussions similaires

  1. serialiser un objet sans utiliser de bibliothèque externe
    Par Jérémy Lefevre dans le forum Langage
    Réponses: 2
    Dernier message: 11/04/2014, 17h02
  2. Réponses: 2
    Dernier message: 23/11/2013, 20h28
  3. Réponses: 3
    Dernier message: 21/03/2010, 21h22
  4. Envoyer une touche clavier sans focus sur fenetre
    Par linked dans le forum Shell et commandes GNU
    Réponses: 0
    Dernier message: 21/04/2009, 20h33
  5. Simulation clavier sans utilisation d'api?
    Par taurus67 dans le forum VB 6 et antérieur
    Réponses: 14
    Dernier message: 30/07/2007, 22h26

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