cpc引流做网站cpa推广,贵州黔序科技有限公司,wordpress 工单,昆明网站快照优化公司本篇将以Windows Mobile为例介绍Windows CE电源管理的实现#xff0c;大体上#xff0c;Windows Mobile分为Pocket PC和Smartphone两种版本。这两者之间的主要区别在于触摸屏和电源模型#xff0c;Smartphone采用的是“Always On”模型。为了说清楚它们的区别#xff0c;我… 本篇将以Windows Mobile为例介绍Windows CE电源管理的实现大体上Windows Mobile分为Pocket PC和Smartphone两种版本。这两者之间的主要区别在于触摸屏和电源模型Smartphone采用的是“Always On”模型。为了说清楚它们的区别我们就先从系统电源状态说起吧这里有些系统电源状态是从WM5开始才有的。 1. Windows Mobile的系统电源状态 On用户与系统交互时的状态 BacklightOff在一段时间内默认15秒如果一直没有用户操作比如按下某个键或者触摸屏幕就关闭背光这时其他的设备都没变化。这个timeout值可以通过控制面板进行设置 UserIdle这个状态只在Smartphone中被使用。经过一段稍长的时间如果一直没有用户操作就关闭背光和LCD。这个timeout值可以通过控制面板进行设置 ScreenOff一般由某些程序指定才进入这个状态。比如音乐播放器程序当你听音乐时按下某个键可以将屏幕关闭。PocketPC和Smartphone都使用这个状态它与UserIdle的不同在于ScreenOff意味着“用户主动关闭了显示只有当他按下电源键时才重新显示”而UserIdle意味着“用户有段时间没操作了那么我们可以关闭屏幕来省电”所以在UserIdle时随便按下Smartphone的哪个键都会启动显示 Suspend这是PocketPC的睡眠模式几乎所有设备都被关闭直到某个硬件设备触发中断才将系统唤醒这个timeout值可以通过控制面板进行设置默认为3分钟 Resuming这是PocketPC被唤醒后的状态这时屏幕是关闭的并启动一个15秒的计时器在这段时间内决定接下来进入哪个状态如果计时器超时则重新回到睡眠状态 Unattended这个状态只在PocketPC中被使用用户对其不会有所察觉。有些程序如ActiveSync每5分钟会唤醒系统进行同步同步完成后再让系统继续睡眠这段时间不希望打扰用户即程序在后台执行。 可以通过注册表查看系统电源状态对应的具体设备的电源状态[HLM\System\CurrentControlSet\Control\Power\State]。 现在我们知道Smartphone没有真正的睡眠模式即使它会在一段时间后关闭背光和屏幕但它并没有睡着只是休息一下眼睛罢了它的大脑和四肢仍在正常工作。PocketPC所采用的模型比Smartphone要复杂的多你可以按下电源键让系统睡眠在必要时也可以唤醒系统做一些工作然后再继续睡眠。如果你在Smartphone上运行一个桌面精灵之类的程序她为了引起你的注意长时间的蹦啊跳啊不管白天还是黑夜可想而知你的待机时间将...... 你可能会觉得PocketPC的“Sleep”模型比Smartphone的“Always On”模型要省电其实恰恰相反。因为在系统睡眠的过程中它需要通知所有的设备驱动为了让它们保存一些重要的信息并关闭相应的硬件设备在系统被唤醒时也需要通知它们恢复先前的工作。这个过程不仅耗时还可能会耗更多的电因为一些设备在频繁的状态转换过程中会消耗比较多的能量。这也就是为什么当你收到一条短信时睡眠状态的PocketPC要花3到6秒的时间来处理而Smartphone只需要几个微秒:) 2. Windows Mobile的电源管理策略 我们可以用系统电源状态机来简单的描述Windows Mobile的电源管理策略以PocketPC为例系统电源状态机如下图所示 系统内部的电源管理器负责协调电源状态的转换电源状态的转换主要由一下几种方式触发 计时器超时SuspendTimeout和ResumingSuspendTimeout分别对应于第一节介绍Suspend和Resuming状态时所提到的计时器。细说起来它们每个又有两个值分别对应着电源供电时和电池供电时的超时值也就是注册表[HLM\System\CurrentControlSet\Control\Power\Timeout]中的ACSuspendTimeout、BattSuspendTimeout、ACResumingSuspendTimeout、BattResumingSuspendTimeout 系统调用驱动程序或应用程序通过相应的API请求进入某种电源状态。这类API在前面的文章中已经有所介绍如SetSystemPowerState、SetPowerRequirement、DevicePowerNotify等 平台相关的系统调用通过PowerPolicyNotify通知电源管理器发生了某个事件它的实现比较灵活驱动程序或应用程序可以通过相应的参数与电源管理器进行交互比如PPN_POWERCHANGE、PPN_SUSPENDKEYPRESSED、PPN_UNATTENDEDMODE等参见pmpolicy.h 直接访问内核对象事件Event作为Windows CE系统的内核对象可以通过事件名称在进程间共享因此我们可以访问电源管理器中的两个事件它们的名字分别是_T(PowerManager/ReloadActivityTimeouts)、_T(PowerManager/SystemIdleTimerReset)。如果你的程序需要动态修改那几个计时器的时间长度可以通过第一个事件通知电源管理器重新读取注册表中计时器的值而第二个事件与SystemIdleTimerReset功能一样可以阻止系统进入睡眠状态。 3. Windows Mobile电源管理相关API的应用 最后通过几个应用场景简单介绍一下常用的电源管理相关的API的使用 如果你在设计的是媒体播放器程序不希望在播放电影时系统自动转入Suspend状态这时可以每隔30秒调用一次SystemIdleTimerReset它会帮你重置那个计时器如果你还想同时保持背光那么可以调用SetPowerRequirement(TEXT(BKL1:), D0, POWER_NAME, NULL, 0);如果你提供一个按钮允许用户关闭屏幕那么调用SetSystemPowerState(NULL, POWER_STATE_IDLE, 0); 如果你在设计的是天气预报程序需要每天早上6点在线更新天气信息这时可以调用CeRunAppAtTime系统到时会被RTC中断唤醒还记得前面提到的那个15秒的计时器吗这时你的程序应该在15秒内请求进入Unattended状态否则系统将重新回到睡眠状态。在处理更新的过程中还是应该每隔30秒调用一次SystemIdleTimerReset在处理完更新后应该再次调用CeRunAppAtTime并放弃Unattended状态。请注意在电源管理器的实现代码中用了一个引用计数的变量gdwUnattendedModeRequests统计所有对Unattended状态的请求所以PowerPolicyNotify(PPN_UNATTENDEDMODE, TRUE);和PowerPolicyNotify(PPN_UNATTENDEDMODE, FALSE);要成对出现否则系统将无法回到睡眠状态。 如果你要开发一个监控电池状态的程序首先应该创建一个接收状态通知的线程在这个线程里调用RequestPowerNotifications这个函数的第一个参数是一个消息队列的句柄所以必须先创建一个消息队列CreateMsgQueue第二个参数是你希望得到的通知类型这里要用到的是PBT_POWERSTATUSCHANGE|PBT_POWERINFOCHANGE然后线程就可以等待通知了WaitForSingleObject一旦有通知到来线程通过ReadMsgQueue读取消息的内容再做些更新UI的工作。 相关示例代码//***************************************************************************// Function Name: PowerNotificationThread//// Purpose: listens for power change notifications//DWORD PowerNotificationThread(LPVOID pVoid){ // size of a POWER_BROADCAST message DWORD cbPowerMsgSize sizeof POWER_BROADCAST (MAX_PATH * sizeof TCHAR); // Initialize our MSGQUEUEOPTIONS structure MSGQUEUEOPTIONS mqo; mqo.dwSize sizeof(MSGQUEUEOPTIONS); mqo.dwFlags MSGQUEUE_NOPRECOMMIT; mqo.dwMaxMessages 4; mqo.cbMaxMessage cbPowerMsgSize; mqo.bReadAccess TRUE; // Create a message queue to receive power notifications HANDLE hPowerMsgQ CreateMsgQueue(NULL, mqo); if (NULL hPowerMsgQ) { RETAILMSG(1, (LCreateMsgQueue failed: %x\n, GetLastError())); goto Error; } // Request power notifications HANDLE hPowerNotifications RequestPowerNotifications(hPowerMsgQ, PBT_POWERSTATUSCHANGE | PBT_POWERINFOCHANGE); if (NULL hPowerNotifications) { RETAILMSG(1, (LRequestPowerNotifications failed: %x\n, GetLastError())); goto Error; } HANDLE rgHandles[2] {0}; rgHandles[0] hPowerMsgQ; rgHandles[1] g_hEventShutDown; // Wait for a power notification or for the app to exit while(WaitForMultipleObjects(2, rgHandles, FALSE, INFINITE) WAIT_OBJECT_0) { DWORD cbRead; DWORD dwFlags; POWER_BROADCAST *ppb (POWER_BROADCAST*) new BYTE[cbPowerMsgSize]; // loop through in case there is more than 1 msg while(ReadMsgQueue(hPowerMsgQ, ppb, cbPowerMsgSize, cbRead, 0, dwFlags)) { switch (ppb-Message) { case PBT_POWERINFOCHANGE: { RETAILMSG(1,(LPower Notification Message: PBT_POWERINFOCHANGE\n)); // PBT_POWERINFOCHANGE message embeds a // POWER_BROADCAST_POWER_INFO structure into the // SystemPowerState field PPOWER_BROADCAST_POWER_INFO ppbpi (PPOWER_BROADCAST_POWER_INFO) ppb-SystemPowerState; if (ppbpi) { RETAILMSG(1,(LLength: %d, ppb-Length)); RETAILMSG(1,(LBatteryLifeTime %d\n,ppbpi-dwBatteryLifeTime)); RETAILMSG(1,(LBatterFullLifeTime %d\n, ppbpi-dwBatteryFullLifeTime)); RETAILMSG(1,(LBackupBatteryLifeTime %d\n, ppbpi-dwBackupBatteryLifeTime)); RETAILMSG(1,(LBackupBatteryFullLifeTime %d\n, ppbpi-dwBackupBatteryFullLifeTime)); RETAILMSG(1,(LACLineStatus %d\n,ppbpi-bACLineStatus)); RETAILMSG(1,(LBatteryFlag %d\n,ppbpi-bBatteryFlag)); RETAILMSG(1,(LBatteryLifePercent %d\n, ppbpi-bBatteryLifePercent)); RETAILMSG(1,(LBackupBatteryFlag %d\n, ppbpi-bBackupBatteryFlag)); RETAILMSG(1,(LBackupBatteryLifePercent %d\n, ppbpi-bBackupBatteryLifePercent)); } break; } default: break; } UpdateUI(); } delete[] ppb; }Error: if (hPowerNotifications) StopPowerNotifications(hPowerNotifications); if (hPowerMsgQ) CloseMsgQueue(hPowerMsgQ); return NULL;} * 原创文章转载请注明出处转载于:https://www.cnblogs.com/jasonye/archive/2008/03/06/1094213.html