using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
//using PointCheck.Core.Util;
namespace PAMS2CE.UTIL
{
public class PowerNotifyEventArgs : EventArgs
{
private uint acLineStatus;
private uint batteryLifePercent;
public uint ACLineStatus
{
get { return acLineStatus; }
}
public uint BatteryLifePercent
{
get { return batteryLifePercent; }
}
public PowerNotifyEventArgs(uint acLineStatus, uint batteryLifePercent)
{
this.acLineStatus = acLineStatus;
this.batteryLifePercent = batteryLifePercent;
}
}
public delegate void PowerNotifyEventHandler(object sender, PowerNotifyEventArgs e);
public class PowerManager
{
public event PowerNotifyEventHandler PowerNotify = null;
Thread PowerThread = null;
protected virtual void OnPowerNotify(PowerNotifyEventArgs e)
{
if (PowerNotify != null)
{
PowerNotify(this, e);
}
}
IntPtr hMsgQ;
IntPtr[] hEvent = new IntPtr[4];
public PowerManager()
{
hEvent[0] = Win32Util.CreateEvent(IntPtr.Zero, false, false, null);
Device.CreatePowerEvent(out hEvent[1], out hEvent[2]);
}
~PowerManager()
{
Win32Util.CloseHandle(hEvent[0]);
Device.ClosePowerEvent();
}
public bool Start()
{
//logger.Info("Start Power Thread");
Win32Util.MSGQUEUEOPTIONS options = new Win32Util.MSGQUEUEOPTIONS();
options.dwSize = 20;
options.dwFlags = 2;
options.dwMaxMessages = 1;
options.cbMaxMessage = 64;
options.bReadAccess = true;
hMsgQ = Win32Util.CreateMsgQueue(null, options);
if (hMsgQ == IntPtr.Zero)
{
return false;
}
IntPtr hNotifi = Win32Util.RequestPowerNotifications(hMsgQ, Win32Util.PBT_POWERINFOCHANGE);
if (hNotifi == IntPtr.Zero)
{
return false;
}
hEvent[3] = hMsgQ;
PowerThread = new Thread(new ThreadStart(this.PowerThreadPorc));
PowerThread.Start();
return true;
}
/// <summary>
/// Stop PowerManagement Thread
/// </summary>
public void Stop()
{
PowerThread.Abort();
Win32Util.EventModify(hEvent[0], Win32Util.EVENT_SET);
Win32Util.StopPowerNotifications(hMsgQ);
Win32Util.CloseMsgQueue(hMsgQ);
}
/// <summary>
/// PowerThreadPorc
/// </summary>
private void PowerThreadPorc()
{
Device.SuspendHold(true);
while (true)
{
uint evt = Win32Util.WaitForMultipleObjects(4, hEvent, false, Win32Util.INFINITE);
switch (evt)
{
case 0://return thread
//Device.SuspendHold(false);//会出现 Power Down Fail!!!
return;
case 2:
Device.SuspendHold(true);
Win32Util.SYSTEM_POWER_STATUS_EX2 status = new Win32Util.SYSTEM_POWER_STATUS_EX2();
if (Win32Util.GetSystemPowerStatusEx2(status, (uint)Marshal.SizeOf(typeof(Win32Util.SYSTEM_POWER_STATUS_EX2)), true) > 0)
{
//logger.Info("BatteryLife{0:D}", status.BatteryLifePercent);
if (status.ACLineStatus != 0x01 && status.BatteryLifePercent <= 7)
{
//StopNetWork(true);
//logger.Info("force suspend");
Win32Util.SetSystemPowerState(null, Win32Util.POWER_STATE_SUSPEND, Win32Util.POWER_FORCE);
break;
}
}
//Device.CheckNetworkStat();
break;
case 3:
uint bytesRead;
uint flags;
Win32Util.POWER_BROADCAST pB = new Win32Util.POWER_BROADCAST();
if (Win32Util.ReadMsgQueue(hMsgQ, out pB, (uint)Marshal.SizeOf(typeof(Win32Util.POWER_BROADCAST)), out bytesRead, Win32Util.INFINITE, out flags))
{
if (pB.Message == Win32Util.PBT_POWERINFOCHANGE && pB.PI.bACLineStatus != 0x01 && pB.PI.bBatteryLifePercent <= 5)
{
//StopNetWork(true);
Win32Util.SetSystemPowerState(null, Win32Util.POWER_STATE_SUSPEND, Win32Util.POWER_FORCE);
break;
}
OnPowerNotify(new PowerNotifyEventArgs(pB.PI.bACLineStatus, pB.PI.bBatteryLifePercent));
}
break;
}
}
}
}
}