屏蔽左右Windows键
以下例程可以实现禁止用户用ALT+TAB或ALT+ESCAPE键切换程序,并且可以屏蔽左右windows键:
unit
Unit1;
interface
uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1
= class(TForm)
btn1: TButton;
btn2: TButton;
procedure
Button1Click(Sender: TObject);
procedure Button2Click(Sender:
TObject);
procedure FormDestroy(Sender: TObject);
procedure
FormClose(Sender: TObject; var Action: TCloseAction);
private
{
Private declarations }
public
{ Public declarations
}end;
{按键消息的结构,Delphi中也没有,自己定义吧。这也就我为什么说用C写
这样的程序更好的原因之一。还必须注意的是这个结构在Windows
NT 4 sp3以上系统
中才能使用}
tagKBDLLHOOKSTRUCT = packed record
vkCode:
DWORD;//虚拟键值
scanCode:
DWORD;//扫描码值(没有用过,我也不懂^_^)
{一些扩展标志,这个值比较麻烦,MSDN上说得也不太明白,但是
根据这个程序,这个标志值的第六位数(二进制)为1时ALT键按下为0相反。}
flags:
DWORD;
time: DWORD;//消息时间戳
dwExtraInfo:
DWORD;//和消息相关的扩展信息
end;
KBDLLHOOKSTRUCT =
tagKBDLLHOOKSTRUCT;
PKBDLLHOOKSTRUCT =
^KBDLLHOOKSTRUCT;
//这个是低级键盘钩子的索引值,Delphi中没有,必须自己定义
const
WH_KEYBOARD_LL = 13;
//定义一个常量好和上面哪个结构中的flags比较而得出ALT键是否按下
const
LLKHF_ALTDOWN = $20;
var
Form1: TForm1;
hhkLowLevelKybd:
HHOOK;
implementation
{$R
*.dfm}
{
功能:低级键盘钩子的回调函数,在里面过滤消息
参数:nCode 是Hook的标志
WParam
表示消息的类型
LParam
是一个指向我们在上面定义的哪个结构KBDLLHOOKSTRUCT的指针
返回值:如果不是0的话windows就把这个消息丢掉,程序就不会再收到这个消息了。
}
function
LowLevelKeyboardProc(nCode: Integer;
WParam: WPARAM;LParam: LPARAM):LRESULT;
stdcall;
var
fEatKeystroke: BOOL;
p:
PKBDLLHOOKSTRUCT;
begin
Result := 0;
fEatKeystroke := FALSE;
p :=
PKBDLLHOOKSTRUCT (lParam);
//nCode值为HC_ACTION时表示WParam和LParam参数包涵了按键消息
if
(nCode = HC_ACTION) then
begin
//拦截按键消息并测试是否是左windows、右windows、Ctrl+Esc、Alt+Tab、和Alt+Esc功能键。
case wParam
of
WM_KEYDOWN,
WM_SYSKEYDOWN,
WM_KEYUP,
WM_SYSKEYUP:
fEatKeystroke :=
(p.vkCode = VK_rwin) or
(p.vkCode = VK_lwin) or
((p.vkCode = VK_TAB) and ((p.flags and
LLKHF_ALTDOWN) <> 0)) or
((p.vkCode = VK_ESCAPE) and ((p.flags
and LLKHF_ALTDOWN) <> 0)) or
((p.vkCode = VK_ESCAPE) and
((GetKeyState(VK_CONTROL) and $8000) <> 0));
end;
end;
if
fEatKeystroke = True then
Result := 1;
if nCode <> 0 then
Result := CallNextHookEx(0, nCode, wParam, lParam);
end;
procedure
TForm1.Button1Click(Sender: TObject);
begin
//设置低级键盘钩子
if
hhkLowLevelKybd = 0 then
begin
hhkLowLevelKybd :=
SetWindowsHookExW(WH_KEYBOARD_LL,
LowLevelKeyboardProc, Hinstance,
0);
if hhkLowLevelKybd <> 0 then
MessageBox(Handle,
'低级键盘钩子设置成功!', '提示', MB_OK)
else
MessageBox(Handle,
'低级键盘钩子设置失败!', '提示', MB_OK);
end
else
MessageBox(Handle,
'低级键盘钩子已设置!', '提示', MB_OK);
end;
procedure TForm1.Button2Click(Sender:
TObject);
begin
//卸载低级键盘钩子
if hhkLowLevelKybd <> 0 then
if
UnhookWindowsHookEx(hhkLowLevelKybd) <> False then
begin
MessageBox(Handle, '低级键盘钩子卸载成功!', '提示', MB_OK);
hhkLowLevelKybd :=
0;
end
else
MessageBox(Handle, '低级键盘钩子卸载失败!', '提示',
MB_OK)
else
MessageBox(Handle, '没有发现低级键盘钩子!', '提示',
MB_OK);
end;
procedure TForm1.FormDestroy(Sender:
TObject);
begin
//在Form关闭的时候检测,如果没有卸载钩子就卸载之
if hhkLowLevelKybd <>
0
then
UnhookWindowsHookEx(hhkLowLevelKybd);
end;
上面例程在WINXP和DELPHI
7.0中使用通过。