using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Runtime.InteropServices; namespace Urovo { #region PowerNotify Event /// /// PowerNotifyEventArgs /// 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; } } /// /// PowerNotifyEvent Delegate /// /// /// public delegate void PowerNotifyEventHandler(object sender, PowerNotifyEventArgs e); #endregion public class PowerManager { #region Event public event PowerNotifyEventHandler PowerNotify = null; protected virtual void OnPowerNotify(PowerNotifyEventArgs e) { if (PowerNotify != null) { PowerNotify(this, e); } } #endregion #region Variable IntPtr hMsgQ; IntPtr hNotify; IntPtr[] hEvent = new IntPtr[2]; #endregion #region Method /// /// Start PowerManagement Thread /// /// public bool Start() { hEvent[0] = Win32.CreateEvent(IntPtr.Zero, false, false, null); Win32.MSGQUEUEOPTIONS options = new Win32.MSGQUEUEOPTIONS(); options.dwSize = 20; options.dwFlags = 2; options.dwMaxMessages = 1; options.cbMaxMessage = 64; options.bReadAccess = true; hMsgQ = Win32.CreateMsgQueue(null, options); if (hMsgQ == IntPtr.Zero) { return false; } hNotify = Win32.RequestPowerNotifications(hMsgQ, Win32.PBT_POWERINFOCHANGE); if (hNotify == IntPtr.Zero) { return false; } hEvent[1] = hMsgQ; Thread t = new Thread(new ThreadStart(this.PowerThreadPorc)); t.Start(); return true; } /// /// Stop PowerManagement Thread /// public void Stop() { PowerNotify = null; Win32.EventModify(hEvent[0], Win32.EVENT_SET); Win32.StopPowerNotifications(hNotify); Win32.CloseMsgQueue(hMsgQ); Win32.CloseHandle(hEvent[0]); } /// /// PowerThreadPorc /// private void PowerThreadPorc() { while (true) { uint evt = Win32.WaitForMultipleObjects(2, hEvent, false, Win32.INFINITE); switch (evt) { case 0: //return thread return; case 1: uint bytesRead; uint flags; Win32.POWER_BROADCAST pB = new Win32.POWER_BROADCAST(); if (Win32.ReadMsgQueue(hMsgQ, out pB, (uint)Marshal.SizeOf(typeof(Win32.POWER_BROADCAST)), out bytesRead, Win32.INFINITE, out flags)) { if (pB.Message == Win32.PBT_POWERINFOCHANGE && pB.PI.bACLineStatus != 0x01 && pB.PI.bBatteryLifePercent <= 5) { Win32.SetSystemPowerState(null, Win32.POWER_STATE_SUSPEND, Win32.POWER_FORCE); break; } OnPowerNotify(new PowerNotifyEventArgs(pB.PI.bACLineStatus, pB.PI.bBatteryLifePercent)); } break; } } } #endregion } }