The event db (it is my naming) holds all events and actions that can be invoked to launch an app or fire some events.
NotificationList
The tool shows all known notifications on a WM device. You can browse the event db and examine the defined events. Additionally, the tool shows power change notifications.
In the mid window above, you can see there is a timed event that will occur at 0:00 and start \windows\calupd.exe. This will wake your device all night and update the calendar entries for re-occurring schedules, etc.
The right window shows the power notifications on a suspend/resume cycle.
Using the options menu, you can save a list of the defined notification events.
There are different notification types:
public enum CeNotificationType
{
CNT_EVENT = 1,
CNT_TIME,
CNT_PERIOD,
CNT_CLASSICTIME
}
CeSetUserNotification
is spared here. This structure is used to display user notification bubbles on the screen.
The notification API enables you to setup notification for different events:
public enum CeNotificationEvent
{
NOTIFICATION_EVENT_NONE,
NOTIFICATION_EVENT_TIME_CHANGE,
NOTIFICATION_EVENT_SYNC_END,
NOTIFICATION_EVENT_ON_AC_POWER,
NOTIFICATION_EVENT_OFF_AC_POWER,
NOTIFICATION_EVENT_NET_CONNECT,
NOTIFICATION_EVENT_NET_DISCONNECT,
NOTIFICATION_EVENT_DEVICE_CHANGE,
NOTIFICATION_EVENT_IR_DISCOVERED,
NOTIFICATION_EVENT_RS232_DETECTED,
NOTIFICATION_EVENT_RESTORE_END,
NOTIFICATION_EVENT_WAKEUP,
NOTIFICATION_EVENT_TZ_CHANGE,
NOTIFICATION_EVENT_MACHINE_NAME_CHANGE,
NOTIFICATION_EVENT_RNDIS_FN_DETECTED,
NOTIFICATION_EVENT_INTERNET_PROXY_CHANGE,
NOTIFICATION_EVENT_LAST = NOTIFICATION_EVENT_INTERNET_PROXY_CHANGE
};
Please note that not all devices support all these types. As the names are more or less speaking names, I do not explain these event types any further.
If you want to add your own periodic, timed, application, you should look at my Tasker application.
PowerNotifications
Although not directly related to the above events db, it may also be good to know how you can subscribe to power notifications. The sample uses the MS PowerNotifications Message queue. When registering for the power messages, you can define a filter to get only power notification messages you are interested in.
const uint POWER_NOTIFY_ALL = 0xFFFFFFFF;
const uint PBT_TRANSITION = 0x00000001;
const uint PBT_RESUME = 0x00000002;
const uint PBT_POWERSTATUSCHANGE = 0x00000004;
const uint PBT_POWERINFOCHANGE = 0x00000008;
Every message comes with a data structure:
[StructLayout(LayoutKind.Sequential)]
struct POWER_BROADCAST
{
UInt32 dwMsg;
UInt32 dwFlags;
UInt32 dwLength;
string sSystemPowerState;
}
And we have a lot of flags to lookup:
[Flags]
enum PowerState:uint
{
POWER_STATE_NA = 0x00,
POWER_STATE_ON = 0x00010000,
POWER_STATE_OFF = 0x00020000,
POWER_STATE_CRITICAL = 0x00040000,
POWER_STATE_BOOT = 0x00080000,
POWER_STATE_IDLE = 0x00100000,
POWER_STATE_SUSPEND = 0x00200000,
POWER_STATE_UNATTENDED = 0x00400000,
POWER_STATE_RESET = 0x00800000,
POWER_STATE_USERIDLE = 0x01000000,
POWER_STATE_BACKLIGHTON = 0x02000000,
POWER_STATE_PASSWORD = 0x10000000,
}
[Flags]
enum PowerEventType
{
PBT_TRANSITION = 0x00000001,
PBT_RESUME = 0x00000002,
PBT_POWERSTATUSCHANGE = 0x00000004,
PBT_POWERINFOCHANGE = 0x00000008,
}
[Flags]
enum PowerState1
{
POWER_STATE_ON = (0x00010000),
POWER_STATE_OFF = (0x00020000),
POWER_STATE_CRITICAL = (0x00040000),
POWER_STATE_BOOT = (0x00080000),
POWER_STATE_IDLE = (0x00100000),
POWER_STATE_SUSPEND = (0x00200000),
POWER_STATE_RESET = (0x00800000),
}
And, of course, we need some P/Invoke:
#region DllImports
[DllImport("coredll.dll")]
private static extern IntPtr RequestPowerNotifications(IntPtr hMsgQ, uint Flags);
[DllImport("coredll.dll")]
private static extern uint WaitForSingleObject(IntPtr hHandle, int wait);
[DllImport("coredll.dll")]
private static extern IntPtr CreateMsgQueue(string name, ref MsgQOptions options);
[DllImport("coredll.dll")]
private static extern bool ReadMsgQueue(IntPtr hMsgQ, byte[] lpBuffer,
uint cbBufSize, ref uint lpNumRead, int dwTimeout, ref uint pdwFlags);
#endregion
The main work is done inside a thread function:
private void DoWork()
{
byte[] buf = new byte[10000];
uint nRead = 0, flags = 0, res = 0;
System.Diagnostics.Debug.WriteLine("starting loop");
try
{
while (!done)
{
res = WaitForSingleObject(ptr, 2500);
if (res == 0)
{
ReadMsgQueue(ptr, buf, (uint)buf.Length, ref nRead, -1, ref flags);
uint flag = ConvertByteArray(buf, 4);
string msg = "";
msg += ((PowerState)flag).ToString();
if (msg=="")
msg = "Unknown Flag: " + flag.ToString();
if (msg=="0")
msg = "POWER_STATE_NA";
if (msg != "")
{
if(OnMsg!=null)
OnMsg(this, new PwrEventArgs(msg, flag));
System.Diagnostics.Debug.WriteLine(msg);
}
}
}
}
catch (Exception ex)
{
if (!done)
{
System.Diagnostics.Debug.WriteLine("Got exception: " + ex);
}
}
System.Diagnostics.Debug.WriteLine("loop ended");
}
The sample code implements some event and delegates that you can subscribe to get power notification messages.
The source code is available via https://win-mobile-code.googlecode.com/svn/trunk/NotificationList/NotificationsList