Windows下如何获取屏幕超时事件 基于.NET WinForms开发屏保应用
.NET WinForm 自定义超时图片屏保实现方案
不用依赖Microsoft.Win32.SystemEvents即可实现,核心通过调用Windows原生API检测系统空闲时间,触发后展示全屏窗口加载下载的图片即可,具体实现步骤如下:
1. 导入Windows API获取系统空闲时间
首先在项目中引入所需的Windows API声明,用于获取用户最后一次输入的时间,计算系统空闲时长:
using System.Runtime.InteropServices; // 声明API所需结构体 [StructLayout(LayoutKind.Sequential)] struct LASTINPUTINFO { public uint cbSize; public uint dwTime; } // 导入系统API [DllImport("user32.dll")] static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); // 封装获取空闲时间的方法,返回空闲秒数 public static int GetIdleSeconds() { LASTINPUTINFO lastInputInfo = new LASTINPUTINFO(); lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo); GetLastInputInfo(ref lastInputInfo); return (Environment.TickCount - (int)lastInputInfo.dwTime) / 1000; }
2. 配置超时检测逻辑
在主窗口或者后台服务逻辑中加入Timer控件,设置Interval为10000(即每10秒检测一次),在Timer的Tick事件中判断是否触发屏保:
// 自定义超时阈值,比如300秒即5分钟无操作触发屏保 private const int IdleTimeout = 300; private bool isScreensaverRunning = false; private void timerDetectIdle_Tick(object sender, EventArgs e) { int idleSeconds = GetIdleSeconds(); if (idleSeconds >= IdleTimeout && !isScreensaverRunning) { isScreensaverRunning = true; // 打开屏保窗口 ScreensaverForm screensaver = new ScreensaverForm(); screensaver.FormClosed += (s, args) => isScreensaverRunning = false; screensaver.Show(); } }
3. 实现屏保展示窗口
新建一个名为ScreensaverForm的Form窗口,做如下配置:
- 基础属性设置:
FormBorderStyle设为None,WindowState设为Maximized,TopMost设为true,背景色设为黑色 - 窗口内加入
PictureBox控件,设置Dock为Fill,SizeMode设为Zoom保证图片不变形 - 提前异步下载网络图片到本地缓存目录,屏保打开时直接从本地读取图片加载到PictureBox即可,需要轮播效果可在窗口内再加一个Timer定时切换图片
4. 配置屏保退出逻辑
给ScreensaverForm绑定按键、鼠标事件,检测到用户操作时直接关闭窗口:
private void ScreensaverForm_KeyDown(object sender, KeyEventArgs e) { this.Close(); } private void ScreensaverForm_MouseClick(object sender, MouseEventArgs e) { this.Close(); } // 鼠标移动事件要判断位移差,避免系统自动的微小位移误触发退出 private Point lastMousePos = Point.Empty; private void ScreensaverForm_MouseMove(object sender, MouseEventArgs e) { if (lastMousePos == Point.Empty) { lastMousePos = e.Location; return; } if (Math.Abs(e.X - lastMousePos.X) > 5 || Math.Abs(e.Y - lastMousePos.Y) >5) { this.Close(); } }
内容的提问来源于stack exchange,提问作者Gulshan Sharma
相关产品推荐
相关产品推荐

