begin process at 2008 05 16 06:02:47
1 173 216 membres
58 nouveaux aujourd'hui
13 970 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

DÉTOURNER LA FRAPPE CLAVIER


Information sur la source

Catégorie :Astuces Classé sous : clavier, hook, simuler, détourner, frappe Niveau : Débutant Date de création : 04/09/2007 Vu / téléchargé: 6 088 / 307

Note :
10 / 10 - par 3 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (6)
Ajouter un commentaire et/ou une note

Description

En réponse à une question du forum, voici un code source montrant comment détourner la frappe au clavier pour afficher, lettre par lettre, un message personnalisé. Un hook global clavier est utilisé. L'astuce réside dans l'emploi de la fonction keybd_event() pour simuler l'appui sur des touches différentes de celles interceptées dans la fonction de hook. Les lettres majuscules et les lettres avec accent circoflexe ou tréma les plus courament utilisées sont traitées.
Pour tester l'exécutable, renommez le en detourneur.exe. Il fonctionne en tâche de fond. Pour regarder son effet, lancez le et essayez de taper du texte dans n'importe quelle application. Lisez le texte qui s'affiche au fur et à mesure de la frappe jusqu'à la fin pour voir comment le quitter.
Amusez-vous bien.

Source

  • #define _WIN32_WINNT 0x0500 // Windows 2000 et supérieur
  • #include <windows.h>
  • HHOOK hHook; // Handle du hook clavier
  • int position=0;// Indicateur de position dans la chaine à afficher
  • // Chaine à afficher:
  • char texte[]="Vous êtes victime d'un programme qui détourne la frappe au clavier pour afficher le présent texte. Pour l'arrêter appuyez sur CTRL + Q ou attendez 3 minutes.\n";
  • // Liste des lettres avec accent circonflexe ou tréma:
  • BYTE avecaccents[]={'â','ê','û','î','ô','ë','ï'};
  • // Liste des lettres sans accent circonflexe ni tréma:
  • BYTE sansaccents[]={'a','e','u','i','o','e','i'};
  • // Liste des flags indiquant l'utilisation de la touche SHIFT:
  • BYTE shifts[]={0,0,0,0,0,1,1};
  • /******************************* Fonction de gestion du hook ****************************/
  • LRESULT CALLBACK HookProc ( int nCode, WPARAM wParam, LPARAM lParam)
  • {
  • // Vérifier si une touche est appuyée:
  • if ((nCode == HC_ACTION) && (wParam == WM_KEYDOWN))
  • {
  • // Obtenir pointeur sur structure KBDLLHOOKSTRUCT:
  • KBDLLHOOKSTRUCT* hookstruct = ((KBDLLHOOKSTRUCT*)lParam);
  • // S'assurer que l'appui sur les tpuches n'est pas simulé:
  • if(hookstruct->dwExtraInfo!=255)
  • {
  • // Vérifier si la touche "Q" est appuyée:
  • if(hookstruct->vkCode==0x51 )
  • {
  • // S'assurer que la touche Control est enfoncée:
  • if(GetKeyState(VK_CONTROL) & 0x8000)
  • {
  • // Envoyer le message de fermeture de l'application:
  • PostThreadMessage(GetCurrentThreadId(),WM_QUIT,0,0);
  • // Sauter les autres hooks:
  • return 1;
  • }
  • }
  • // Convertir le caractère courant en virtual-key code:
  • SHORT vcode=VkKeyScan(texte[position]);
  • SHORT vcode2;
  • // Si le caractère comporte un tréma ou accent circonflexe:
  • if(vcode==-1)
  • {
  • int i;
  • // Chercher le caractère dans la liste:
  • for(i=0; i<7; i++)
  • {
  • if((BYTE)texte[position]==avecaccents[i]) break;
  • }
  • // Si pas trouvé alors sauter les autres hooks:
  • if(i==7) return 1;
  • // Trouver le virtuel-key code de la lettre non accentuée correspondante:
  • vcode2=VkKeyScan(sansaccents[i]);
  • // Si tréma, simuler appui sur la touche SHIFT:
  • if(shifts[i]) keybd_event(VK_SHIFT,0,0,255);
  • // Simuler appui sur la dead-key de l'accent circonflexe et le tréma:
  • keybd_event(VK_OEM_6,26,0,255);
  • keybd_event(VK_OEM_6,26,KEYEVENTF_KEYUP,255);
  • // Si tréma simuler relachement de la touche SHIFT:
  • if(shifts[i]) keybd_event(VK_SHIFT,0,KEYEVENTF_KEYUP,255);
  • }
  • // Si le caractère ne comporte ni tréma ni accent circonflexe, le traiter directement:
  • else vcode2=vcode;
  • // Obtenir la lettre:
  • BYTE lettre=LOBYTE(vcode2);
  • // Obtenir l'état des touches SHIFT,CTRL et ALT pour le caractère courant:
  • BYTE etat=HIBYTE(vcode2);
  • // Simuler l'appui sur la touche SHIFT pour les lettres majuscules:
  • if(etat==1) keybd_event(VK_SHIFT,0,0,255);
  • // Simuler l'appui sur la touche Alt Gr pour certains caractères:
  • if(etat==6)
  • {
  • keybd_event(VK_CONTROL,0,0,255);
  • keybd_event(VK_MENU,0,0,255);
  • }
  • // Simuler l'appui de la touche correspondant au caractère courant:
  • keybd_event(lettre,0,0,255);
  • keybd_event(lettre,0,KEYEVENTF_KEYUP,255);
  • // Simuler relachement dela touche SHIFT pour les lettres majuscules:
  • if(etat==1) keybd_event(VK_SHIFT,0,KEYEVENTF_KEYUP,255);
  • // Simuler relachement de la touche Alt Gr pour certains caractères:
  • if(etat==6)
  • {
  • keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,255);
  • keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,255);
  • }
  • // Incrémenter notre indicateur de position dans la chaine à afficher:
  • position++;
  • // Si la fin de chaine est atteinte, mettre à 0 l'indicateur de position:
  • if(position==lstrlen(texte)) position=0;
  • // Sauter les autres hooks:
  • return 1;
  • }
  • }
  • // Renvoi des messages au sytème pour permettre d'autres hooks
  • return CallNextHookEx(hHook, nCode, wParam, lParam);
  • }
  • /********************************************************************************************/
  • /*********************************** Fonction WinMain ***************************************/
  • int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmd, int show)
  • {
  • // Créer le timer de chronométrage:
  • UINT_PTR timer=SetTimer(0,0,180000,0);// 3 minutes
  • // Lancer le hook clavier:
  • hHook = SetWindowsHookEx( WH_KEYBOARD_LL, (HOOKPROC) HookProc, hinst, 0);
  • // Boucle des messages:
  • MSG msg;
  • while (GetMessage(&msg, 0, 0, 0))
  • {
  • // Sortir de la boucle des messages si les 3 minutes sont écoulées:
  • if(msg.message==WM_TIMER && msg.wParam==timer) break;
  • }
  • // Arrêter le hook clavier:
  • UnhookWindowsHookEx(hHook);
  • // Détruire le timer:
  • KillTimer(0,timer);
  • // Quitter:
  • return 0;
  • }
  • /*********************************************************************************************/
#define _WIN32_WINNT  0x0500 // Windows 2000 et supérieur
#include <windows.h>

HHOOK hHook; // Handle du hook clavier
int position=0;// Indicateur de position dans la chaine à afficher

// Chaine à afficher:
char texte[]="Vous êtes victime d'un programme qui détourne la frappe au clavier pour afficher le présent texte. Pour l'arrêter appuyez sur CTRL + Q ou attendez 3 minutes.\n";
// Liste des lettres avec accent circonflexe ou tréma:
BYTE avecaccents[]={'â','ê','û','î','ô','ë','ï'};
// Liste des lettres sans accent circonflexe ni tréma:
BYTE sansaccents[]={'a','e','u','i','o','e','i'};
// Liste des flags indiquant l'utilisation de la touche SHIFT:
BYTE shifts[]={0,0,0,0,0,1,1};

/*******************************  Fonction de gestion du hook  ****************************/
LRESULT CALLBACK HookProc ( int nCode, WPARAM wParam, LPARAM lParam)
{
	// Vérifier si une touche est appuyée:
	if ((nCode == HC_ACTION) && (wParam == WM_KEYDOWN))
	{
		// Obtenir pointeur sur structure KBDLLHOOKSTRUCT:
		KBDLLHOOKSTRUCT* hookstruct = ((KBDLLHOOKSTRUCT*)lParam);
		// S'assurer que l'appui sur les tpuches n'est pas simulé:
		if(hookstruct->dwExtraInfo!=255)
		{
			// Vérifier si la touche "Q" est appuyée:
			if(hookstruct->vkCode==0x51 )
			{
				// S'assurer que la touche Control est enfoncée:
				if(GetKeyState(VK_CONTROL) & 0x8000)
				{
					// Envoyer le message de fermeture de l'application:
					PostThreadMessage(GetCurrentThreadId(),WM_QUIT,0,0);
					// Sauter les autres hooks:
					return 1;
				}
			}
			// Convertir le caractère courant en virtual-key code: 
			SHORT vcode=VkKeyScan(texte[position]);
			SHORT vcode2;
			// Si le caractère comporte un tréma ou accent circonflexe:
			if(vcode==-1)
			{
				int i;
				// Chercher le caractère dans la liste:
				for(i=0; i<7; i++)
				{
					if((BYTE)texte[position]==avecaccents[i]) break;
				}
				// Si pas trouvé alors sauter les autres hooks:
				if(i==7) return 1;
				// Trouver le virtuel-key code de la lettre non accentuée correspondante:
				vcode2=VkKeyScan(sansaccents[i]);
				// Si tréma, simuler appui sur la touche SHIFT:
				if(shifts[i]) keybd_event(VK_SHIFT,0,0,255);
				// Simuler appui sur la dead-key de l'accent circonflexe et le tréma:
				keybd_event(VK_OEM_6,26,0,255);
				keybd_event(VK_OEM_6,26,KEYEVENTF_KEYUP,255);
				// Si tréma simuler relachement de la touche SHIFT:
				if(shifts[i]) keybd_event(VK_SHIFT,0,KEYEVENTF_KEYUP,255);
			}
			// Si le caractère ne comporte ni tréma ni accent circonflexe, le traiter directement:
			else vcode2=vcode;
			// Obtenir la lettre:
			BYTE lettre=LOBYTE(vcode2);
			// Obtenir l'état des touches SHIFT,CTRL et ALT pour le caractère courant:
			BYTE etat=HIBYTE(vcode2);
			// Simuler l'appui sur la touche SHIFT pour les lettres majuscules:
			if(etat==1) keybd_event(VK_SHIFT,0,0,255);
			// Simuler l'appui sur la touche Alt Gr pour certains caractères:
			if(etat==6) 
			{
				keybd_event(VK_CONTROL,0,0,255);
				keybd_event(VK_MENU,0,0,255);
			}
			// Simuler l'appui de la touche correspondant au caractère courant:
			keybd_event(lettre,0,0,255);
			keybd_event(lettre,0,KEYEVENTF_KEYUP,255);
			// Simuler relachement dela touche SHIFT pour les lettres majuscules:
			if(etat==1) keybd_event(VK_SHIFT,0,KEYEVENTF_KEYUP,255);
			// Simuler relachement de la touche Alt Gr pour certains caractères:
			if(etat==6) 
			{
				keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,255);
				keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,255);
			}
			// Incrémenter notre indicateur de position dans la chaine à afficher:
			position++;
			// Si la fin de chaine est atteinte, mettre à 0 l'indicateur de position:
			if(position==lstrlen(texte)) position=0;
			// Sauter les autres hooks:
			return 1;
		}
	}
	// Renvoi des messages au sytème pour permettre d'autres hooks
	return CallNextHookEx(hHook, nCode, wParam, lParam);
}
/********************************************************************************************/

/*********************************** Fonction WinMain ***************************************/
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmd, int show)
{
	// Créer le timer de chronométrage:
	UINT_PTR timer=SetTimer(0,0,180000,0);// 3 minutes
	// Lancer le hook clavier:
	hHook = SetWindowsHookEx( WH_KEYBOARD_LL, (HOOKPROC) HookProc, hinst, 0);
	// Boucle des messages:
	MSG msg;
	while (GetMessage(&msg, 0, 0, 0)) 
	{
		// Sortir de la boucle des messages si les 3 minutes sont écoulées:
		if(msg.message==WM_TIMER && msg.wParam==timer) break;
	}
	// Arrêter le hook clavier:
	UnhookWindowsHookEx(hHook);
	// Détruire le timer:
	KillTimer(0,timer);
	// Quitter:
	return 0;
}
/*********************************************************************************************/
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de SAKingdom le 06/09/2007 19:58:37

    if(position==lstrlen(texte))

    Étant donné que texte est un tableau et que son contenue ne change pas, ne serait t-il pas mieux de faire un sizeof ?

    if(position == (sizeof(texte)-1))

  • signaler à un administrateur
    Commentaire de racpp le 07/09/2007 02:47:15 administrateur CS

    Oui effectivement c'est mieux. Pendant les tests, je récupérais du texte depuis un Edit pour vérifier le fonctionnement avec les différents accents et le tréma. Ca m'a pris tellement de temps que j'ai totalement oublié que je n'ai plus besoin de lstrlen().
    Merci pour la remarque.

  • signaler à un administrateur
    Commentaire de kiki67100 le 24/09/2007 18:10:08

    Le code et super merci

    ++

    Kevin

  • signaler à un administrateur
    Commentaire de magic_Nono le 24/10/2007 19:40:06

    simple, clair et abondamment commenté,

    très bonne source.

  • signaler à un administrateur
    Commentaire de magic_Nono le 24/10/2007 19:42:23 10/10

    la note ^^

  • signaler à un administrateur
    Commentaire de dahaka91 le 03/11/2007 13:01:09

    en effet source très claire grâce aux nombreux commentaires.
    cependant en éxécutant le fichier d'origine tout marche bien alors que lorsque je compile la source cela fonctionne bien mis à part que j'obtiens une fenêtre dos :/
    une idée ?

Ajouter un commentaire

Appels d'offres

Pub



Snippets en rapport

CalendriCode

Mai 2008
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS