//========================================================================
//TITLE:
// WinCE实时获取电源状态变化
//AUTHOR:
// norains
//DATE:
// Friday 20-July-2007
//Environment:
// EVC4.0 + Windows CE 5.0 Standard SDK
//========================================================================
使用CTpowerThread很简单实现实时获取电源的状态.在该类的内部创建了一个获取电量的线程,只要设置好回调函数,就可以自动接收设定间隔的电源状态.
现在我们来看看该类的具体操作方法:
//获取类的实例
CPowerThread *pPowThrd = CPowerThread::GetInstance();
if(pPowThrd != NULL)
{
//设置回调函数
pPowThrd->SetCallbackFunction(NotifyPowerStatus);
//启动线程,开始捕抓电量
pPowThrd->StartCapture();
}
这段代码中最重要的是设置回调函数,该函数的声明如下:
void NotifyPowerStatus(PowerStatusType powStatus, int iBatteryPercent)
powStatus是电源的简易状态,分为七个部分,取值为其中之一:
POW_UNKNOW, //Unknow the status
POW_CHARGING, //It's charging now
POW_CHARGEFULL, //Full charge
POW_VLOW, //The battery level is very low
POW_LOW,
POW_NORMAL,
POW_HIGH,
iBatteryPercent为当前电源的百分比,取值为:0~1.
下面给出一个回调函数的样例代码:
void NotifyPowerStatus(PowerStatusType powStatus, int iBatteryPercent)
{
switch(powStatus)
{
case POW_UNKNOW:
//当前状态不明
break;
case POW_CHARGING:
//充电中
break;
case POW_VLOW:
//电池电量非常低
break;
...
}
}
再来看看该类的其它接口函数:
SetWaitTime(ULONG ulTime)
该函数设置线程的超时时间.如果设置为INFINITE,则只有当电源状态有变化时才会调用回调函数.
GetCallbackFunction(void (* *pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent))
获取已设置的回调函数的指针
StopCapture()
停止线程.如果超时时间设为为INFINITE,则只有获取下次电源状态后才退出.
GetRunStatus()
获取当前线程的运行状态.
以下为该CPowerthread的完整源码:
源代码的具体原理可参考此篇文章:<EVC获取电源属性>http://blog.csdn.net/norains/archive/2006/09/07/1189157.aspx
/ /
// PowerThread.h: interface for the CPowerThread class.
//
// Version:
// 1.0.1
// Date:
// 2007.07.20
/ /
#ifndef POWERTHREAD_H
#define POWERTHREAD_H
#include " Pm.h "
// -----------------------------------------------------------------
// Enum data type
enum PowerStatusType
{
POW_UNKNOW, // Unknow the status
POW_CHARGING, // It's charging now
POW_CHARGEFULL, // Full charge
POW_VLOW, // The battery level is very low
POW_LOW,
POW_NORMAL,
POW_HIGH,
POW_VHIGH // The battery level is very high
};
// ----------------------------------------------------------------
class CPowerThread
{
public :
void GetCallbackFunction( void ( * * pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent));
void SetCallbackFunction( void ( * pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent));
void StopCapture();
BOOL StartCapture();
BOOL GetRunStatus();
void SetTimeout(ULONG ulTime);
static CPowerThread * GetInstance();
virtual ~ CPowerThread();
protected :
CPowerThread();
PowerStatusType GetPowerStatus(PPOWER_BROADCAST pPowerInfo, int * piPercent);
static DWORD WINAPI PowerThread(PVOID pArg);
static CPowerThread * m_pInstance;
BOOL m_bExitThread;
ULONG m_ulWaitTime;
BOOL m_bRunning;
CRITICAL_SECTION m_csLock;
// The critical section function
inline void InitLock() { InitializeCriticalSection( & m_csLock); }
inline void LockThis() { EnterCriticalSection( & m_csLock); }
inline void UnLockThis() { LeaveCriticalSection( & m_csLock); }
inline void DelLock() { DeleteCriticalSection( & m_csLock); }
// This is for callback function.
void ( * m_pNotifyPower)(PowerStatusType powStatus, int iBatteryPercent);
};
#endif // #ifndef POWERTHREAD_H
/ /
// PowerThread.cpp: implementation of the CPowerThread class.
//
/ /
#include " stdafx.h "
#include " PowerThread.h "
#include " Msgqueue.h "
// --------------------------------------------------------------------
// Macro define
#define DEFAULT_TIMEOUT 1000ms // 1000ms
// ---------------------------------------------------------------------
// Initialize
CPowerThread * CPowerThread::m_pInstance = NULL;
// ----------------------------------------------------------------------
/ /
// Construction/Destruction
/ /
CPowerThread::CPowerThread():
m_bExitThread(TRUE),
m_ulWaitTime(DEFAULT_TIMEOUT),
m_bRunning(FALSE),
m_pNotifyPower(NULL)
{
InitLock();
}
CPowerThread:: ~ CPowerThread()
{
if (m_pInstance != NULL)
{
delete m_pInstance;
m_pInstance = NULL;
}
DelLock();
}
// ------------------------------------------------------------------
// Description:
// Get the level of power from the PPOWER_BROADCAST struct
//
// Parameters:
// pPowerInfo:[in] The struct includes the power information
// piPercent:[out] The battery life percent.
//
// Return Values:
// The power status
// ----------------------------------------------------------------
PowerStatusType CPowerThread::GetPowerStatus(PPOWER_BROADCAST pPowerInfo, int * piPercent)
{
PowerStatusType powStatus = POW_UNKNOW;
if ( ! pPowerInfo )
{
return POW_UNKNOW;
}
PPOWER_BROADCAST_POWER_INFO ppbpi = (PPOWER_BROADCAST_POWER_INFO) pPowerInfo -> SystemPowerState;
if ( ! ppbpi )
{
return POW_UNKNOW;
}
* piPercent = ppbpi -> bBatteryLifePercent;
if (ppbpi -> bACLineStatus == AC_LINE_ONLINE)
{
if (ppbpi -> bBatteryFlag == BATTERY_FLAG_CHARGING)
{
// Charging
powStatus = POW_CHARGING;
}
else
{
// May be full charging,or may be no battery
powStatus = POW_CHARGEFULL;
}
}
else
{
// Use battery
if ( 0 <= ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 20 )
{
powStatus = POW_VLOW;
}
else if ( 20 < ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 40 )
{
powStatus = POW_LOW;
}
else if ( 40 < ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 60 )
{
powStatus = POW_NORMAL;
}
else if ( 60 < ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 80 )
{
powStatus = POW_HIGH;
}
else if ( 80 < ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 100 )
{
powStatus = POW_VHIGH;
}
else
{
powStatus = POW_UNKNOW;
}
}
return powStatus;
}
// ------------------------------------------------------------------
// Description:
// Thread to get the power status
// ----------------------------------------------------------------
DWORD WINAPI CPowerThread::PowerThread(PVOID pArg)
{
m_pInstance -> m_bRunning = TRUE;
BYTE pbMsgBuf[ sizeof (POWER_BROADCAST) + sizeof (POWER_BROADCAST_POWER_INFO)];
PPOWER_BROADCAST ppb = (PPOWER_BROADCAST) pbMsgBuf;
MSGQUEUEOPTIONS msgopts;
// Create our message queue
memset( & msgopts, 0 , sizeof (msgopts));
msgopts.dwSize = sizeof (msgopts);
msgopts.dwFlags = 0 ;
msgopts.dwMaxMessages = 0 ;
msgopts.cbMaxMessage = sizeof (pbMsgBuf);
msgopts.bReadAccess = TRUE;
HANDLE rghWaits[ 1 ] = { NULL };
rghWaits[ 0 ] = CreateMsgQueue(NULL, & msgopts);
if ( ! rghWaits[ 0 ])
{
// erro
return 0x10 ;
}
HANDLE hReq = NULL;
// Request notifications
hReq = RequestPowerNotifications(rghWaits[ 0 ], PBT_POWERINFOCHANGE);
if ( ! hReq)
{
CloseHandle( rghWaits[ 0 ] );
// erro
return 0x15 ;
}
while (m_pInstance -> m_bExitThread == FALSE)
{
DWORD dwWaitCode = MsgWaitForMultipleObjectsEx( 1 , rghWaits, m_pInstance -> m_ulWaitTime, QS_ALLINPUT, MWMO_INPUTAVAILABLE );
if ( dwWaitCode == WAIT_OBJECT_0 )
{
DWORD dwSize, dwFlags;
BOOL bReadResult = ReadMsgQueue(rghWaits[ 0 ], ppb, sizeof (pbMsgBuf), & dwSize, 0 , & dwFlags);
if (bReadResult == TRUE)
{
int iPowPercent;
PowerStatusType powStatus = m_pInstance -> GetPowerStatus(ppb, & iPowPercent);
m_pInstance -> LockThis();
if (m_pInstance -> m_pNotifyPower != NULL)
{
m_pInstance -> m_pNotifyPower(powStatus,iPowPercent);
}
m_pInstance -> UnLockThis();
}
else
{
// We should never get here
break ;
}
}
}
m_pInstance -> m_bRunning = FALSE;
return 0 ;
}
// ------------------------------------------------------------------
// Description:
// Get instance
// ----------------------------------------------------------------
CPowerThread * CPowerThread::GetInstance()
{
if (m_pInstance == NULL)
{
m_pInstance = new CPowerThread();
}
return m_pInstance;
}
// ------------------------------------------------------------------
// Description:
// Set the timeout for the wait thread. It is only for the MsgWaitForMultipleObjectsEx()
// The default value is DEFAULT_TIMEOUT
// ----------------------------------------------------------------
void CPowerThread::SetTimeout(ULONG ulTime)
{
m_ulWaitTime = ulTime;
}
// ------------------------------------------------------------------
// Description:
// Get the status of thread
//
// Return Values:
// TRUE: The thread is running for capturing the power status.
// FALSE: No thread running.
// ----------------------------------------------------------------
BOOL CPowerThread::GetRunStatus()
{
return m_bRunning;
}
// ------------------------------------------------------------------
// Description:
// start capturing the power status.If there is thread running,
// it will return FALSE;
//
// ------------------------------------------------------------------
BOOL CPowerThread::StartCapture()
{
if (m_bRunning == TRUE)
{
return FALSE;
}
m_bExitThread = FALSE;
// Create the thread for batter sampled
DWORD dwPwrThdID;
HANDLE hdThrd = CreateThread(NULL, 0 ,PowerThread,NULL, 0 , & dwPwrThdID);
if (hdThrd == NULL)
{
return FALSE;
}
CloseHandle(hdThrd);
return TRUE;
}
// -----------------------------------------------------------------------------
// Description:
// Stop capturing.
//
// --------------------------------------------------------------------------------
void CPowerThread::StopCapture()
{
m_bExitThread = TRUE;
}
// ------------------------------------------------------------------
// Description:
// Set the callback function for receive the power status
// ------------------------------------------------------------------
void CPowerThread::SetCallbackFunction( void ( * pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent))
{
LockThis();
m_pNotifyPower = pCallbackFunc;
UnLockThis();
}
// ------------------------------------------------------------------
// Description:
// Get the callback function
// ------------------------------------------------------------------
void CPowerThread::GetCallbackFunction( void ( * * pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent))
{
LockThis();
* pCallbackFunc = m_pNotifyPower;
UnLockThis();
}
//TITLE:
// WinCE实时获取电源状态变化
//AUTHOR:
// norains
//DATE:
// Friday 20-July-2007
//Environment:
// EVC4.0 + Windows CE 5.0 Standard SDK
//========================================================================
使用CTpowerThread很简单实现实时获取电源的状态.在该类的内部创建了一个获取电量的线程,只要设置好回调函数,就可以自动接收设定间隔的电源状态.
现在我们来看看该类的具体操作方法:
//获取类的实例
CPowerThread *pPowThrd = CPowerThread::GetInstance();
if(pPowThrd != NULL)
{
//设置回调函数
pPowThrd->SetCallbackFunction(NotifyPowerStatus);
//启动线程,开始捕抓电量
pPowThrd->StartCapture();
}
这段代码中最重要的是设置回调函数,该函数的声明如下:
void NotifyPowerStatus(PowerStatusType powStatus, int iBatteryPercent)
powStatus是电源的简易状态,分为七个部分,取值为其中之一:
POW_UNKNOW, //Unknow the status
POW_CHARGING, //It's charging now
POW_CHARGEFULL, //Full charge
POW_VLOW, //The battery level is very low
POW_LOW,
POW_NORMAL,
POW_HIGH,
iBatteryPercent为当前电源的百分比,取值为:0~1.
下面给出一个回调函数的样例代码:
void NotifyPowerStatus(PowerStatusType powStatus, int iBatteryPercent)
{
switch(powStatus)
{
case POW_UNKNOW:
//当前状态不明
break;
case POW_CHARGING:
//充电中
break;
case POW_VLOW:
//电池电量非常低
break;
...
}
}
再来看看该类的其它接口函数:
SetWaitTime(ULONG ulTime)
该函数设置线程的超时时间.如果设置为INFINITE,则只有当电源状态有变化时才会调用回调函数.
GetCallbackFunction(void (* *pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent))
获取已设置的回调函数的指针
StopCapture()
停止线程.如果超时时间设为为INFINITE,则只有获取下次电源状态后才退出.
GetRunStatus()
获取当前线程的运行状态.
以下为该CPowerthread的完整源码:
源代码的具体原理可参考此篇文章:<EVC获取电源属性>http://blog.csdn.net/norains/archive/2006/09/07/1189157.aspx
/ /
// PowerThread.h: interface for the CPowerThread class.
//
// Version:
// 1.0.1
// Date:
// 2007.07.20
/ /
#ifndef POWERTHREAD_H
#define POWERTHREAD_H
#include " Pm.h "
// -----------------------------------------------------------------
// Enum data type
enum PowerStatusType
{
POW_UNKNOW, // Unknow the status
POW_CHARGING, // It's charging now
POW_CHARGEFULL, // Full charge
POW_VLOW, // The battery level is very low
POW_LOW,
POW_NORMAL,
POW_HIGH,
POW_VHIGH // The battery level is very high
};
// ----------------------------------------------------------------
class CPowerThread
{
public :
void GetCallbackFunction( void ( * * pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent));
void SetCallbackFunction( void ( * pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent));
void StopCapture();
BOOL StartCapture();
BOOL GetRunStatus();
void SetTimeout(ULONG ulTime);
static CPowerThread * GetInstance();
virtual ~ CPowerThread();
protected :
CPowerThread();
PowerStatusType GetPowerStatus(PPOWER_BROADCAST pPowerInfo, int * piPercent);
static DWORD WINAPI PowerThread(PVOID pArg);
static CPowerThread * m_pInstance;
BOOL m_bExitThread;
ULONG m_ulWaitTime;
BOOL m_bRunning;
CRITICAL_SECTION m_csLock;
// The critical section function
inline void InitLock() { InitializeCriticalSection( & m_csLock); }
inline void LockThis() { EnterCriticalSection( & m_csLock); }
inline void UnLockThis() { LeaveCriticalSection( & m_csLock); }
inline void DelLock() { DeleteCriticalSection( & m_csLock); }
// This is for callback function.
void ( * m_pNotifyPower)(PowerStatusType powStatus, int iBatteryPercent);
};
#endif // #ifndef POWERTHREAD_H
/ /
// PowerThread.cpp: implementation of the CPowerThread class.
//
/ /
#include " stdafx.h "
#include " PowerThread.h "
#include " Msgqueue.h "
// --------------------------------------------------------------------
// Macro define
#define DEFAULT_TIMEOUT 1000ms // 1000ms
// ---------------------------------------------------------------------
// Initialize
CPowerThread * CPowerThread::m_pInstance = NULL;
// ----------------------------------------------------------------------
/ /
// Construction/Destruction
/ /
CPowerThread::CPowerThread():
m_bExitThread(TRUE),
m_ulWaitTime(DEFAULT_TIMEOUT),
m_bRunning(FALSE),
m_pNotifyPower(NULL)
{
InitLock();
}
CPowerThread:: ~ CPowerThread()
{
if (m_pInstance != NULL)
{
delete m_pInstance;
m_pInstance = NULL;
}
DelLock();
}
// ------------------------------------------------------------------
// Description:
// Get the level of power from the PPOWER_BROADCAST struct
//
// Parameters:
// pPowerInfo:[in] The struct includes the power information
// piPercent:[out] The battery life percent.
//
// Return Values:
// The power status
// ----------------------------------------------------------------
PowerStatusType CPowerThread::GetPowerStatus(PPOWER_BROADCAST pPowerInfo, int * piPercent)
{
PowerStatusType powStatus = POW_UNKNOW;
if ( ! pPowerInfo )
{
return POW_UNKNOW;
}
PPOWER_BROADCAST_POWER_INFO ppbpi = (PPOWER_BROADCAST_POWER_INFO) pPowerInfo -> SystemPowerState;
if ( ! ppbpi )
{
return POW_UNKNOW;
}
* piPercent = ppbpi -> bBatteryLifePercent;
if (ppbpi -> bACLineStatus == AC_LINE_ONLINE)
{
if (ppbpi -> bBatteryFlag == BATTERY_FLAG_CHARGING)
{
// Charging
powStatus = POW_CHARGING;
}
else
{
// May be full charging,or may be no battery
powStatus = POW_CHARGEFULL;
}
}
else
{
// Use battery
if ( 0 <= ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 20 )
{
powStatus = POW_VLOW;
}
else if ( 20 < ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 40 )
{
powStatus = POW_LOW;
}
else if ( 40 < ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 60 )
{
powStatus = POW_NORMAL;
}
else if ( 60 < ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 80 )
{
powStatus = POW_HIGH;
}
else if ( 80 < ppbpi -> bBatteryLifePercent && ppbpi -> bBatteryLifePercent <= 100 )
{
powStatus = POW_VHIGH;
}
else
{
powStatus = POW_UNKNOW;
}
}
return powStatus;
}
// ------------------------------------------------------------------
// Description:
// Thread to get the power status
// ----------------------------------------------------------------
DWORD WINAPI CPowerThread::PowerThread(PVOID pArg)
{
m_pInstance -> m_bRunning = TRUE;
BYTE pbMsgBuf[ sizeof (POWER_BROADCAST) + sizeof (POWER_BROADCAST_POWER_INFO)];
PPOWER_BROADCAST ppb = (PPOWER_BROADCAST) pbMsgBuf;
MSGQUEUEOPTIONS msgopts;
// Create our message queue
memset( & msgopts, 0 , sizeof (msgopts));
msgopts.dwSize = sizeof (msgopts);
msgopts.dwFlags = 0 ;
msgopts.dwMaxMessages = 0 ;
msgopts.cbMaxMessage = sizeof (pbMsgBuf);
msgopts.bReadAccess = TRUE;
HANDLE rghWaits[ 1 ] = { NULL };
rghWaits[ 0 ] = CreateMsgQueue(NULL, & msgopts);
if ( ! rghWaits[ 0 ])
{
// erro
return 0x10 ;
}
HANDLE hReq = NULL;
// Request notifications
hReq = RequestPowerNotifications(rghWaits[ 0 ], PBT_POWERINFOCHANGE);
if ( ! hReq)
{
CloseHandle( rghWaits[ 0 ] );
// erro
return 0x15 ;
}
while (m_pInstance -> m_bExitThread == FALSE)
{
DWORD dwWaitCode = MsgWaitForMultipleObjectsEx( 1 , rghWaits, m_pInstance -> m_ulWaitTime, QS_ALLINPUT, MWMO_INPUTAVAILABLE );
if ( dwWaitCode == WAIT_OBJECT_0 )
{
DWORD dwSize, dwFlags;
BOOL bReadResult = ReadMsgQueue(rghWaits[ 0 ], ppb, sizeof (pbMsgBuf), & dwSize, 0 , & dwFlags);
if (bReadResult == TRUE)
{
int iPowPercent;
PowerStatusType powStatus = m_pInstance -> GetPowerStatus(ppb, & iPowPercent);
m_pInstance -> LockThis();
if (m_pInstance -> m_pNotifyPower != NULL)
{
m_pInstance -> m_pNotifyPower(powStatus,iPowPercent);
}
m_pInstance -> UnLockThis();
}
else
{
// We should never get here
break ;
}
}
}
m_pInstance -> m_bRunning = FALSE;
return 0 ;
}
// ------------------------------------------------------------------
// Description:
// Get instance
// ----------------------------------------------------------------
CPowerThread * CPowerThread::GetInstance()
{
if (m_pInstance == NULL)
{
m_pInstance = new CPowerThread();
}
return m_pInstance;
}
// ------------------------------------------------------------------
// Description:
// Set the timeout for the wait thread. It is only for the MsgWaitForMultipleObjectsEx()
// The default value is DEFAULT_TIMEOUT
// ----------------------------------------------------------------
void CPowerThread::SetTimeout(ULONG ulTime)
{
m_ulWaitTime = ulTime;
}
// ------------------------------------------------------------------
// Description:
// Get the status of thread
//
// Return Values:
// TRUE: The thread is running for capturing the power status.
// FALSE: No thread running.
// ----------------------------------------------------------------
BOOL CPowerThread::GetRunStatus()
{
return m_bRunning;
}
// ------------------------------------------------------------------
// Description:
// start capturing the power status.If there is thread running,
// it will return FALSE;
//
// ------------------------------------------------------------------
BOOL CPowerThread::StartCapture()
{
if (m_bRunning == TRUE)
{
return FALSE;
}
m_bExitThread = FALSE;
// Create the thread for batter sampled
DWORD dwPwrThdID;
HANDLE hdThrd = CreateThread(NULL, 0 ,PowerThread,NULL, 0 , & dwPwrThdID);
if (hdThrd == NULL)
{
return FALSE;
}
CloseHandle(hdThrd);
return TRUE;
}
// -----------------------------------------------------------------------------
// Description:
// Stop capturing.
//
// --------------------------------------------------------------------------------
void CPowerThread::StopCapture()
{
m_bExitThread = TRUE;
}
// ------------------------------------------------------------------
// Description:
// Set the callback function for receive the power status
// ------------------------------------------------------------------
void CPowerThread::SetCallbackFunction( void ( * pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent))
{
LockThis();
m_pNotifyPower = pCallbackFunc;
UnLockThis();
}
// ------------------------------------------------------------------
// Description:
// Get the callback function
// ------------------------------------------------------------------
void CPowerThread::GetCallbackFunction( void ( * * pCallbackFunc)(PowerStatusType powStatus, int iBatteryPercent))
{
LockThis();
* pCallbackFunc = m_pNotifyPower;
UnLockThis();
}