DLL:
library Project2;
Uses Windows,Messages;
Var SysHook:HHook=0;
Function SysMsgProc(Code:Integer; WParam:LongInt; LParam:LongInt):LongInt; stdcall;
Var Msg:TMessage;
Begin
IF Code=HC_ACTION then
Case TMsg(Pointer(LParam)^).Message OF
WM_RBUTTONDOWN,WM_RBUTTONUP,WM_RBUTTONDBLCLK: TMsg(Pointer(LParam)^).Message:=WM_NULL
else Result:=CallNextHookEx(SysHook,Code,WParam,LParam);
End;
end;
procedure Hook(Flag:Boolean); export; stdcall;
Begin
IF Flag then SysHook:=SetWindowsHookEx(WH_GETMESSAGE,@SysMsgProc,HInstance,0) Else
Begin
UnhookWindowsHookEx(SysHook);
SysHook:=0;
End;
End;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IF Button=mbRight then ShowMessage('Right mouse key pressed');
end;
procedure TForm1.Button1Click(Sender: TObject);
Var Hook: MyProcType;
Begin
@Hook:=nil;
HDLL:=LoadLibrary(PChar('project2.dll'));
IF HDLL>HINSTANCE_ERROR then
Begin
@Hook:=GetProcAddress(HDLL,'Hook');
Hook(True);
End else MessageDlg('Ошибка загрузки DLL.',mtError,[mbIgnore],0);
end;
procedure TForm1.Button2Click(Sender: TObject);
Var Hook: MyProcType;
Begin
@Hook:=nil;
IF HDLL>HINSTANCE_ERROR then
Begin
@Hook:=GetProcAddress(HDLL,'Hook');
Hook(False);
End;
End;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Button2.Click;
end;
end.
Файлы для демонстрации можно взять здесь: http://coolsong.narod.ru/hook.rar
Работает так: при неустановленном хуке правая кнопка работает (о чём свидетельствует нажатие правой кнопки мыши - событие TForm.onMouseDown и сообщение). После установки хука кнопкой "Install", события от мыши перестают обрабатываться (сообщение "Right mouse key pressed" не выдаётся). после снятия хука (кнопка "Remove") - всё возвращается к первоначальному состоянию.
Если требуется перехватывать клавиши, тогда из вышеобозначенной теории нам известны варианты: WH_KEYBOARD, WH_KEYBOARD_LL или WH_GETMESSAGE+WM_CHAR/WM_KEYDOWN/UP
Однако, если требуется перехватить всего лишь отдельную клавишу, будь то одну либо с нажатым Ctrl, Alt, Shift, рациональней для этого воспользоваться назначением горячей клавиши, через RegisterHotKey().
Рабочий пример такого приёма:
Пример регистрации горячих клавиш
procedure TForm1.hotykey(var msg:TMessage);
begin
if (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=81) then
begin
ShowMessage('Ctrl + Q wurde gedrьckt !');
end;
if (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=82) then
begin
ShowMessage('Ctrl + R wurde gedrьckt !');
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
id:=GlobalAddAtom('hotkey');
RegisterHotKey(handle,id,mod_control,81);
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnRegisterHotKey(handle,id);
UnRegisterHotKey(handle,id2);
end;
Блокировка клавиатуры/мыши.
Родственная тема, поэтому помещена в этот же вопрос.
Итак, заблокировать можно хуком. Но в некоторых случаях можно обойтись и "малой кровью".
Вы можете использовать ф-ию BlockInput. Она живёт в user32.dll Также она блокирует одновременно и мышь.
Однако имейте ввиду, что BlockInput() не заблокирует CAD. Кроме того, её работа блокируется по нажатию трёх пальцев.Для блокировки CAD в w9x, мы можем использовать режим скринсэйвера, в NT, увы никак.
Ф-ия BlockInput() явилась продолжением ф-ии EnableHardwareInput(), которая как мы знаем использовалась в 16-разрядных приложениях.
Кроме того, для блокировки, мы можем использовать некоторые недокументированные возможности, однако их недастаток в том, что обратно клавиатуру/мышь уже включить нельзя:
Запустить эти команды мы можем самое простое через ShellExecute() или WinExec():
ShellExecute(Application.Handle,'open','C:\Windows\Rundll32.exe',
'команда','C:\Windows',SW_HIDE);