Tasten - systemweit abfangen (Hooks)



  • hi!

    wie kann ich mit meinem im hintergrund laufenden prog tastatureingaben abfangen, wenn der anwender gerade ein anderes fenster
    auf dem desktop aktiviert hat?

    ThanX

    mc

    [ Dieser Beitrag wurde am 29.12.2001 um 18:58 Uhr von Jansen editiert. ]



  • Du mußt hierfür eine DLL erzeugen und dann in dein Projekt mit einbinden.

    Die ganze Sache läuft über Hook-Funktionen in die du dich einklinken mußt.

    Vorgehensweise:

    1. Erzeuge eine DLL über den DLL-Experten

    2. Füge folgenden Code in die DLL-CPP-Datei ein.

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <windows.h>
    #pragma hdrstop
    //---------------------------------------------------------------------------
    
    #define WM_KEYHOOK WM_USER+100
    HHOOK ghhookKB;
    HINSTANCE ghInst;
    #pragma argsused
    //---------------------------------------------------------------------------
    
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
      ghInst = hinst;
      return (1);
    }
    //---------------------------------------------------------------------------
    
    extern "C" __declspec(dllexport) __stdcall void SetHook(void);
    extern "C" __declspec(dllexport) __stdcall void RemoveHook(void);
    extern "C" __declspec(dllexport) __stdcall DWORD CheckKey(int, WORD,LONG);
    //---------------------------------------------------------------------------
    
    void __stdcall SetHook(void)
    {
      HOOKPROC lpfnHookProc = NULL;
      lpfnHookProc = GetProcAddress(GetModuleHandle("keydll.dll"),"CheckKey");
      ghhookKB = SetWindowsHookEx(WH_KEYBOARD, lpfnHookProc, ghInst, NULL);
    }
    //---------------------------------------------------------------------------
    
    void __stdcall RemoveHook(void)
    {
      UnhookWindowsHookEx(ghhookKB);
    }
    //---------------------------------------------------------------------------
    
    DWORD __stdcall CheckKey(int nCode, WORD wParam, LONG lParam)
    {
      HWND ghAppWnd = FindWindow("TKeyHookForm", 0);
      if((nCode < 0) || nCode == HC_NOREMOVE)
        return CallNextHookEx(ghhookKB, nCode, wParam, lParam);
    
      // Skip if it's a repeat
      if(lParam & 0x40000000)
        return CallNextHookEx(ghhookKB, nCode, wParam, lParam);
    
      // Send key information to the main window
      SendMessage(ghAppWnd, WM_KEYHOOK, wParam, lParam);
    
      return CallNextHookEx(ghhookKB, nCode, wParam, lParam);
    }
    //---------------------------------------------------------------------------
    

    3. Die Headerdatei der Form, in der du den Hook verwenden willst sieht dann so aus:

    //---------------------------------------------------------------------------
    
    #ifndef Unit1H
    #define Unit1H
    #define WM_KEYHOOK WM_USER+100
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    class TKeyHookForm : public TForm
    {
    __published:    // Von der IDE verwaltete Komponenten
            TListBox *ListBox1;
            void __fastcall FormCreate(TObject *Sender);
            void __fastcall FormDestroy(TObject *Sender);
    private: // User declarations
      MESSAGE void __fastcall KeyHook(TMessage &Message);
        BEGIN_MESSAGE_MAP
          MESSAGE_HANDLER(WM_KEYHOOK, TMessage, KeyHook);
        END_MESSAGE_MAP(TForm);
    public:     // Anwender-Deklarationen
            __fastcall TKeyHookForm(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TKeyHookForm *KeyHookForm;
    //---------------------------------------------------------------------------
    #endif
    

    4. Und zum Schluss die .cpp der Form:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TKeyHookForm *KeyHookForm;
    
    extern "C" __declspec(dllexport) __stdcall void SetHook(void);
    extern "C" __declspec(dllexport) __stdcall void RemoveHook(void);
    extern "C" __declspec(dllexport) __stdcall DWORD CheckKey(int, WORD,LONG);
    
    //---------------------------------------------------------------------------
    __fastcall TKeyHookForm::TKeyHookForm(TComponent* Owner)
      : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TKeyHookForm::KeyHook(TMessage &Message)
    {
      char Key[80];
      GetKeyNameText(Message.LParam, Key, 80);
      ListBox1->Items->Add(Key);
    }
    //---------------------------------------------------------------------------
    void __fastcall TKeyHookForm::FormCreate(TObject *Sender)
    {
      SetHook();
    }
    //---------------------------------------------------------------------------
    void __fastcall TKeyHookForm::FormDestroy(TObject *Sender)
    {
      RemoveHook();
    }
    //---------------------------------------------------------------------------
    


  • @happy builder

    vielen dank, funzt einwandfrei.
    desweiteren check´ ich jetzt endlich
    die dll-geschichte (einbinden etc.)

    ThanX

    <edit>
    Bitte unbedingt beachten:
    Die DLL muss, damit alles klappt, als Endgültige Version kompiliert werden. (Projekt->Optionen->Compiler).
    Ausserdem muss der Name der DLL "keydll.dll" lauten, oder aber der Code entsprechend angepasst werden.
    </edit>


Anmelden zum Antworten