Приступим к реализации. Создайте новый DLL-проект; VCL можно отключить.
Код процедуры в DLL:
extern "C" __export LRESULT CALLBACK
DebugProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HC_ACTION)
{
if(wParam == WH_KEYBOARD)
{
if(MessageBox(NULL, "Do you want to pass keyboard message to WH_KEYBOARD hook-procedure?",
"Confirmation",
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 |
MB_TOPMOST | MB_SYSTEMMODAL) == IDNO)
return 1;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
|
Всё очень просто - мы проверяем тип вызываемой ловушки на соответствие WH_KEYBOARD, и, если равенство верное, запрашиваем подтверждение на вызов этой процедуры. Если в пропуске отказано, возвращаем ненулевое значение.
Теперь осталось написать приложение, ответственное за установку и снятие этой ловушки.
Код:
// Глобальные переменные:
HMODULE hDLL = NULL;
HHOOK hHook = NULL;
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(hHook != NULL)
{
ShowMessage("The Hook has already been set.");
return;
}
hDLL = LoadLibrary("hook.dll");
if(hDLL == NULL)
{
ShowMessage("Can't load hook.dll. Reason:\n" + SysErrorMessage(GetLastError()));
return;
}
typedef LRESULT __import (CALLBACK *fnType)(int, WPARAM, LPARAM);
fnType DebugProc = (fnType)GetProcAddress(hDLL, "DebugProc");
if(DebugProc == NULL)
{
FreeLibrary(hDLL);
hDLL = NULL;
ShowMessage("Can't find \"DebugProc\" in hook.dll.");
return;
}
hHook = SetWindowsHookEx(WH_DEBUG, (HOOKPROC)DebugProc, hDLL, 0);
if(hHook == NULL)
{
FreeLibrary(hDLL);
hDLL = NULL;
ShowMessage("Can't set WH_DEBUG hook. Reason:\n" + SysErrorMessage(GetLastError()));
return;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if(hDLL)
FreeLibrary(hDLL);
if(hHook)
{
UnhookWindowsHookEx(hHook);
hHook = NULL;
}
}
|
Недостатки примера: