请教!有没有好的解决方案?
系统是自助机系统,不知道用钩子能不能监控到屏幕点击事件?
添加一个mousemove 和keydown 共同改变的一个变量,这两个事件一发生时便将这个变量重置。比如 int x=0,添加个timer不停 x++,设置其interval=1000,然后mousemove和keydown一触发便使x=0;当x=60的时候弹出窗口就好。
你是想监控耗时操作吗?可以去我主页的资源看看,我封装了一个dll,或许可以满足你的需求
public
long
getIdleTick()
{
LASTINPUTINFO vLastInputInfo =
new
LASTINPUTINFO();
vLastInputInfo.cbSize = Marshal.SizeOf(vLastInputInfo);
if
(!GetLastInputInfo(
ref
vLastInputInfo))
return
0;
return
Environment.TickCount - (
long
)vLastInputInfo.dwTime;
}
/***************获取鼠标键盘未操作时间***************************/
[StructLayout(LayoutKind.Sequential)]
public
struct
LASTINPUTINFO
{
[MarshalAs(UnmanagedType.U4)]
public
int
cbSize;
[MarshalAs(UnmanagedType.U4)]
public
uint
dwTime;
}
[DllImport(
"user32.dll"
)]
public
static
extern
bool
GetLastInputInfo(
ref
LASTINPUTINFO plii);
临时凑合改的,鼠标判断自己加上去,只判断按键
using
System;
using
System.Reflection;
using
System.Runtime.InteropServices;
using
System.Threading.Tasks;
using
System.Windows.Forms;
namespace
Test_10
{
public
partial
class
Form1 : Form
{
public
static
Timer timer =
new
Timer();
public
static
DateTime TimeRecord =
new
DateTime();
public
static
TimeSpan midTime;
public
class
KeyRecord
{
private
const
int
WM_KEYDOWN = 0x100;
private
const
int
WM_KEYUP = 0x101;
private
const
int
WM_SYSKEYDOWN = 0x104;
private
const
int
WM_SYSKEYUP = 0x105;
public
event
KeyEventHandler OnKeyDownEvent;
public
event
KeyEventHandler OnKeyUpEvent;
public
event
KeyPressEventHandler OnKeyPressEvent;
static
int
hKeyboardHook = 0;
public
const
int
WH_KEYBOARD_LL = 13;
HookProc KeyboardHookProcedure;
[StructLayout(LayoutKind.Sequential)]
public
class
KeyboardHookStruct
{
public
int
vkCode;
public
int
scanCode;
public
int
flags;
public
int
time;
public
int
dwExtraInfo;
}
[DllImport(
"user32.dll"
, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public
static
extern
int
SetWindowsHookEx(
int
idHook, HookProc lpfn, IntPtr hInstance,
int
threadId);
[DllImport(
"user32.dll"
, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public
static
extern
bool
UnhookWindowsHookEx(
int
idHook);
[DllImport(
"user32.dll"
, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public
static
extern
int
CallNextHookEx(
int
idHook,
int
nCode, Int32 wParam, IntPtr lParam);
[DllImport(
"user32"
)]
public
static
extern
int
GetKeyboardState(
byte
[] pbKeyState);
public
delegate
int
HookProc(
int
nCode, Int32 wParam, IntPtr lParam);
public
KeyRecord()
{
this
.OnKeyPressEvent +=
new
KeyPressEventHandler(KeyBordHook_OnKeyPressEvent);
Start();
}
public
void
Start()
{
if
(hKeyboardHook == 0)
{
KeyboardHookProcedure =
new
HookProc(KeyboardHookProc);
Module m = Assembly.GetExecutingAssembly().GetModules()[0];
IntPtr itp = Marshal.GetHINSTANCE(m);
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, itp, 0);
if
(hKeyboardHook == 0) Stop();
}
}
public
void
Stop()
{
bool
retKeyboard =
true
;
if
(hKeyboardHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
}
}
private
int
KeyboardHookProc(
int
nCode, Int32 wParam, IntPtr lParam)
{
if
((nCode >= 0) && (OnKeyDownEvent !=
null
|| OnKeyUpEvent !=
null
|| OnKeyPressEvent !=
null
))
{
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam,
typeof
(KeyboardHookStruct));
if
(OnKeyPressEvent !=
null
&& (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
{
TimeRecord = DateTime.Now;
}
}
return
CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
private
void
KeyBordHook_OnKeyPressEvent(
object
sender, KeyPressEventArgs e) { }
}
public
Form1()
{
InitializeComponent();
timer.Interval = 1000;
TimeRecord = DateTime.Now;
timer.Start();
KeyRecord kr =
new
KeyRecord();
kr.Start();
Task.Run(() =>
{
while
(
true
)
{
midTime = DateTime.Now.Subtract(TimeRecord);
if
(midTime.Seconds>60)
{
MessageBox.Show(
"No KeyPress."
);
TimeRecord = DateTime.Now;
}
}
});
}
}
}
调用GetIdleTick()方法即可
#region 判断鼠标键盘空闲
/// <summary>
/// 获取鼠标键盘空闲时间
/// </summary>
/// <returns></returns>
public
static
long
GetIdleTick()
{
LASTINPUTINFO lastInputInfo =
new
LASTINPUTINFO();
lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo);
if
(!GetLastInputInfo(
ref
lastInputInfo))
return
0;
return
Environment.TickCount - (
long
)lastInputInfo.dwTime;
}
[StructLayout(LayoutKind.Sequential)]
private
struct
LASTINPUTINFO
{
[MarshalAs(UnmanagedType.U4)]
public
int
cbSize;
[MarshalAs(UnmanagedType.U4)]
public
uint
dwTime;
}
/// <summary>
/// 调用windows API获取鼠标键盘空闲时间
/// </summary>
/// <param name="plii"></param>
/// <returns></returns>
[DllImport(
"user32.dll"
)]
private
static
extern
bool
GetLastInputInfo(
ref
LASTINPUTINFO plii);
#endregion
//下面是判断 加在计时器方法中
//判断空闲时间是否超过设定秒,超过则自动弹出窗口,单位:秒
if
(GetIdleTick() / 1000 >= 60)
{
MessageBox.Show(“登录超时”);
}
不是用钩子么?
好吧,5楼钩子,
其他
https://www.cnblogs.com/fenglx/archive/2011/06/10/2077441.html
监控超时,一般是判断系统空闲等待,idle 。判断键盘有点累。
后台线程或者是timer计时呗,有操作就重置时间,时间到该干嘛干嘛,比较粗暴
要确认自己认为的无操作是指什么,鼠标和键盘?热键算不算?
用钩子要有些WindowsApi基础,资源下载从VC过来的最好。
否则只是在Form监控 Keydown和MouseHover事件就足够了,毕竟只是WinForm层次,并不是桌面层次,用不到钩子。