WinCE实时获取电源状态变化

//========================================================================
//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();
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值