您的位置:首页 > 其它

[Windows Hook] 屏蔽键盘按键

2009-04-26 08:55 267 查看
以前一直以为全局钩子必须在DLL中创建,查了一下MSDN才发现,有4种钩子是在当前线程的上下文中创建即有全局钩子效果的!其中包括鼠标低级钩子与键盘低级钩子!为调这个,死了3次机......

//该例程为在系统级屏蔽一些系统键、如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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: