Interessanter Fehler, leider bekmm ich den nciht weg
-
Ich hab mir nen Hook zusammengebaut. Und nun stehe ich vor einem seltsamen Problem.
Wenn ich die Funktionen aus der hook-dll in meinem Programm aufrufe, bekomme ich immer einen Fehler beim Speicherzugriff in Adresse ........
Wenn ich aber direkt hinter den Aufruf ein "ShowMessage("");" setzte, funktioniert das.
So funktioniert es:void __fastcall TForm1::Button2Click(TObject *Sender) { keys.KEY = 66; RenewKBHook(keys); ShowMessage(""); }
So bekomme ich eine Zugriffsverletzung:
void __fastcall TForm1::Button2Click(TObject *Sender) { keys.KEY = 66; RenewKBHook(keys); ShowMessage(""); }
Im LowLevelKeyboardProc geht es auch wunderbar so:
void __fastcall TForm1::KB_Hook(TMessage &msg) { SetMSHook(Handle); ShowMessage(""); }
So aber nicht:
void __fastcall TForm1::KB_Hook(TMessage &msg) { SetMSHook(Handle); }
Der Quelltext der DLL ist folgender:
//--------------------------------------------------------------------------- #include <windows.h> #pragma hdrstop //--------------------------------------------------------------------------- #define WM_KEYHOOK WM_USER+101 typedef struct { int KEY; bool SHIFT; bool CONTROL; bool MENU; } CHECKKEY; bool alt = false, shift = false, ctrl = false; HHOOK ghKBHook; HINSTANCE ghKBInst; HWND MSG_TARGET; CHECKKEY usekey; //--------------------------------------------------------------------------- int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) { ghKBInst = hinst; return 1; } //--------------------------------------------------------------------------- #define EXPORT extern "C" __declspec(dllexport) //--------------------------------------------------------------------------- EXPORT DWORD CALLBACK llKBHook(int nCode, WPARAM wParam, LPARAM lParam) { if((nCode < 0) || (nCode != HC_ACTION)){ return CallNextHookEx(ghKBHook, nCode, wParam, lParam); } // Skip if it's a repeat if(lParam & 0x40000000) return CallNextHookEx(ghKBHook, nCode, wParam, lParam); PKBDLLHOOKSTRUCT p; p = (PKBDLLHOOKSTRUCT) lParam; if(wParam == WM_KEYDOWN){ if(p->vkCode == VK_SHIFT){ //Kann das hier überhaupt funktionieren? Oder wie kann ich angucken, ob noch Systemtasten gedrückt werden? shift = true; } if(p->vkCode == VK_MENU){ alt = true; } if(p->vkCode == VK_CONTROL){ ctrl = true; } if( (p->vkCode == usekey.KEY) && (usekey.SHIFT == shift) && (usekey.CONTROL == ctrl) && (usekey.MENU == alt) ){ PostMessage(MSG_TARGET, WM_KEYHOOK, lParam, p->vkCode); return 1; } } if(wParam == WM_KEYUP){ if(p->vkCode == VK_SHIFT){ shift = false; } if(p->vkCode == VK_MENU){ alt = false; } if(p->vkCode == VK_CONTROL){ ctrl = false; } } return CallNextHookEx(ghKBHook, nCode, wParam, lParam); } EXPORT void CALLBACK SetKBHook(HWND send_to_hwnd, CHECKKEY keys) { usekey = keys; MSG_TARGET = send_to_hwnd; ghKBHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC) llKBHook, ghKBInst, 0); } EXPORT void CALLBACK RemoveKBHook(void) { UnhookWindowsHookEx(ghKBHook); } EXPORT void CALLBACK RenewKBHook(CHECKKEY NewKey) { usekey = NewKey; }
Im Programm wird das ganze so eingebunden:
//header class TForm1 : public TForm { __published: // Von der IDE verwaltete Komponenten //... private: // Benutzer-Deklarationen //... void __fastcall KB_Hook(TMessage &msg); typedef void (setKBHook) (HWND, CHECKKEY); setKBHook *SetKBHook; typedef void (renewKBHook) (CHECKKEY); renewKBHook *RenewKBHook; typedef void (removeKBHook) (void); removeKBHook *RemoveKBHook; public: // Benutzer-Deklarationen BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_KEYHOOK, TMessage, KB_Hook); MESSAGE_HANDLER(WM_MOUSEHOOK, TMessage, MS_Hook); END_MESSAGE_MAP(TForm); //... //cpp-file //... HINSTANCE kbhook_dll; //... __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { //DLLs laden + Fehlerüberprüfung //... kbhook_dll = LoadLibrary("kbhook.dll"); SetKBHook = (setKBHook*) GetProcAddress((HMODULE)kbhook_dll, "SetKBHook"); RenewKBHook = (renewKBHook*) GetProcAddress((HMODULE)kbhook_dll, "RenewKBHook"); RemoveKBHook = (removeKBHook*) GetProcAddress((HMODULE)kbhook_dll, "RemoveKBHook"); //... } void __fastcall TForm1::KB_Hook(TMessage &msg) { SetMSHook(Handle); ShowMessage(""); } void __fastcall TForm1::BtChangeLookupKeyClick(TObject *Sender) { keys.KEY = 66; RenewKBHook(keys); ShowMessage(""); }
Irgendwie ist dieses Phänomen sehr merkwürdig. Aber vllt weis ja einer eine Lösung?