How can I run code on Windows Mobile while being suspended?
I'd like to run some C++ code while the Windows Mobile PocketPC is (or seems) being suspended. An example what I mean is the HTC Home plugin that shows (among others) a tab where the HTC Audio Manager can be used to play back mp3 files. When I press the on/off button, the display goes black, but the audio keeps playing. The only button to switch back on is the on/off button, as expected.
What I tried so far is to capture hardware button presses (works) and switch off the video display (works). What doesn't work with this approach is that when (accidentally) pressing any key on the device, the video display is switched on. I think this isn't the approach taken in the HTC Audio Manager.
I'm guessing on some low-level API magic for this to work, or that the code to play back audio runs at some interrupt level, or the device goes into a different suspend mode.
I found sourcecode on the xda-developers forum that explains what to do, and it works as thought. The main points are:
- Set the device to send a notification when going into "unattended" mode. This is done with PowerPolicyNotify(PPN_UNATTENDEDMODE, TRUE)
- For every device that you need during unattended mode, call SetPowerRequirement(L"gpd0:", D0, POWER_NAME|POWER_FORCE, NULL, NULL); The "gpd0:" device is the GPS Intermediate driver; replace or duplicate call with any device you need, e.g. "wav1:" for audio, "dsk1:" for memory card or "com1:" for serial port 1.
- Create a message queue and request power notifications using RequestPowerNotifications(hMsgQueue, PBT_POWERINFOCHANGE | PBT_TRANSITION)
- Every time a power notification is sent, the message queue is filled with a struct of type POWER_BROADCAST.
- Look for PBT_TRANSITION message type. The field pPwrBrodcast->SystemPowerState then contains a string "unattended" when the device is shut off, e.g. by the user pressing the off button
- In this transition, just call SystemIdleTimerReset() to tell the device to not shut off
- Repeat when the transition occurs again
- When shutting down, call PowerPolicyNotify() to leave unattended mode, release any devices with ReleasePowerRequirement() and stop receiving power notifications with StopPowerNotifications().
At first have a look at this blog entry in order to understand the various power states. What you basically need is to force the ScreenOff state. Have a look at the SetSystemPowerState function.