Keyboard Hook



  • Hallo,

    warscheinlich ein zeimlich abgelutschtes Thema. Ich habe hier im Forum dazu den Artikel http://www.c-plusplus.net/forum/topic,39145.html gelesen und wollte auch darein schrchreiben, allerdings wurde mir bei dem Versuch ausgegeben, das nur Moderatoren dazu berechtigt seien?!

    Nun Ja,
    ich habe also das Beispiel in Borland C++ Builder V5.0 nachgebaut.

    Habe eine dll mit dem dll experten erstellt und diese dann in mein projekt über projekt|dme projekt hinzufügewn eingebunden.

    beim compilieren gibt er keine fehler aus und es wird ein fenster erzeugt, welches eine einfache listenansicht hat.
    jedoch passiert absolut nichts wenn ich in die tasten haue. soweit ich das verstanden habe, sollte doch bei jeder tasteneingabe in dem listenfeld ein neuer eintrag mit deder entasprechenden tastenbezeichnung entstehen, oder?

    nun ja, leider hab ich da keinen ansatz, villeicht kann mir jemand erklären was ich falsch mache.
    ich poste hier nochmal die verscheidnenen source-dateien.

    Unit1.cpp

    //---------------------------------------------------------------------------
    //http://www.c-plusplus.net/forum/topic,39145.html
    #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();
    }
    //---------------------------------------------------------------------------
    

    Unit1.dfm

    object KeyHookForm: TKeyHookForm
      Left = 203
      Top = 125
      Width = 282
      Height = 214
      Caption = 'TypeStat'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object ListBox1: TListBox
        Left = 8
        Top = 8
        Width = 257
        Height = 169
        ItemHeight = 13
        TabOrder = 0
      end
    end
    

    Unit1.cpp

    //---------------------------------------------------------------------------
    
    #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
    

    keydll.cpp

    //---------------------------------------------------------------------------
    
    #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, 0, lParam);
    
      return CallNextHookEx(ghhookKB, nCode, wParam, lParam);
    }
    //---------------------------------------------------------------------------
    

    also, ich freu mich auf antworten...

    tobias



  • FAQ-Beitrag schrieb:

    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.



  • danke für deine flotte antwort.
    also muss die datei, schon vor dem compilieren keydll.dll heisßen? oder wird die nicht compiliert? oder wie geht das von statten.

    außerdem frage ich mich das mit dem "Endgültige Version". Ich habe erst versucht die dll als eigenes projekt zu kompilieren, dort habe ich dann unter projekt|optionen -> compiler den knopf endgültig getätigt. allerdings kahm beim compilen die meldung das etwas fehlt. also dachte ich, muss man die datei wohl dem anderen projekt hinzufügen, oder?
    die einstellung "endgültig" habe ich auch dort getätigt. aber, dort ist das dann ja für das ganze projekt, oder?

    danke

    tobias



  • Die DLL ist ein eigenes Projekt. Idealerweise achtet man beim Speichern darauf, die BPR gleich keydll.bpr zu nennen (unit1 bleibt unit1), dann werden DLL und Lib automatisch als keydll.* erzeugt.



  • ok, das hab ich auch soweit gemacht.
    jetzt beomme ich beim compilieren der dll den fehler: die fehlersuche für ein projekt kann nicht gestartet werden, solange keine host-anwendung definiert ist. verwenden sie das dialogfenster start|parameter...
    die dll wird aber trotz allem erzeugt.

    wenn ich dann mein projekt, was ja letztendlich die dll verwenden soll comipilieren möchte kommen folgende meldungen:
    [Linker Fehler] Unresolver external 'SetHook' referenced from C:\...\UNIT1.OBJ
    [Linker Fehler] Unresolver external 'RemoveHook' referenced from C:\...\UNIT1.OBJ

    Was mache ich da falsch? muss ich noch irgednwas einbinden?

    danke,

    tobias



  • Hallo

    jetzt beomme ich beim compilieren der dll den fehler: die fehlersuche für ein projekt kann nicht gestartet werden, solange keine host-anwendung definiert ist. verwenden sie das dialogfenster start|parameter...

    Das ist keine Fehlermeldung sondern ein Hinweis. Bittelies dir den nochmal durch und befolge was dort steht.

    Was mache ich da falsch? muss ich noch irgednwas einbinden?

    Du must noch die aus der DLL mitenstehende .lib in das Zielprojekt mit einbinden und in den Projektoptionen des Zielprojekts den Bibliothekspfad zu lib hinzufügen (wenn nicht schon vorhanden)

    bis bald
    akari



  • also, tut mir leid das ich den ganzen kram frage. scheint ja wirklich trivial zu sein. ich hab keine ahnung davon, hab noch nie mit c++ builder und grafischen oberflächen, geschweige denn dlls gearbeitet.

    ich habe also jetzt die lib dem projekt hinzugefügt. dannach compiled er das projekt auch ohne zicken. allerdings mit dem gleichen ergebnis wie vorher, also ohne funktion.

    in den Projektoptionen des Zielprojekts den Bibliothekspfad zu lib hinzufügen (wenn nicht schon vorhanden)

    das verstehe ich nicht ganz. habe in den projekt-optionen rumgesucht, aber keine sachen gefunden, die zu deiner aussage passen.

    auch das mit dem hinweis verstehe ich nicht. wenn ich unter start|parameter.. schau, kann ich dort eine exe datei angeben. wenn ich da also jetzt die exe aus meinem projekt angebe, wird nach dem compilen der dll die exe ausgeführt. aber auch ohne funktion.

    was mache ich falsch?

    ..danke

    tobias



  • weis denn niemand woran das liegen kann? oder bin ich einfach zu blöd?

    weis jetzt was du mit dem pfad für die lib meinst, habe das auch eingestellt. allerdings wird der neu eingegebene pfad immer gelöscht, nachdem ich auf ok geklickt habe. warscheinlich weil er bereits in den existierenden angaben erfast ist(?).

    als hostanwendung habe ich auf jeden fall mein projekt bei der ddl angeben. müsst doch so richtig sein, oder? ich denke zumindest dass das der einzig logisch zusammenhang ist, wenn man von hostanwendung bei einer dll spricht.

    ich hab echt keine ahnung wo ich weiter suchen soll. es kommt ja auch keine fehlermeldung.

    hat jemand noch eine idee oder evt. sogar ein funktionierendes beispiel.
    ich finde im internet viele beispiele zu dem thema, allerdings nichts für borland. irgendwas fehlt immer. dies war das einzige beispiel was ich zum borland builder gefunden habe.

    würde mich über weitere anstöße freuen.

    danke

    tobias



  • hi,

    dürfte dich für den anfang weiter bringen: <URL entfernt> (borland builder in 21 tagen). dort hast du auch beispiele für den umgang mit dll´s.

    Edit:
    Bitte keine Links zu urheberrechtlich geschütztem Material. Danke!



  • tja schade, den link hab ich leider nicht mehr bekommen.
    also ich hab die beiden projekte nochmal neu gemacht und alles ganz sauber mit den neuen erkenntniissen erstellt. soweit auch ohne probleme, sogar ohne jegliche fehlermeldung.
    leider immer noch das gleiche problem.
    muss denn mit der dll irgendwas gemacht werden, oder läuft das so, wenn sie im gleichen ordner wie die exe liegt? ich hab borland builder 5 auf win xp sp2 laufen.

    hab hier nochmal das ganze projekt mit exe, so wie sie bei mir erzeugt wurde usw. angehängt. villeicht findet ja jemand was?

    http://tvielmetter.de/projektcpphook.zip

    danke

    tobias



  • also ich hab den fehler nach langer suche endlich gefunden. es ist eigentlich alles richtig gewesen, nur habe ich in den eigenschaften vom form bei oncreate und ondestroy nicht die entsprechende methode ausgewählt. so wurden diese nicht vom programm ausgeführt. dies ist mir aufgefallen, nachdem ich in die listbox einfach mal in der formcreate methode ein a hinzufügen wollte, und dieses nicht in der listbox erschien. dannach war mir klar das die methode nicht aufgerufen wird.
    tja, trügerisch wenn man sich an bespielcode orientiert und noch nie mit einer visual IDE gearbeitet hat.

    danke soweit für die hilfe,

    tobias



  • @Avalon: Kannst du mir bitte den Link per Mail zuschicken? Meine Email-Adresse ist webfritzi[at]gmx.de. Danke.

    @Mods: Sorry, dass ich Avalon so anspreche.🙄 Aber er hat nunmal keine Email-Adresse angegeben.


Anmelden zum Antworten