//========================================================================
//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();
}