2008年7月15日 星期二

Check Keyboard & Mouse Hook #1

如果你不需要屏蔽Ctrl+Alt+Del組合鍵,可以使用低級鍵盤鉤子(WH_KEYBOARD_LL)與低級鼠標鉤子(WH_MOUSE_LL),這兩種消息鉤子的好處是不需要放在動態鏈接庫中就可以作全局鉤子,將鍵盤消息與鼠標消息截獲.

unit uHookKeyAndMouse;
{ 該單元利用WH_KEYBOARD_LL與WH_MOUSE_LL兩種類型的鉤子分別截獲鍵盤消息與鼠標消息}
{ 由於這裡只是需要將消息屏蔽,故只需對鉤子函數的返回結果設為1即可. }
{ 提供兩個函數StartHookKeyMouse與StopHookKeyMouse兩個函數. }

interface

uses
Windows, Messages, SysUtils;

const
WH_KEYBOARD_LL =13;
WH_MOUSE_LL =14;

procedure StartHookKeyMouse;
procedure StopHookKeyMouse;

implementation

var
hhkLowLevelKybd:HHook=0;
hhkLowLevelMouse:HHook=0;

function LowLevelKeyboardProc(nCode:Integer; WParam:WPARAM; LParam:LPARAM):LRESULT; stdcall;
begin
Result:=1;
if nCode<>0 then Result:=CallNextHookEx(0,nCode,WParam,LParam);
end;

function LowLevelMouseProc(nCode:Integer; WParam:WPARAM; LParam:LPARAM):LRESULT; stdcall;
begin
Result:=1;
if nCode<>0 then Result:=CallNextHookEx(0,nCode,WParam,LParam);
end;

procedure StartHookKeyMouse;
begin
if hhkLowLevelKybd = 0 then
begin
hhkLowLevelKybd := SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, Hinstance, 0);
end;
if hhkLowLevelMouse = 0 then
begin
hhkLowLevelMouse:=SetWindowsHookEx(WH_MOUSE_LL,LowlevelMouseProc,HInstance,0);
end;
end;

procedure StopHookKeyMouse;
begin
if hhkLowLevelKybd <> 0 then
begin
UnhookWindowsHookEx(hhkLowLevelKybd);
hhkLowLevelKybd:=0;
end;
if hhkLowLevelMouse <> 0 then
begin
UnHookWindowsHookEx(hhkLowLevelMouse);
hhkLowLevelMouse:=0;
end;
end;

initialization
hhkLowLevelKybd:=0;
hhkLowLevelMouse:=0;
finalization
if hhkLowLevelKybd <> 0 then UnhookWindowsHookEx(hhkLowLevelKybd);
if hhkLowLevelMouse <> 0 then UnhookWindowsHookEx(hhkLowLevelMouse);
end.


來自:conworld, 時間:2005-2-24 16:06:31, ID:2996263
高手終於出現了,謝謝
你的方法確實實現了鎖定鼠標,但是我想達到的效果是:
1.鎖定鍵盤
2.鼠標只能在我的程序窗口中操作
謝謝


來自:smokingroom, 時間:2005-2-24 17:01:12, ID:2996381
要求2(鼠標只能在我的程序窗口中操作)的實現:
修改LowLevelMouseProc過程如下:

type
PMSLLHOOKSTRUCT=^MSLLHOOKSTRUCT;
MSLLHOOKSTRUCT = record
pt:TPoint;
mouseData:DWORD;
flags:DWORD;
time:DWORD;
dwExtraInfo:DWORD;
end;

var
MouseRect:TRect; //這是你需要限制的Mouse活動範圍.

function LowLevelMouseProc(nCode:Integer; WParam:WPARAM; LParam:LPARAM):LRESULT; stdcall;
var
p:PMSLLHOOKSTRUCT;
begin
Result:=0;
if nCode=HC_ACTION then
begin
p:=PMSLLHOOKSTRUCT(LParam);
if (p.pt.X <> MouseRect.Right) or
(p.pt.Y <> MouseRect.Bottom) then
Result:=1;
end else
if nCode<>0 then Result:=CallNextHookEx(0,nCode,WParam,LParam);
end;

附取得MouseRect的代碼,假定你的主窗體體為MainFrm
MouseRect:=MainFrm.ClientRect;
MouseRect.TopLeft:=MainFrm.ClientToScreen(MouseRect.TopLeft);
MouseRect.BottomRight:=MainFrm.ClientToScreen(MouseRect.BottomRight);


另在Result:=1之前加多一個ClipCursor(@MouseRect)效果會更好,可以有效解決當按下Ctrl+Alt+Del後將Mouse移出窗體後,Mouse失效的情況.
if (p.pt.X <> MouseRect.Right) or
(p.pt.Y <> MouseRect.Bottom) then
begin
ClipCursor(@MouseRect)
Result:=1;
end

沒有留言: