C# 我使用什么事件来移动鼠标和停止鼠标
我是新来的C#,我正在使用windows窗体。我构建了一个应用程序,在这个应用程序中,如果鼠标停止(没有活动)5秒钟,我想使用计时器显示一个消息,当鼠标移动时,计时器会重置 我有C# 我使用什么事件来移动鼠标和停止鼠标,c#,C#,我是新来的C#,我正在使用windows窗体。我构建了一个应用程序,在这个应用程序中,如果鼠标停止(没有活动)5秒钟,我想使用计时器显示一个消息,当鼠标移动时,计时器会重置 我有Form1,带有一些控件(按钮和文本框)和计时器。我只是想做一些像屏幕保护程序的事情,所以当Form1加载并且在某个时间内没有活动(鼠标停止)时,必须采取一个动作(例如show message) 我尝试了下面的代码(作为一个示例),但效果不好,当Form1加载计时器时,计时器开始计数,如果我移动鼠标(在I==5之前),计
Form1
,带有一些控件(按钮和文本框)和计时器。我只是想做一些像屏幕保护程序的事情,所以当Form1
加载并且在某个时间内没有活动(鼠标停止)时,必须采取一个动作(例如show message)
我尝试了下面的代码(作为一个示例),但效果不好,当Form1
加载计时器时,计时器开始计数,如果我移动鼠标(在I==5
之前),计时器将重置,并且不再开始计数
int i = 0;
private void Form1_Load(object sender, EventArgs e)
{
timer1.Start();
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
i = 0;
timer1.Stop();
textBox1.Text = i.ToString();
}
private void Form1_MouseHover(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
i = i + 1;
textBox1.Text = i.ToString();
if(i==5)
{
MessageBox.Show("Time is over");
}
}
我不知道我是否在使用鼠标右键事件,甚至不知道在这种情况下使用这些事件是否正确。如果鼠标在5秒钟内不移动,我如何显示消息?不幸的是,WinForms没有像WPF那样的PreviewMouseMove
事件,因此当您将鼠标移动到控件上时,表单
将永远不会知道它。但是,每次在表单中注册鼠标事件时,都可以使用系统功能重置计时器
如果您对用户上次在操作系统的任何地方进行任何类型的输入感兴趣(就像屏幕保护程序一样),您也应该看看这个函数
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
}
[StructLayout(LayoutKind.Sequential)]
public struct MouseHookStruct
{
public POINT pt;
public int hwnd;
public int hitTestCode;
public int dwExtraInfo;
}
[DllImport("user32.dll", SetLastError = true)]
static extern int SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hInstance, uint dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
static extern int CallNextHookEx(int hook, int code, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static int _hHook;
private readonly Timer _timer1;
public Form1()
{
InitializeComponent();
_timer1 = new Timer();
// setting the interval to 5000 is a lot easier than counting up to 5 ;)
_timer1.Interval = 5000;
_timer1.Tick += Timer1OnTick;
}
private void Form1_Load(object sender, EventArgs e)
{
// hook up to mouse events (or keyboard with WH_KEYBOARD)
_hHook = SetWindowsHookEx(HookType.WH_MOUSE, MouseHookProc, IntPtr.Zero, (uint)GetCurrentThreadId());
_timer1.Start();
}
// This function will get called every time there is a mouse event
private int MouseHookProc(int code, IntPtr wParam, IntPtr lParam)
{
// Mouse event --> reset Timer
_timer1.Stop();
_timer1.Start();
return CallNextHookEx(_hHook, code, wParam, lParam);
}
// 5000 ms without any mouse events --> show message
private void Timer1OnTick(object sender, EventArgs eventArgs)
{
//Stop timer, Show message, start timer
_timer1.Stop();
MessageBox.Show("You have been idle for " + _timer1.Interval + " ms!");
_timer1.Start();
}
}
}
而不是MouseHover事件puttimer1.Start()
直接在MouseMove事件结束时…您必须查看鼠标在每个刻度上的位置。你怎么知道它是否移动了?如果位置相同,则您知道它不会移动。顺便说一句,HanletEscano建议在效率方面提供更好的解决方案…您忘记再次调用timer1.Start()。这不是正确的方法,您需要实现IMessageFilter,这样才能看到每个动作。