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