//========================================================================
//TITLE:
// CPowerThread更新至v1.1.0
//AUTHOR:
// norains
//DATE:
// Tuesday 25-December-2007
//Environment:
// EVC4.0 + Windows CE 5.0 Standard SDK
// EVC4.0 + SDK-WINCE5.0-MIPSII
// VS2005 + SDK-WINCE5.0-MIPSII
//========================================================================
相对于v1.0.0版本,有如下变动:
1.去掉GetInstance()函数,不用获取对象实例,可以直接声明对象实例使用
2.改进该类以令其在继承之后能正常工作.
3.增加OnNotifyPower()函数,可以不设置回调函数而通过重载该函数监视电源的变化.
v1.0.0版本:http://blog.csdn.net/norains/archive/2007/07/20/1700980.aspx
/////////////////////////////////////////////////////////////////////
/
//
PowerThread.h: interface for the CPowerThread class.
//
//
Version:
//
1.1.0
//
Date:
//
2007.11.15
/////////////////////////////////////////////////////////////////////
/
#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
:
BOOL ResumnSign();
//
Not support now
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);
CPowerThread();
virtual
~
CPowerThread();
protected
:
virtual
void
OnNotifyPower(PowerStatusType powStatus,
int
iBatteryPercent);
//
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); }
private
:
PowerStatusType GetPowerStatus(PPOWER_BROADCAST pPowerInfo,
int
*
piPercent);
static
DWORD WINAPI PowerThread(PVOID pArg);
BOOL m_bExitThread;
ULONG m_ulWaitTime;
BOOL m_bRunning;
CRITICAL_SECTION 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 1000
//
1000ms
//
----------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////
/
//
Construction/Destruction
/////////////////////////////////////////////////////////////////////
/
CPowerThread::CPowerThread():
m_bExitThread(TRUE),
m_ulWaitTime(DEFAULT_TIMEOUT),
m_bRunning(FALSE),
m_pNotifyPower(NULL)
{
InitLock();
}
CPowerThread::
~
CPowerThread()
{
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)
{
CPowerThread
*
pObject
=
(CPowerThread
*
) pArg;
pObject
->
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
(pObject
->
m_bExitThread
==
FALSE)
{
DWORD dwWaitCode
=
MsgWaitForMultipleObjectsEx(
1
, rghWaits, pObject
->
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
=
pObject
->
GetPowerStatus(ppb,
&
iPowPercent);
pObject
->
LockThis();
if
(pObject
->
m_pNotifyPower
!=
NULL)
{
pObject
->
m_pNotifyPower(powStatus,iPowPercent);
}
pObject
->
OnNotifyPower(powStatus,iPowPercent);
pObject
->
UnLockThis();
}
else
{
//
We should never get here
break
;
}
}
}
pObject
->
m_bRunning
=
FALSE;
return
0
;
}
//
------------------------------------------------------------------
//
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,(
void
*
)
this
,
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();
}
//
------------------------------------------------------------------
//
Description:
//
Resumn the sign order to get the current power status,or the power
//
status will return untill the power status changed.
//
------------------------------------------------------------------
BOOL CPowerThread::ResumnSign()
{
/*
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 FALSE;
}
// Request notifications
HANDLE hReq = RequestPowerNotifications(rghWaits[0], PBT_POWERINFOCHANGE);
if (!hReq)
{
CloseHandle( rghWaits[ 0 ] );
//erro
return FALSE;
}
return TRUE;
*/
return
FALSE;
}
//
------------------------------------------------------------------
//
Description:
//
Notify the power. It's used as call back funtion.
//
------------------------------------------------------------------
void
CPowerThread::OnNotifyPower(PowerStatusType powStatus,
int
iBatteryPercent)
{
return
;
}