[C++] Keyboard hook probleem

Pagina: 1
Acties:

  • PKP B-Man
  • Registratie: November 2002
  • Laatst online: 19-07-2023
Ik heb een programmatje weten te schrijven dat je keyboard hookt... Dit programma werkt perfect, en hij logt ook alle knoppen die de gebruiker intoetst, in elk willekeurig scherm. Het is geschreven door gebruik te maken van een HOOK_DLL, de belangrijkste code staat hieronder weergeven:
C++:
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
int __stdcall GlobalKeyBoardHook(int code,WPARAM wParam, LPARAM lParam)
{       if (code<0)  //if code is <0 your keyboard hook should always run CallNextHookEx instantly and
           return(CallNextHookEx(CurrentHook,code,wParam,lParam)); //then return the value from it.

        //if ((wParam>=65) && (wParam<=90))
        {    KeyArray[KeyArrayPtr]=wParam;
             KeyArrayPtr=KeyArrayPtr+1;
             //if (KeyArrayPtr > sizeof(KeyArray))
             {  FILE *wParamFile, *lParamFile, *KLTextFile;
                wParamFile = fopen("c:\\wParam.bwr", "a+");
                lParamFile = fopen("c:\\lParam.bwr", "a+");
                fwrite(&wParam, sizeof(wParam), 1, wParamFile);
                fwrite(&lParam, sizeof(lParam), 1, lParamFile); 
                fwrite("*", sizeof("*"), 1, lParamFile); 

                int KeyUp = (lParam & 0x80000000 );
                if ((wParam>=65) && (wParam<=90) && (KeyUp!=0) )
                {   KLTextFile = fopen("c:\\KLText.bwr", "a+");
                    fwrite(&wParam, 1, 1, KLTextFile); 
                    fclose(KLTextFile);
                }
                fclose(wParamFile);
                fclose(lParamFile);
                KeyArrayPtr=0;
             }
        }
        /*unsigned char state [256] ;
        GetKeyboardState(state);
        FILE *StateFile;
        StateFile = fopen("c:\\State.bwr", "a+");
        fwrite(&state, sizeof(state), 1, StateFile);
        fclose(StateFile);*/

        CallNextHookEx(CurrentHook,code,wParam,lParam);  //call the next hook proc if there is one
        return 0; //if GlobalKeyBoardHook returns a non-zero value, the window that should get
                    //the keyboard message doesnt get it.
}


Deze code en de "gecommente" code werken perfect. In de file wParam.bwr staan alle wParam parameters, zelfde geld voor de lParam. In de tekstfile KLText.bwr komen alle letters te staan (1x, ook als de knop word ingehouden).
Nu kan ik de paramfile weer uitlezen met de volgende code:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        WPARAM wParam;
        LPARAM lParam;
        FILE *wParamFile, *lParamFile;

        wParamFile = fopen("c:\\wParam.bwr", "r");
        lParamFile = fopen("c:\\lParam.bwr", "r");
        fseek(wParamFile, 0, SEEK_SET);
        fseek(lParamFile, 0, SEEK_SET);

        while(!feof(wParamFile) && !feof(lParamFile))
        {   fread(&wParam,sizeof(wParam),1,wParamFile);
            fread(&lParam,sizeof(lParam),1,lParamFile);
        }
        fclose(wParamFile);
        fclose(lParamFile);


En dan komt nu het probleem:
Hoe kan ik nu deze tekst files weer zo "afspelen" dat ze het keyboard weer nabootsen. Ik was van mening dat ik dit kon doen met SendMessage, maar dit kan niet, of ik doe het verkeerd. Wat hij echter wel doet met SendMessage is, als ik het commando WM_CHAR gebruik, alle letters en cijfers op de juiste manier op het scherm tonen. Maar alle letters komen dubbel op het scherm te staan en de toetsencombinaties zoals CTRL+HOME en CTRL+A en bijvoorbeeld alle F-toetsen werken op deze manier niet.
Is er een andere functie die ik kan/moet gebruiken, of doe ik iets verkeerd?

Alvast bedankt voor jullie hulp

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

aan het zenden van WM_CHARs heb je weinig, aangezien dat gewoon enkele toetsaanslagen zijn van vooral printable characters.

Als je echt input wilt versturen alsof het van je toetsenbord afkomt moet je SendInput () gebruiken

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

.oisyn schreef op 04 April 2003 @ 12:38:
aan het zenden van WM_CHARs heb je weinig, aangezien dat gewoon enkele toetsaanslagen zijn van vooral printable characters.

Als je echt input wilt versturen alsof het van je toetsenbord afkomt moet je SendInput () gebruiken
Of de klassieke, simpelere en meer portable (want ook Win95/NTpreSP3) variant nl. keybd_event.

De echt sublieme methode voor playback is natuurlijk om met journaling hook te werken (zie SetWindowsHookEx docs).

Professionele website nodig?


  • PKP B-Man
  • Registratie: November 2002
  • Laatst online: 19-07-2023
Dank je voor jullie replies!

Het werkt nu wel, maar er zitten nog een paar eigen naardigheden in... De extra code om het af te spelen is de volgende:
C++:
1
2
3
4
5
INPUT input[1];
memset(input, 0, sizeof(input));
input[0].type= INPUT_KEYBOARD;
input[0].ki.wVk = wParam;
SendInput(1, input, sizeof(INPUT));


Maar zoals je ziet wordt er niets met de lParam gedaan, en in de lParam staat wel degelijk belangrijke informatie:
lParam

Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag. This parameter can be a combination of the following values:

Value Description
0-15 Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user's holding down the key.
16-23 Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24 Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
25-28 Reserved.
29 Specifies the context code. The value is 1 if the ALT key is down; otherwise, it is 0.
30 Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.
31 Specifies the transition state. The value is 0 if the key is being pressed and 1 if it is being released.
Dit heeft dan ook voor gevolg dat de toetsen worden getoggled i.p.v. worden verstuurd. Een mooi voorbeeld waaraan je dat kunt zien is als je 1234567 invoert, maar bij het indrukken van de 1 deze in blijft houden. De playback functie zal dan de volgende code laten zien: 12345671

Ik kwam die record functie inderdaad tegen, maar toen was ik al in een ver gevorderd stadium van de keyboard-hook die ik nu gebruik dat ik het nut hiervan niet verder heb uitgediept.

De functie SendInput komt trouwens helemaal niet voor in mijn help-bijbels :? :? zowel niet in die van Borland als in de Win32.hlp, vandaar dat ik deze ook nooit ben tegen gekomen. Geen idee waarom dit niet niet erin voorkomt .....

B-Man

edit:
[offtopic]Ik zag dat je ziek was toen ik dit bericht poste, .oisyn. Verstandig van je dat je toch maar weer beter bent geworden ;) [/offtopic]

[ Voor 4% gewijzigd door PKP B-Man op 04-04-2003 15:26 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

SendInput documentatie in de online MSDN :)

hoe oud is jouw help? Download anders een platform SDK update, daar zitten de nieuwste APIs + documentatie bij

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.