我正在为自助服务终端编写WPF应用程序。售货亭将长时间不使用,因此我想创建一个“屏幕保护程序”式功能,我可以在其中显示一些促销幻灯片,然后在人触摸屏幕并启动应用程序时中断。我怎么能这样做呢?
答案 0 :(得分:6)
我不知道是否有什么东西,但你可以做到。
别忘了添加一个计时器来启动它。
顺便说一下,我只是google你的问题并找到了很多样本:
答案 1 :(得分:4)
这听起来像是一个屏幕保护程序可以做你想要的(就像其他人说过的那样),但是你要求屏幕保护功能。我假设你不需要帮助制作一个窗口并显示幻灯片。可能更像是何时展示它。
我几年前为一个客户编写了一个应用程序(WPF)(4+?),需要跟踪用户何时在应用程序中并且没有主动执行某些操作。谷歌(搜索 - 而不是谷歌本身),我想出了以下内容。希望对你有帮助。使用它:
AppActivityTimer activityTimer; // In my app, this is a member variable of the main window
activityTimer = new AppActivityTimer(
30*1000, // plain timer, going off every 30 secs - not useful for your question
5*60*1000, // how long to wait for no activity before firing OnInactive event - 5 minutes
true); // Does mouse movement count as activity?
activityTimer.OnInactive += new EventHandler(activityTimer_OnInactive);
activityTimer.OnActive += new PreProcessInputEventHandler(activityTimer_OnActive);
activityTimer.OnTimePassed += new EventHandler(activityTimer_OnTimePassed);
void activityTimer_OnTimePassed(object sender, EventArgs e)
{
// Regular timer went off
}
void activityTimer_OnActive(object sender, PreProcessInputEventArgs e)
{
// Activity detected (key press, mouse move, etc) - close your slide show, if it is open
}
void activityTimer_OnInactive(object sender, EventArgs e)
{
// App is inactive - activate your slide show - new full screen window or whatever
// FYI - The last input was at:
// DateTime idleStartTime = DateTime.Now.Subtract(activityTimer.InactivityThreshold);
}
AppActivityTimer类本身:
public class AppActivityTimer
{
#region Events - OnActive, OnInactive, OnTimePassed
public event System.Windows.Input.PreProcessInputEventHandler OnActive;
public event EventHandler OnInactive;
public event EventHandler OnTimePassed;
#endregion
#region TimePassed
private TimeSpan _timePassed;
private DispatcherTimer _timePassedTimer;
#endregion
#region Inactivity
public TimeSpan InactivityThreshold { get; private set; }
private DispatcherTimer _inactivityTimer;
private Point _inactiveMousePosition = new Point(0, 0);
private bool _MonitorMousePosition;
#endregion
#region Constructor
/// <summary>
/// Timers for activity, inactivity and time passed.
/// </summary>
/// <param name="timePassedInMS">Time in milliseconds to fire the OnTimePassed event.</param>
/// <param name="IdleTimeInMS">Time in milliseconds to be idle before firing the OnInactivity event.</param>
/// <param name="WillMonitorMousePosition">Does a change in mouse position count as activity?</param>
public AppActivityTimer(int timePassedInMS, int IdleTimeInMS, bool WillMonitorMousePosition)
{
_MonitorMousePosition = WillMonitorMousePosition;
System.Windows.Input.InputManager.Current.PreProcessInput += new System.Windows.Input.PreProcessInputEventHandler(OnActivity);
// Time Passed Timer
_timePassedTimer = new DispatcherTimer();
_timePassed = TimeSpan.FromMilliseconds(timePassedInMS);
// Start the time passed timer
_timePassedTimer.Tick += new EventHandler(OnTimePassedHandler);
_timePassedTimer.Interval = _timePassed;
_timePassedTimer.IsEnabled = true;
// Inactivity Timer
_inactivityTimer = new DispatcherTimer();
InactivityThreshold = TimeSpan.FromMilliseconds(IdleTimeInMS);
// Start the inactivity timer
_inactivityTimer.Tick += new EventHandler(OnInactivity);
_inactivityTimer.Interval = InactivityThreshold;
_inactivityTimer.IsEnabled = true;
}
#endregion
#region OnActivity
void OnActivity(object sender, System.Windows.Input.PreProcessInputEventArgs e)
{
System.Windows.Input.InputEventArgs inputEventArgs = e.StagingItem.Input;
if (inputEventArgs is System.Windows.Input.MouseEventArgs || inputEventArgs is System.Windows.Input.KeyboardEventArgs)
{
if (inputEventArgs is System.Windows.Input.MouseEventArgs)
{
System.Windows.Input.MouseEventArgs mea = inputEventArgs as System.Windows.Input.MouseEventArgs;
// no button is pressed and the position is still the same as the application became inactive
if (mea.LeftButton == System.Windows.Input.MouseButtonState.Released &&
mea.RightButton == System.Windows.Input.MouseButtonState.Released &&
mea.MiddleButton == System.Windows.Input.MouseButtonState.Released &&
mea.XButton1 == System.Windows.Input.MouseButtonState.Released &&
mea.XButton2 == System.Windows.Input.MouseButtonState.Released &&
(_MonitorMousePosition == false ||
(_MonitorMousePosition == true && _inactiveMousePosition == mea.GetPosition(Application.Current.MainWindow)))
)
return;
}
// Reset idle timer
_inactivityTimer.IsEnabled = false;
_inactivityTimer.IsEnabled = true;
_inactivityTimer.Stop();
_inactivityTimer.Start();
if (OnActive != null)
OnActive(sender, e);
}
}
#endregion
#region OnInactivity
void OnInactivity(object sender, EventArgs e)
{
// Fires when app has gone idle
_inactiveMousePosition = System.Windows.Input.Mouse.GetPosition(Application.Current.MainWindow);
_inactivityTimer.Stop();
if (OnInactive != null)
OnInactive(sender, e);
}
#endregion
#region OnTimePassedHandler
void OnTimePassedHandler(object sender, EventArgs e)
{
if (OnTimePassed != null)
OnTimePassed(sender, e);
}
#endregion
}
答案 2 :(得分:0)
我相信 display 屏幕保护程序没有问题。人们可以简单地在所有内容上显示黑色窗口:
<Window WindowStyle="None" WindowState="Maximized" Background="Black" Topmost="True" ... >
当显示此类窗口时,实际问题是。有很多可能性,我最喜欢的一种方法是使用winapi GetLastInputInfo
方法,该方法自上次输入后返回ms
。使用优选的轮询方式(例如DispatcherTimer
),如果时间超过阈值 - 显示窗口,否则 - 隐藏窗口。
当处理来自C#的winapi时,使用pinvoke.net来获取互操作信息以及通常现成的函数,例如: GetLastInputTime
以下是复制/粘贴使用的完整代码段:
[DllImport("user32.dll")]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
[MarshalAs(UnmanagedType.U4)]
public UInt32 cbSize;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwTime;
}
// returns seconds since last input
long GetIdleTime()
{
var info = new LASTINPUTINFO { cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO)) };
GetLastInputInfo(ref info);
return (Environment.TickCount - info.dwTime) / 1000;
}
用法:
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1), IsEnabled = true };
timer.Tick += (s, e) =>
{
if (GetIdleTime() > 10*60) // 10 min
ShowWindow();
else
HideWindow();
};