Windows如何决定显示屏幕

ste*_*rnr 1 c# windows winapi screensaver

Windows有一个内部机制,通过检查用户交互性和其他任务(某人正在观看视频等)来决定何时显示屏幕保护程序(或关闭屏幕).

是否有Win API允许我询问用户是否处于活动状态,或者他们最后一次处于活动状态?

Han*_*ant 6

它被称为"空闲计时器".您可以通过调用CallNtPowerInformation()来获取其值,请求SystemPowerInformation.返回的SYSTEM_POWER_INFORMATION.TimeRemaining字段告诉您空闲计时器剩余多少时间.SystemExecutionState请求告诉您是否有任何线程调用SetThreadExecutionState()来停止计时器,就像显示视频的应用程序所做的那样.

using System;
using System.Runtime.InteropServices;

public static class PowerInfo {
    public static int GetIdleTimeRemaining() {
        var info = new SYSTEM_POWER_INFORMATION();
        int ret = GetSystemPowerInformation(SystemPowerInformation, IntPtr.Zero, 0, out info, Marshal.SizeOf(info));
        if (ret != 0) throw new System.ComponentModel.Win32Exception(ret);
        return info.TimeRemaining;
    }

    public static int GetExecutionState() {
        int state = 0;
        int ret = GetSystemExecutionState(SystemExecutionState, IntPtr.Zero, 0, out state, 4);
        if (ret != 0) throw new System.ComponentModel.Win32Exception(ret);
        return state;
    }

    private struct SYSTEM_POWER_INFORMATION {
        public int MaxIdlenessAllowed;
        public int Idleness;
        public int TimeRemaining;
        public byte CoolingMode;
    }
    private const int SystemPowerInformation = 12;
    private const int SystemExecutionState = 16;
    [DllImport("powrprof.dll", EntryPoint = "CallNtPowerInformation", CharSet = CharSet.Auto)]
    private static extern int GetSystemPowerInformation(int level, IntPtr inpbuf, int inpbuflen, out SYSTEM_POWER_INFORMATION info, int outbuflen);
    [DllImport("powrprof.dll", EntryPoint = "CallNtPowerInformation", CharSet = CharSet.Auto)]
    private static extern int GetSystemExecutionState(int level, IntPtr inpbuf, int inpbuflen, out int state, int outbuflen);

}
Run Code Online (Sandbox Code Playgroud)