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

WinDev Discussion :

Problème d'affichage de caractère suite à la capture des touches clavier [WD18]


Sujet :

WinDev

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 223
    Points : 47
    Points
    47
    Par défaut Problème d'affichage de caractère suite à la capture des touches clavier
    Le titre n'est peut être pas facile à comprendre je vais donc essayer de vous expliquer le mieux possible ici :

    Je dois modifier une appli existante qui utilise la capture des touches du clavier.
    Le problème est que lorsque la capture du clavier est lancée, si l'on utilise un traitement de texte par exemple et que l'on désite utiliser la touche ¨^ pour faire un accent circonflexe ou tréma, ces caractères ne se mettent pas sur la lettre comme voulu mais à coté (et se doublent).

    Exemple je veux taper "tête" et cela affichera "t^^ete".
    Pareil pour le ¨.

    Je suppose donc que la touche qui permet l'affichage de ces caractère n'est pas bien prise en compte.

    Voila une partie du code utilisé, je ne sais pas si quelqu'un pourra m'aider mais ça serait super :

    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
     
     
    clavier est un KBDLLHOOKSTRUCT
    KeyState est un tableau fixe de 256 entiers sans signe sur 1 octet
    MonCharEx est un tableau fixe de 2 caractères
    RetourFonction est un entier
    vk est un entier sans signe
    keylayout est un entier 
    tailleChar est un entier
    x est un entier
     
     
    SI ncode = HC_ACTION ALORS
    	// Sur touche enfoncé uniquement
    	SI  wparam <> WM_KEYDOWN  ET wparam <> WM_SYSKEYDOWN  ALORS
    		RENVOYER API("user32","CallNextHookEx",gnHandleHook, ncode, wparam, lparam) 
    	FIN
    	Transfert(&clavier,lparam,Dimension(clavier)) 
     
    	keylayout=API("USER32","GetKeyboardLayout",0)
    	RetourFonction=API("USER32","GetKeyboardState",&KeyState)
    	vk = API("USER32","MapVirtualKeyExA",clavier:scanCode,3,keylayout)
    	KeyState[VK_SHIFT +1]= ETBinaire((API("USER32","GetAsyncKeyState",VK_SHIFT)/256),255)
    	KeyState[VK_MENU +1]= ETBinaire((API("USER32","GetAsyncKeyState",VK_CONTROL)/256),255)
    	KeyState[VK_CONTROL +1]= ETBinaire((API("USER32","GetAsyncKeyState",VK_CONTROL)/256),255)
    	// on appelle ToAsciiEx plus balaise de ToAscii
    	tailleChar =API("USER32","ToAsciiEx",vk, clavier:scanCode,&KeyState,&MonCharEx, 0, keylayout)
    	//
    	SI tailleChar = 0 ALORS
    		Machaine = ""
    		SELON clavier:vkCode
    			CAS	VK_NUMPAD0 : Machaine = "0"
    			CAS	VK_NUMPAD1 : Machaine = "1"				
    			CAS	VK_NUMPAD2 : Machaine = "2"
    			CAS	VK_NUMPAD3 : Machaine = "3"
    			CAS	VK_NUMPAD4 : Machaine = "4"
    			CAS	VK_NUMPAD5 : Machaine = "5"
    			CAS	VK_NUMPAD6 : Machaine = "6"
    			CAS	VK_NUMPAD7 : Machaine = "7"
    			CAS	VK_NUMPAD8 : Machaine = "8"
    			CAS	VK_NUMPAD9 : Machaine = "9"		
    		FIN
     
    RENVOYER API("user32","CallNextHookEx",gnHandleHook, ncode, wparam, lparam)
    Même une petite piste concernant l'api de windows car j'ai du mal à comprendre comment cela marche

  2. #2
    Membre habitué
    Avatar de jdsetls
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Décembre 2012
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Rédacteur technique
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Décembre 2012
    Messages : 209
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Dans la mesure où ton parcours de chaîne intercepte code par code, en analysant même les invisibles, J'ai testé ceci qui fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Selon  Ma_variable_interceptée  
     cas  = "^"
    //Tester caractère_suivant
    Si caractère_suivant = "a"
       Caractère_à_transmettre = "â"
        sinon Si caractère_suivant = "e"
        Caractère_à_transmettre = "ê"
    //tester les cas possibles y compris les majuscules ?
    Fin
    Bien cordialement,

    Jacques De Schryver

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 223
    Points : 47
    Points
    47
    Par défaut
    Merci pour ton aide, cependant je n'arrive pas à utiliser ta fonction, je ne sais pas comment l'implanter dans mon code et surtout je crois que tu n'as pas bien compris mon problème car en fait ce n'est pas dans l'application que le problème se pose mais dans l'environnement windows.

    Par exemple lorsque je tape les caractères ^ ou ¨ dans un champs de recherche windows ou même dans un traitement de texte le bug se produit (ex: "fe^^te" à la place de "fête").

    Merci

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    303
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 303
    Points : 815
    Points
    815
    Par défaut
    Salut pixel016 !

    Effectivement, ton problème n'est pas simple du tout.

    Il s'agit de gérer correctement un "dead key" (je te le mets en anglais pour tes recherches sur le web).
    (parfois on parle aussi de "DEAD CHAR" mais c'est plutôt en relation avec le message Windows WM_DEADCHAR)

    Si j'ai bien compris ce que j'ai pu lire sur le web,
    c'est l'appel à la fonction API ToAsciiEx qui perturbe "l'état interne logique du clavier", et qui fait perdre l'indication de dead key pour le prochain appel à la fonction API CallNextHookEx.

    Je n'ai pas vu grand chose comme solution.

    Ici une proposition de solution (mais je n'ai pas tout suivi en détails)
    http://www.experts-exchange.com/Prog..._23453780.html

    Bon courage !

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 223
    Points : 47
    Points
    47
    Par défaut
    Merci pour ta contribution OnePoint, je vais essayer de regarder ça mais c'est quand même pas évident.

    Si jamais JurassicPorc qui est l'auteur du code que j'utilise passe par la peut être aura il une idée précise

  6. #6
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 032
    Points : 9 433
    Points
    9 433
    Par défaut
    Hello,
    j'ai regardé le lien de Onepoint, c'est vrai que ce n'est pas évident au premier abord, mais j'ai quand même réussi à pondre un code qui m'a l'air de fonctionner (basiquement).
    Les modifications :
    1 - Rajout des variables globales dans le code du projet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ClavierMémorisé est un KBDLLHOOKSTRUCT
    ShiftMémorisé est un entier sans signe sur 1 octet
    et la procédure "hookeuse" ressemble à ceci :
    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
    PROCEDURE Procédure_Hookeuse(ncode,wparam,lparam)
    clavier est un KBDLLHOOKSTRUCT
     
    KeyState est un tableau fixe de 256 entiers sans signe sur 1 octet
    MonCharEx est un tableau fixe de 2 caractères
    RetourFonction est un entier
    vk est un entier sans signe
    keylayout est un entier 
    tailleChar est un entier
    x est un entier
    FenêtreCourante est une chaîne
    Machaine est une chaîne
     
     
    SI ncode = HC_ACTION ALORS
    	// Sur touche enfoncé uniquement
    	SI  wparam <> WM_KEYDOWN  ET wparam <> WM_SYSKEYDOWN  ALORS
    		RENVOYER API("user32","CallNextHookEx",gnHandleHook, ncode, wparam, lparam) 
    	FIN
    	Transfert(&clavier,lparam,Dimension(clavier)) // transfert de la structure ( méthode peu recommandable avez-vous mieux ? cast?)
    	FenêtreCourante = SysFenTitre (SysFenActive ())
     
    	SI FenêtreCourante <> FenêtreMémorisée  ALORS
    		FenêtreMémorisée = FenêtreCourante	
    		FEN_SansNom1.Memo  += RC + FenêtreMémorisée + "++++++++++++++++++++++++++" + RC
    	FIN
    	keylayout=API("USER32","GetKeyboardLayout",0)
    	RetourFonction=API("USER32","GetKeyboardState",&KeyState)
    	vk = API("USER32","MapVirtualKeyExA",clavier:scanCode,3,keylayout)
    	KeyState[VK_SHIFT +1]= ETBinaire((API("USER32","GetAsyncKeyState",VK_SHIFT)/256),255)
    	KeyState[VK_MENU +1]= ETBinaire((API("USER32","GetAsyncKeyState",VK_CONTROL)/256),255)
    	KeyState[VK_CONTROL +1]= ETBinaire((API("USER32","GetAsyncKeyState",VK_CONTROL)/256),255)
    	// on appelle ToAsciiEx plus balaise de ToAscii
    	tailleChar =API("USER32","ToAsciiEx",vk, clavier:scanCode,&KeyState,&MonCharEx, 0, keylayout)
    	// si le retour de ToAsciiEx est -1 
    	SI tailleChar = -1 ALORS
    		// on mémorise l'état du clavier
    		 ClavierMémorisé = clavier
    		 ShiftMémorisé = KeyState[VK_SHIFT +1]
    		// on vide le buffer pour revenir à l'état précédent
    		TANTQUE API("USER32","ToAsciiEx",vk, clavier:scanCode,&KeyState,&MonCharEx, 0, keylayout) < 0 
     
    		FIN
    	SINON
    	// gestion du return
    	SI 	clavier:vkCode = VK_RETURN ALORS  	FEN_SansNom1.Memo += RC
    	POUR x = 1 A tailleChar
    		FEN_SansNom1.Memo += MonCharEx[x] // Memo est un champ de saisie qui affiche les caractères tapés	
    	FIN
    	SI tailleChar = 0 ALORS
    		Machaine = ""
    		SELON clavier:vkCode
    			CAS	VK_NUMPAD0 : Machaine = "0"
    			CAS	VK_NUMPAD1 : Machaine = "1"				
    			CAS	VK_NUMPAD2 : Machaine = "2"
    			CAS	VK_NUMPAD3 : Machaine = "3"
    			CAS	VK_NUMPAD4 : Machaine = "4"
    			CAS	VK_NUMPAD5 : Machaine = "5"
    			CAS	VK_NUMPAD6 : Machaine = "6"
    			CAS	VK_NUMPAD7 : Machaine = "7"
    			CAS	VK_NUMPAD8 : Machaine = "8"
    			CAS	VK_NUMPAD9 : Machaine = "9"		
    		FIN
    		SI Machaine <> "" ALORS 	FEN_SansNom1.Memo += Machaine
    	FIN
    	SI ClavierMémorisé:vkCode <> 0 ALORS
    	// A Faire : il serait plus sûr de réinitialiser le Keystate avec des zéros. A voir si bug		
        // on restitue l'état du shift
    	KeyState[VK_SHIFT +1] = ShiftMémorisé
    	// on renvoie l'ancien vkcode vers le buffer local	
    	API("USER32","ToAsciiEx",ClavierMémorisé:vkCode, ClavierMémorisé:scanCode,&KeyState,&MonCharEx, 0, keylayout)
    	// on met le vkcode à zéro pour invalider le ClavierMémorisé
    	ClavierMémorisé:vkCode = 0
    	FIN	
    	FIN
    FIN
    // Renvoie la suite du hook afin de permettre le traitement de l'appui par la fenetre d'origine
    RENVOYER API("user32","CallNextHookEx",gnHandleHook, ncode, wparam, lparam)
    Je ne garantis pas le code car le KeyState n'est pas remis à zéro et je ne suis pas un spécialiste .


    Ami calmant, J.P

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 223
    Points : 47
    Points
    47
    Par défaut
    Tout d'abord merci beaucoup Jurassic Pork car je viens d'essayer et ça à l'air de fonctionner correctement.

    Tu n'imagine pas à quel point tu m'enlève une épine du pied avec ce bug que j'avais depuis des mois et que je n'arrivais pas à corriger (je n'ai d'ailleurs pas tout compris lol).

    En tout cas un grand grand merci à toi et ta générosité, je ne sais pas de quelle région tu es mais je t'offrirai bien un café pour te remercier !

    Merci

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

Discussions similaires

  1. Réponses: 15
    Dernier message: 04/01/2007, 08h47
  2. [SQL] Problème d'affichage de caractère spéciaux dans une variable chaîne
    Par Kryptonaute dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 18/08/2006, 08h40
  3. [MySQL] Problème d'affichage de caractères UTF-8
    Par Metallic-84s dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 19/05/2006, 16h38
  4. Problème d'affichage de caractères sous IE
    Par arnaud_verlaine dans le forum Autres Logiciels
    Réponses: 3
    Dernier message: 18/07/2005, 22h21
  5. [JEditorPane]Captures des touches claviers
    Par splend_f dans le forum Agents de placement/Fenêtres
    Réponses: 5
    Dernier message: 17/05/2004, 14h57

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