控制PDA的背光和电源

2019-07-14 02:45发布

PDA为了省电,会自动挂起,如果我们的程序需要长时间工作,就需要对其背光和电源进行管理。
控制代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32; namespace Streamsea.CommModel
{
    public class PowerEx
    {
        private const string POWER_TIMEOUT = @"System/CurrentControlSet/Control/Power/Timeouts";
        private const string POWER_STATE_SUSPEND = @"System/CurrentControlSet/Control/Power/State/Suspend";         ///
        /// 重设Windows CE用来监视用户操作的定时器
        ///

        [DllImport("CoreDll")]
        public static extern void SystemIdleTimerReset();         ///
        /// 设置电源的关闭时间,0为不关闭
        ///

        public int PowerOffTime
        {
            set
            {
                //系统的闲置关闭时间设置,对应 "设置->系统->电源->高级" 中的两个选择项。
                RegistryKey rktimeout = Registry.LocalMachine.OpenSubKey(POWER_TIMEOUT, true);
                if (rktimeout != null)
                {
                    //外接电源的闲置关闭时间,为0时系统将不会挂起。
                    rktimeout.SetValue("ACSuspendTimeout", value, RegistryValueKind.DWord);
                    //电池电源的闲置关闭时间
                    rktimeout.SetValue("BattSuspendTimeout", value, RegistryValueKind.DWord);
                    rktimeout.Close();
                }
                //在设置闲置关闭时间为0时,如果将注册表做如下修改那么硬件上的挂起按钮将无效。
                RegistryKey rksuspend = Registry.LocalMachine.OpenSubKey(POWER_STATE_SUSPEND, true);
                if (rksuspend != null)
                {
                    rksuspend.SetValue("Default", value == 0 ? 0 : 3, RegistryValueKind.DWord);
                    rksuspend.SetValue("Flags", value == 0 ? 0 : 209152, RegistryValueKind.DWord);
                    rksuspend.Close();
                }
            }
        }
    }
}
使用方法:
在程序启动时设置PowerOffTime属性的值,设为0时系统将不会自动挂起,但最好每隔几分钟调用一次SystemIdleTimerReset函数,因为我在我的Panda E88上设为0后会随机的发生一点击屏幕就挂起的情况。这样系统就不会自动挂起了。
退出系统时再设置为以前的值,如180


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; namespace Streamsea.CommModel
{
    public class ScreenEx
    {
        // GDI Escapes for ExtEscape()
        private const uint QUERYESCSUPPORT = 8;         // The following are unique to CE
        private const uint GETVFRAMEPHYSICAL = 6144;
        private const uint GETVFRAMELEN = 6145;
        private const uint DBGDRIVERSTAT = 6146;
        private const uint SETPOWERMANAGEMENT = 6147;
        private const uint GETPOWERMANAGEMENT = 6148;         private const int SHFS_SHOWSTARTICON = 0x0010;
        private const int SHFS_HIDESTARTICON = 0x0020;         ///
        /// 关闭屏幕背光
        ///

        public static void PowerOff()
        {
            IntPtr hdc = GetDC(IntPtr.Zero);             uint size = 12;
            byte[] vpm = new byte[size];             //structure size
            BitConverter.GetBytes(size).CopyTo(vpm, 0);
            //dpms version
            BitConverter.GetBytes(0x0001).CopyTo(vpm, 4);
            //power state
            BitConverter.GetBytes((uint)ScreenPowerState.ScreenPowerOff).CopyTo(vpm, 8);             ExtEscapeSet(hdc, SETPOWERMANAGEMENT, size, vpm, 0, IntPtr.Zero);
        }         ///
        /// 打开屏幕背光
        ///

        public static void PowerOn()
        {
            IntPtr hdc = GetDC(IntPtr.Zero);             uint size = 12;
            byte[] vpm = new byte[size];             //structure size
            BitConverter.GetBytes(size).CopyTo(vpm, 0);
            //dpms version
            BitConverter.GetBytes(0x0001).CopyTo(vpm, 4);
            //power state
            BitConverter.GetBytes((uint)ScreenPowerState.ScreenPowerOn).CopyTo(vpm, 8);             ExtEscapeSet(hdc, SETPOWERMANAGEMENT, size, vpm, 0, IntPtr.Zero);
        }         [DllImport("coredll", EntryPoint = "ExtEscape")]
        private static extern int ExtEscapeSet(
            IntPtr hdc,
            uint nEscape,
            uint cbInput,
            byte[] lpszInData,
            int cbOutput,
            IntPtr lpszOutData
            );         [DllImport("coredll")]
        private static extern IntPtr GetDC(IntPtr hwnd);
    }     ///
    /// 屏幕电源状态
    ///

    public enum ScreenPowerState : uint
    {
        ///
        /// 打开状态
        ///

        ScreenPowerOn = 1,
        ///
        /// 标准状态
        ///

        ScreenPowerStandBy,
        ///
        /// 挂起状态
        ///

        ScreenPowerSuspend,
        ///
        /// 关闭状态
        ///

        ScreenPowerOff
    }
}
如果让屏幕一直开着,是很耗电的,如果程序在运行时不需要观看屏幕,可以用上面这个类提供的方法关闭屏幕,要注意的是PowerOff只是关闭屏幕,如果点击屏幕上的按钮,点击操作还是会有效的。在这种关闭状态下,按硬件的挂起按钮会打开屏幕背光。
我做了一下测试,我的E88 待机时间大概为2天,开着屏幕时可用5个小时,关闭屏幕可用14个小时,而且还是每隔1分钟就通过GPRS发送数据。所以还是很有用的。   呵~~关于电源不关闭似乎有些问题, 其实只需要在小于能设置的最短的时间内调用SystemIdleTimerReset刷新记时器就可以了, SystemIdleTimerReset方法不会让注册表里的新设置生效, 如果用改注册表的方法还应该触发一个事件来使设置生效, 这个事件在平台API 中的CreateEvent方法创建, 不知道说的对不对, 我这里写过这两种方法http://endink.cnblogs.com