2010年1月24日 星期日

CuPowerNotification - to register for power notification events.

// to register for power notification events.



// CuPowerNotification.h


class CuPowerNotification  
{
    HANDLE m_hRequestPowerNotifications;

    CuWinThread *m_pWinThread;

    CuMsgQueue m_MsgQueue;

public:
    virtual void OnPowerNotification(PPOWER_BROADCAST ppower_broadcast){};
    BOOL StopPowerNotifications();
    HANDLE RequestPowerNotifications(DWORD Flags = POWER_NOTIFY_ALL, wstring strMsgQueueName = L"");
    CuPowerNotification();
    virtual ~CuPowerNotification();


private:
    static DWORD Process(LPVOID lpVoid);

};


// CuPowerNotification.cpp


#define QUEUE_ENTRIES 3
#define QUEUE_SIZE ( QUEUE_ENTRIES * (sizeof(POWER_BROADCAST) + sizeof(POWER_BROADCAST_POWER_INFO)) )
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CuPowerNotification::CuPowerNotification()
:m_hRequestPowerNotifications(NULL)
,m_pWinThread(NULL)

{

}

CuPowerNotification::~CuPowerNotification()
{
    StopPowerNotifications();
}

HANDLE CuPowerNotification::RequestPowerNotifications(
DWORD Flags /* = POWER_NOTIFY_ALL */
, wstring strMsgQueueName /*= L""*/)
{

    StopPowerNotifications();

    MSGQUEUEOPTIONS MsgQueueOptions;

    memset(&MsgQueueOptions , 0, sizeof( MsgQueueOptions));
    
    MsgQueueOptions.dwSize = sizeof( MSGQUEUEOPTIONS );
    MsgQueueOptions.dwFlags = 0  ;
    MsgQueueOptions.dwMaxMessages = QUEUE_ENTRIES;
    MsgQueueOptions.cbMaxMessage =  QUEUE_SIZE;
    MsgQueueOptions.bReadAccess = TRUE ;
    //TCHAR *pszMsgQueue = strMsgQueueName.c_str();
    TCHAR szMsgQueueName[64] = L"";

    if( strMsgQueueName.empty() )
        wsprintf( szMsgQueueName, L"%x", (int)this );
    else
        wsprintf( szMsgQueueName, L"%s", strMsgQueueName.c_str());
    m_MsgQueue.CreateMsgQueue(szMsgQueueName, &MsgQueueOptions);

    m_hRequestPowerNotifications = ::RequestPowerNotifications(  m_MsgQueue, Flags );

    if( m_hRequestPowerNotifications )
        m_pWinThread = _BeginThread((_THREADPROC)CuPowerNotification::Process,
          (LPVOID)this);

    return m_hRequestPowerNotifications;

}

BOOL CuPowerNotification::StopPowerNotifications()
{

    if( m_pWinThread )
        m_pWinThread->Delete();

    m_pWinThread = NULL;

    return ::StopPowerNotifications(m_hRequestPowerNotifications);
}


DWORD CuPowerNotification::Process(LPVOID lpVoid)
{
    CuPowerNotification *pPowerNotification = (CuPowerNotification *)lpVoid;

    static BYTE buf[QUEUE_SIZE];
    static unsigned long nRead = 0;
    static unsigned long flags = 0;
    
    DWORD dwResult;
    while(1)
    {
        dwResult = WaitForSingleObject(pPowerNotification->m_MsgQueue, INFINITE);
        if( dwResult == WAIT_OBJECT_0 )
        {
            memset(&buf , 0, QUEUE_SIZE);
            dwResult = pPowerNotification->m_MsgQueue.ReadMsgQueue( 
            &buf, QUEUE_SIZE, &nRead, INFINITE, &flags);
            if( dwResult != FALSE )
                pPowerNotification->OnPowerNotification((PPOWER_BROADCAST)buf);
        }
    }

    return 0;
}

1 則留言:

  1. 這個東西看起來已經很複雜了, 如果CuMsgQueue 沒有封裝起來, 還真的不知道如何簡化複雜度.

    回覆刪除