반응형
Xeno's Study Blog (http://XenoStudy.tistory.com )
- 글쓴이 : Xeno
- 출처 : 인터넷
- 기타사항 : windows Mobile 에만 해당되는 사항임. 테스트완료
windows Mobile 의 경우 여러가지 power State 가 존재한다.
드라이버/App 모두 각 pwer State 마다 해줘야할 작업이 따로 있다고 하면 아래와 같은 코드로 간단히 event를 받아서 처리를 할수있다.
관련 MSDN
- RequestPowerNotifications() : http://msdn.microsoft.com/en-us/library/ms919833.aspx
#include <windows.h> #include <PM.h> // from pmimpl.h file. #ifndef QUEUE_ENTRIES #define QUEUE_ENTRIES 3 #endif #ifndef MAX_NAMELEN #define MAX_NAMELEN 128 #endif #ifndef QUEUE_SIZE #define QUEUE_SIZE (QUEUE_ENTRIES * (sizeof(POWER_BROADCAST) + (MAX_NAMELEN * sizeof(TCHAR)))) #endif int WINAPI PMNotifyThread(LPVOID pvParam); void PMNotification(HANDLE hMsgQ); HANDLE ghPMNotifyQ = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { MSGQUEUEOPTIONS msgQpm = {0}; HANDLE hPwrNotify=NULL; // Power manager handle HANDLE hPMThread=NULL; // create a message queue for Power Manager notifications msgQpm.dwSize = sizeof(MSGQUEUEOPTIONS); msgQpm.dwFlags = 0; msgQpm.dwMaxMessages = QUEUE_ENTRIES; msgQpm.cbMaxMessage = sizeof(POWER_BROADCAST) + MAX_NAMELEN; msgQpm.bReadAccess = TRUE; ghPMNotifyQ= CreateMsgQueue(NULL, &msgQpm); if (ghPMNotifyQ == NULL) { DWORD dwErr = GetLastError(); RETAILMSG(1, (TEXT(" PMNotify:CreateMessageQueue ERROR:%d \r\n"), dwErr)); return 1; } // request Power notifications hPwrNotify = RequestPowerNotifications(ghPMNotifyQ, PBT_TRANSITION | PBT_RESUME); if (hPwrNotify == NULL) { DWORD dwErr = GetLastError(); RETAILMSG(1, (TEXT(" PMNotify:RequestPowerNotifications ERROR:%d\r\n"), dwErr)); return 2; } // Create PMNotifyThread hPMThread = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE )PMNotifyThread, NULL, 0, NULL); if(hPMThread) { // wait for PMNotifyThread done WaitForSingleObject(hPMThread, INFINITE); CloseHandle(hPMThread); if(hPwrNotify) { StopPowerNotifications(hPwrNotify); } } return 0; } // PMNotifyThread: Wait for Message from PM Driver. // int WINAPI PMNotifyThread(LPVOID pvParam) { DWORD dwStatus; while (TRUE) { dwStatus = WaitForSingleObject(ghPMNotifyQ, INFINITE); if(dwStatus == WAIT_OBJECT_0) { PMNotification(ghPMNotifyQ); } else { RETAILMSG(1, (TEXT(" PMNotify: WaitForSingleObject returned %d(error %d)\r\n"),dwStatus, GetLastError())); break; } } return 0; } void PMNotification(HANDLE hMsgQ) { UCHAR pmbuf[QUEUE_SIZE]; int nBytesRead=0; DWORD dwFlags = 0; int dwCount = 0; memset(pmbuf, 0, sizeof(pmbuf)); if ( !ReadMsgQueue(hMsgQ, pmbuf, QUEUE_SIZE, (LPDWORD)&nBytesRead, INFINITE, // Timeout &dwFlags)) { DWORD dwErr = GetLastError(); RETAILMSG(1, (TEXT(" ProcessPowerNotification: ReadMsgQueue:ERROR:%d\n"), dwErr)); } else if(nBytesRead >= sizeof(POWER_BROADCAST)) { // process power notifications //----------------------------- PPOWER_BROADCAST pPB = (PPOWER_BROADCAST) pmbuf; switch (pPB->Message) { case PBT_RESUME: RETAILMSG(1, (TEXT(" PMNotify:PBT_RESUME \r\n"))); break; case PBT_POWERSTATUSCHANGE: RETAILMSG(1, (TEXT(" PMNotify:PBT_POWERSTATUSCHANGE: \r\n"))); break; case PBT_POWERINFOCHANGE: RETAILMSG(1, (TEXT(" PMNotify:PBT_POWERSTATUSCHANGE: \r\n"))); break; case PBT_TRANSITION: { switch (POWER_STATE(pPB->Flags)) { case POWER_STATE_ON: break; case POWER_STATE_OFF: break; case POWER_STATE_CRITICAL: break; case POWER_STATE_BOOT: break; case POWER_STATE_IDLE: break; case POWER_STATE_SUSPEND: break; case POWER_STATE_RESET: break; default: break; } break; } default: break; } } }
반응형