我一直在搜索,我在计时器上发现了很多非常好的文章。
这篇文章Monitor the idle time between user and application是最好的,但我在此代码中遇到了一些问题。
问题是,这是用户和操作系统(不是应用程序)之间的空闲时间。当我在屏幕上移动鼠标时,它会重置计时器。
我需要跟踪鼠标在应用程序内部移动时的空闲时间。如果用户不在做什么"无论什么"在操作系统中,计时器正在运行。
有没有人有关于跟踪应用程序和用户操作的空闲时间的任何建议或文章?
到目前为止我有什么
int totaltime = 0;
LASTINPUTINFO lastInputInf = new LASTINPUTINFO();
[DllImport("user32.dll")]
public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
[StructLayout(LayoutKind.Sequential)]
public struct LASTINPUTINFO
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int dwTime;
}
private void MainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
DispatcherTimer dt = new DispatcherTimer();
dt.Tick += dispatcherTimer_Tick;
dt.Interval = new TimeSpan(0, 0, 1);
dt.Start();
}
public void dispatcherTimer_Tick(object sender, EventArgs e)
{
DisplayTime();
}
public int GetLastInputTime()
{
int idletime = 0;
idletime = 0;
lastInputInf.cbSize = Marshal.SizeOf(lastInputInf);
lastInputInf.dwTime = 0;
if (GetLastInputInfo(ref lastInputInf))
{
idletime = Environment.TickCount - lastInputInf.dwTime;
}
if (idletime != 0)
{
return idletime / 1000;
}
else
{
return 0;
}
}
private void DisplayTime()
{
totaltime = GetLastInputTime();
if (GetLastInputTime().Equals(1))
{
Label1.Content = "Tempo di inattività pari a" + " " + GetLastInputTime().ToString() + " " + "secondo";
}
else
{
Label1.Content = "Tempo di inattività pari a" + " " + GetLastInputTime().ToString() + " " + "secondi";
}
}
private void Window_MouseMove(System.Object sender, System.Windows.Input.MouseEventArgs e)
{
if (totaltime > 5)
{
FrmLogin log = new FrmLogin();
log.ShowDialog();
}
}
答案 0 :(得分:0)
好的,所以在WPF这里是一个选项。如果你愿意,你仍然可以使用鼠标进入并离开,但这很有用。我做了一个简单的应用程序来展示。这是文件。当应用程序失去焦点时,计时器将在几毫秒内启动,当您返回时它会停止。您可以看到您离开应用程序的时间。根据需要修改;这只是为了展示和逻辑。
<强>的App.xaml 强>
<Application x:Class="TimingLostFocus.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
Activated="Application_Activated"
Deactivated="Application_Deactivated"
Startup="Application_Startup">
</Application>
<强> App.xaml.cs 强>
using System;
using System.ComponentModel;
using System.Timers;
using System.Windows;
namespace TimingLostFocus
{
public partial class App : Application, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private long millisecondsWithoutFocus;
private void Application_Startup(object sender, StartupEventArgs eventArgs) => Timer.Elapsed += (s, e) => MillisecondsWithoutFocus++;
private void Application_Activated(object sender, EventArgs e) => Timer.Stop();
private void Application_Deactivated(object sender, EventArgs e) =>Timer.Start();
public Timer Timer { get; set; } = new Timer(100);
public long MillisecondsWithoutFocus
{
get => millisecondsWithoutFocus;
set
{
millisecondsWithoutFocus = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MillisecondsWithoutFocus)));
}
}
}
}
<强> MainWindow.xaml 强>
<Window x:Name="mainWindow" x:Class="TimingLostFocus.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBlock Text="Milliseconds Without Focus" />
<TextBlock x:Name="millisecondsWithoutFocusTextBlock" />
</StackPanel>
</Window>
<强> MainWindow.xaml.cs 强>
using System;
using System.Windows;
namespace TimingLostFocus
{
public partial class MainWindow : Window
{
public static int WindowsCount = 0;
public MainWindow()
{
InitializeComponent();
if (Application.Current is App app)
{
app.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(App.MillisecondsWithoutFocus))
{
Dispatcher.BeginInvoke(new Action(() => millisecondsWithoutFocusTextBlock.Text = app.MillisecondsWithoutFocus.ToString()));
}
};
}
}
}
}