大悟还俗

邮箱 key_ok@qq.com 我的收集 http://pan.baidu.com/share/home?uk=1177427271
  新随笔  :: 联系 :: 订阅 订阅  :: 管理

[Windows Hook] 屏蔽键盘按键

Posted on 2013-10-09 11:20  大悟还俗_2  阅读(536)  评论(0编辑  收藏  举报
//该例程为在系统级屏蔽一些系统键、如WIN、TAB、CAP、POWER、SLEEP、HOME等!
//屏蔽组合键下面例程不适用!(比如CTRL+ESC需要在钩子函数中用(p.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000) <> 0)进行判断,也不难,这里只是举个简单的例子)
unit KeyBlocker;

interface

uses
  SysUtils, Classes, Windows, Messages;

const
  WH_KEYBOARD_LL = 13;

type
  PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
  KBDLLHOOKSTRUCT = packed record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    Time: DWORD;
    dwExtraInfo: DWORD;
  end;

  TBlockKeyEvent = procedure(VirtualKey: Cardinal) of object;

  TKeyBlocker = class
  private
    FEnabled: Boolean;
    FCustomKey:Cardinal;
    FOnBlockKey: TBlockKeyEvent;
    procedure SetEnabled(const Value: Boolean);
    procedure SetCustomKey(const Value: Cardinal);
    procedure DoBlock(VirtualKey: Cardinal);
    procedure UpdateKeyBlock;
  public
    constructor Create;
    destructor  Destroy; override;
    property    CustomKey: Cardinal read FCustomKey write SetCustomKey default 0;
    property    Enabled: Boolean read FEnabled write SetEnabled default False;
    property    OnBlockKey: TBlockKeyEvent read FOnBlockKey write FOnBlockKey;
  end;

implementation

{ TKeyBlocker }

var
  KeyboardHook: HHOOK = 0;
  FKeyBlocker: TKeyBlocker = nil;//设计这一变量的作用就是能在LowLevelfunction中访问类成员变量!
//LowLevelfunction为系统回调函数,为确保在系统调用时存在,就必须把之设计为一个类函数或静态函数,使之在编译期就能生成地址,如果设计为虚函数,系统就晕了

constructor TKeyBlocker.Create;
begin
  inherited;
  FKeyBlocker := Self;
end;

destructor TKeyBlocker.Destroy;
begin
  Enabled := False;
  FKeyBlocker := nil;
  inherited;
end;

procedure TKeyBlocker.DoBlock(VirtualKey: Cardinal);
begin
  if Assigned(FOnBlockKey) then
    FOnBlockKey(VirtualKey);
end;

procedure TKeyBlocker.SetCustomKey(const Value: Cardinal);
begin
  FCustomKey := Value;
end;

procedure TKeyBlocker.SetEnabled(const Value: Boolean);
begin
  FEnabled := Value;
  UpdateKeyBlock;
end;
//核心部分
function LowLevelKeyboardFunc(nCode: INTEGER; w_Param: WPARAM;
  l_Param: LPARAM): LRESULT; stdcall;
var
  boolKey: Boolean;
  p: PKBDLLHOOKSTRUCT;
begin
  boolKey := False;
  p := nil;
  if nCode = HC_ACTION then
  begin
    case w_Param of
      WM_KEYDOWN, WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP:
        begin
          p := PKBDLLHOOKSTRUCT(l_Param);
            if (p.vkCode = FKeyBlocker.FCustomKey)  then
              boolKey := True;
        end;
    end;
  end;

  if boolKey and (p <> nil) then
  begin
    FKeyBlocker.DoBlock(p.vkCode);
    Result := 1;
    Exit;
  end;

  Result := CallNextHookEx(0, nCode, w_Param, l_Param);
end;
//装载hook与卸载hook
procedure TKeyBlocker.UpdateKeyBlock;
begin
  if KeyboardHook <> 0 then Exit;
  case FEnabled of
    True:
       KeyboardHook := SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardFunc, HInstance, 0);
    False:
       UnhookWindowsHookEx(KeyboardHook); 
  end;
end;

end.
----------------------------------------------------------------
//调用程序

procedure BlockProc(VirtualKey: Cardinal);
begin
  //to do ..
end;
procedure TForm1.btn1Click(Sender: TObject);
var
  KeyBlockerTest:TKeyBlocker;
begin
  KeyBlockerTest:=TKeyBlocker.Create;
  KeyBlockerTest.CustomKey:=VK_CAPITAL;
  KeyBlockerTest.OnBlockKey:=BlockProc;
  KeyBlockerTest.Enabled:=true;
end;
View Code