如何检测当键盘和鼠标一段时间后没有动作,将进入保护状态。 (50分)

  • 主题发起人 主题发起人 zhiqunluodelphi
  • 开始时间 开始时间
Z

zhiqunluodelphi

Unregistered / Unconfirmed
GUEST, unregistred user!
我是使用HOOK来做,但不知为什么,当我的键盘有动作,却不执行HOOK程序。请各位帮帮小弟!
//检测键盘是否有反应
function HookProc(iCode: integer; wParam: wParam; lParam: lParam): LResult; stdcall;
begin
Timesnum := 0;
Result := 0;
end;

function StartHook: Boolean;
begin
Result := False;
if KeyMouhHook = 0 then
begin
KeyMouhHook := SetWindowsHookEx(WH_kEYBOARD, HookProc, HInstance, 0);
if KeyMouhHook > 0 then
begin
Result := True;
end;
end;
if KeyMousehHook = 0 then
begin
KeyMousehHook := SetWindowsHookEx(WH_MOUSE, HookProc, HInstance, 0);
if KeyMousehHook > 0 then
begin
Result := True;
end
else
Result := False;
end;
end;

procedure StopHook;
begin
if KeyMouhHook > 0 then
begin
UnHookWindowsHookEx(KeyMouhHook);
KeyMouhHook := 0;
end;
if KeyMousehHook > 0 then
begin
UnHookWindowsHookEx(KeyMousehHook);
KeyMousehHook := 0;
end;
end;
 
系统空闲时间检测 Idle
我们知道,当用户超过一定的时间没有输入之后,Windows就会启动屏幕保护功能,那么在程序中如何做到这一点呢?就是说我如何检测到用户多久没有输入呢?大家知道,在Windows中有一个Hook技术,就是钩子,我们利用Hook技术,Hook键盘和鼠标,这样就可以知道用户有没有输入了!因此,我们可以修改Timer控件,继承下来就可以了:
用法:
if IdleTimer1.Snooze>6000 then
ShowMessage('用户已经有6秒钟没有输入了!');
///FileName:IdleTimer.Pas
unit IdleTimer;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;

type
TIdleTimer = class(TTimer)
private
function GetSnooze: Longint;
procedure SetSnooze(const Value: Longint);
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
property Snooze:Longint read GetSnooze write SetSnooze;
published
{ Published declarations }
end;

procedure Register;

implementation

var
Instances:integer;
ElapsedTime:Longint;
whKeyBoard,whMouse:HHook;

procedure Register;
begin
RegisterComponents('System', [TIdleTimer]);
end;

{ TIdleTimer }

function MouseHookCallBack(Code:integer;Msg:lParam;MouseHook:wParam):DWORD;stdcall;
begin
if Code>=0 then ElapsedTime :=GetTickCount;
Result := CallNextHookEx(whMouse,Code,Msg,MouseHook);
end;

function KeyBoardCallBack(Code:integer;Msg:word;KeyBoardHook:Longint):LongInt;stdcall;
begin
if Code>=0 then ElapsedTime :=GetTickCount;
Result := CallNextHookEx(whKeyBoard,Code,Msg,KeyBoardHook);
end;

constructor TIdleTimer.Create(AOwner: TComponent);
function GetModuleHandleFromInstance:THandle;
var
s:array[0..512] of char;
begin
GetModuleFileName(HInstance,s,SizeOf(s)-1);
Result :=GetModuleHandle(s);
end;

begin
inherited Create(AOwner);
Inc(Instances);
if Instances =1 then begin
ElapsedTime :=GetTickCount;
whMouse := SetWindowsHookEx(WH_MOUSE,@MouseHookCallback,GetModuleHandleFromInstance,0);
whKeyBoard :=SetWindowsHookEx(WH_KEYBOARD,@KeyBoardCallBack,GetModuleHandleFromInstance,0);
end;
end;

destructor TIdleTimer.Destroy;
begin
Dec(Instances);
if Instances =0 then begin
UnhookWindowsHookEx(whKeyBoard);
UnhookWindowsHookEx(whMouse);
end;
inherited;
end;

function TIdleTimer.GetSnooze: Longint;
begin
Result:= GetTickCount - ElapsedTime;
end;

procedure TIdleTimer.SetSnooze(const Value: Longint);
begin
ElapsedTime := GetTickCount + Value;
end;

end.
 
在http://www.tommstudio.com/newclub30/ 里有相应的技巧。
 
你的hook只是一个窗体的,不是全局的。
 
谢谢大家的帮忙.
vine:我试了一下,不知什么原因,我在其它地方输入东西,IdleTimer不能检测到键盘的输入.跟定时器一样.
zw84611:我如何做成全局的HOOK了,我试了一下午,还是不行,你帮忙给我看看.我不知在SetWindowsHookEx中的HInstance用什么来代替.
library PKeyIsDowm;
uses
windows,
messages,
HookProc in 'HookProc.pas';

exports
setkeyhook,
GetSysCurrentTime,
endkeyhook;
begin
nexthookproc:=0;
IcurrentTime:=GetTickCount;
end.

//'HookProc.pas';

unit HookProc;
interface
uses
Windows, Messages, SysUtils, Controls, StdCtrls;
var

nexthookproc:hhook;
IcurrentTime:LongInt;
function keyboardhookhandler(icode:integer;wparam:wparam;
lparam:lparam):lresult;stdcall;export;
function setkeyhook:bool;export;//加载钩子
function endkeyhook:bool;export;//卸载钩子
function GetSysCurrentTime :LongInt; export; //得到系统时间



implementation

function GetSysCurrentTime :LongInt; export;

begin
//IcurrentTime:=GetTickCount div 1000; //开始时间
result:=IcurrentTime;

end;


function keyboardhookhandler(icode:integer;wparam:wparam;
lparam:lparam):lresult;stdcall;export;
begin
IcurrentTime:=GetTickCount;
Result := 0;
if icode<0 then
begin
result:=callnexthookex(nexthookproc,icode,wparam,lparam);
end;

end;



function setkeyhook:bool;export;
begin
Result := False;
if (nexthookproc = 0) then
begin
nexthookproc := SetWindowsHookEx(WH_JOURNALRECORD, keyboardhookhandler, HInstance, 0);

if (nexthookproc > 0) then
begin
Result := True;
end;
end;
end;

function endkeyhook:bool;export;
begin
if (nexthookproc<>0) then
begin
unhookwindowshookex(nexthookproc);
nexthookproc:=0;

end;
result:=nexthookproc=0;
end;


end.
 
我以前试过
运行例子
然后切换到其它程序

是可以检测到键盘动作的
不过对鼠标象是没反应
 
我在2000下试,不行,你看看是不是这样子.
procedure TForm1.IdleTimer1Timer(Sender: TObject);
begin
if IdleTimer1.Snooze>600000 then
ShowMessage('用户已经有10分钟没有输入了!');
end;
 
不是这样用呵
你只要创建IdleTimer1或放置在窗体上
另外用个TTImer来检测IdleTimer1.Snooze


 
Sorry
我的象没有用
 
To zhiqunluodelphi
把你的HOOK写成DLL就行了
留下你的QQ和mail吧
 
老人家:我的EMAIL为zhiqunluo@hotmail.com
我已经写成DLL了原码在上面,不知为何不行,谢了!
 
www.playicq.com里有个万能关机的例子,对你一定有用
下载地址http://www.playicq.com/dispdoc.php?t=&id=1965
别忘记给我分哦,哈
 
是的
我测试过了
能达到效果
 
多谢大家的帮忙,只可惜我的分太少了.
 
idletimer is very good.
 
后退
顶部