*
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?