Kurze Frage zu KBDLLHOOKSTRUCT



  • Moin ich habe mir gerade mal die Windows Hooks angeschaut und auch ein paar Beispiele zu dem Thema im Internet gefunden.

    Aber eine Sache verstehe ich nicht:

    LRESULT WINAPI KbdProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
            if(nCode == HC_ACTION)
            {
              cout<<"VirtualKeyCode: " << (( KBDLLHOOKSTRUCT * ) lParam )-> vkCode<<endl;
            }
    return CallNextHookEx(0, nCode, wParam, lParam);
    }
    
    (( KBDLLHOOKSTRUCT * ) lParam )-> vkCode;
    

    Ist das hier nicht einfach nur eine Typkonvertierung von LPARAM auf KBDLLHOOKSTRUCT ?

    Wieso wird das 2 mal umklammert?
    Müsste das nicht auch so funktionieren?

    ( KBDLLHOOKSTRUCT * ) lParam -> VkCode;
    

    Und wieso bekomme ich hier einen AccessViolation

    KBDLLHOOKSTRUCT *kbd={0};
    LRESULT WINAPI KbdProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
            if(nCode == HC_ACTION)
            {
              cout<< kbd->vkCode << endl;
            }
    return CallNextHookEx(0, nCode, wParam, lParam);
    }
    

    Verschweigt die MSDN da wieder irgendwas?



  • Hast Du auf die Compiler Warnungen geachtet? Wenn nicht solltest Du dies tun.



  • Wobei soll den eine Warnung ausgegeben werden?

    Gibt keine Warnung aus:

    cout<<"VirtualKeyCode: " << (( KBDLLHOOKSTRUCT * ) lParam )-> vkCode<<endl;
    Genau so wie hier:
    cout<< kbd->vkCode << endl;  Gibt auch keine Warnung aus
    

    Ich weiss nicht worauf du hinaus willst.



  • Ok warum das hier Müll ist weiss ich jetzt. 🤡

    KBDLLHOOKSTRUCT *kbd={0}; 
     LRESULT WINAPI KbdProc(int nCode, WPARAM wParam, LPARAM lParam) 
     { 
             if(nCode == HC_ACTION) 
             { 
               cout<< kbd->vkCode << endl; 
             } 
    return CallNextHookEx(0, nCode, wParam, lParam); 
     }
    

    Da habe ich den MSDN Artikel nur überflogen. 😃

    ( KBDLLHOOKSTRUCT * ) lParam -> vkCode;
    

    Das funktioniert ja anscheind nicht weil es sich um eine typedef Struktur handelt.

    Bsp:

    typedef struct mystru {
      int     abc;
    } stru;
    
    int n;
    cout<<(( stru * ) n )-> abc<<endl; // Okay
    cout<<( stru * ) n -> abc<<endl; // Fehler: [C++ Fehler] Unit1.cpp(17): E2288 Zeiger auf Struktur auf linker Seite von -> oder von ->* erforderlich*
    
    Das hier schlägt wieder Fehl:
    struct mystru {
      int     abc;
    } stru;
    
    int n;
    cout<<(( stru * ) n )-> abc<<endl; // Fehler
    cout<<( stru * ) n -> abc<<endl; // Fehler
    cout<<stru.abc<<endl; // Okay
    

    Bei einer typdef Struktur wird wohl diese Syntax benötigt:
    ((StukturName*)VariableAufDieGecastetWird)->VariableAusDerStruktur

    Kann man das so sagen oder ist das falsch?



  • Fragezeichen über Fragezeichen. Weisst Du was!? Du hast nicht Probleme mit Hooks sondern mit den C/C++ Grundlagen!



  • Mag sein, deswegen frage ich ja.



  • Ja es ist so. Solltest Dir nochmal die Kapitel über Zeiger/Pointer und Strukturen anschauen. Dies ist enorm wichtig, da es sonnst zu einem puren rate-Spiel wird. Nachdem wird sich Deine Frage in Luft auflösen 😉



  • Haken schrieb:

    Wieso wird das 2 mal umklammert?
    Müsste das nicht auch so funktionieren?

    ( KBDLLHOOKSTRUCT * ) lParam -> VkCode;
    

    Sieh dir mal http://en.cppreference.com/w/cpp/language/operator_precedence an. -> bindet stärker als der Cast (KBDLLHOOKSTRUCT * ).
    ( ( KBDLLHOOKSTRUCT * ) lParam ) -> VkCode; bedeutet er soll lParam in ein *KBDLLHOOKSTRUCT ** umcasten und dann von dem KBDLLHOOKSTRUCT das Element VkCode wählen. Alles gut.
    ( KBDLLHOOKSTRUCT * ) lParam -> VkCode; bedeutet, er soll von lParam das Element VkCode nehmen und daraus ein *KBDLLHOOKSTRUCT ** machen. Da aber ein lParam kein VkCode-Element hat sagt der Compiler dass das nicht geht.

    Haken schrieb:

    Und wieso bekomme ich hier einen AccessViolation

    KBDLLHOOKSTRUCT *kbd={0};
    LRESULT WINAPI KbdProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
            if(nCode == HC_ACTION)
            {
              cout<< kbd->vkCode << endl;
            }
    return CallNextHookEx(0, nCode, wParam, lParam);
    }
    

    kbd ist ein Pointer der auf Adresse 0 zeigt, wie du in Zeile 1 geschrieben hast. kbd->vkCode liest jetzt den Speicher nahe Adresse 0, aber da darf er nicht drauf zugreifen, daher der Zugriffsfehler.
    Wahrscheinlich willst du den *** wegnehmen und KBDLLHOOKSTRUCT kbd={0} schreiben. Aus kbd wird dann &kbd. Und &kbd->vkCode geht nicht (-> bindet stärker als &), deshalb muss man Klammern: (&kbd)->vkCode. Das ist korrekt aber unüblich. Üblicherweise schreibt man kbd.vkCode.

    MFG.


Anmelden zum Antworten