在windows上写游戏时有时想屏蔽键盘上的某些键,比如"Win"键以防止以弹出开始菜单导致游戏窗口失焦或全屏切出.对于那种没有失焦处理的游戏遇到PK时可能损失是极大的,这对玩家来说是不可接受的.这里我们用Pascal来介绍关键性代码,代码很简单,效果却很好.(代码摘自遥远年代的个人作品中的一部分).
首先我们需要写一个单独的Dll,以实现全局挂钩.
var hHk:HHOOK; type PKBDLLHOOKSTRUCT=^KBDLLHOOKSTRUCT; KBDLLHOOKSTRUCT=record vkCode:DWORD; ScanCode:DWORD; Flags:DWORD; Time:DWORD; dwExtraInfo:DWORD; end;
function DisableWinKey:Boolean; Stdcall; Export; begin if hHk=0 then begin hHk:=SetWindowsHookEx(13,@keyHookProc,HInstance,0); Result:=True; end else Result:=False; end;
function EnableWinKey:Boolean; Stdcall; Export; begin if hHk<>0 then begin UnhookWindowsHookEx(hHk); hHk:=0; Result:=True; end else Result:=False; end;以上实现对键盘Hook,然后关键的地方就是对按键的过滤:
function keyHookProc(nCode:Integer;WParam:WParam;LParam:LParam):LRESULT; Stdcall; var p:PKBDLLHOOKSTRUCT; y:Integer; begin if nCode<0 then Result:=CallNextHookEx(hHk,nCode,WParam,LParam) else begin y:=0; case WParam of WM_KEYDOWN,WM_SYSKEYDOWN://按键后判断所按键 begin p:=PKBDLLHOOKSTRUCT(LParam); if p^.vkCode=VK_LWIN then y:=1; if p^.vkCode=VK_RWIN then y:=1; end; WM_KEYUP,WM_SYSKEYUP://松开按键后判断所按键 begin p:=PKBDLLHOOKSTRUCT(LParam); if p^.vkCode=VK_LWIN then y:=1; if p^.vkCode=VK_RWIN then y:=1; end; end; if y=1 then Result:=1//如果为WIN功能键则屏蔽 else Result:=CallNextHookEx(hHk,nCode,WParam,LParam);//继续下一个钩子 end end;很简单不是吗,接下来导出二个fun
exports EnableWinKey, DisableWinKey;我们编译这个dpr,得到一个dll文件,接下来我们只需要一个host主程序来使用这个dll,这个就自由发挥了,这里给出我的一个简单示例:
首先我们定义导出范式
type DisableWinKeyProc=function:Boolean;stdcall; EnableWinKeyProc=function:Boolean;stdcall;然后声明
DisWinKey:DisableWinKeyProc; EnaWinKey:EnableWinKeyProc; const DllFileName='DisableWinKey.dll';//你自己的dll文件名接下来我们动态载入Dll
DllHandle:=LoadLibrary(DllFileName); if DllHandle<>0 then begin @DisWinKey:=GetProcAddress(DllHandle,'DisableWinKey'); @EnaWinKey:=GetProcAddress(DllHandle,'EnableWinKey'); end;
OK,现在我们就可以调用,看看效果吧:)
注意Host程序关闭前记得一定要释放,否则Win键不会自动恢复.
EnaWinKey(); FreeLibrary(DllHandle);