WinCE实时获取电源状态变化

来源:互联网 发布:海洛因是有多爽 知乎 编辑:程序博客网 时间:2024/05/16 10:14
 //========================================================================
//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();
}
原创粉丝点击