Hail all!
I want to display notification and play custom sound on my Windows Mobile 5/6 device.
I have tried something like that, but my custom sound does not play, though message is displayed with standart sound.
If i edit Wave key in [HKEY_CURRENT_USER\ControlPanel\Notifications{15F11F90-8A5F-454c-89FC-BA9B7AAB0CAD}] to sound file i need then it plays okay.
But why there are flag NotificationAction.Sound and property UserNotification.Sound? It doesn't work. Also Vibration and Led don't work, if i use such flags.
(You can obtain full project sources from http://dl.dropbox.com/u/1758206/Code/Thunder.zip)
var trigger = new UserNotificationTrigger
{
StartTime = DateTime.Now + TimeSpan.FromSeconds(1),
Type = NotificationType.ClassicTime
};
var userNotification = new UserNotification
{
Sound = @"\Windows\Alarm1.wma",
Text = "Hail from Penza, Russia!",
Action = NotificationAction.Dialog | NotificationAction.Sound,
Title = string.Empty,
MaxSound = 16384
};
NotificationTools.SetUserNotification(0, trigger, userNotification);
UserNotificationTrigger.cs:
using System;
using System.Runtime.InteropServices;
namespace Thunder.Lib.ThunderMethod1
{
/// <summary>
/// Specifies the type of notification.
/// </summary>
public enum NotificationType
{
/// <summary>
/// Equivalent to using the SetUserNotification function.
/// The standard command line is supplied.
/// </summary>
ClassicTime = 4,
/// <summary>
/// System event notification.
/// </summary>
Event = 1,
/// <summary>
/// Time-based notification that is active for the time period between StartTime and EndTime.
/// </summary>
Period = 3,
/// <summary>
/// Time-based notification.
/// </summary>
Time = 2
}
/// <summary>
/// System Event Flags
/// </summary>
public enum NotificationEvent
{
None,
TimeChange,
SyncEnd,
OnACPower,
OffACPower,
NetConnect,
NetDisconnect,
DeviceChange,
IRDiscovered,
RS232Detected,
RestoreEnd,
Wakeup,
TimeZoneChange,
MachineNameChange,
RndisFNDetected,
InternetProxyChange
}
/// <summary>
/// Defines what event activates a notification.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class UserNotificationTrigger
{
internal int dwSize = 52;
private int dwType;
private int dwEvent;
[MarshalAs(UnmanagedType.LPWStr)]
private string lpszApplication = string.Empty;
[MarshalAs(UnmanagedType.LPWStr)]
private string lpszArguments;
internal SYSTEMTIME stStartTime;
internal SYSTEMTIME stEndTime;
/// <summary>
/// Specifies the type of notification.
/// </summary>
public NotificationType Type
{
get { return (NotificationType) dwType; }
set { dwType = (int) value; }
}
/// <summary>
/// Specifies the type of event should Type = Event.
/// </summary>
public NotificationEvent Event
{
get { return (NotificationEvent) dwEvent; }
set { dwEvent = (int) value; }
}
/// <summary>
/// Name of the application to execute.
/// </summary>
public string Application
{
get { return lpszApplication; }
set { lpszApplication = value; }
}
/// <summary>
/// Command line (without the application name).
/// </summary>
public string Arguments
{
get { return lpszArguments; }
set { lpszArguments = value; }
}
/// <summary>
/// Specifies the beginning of the notification period.
/// </summary>
public DateTime StartTime
{
get { return stStartTime.ToDateTime(); }
set { stStartTime = SYSTEMTIME.FromDateTime(value); }
}
/// <summary>
/// Specifies the end of the notification period.
/// </summary>
public DateTime EndTime
{
get { return stEndTime.ToDateTime(); }
set { stEndTime = SYSTEMTIME.FromDateTime(value); }
}
}
}
UserNotification.cs:
using System.Runtime.InteropServices;
namespace Thunder.Lib.ThunderMethod1
{
/// <summary>
/// Contains information used for a user notification.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class UserNotification
{
private int ActionFlags;
[MarshalAs(UnmanagedType.LPWStr)] private string pwszDialogTitle;
[MarshalAs(UnmanagedType.LPWStr)] private string pwszDialogText;
[MarshalAs(UnmanagedType.LPWStr)] private string pwszSound;
private int nMaxSound;
private int dwReserved;
/// <summary>
/// Any combination of the <see cref="T:Thunder.Lib.NotificationAction" /> members.
/// </summary>
/// <value>Flags which specifies the action(s) to be taken when the notification is triggered.</value>
/// <remarks>Flags not valid on a given hardware platform will be ignored.</remarks>
public NotificationAction Action
{
get { return (NotificationAction) ActionFlags; }
set { ActionFlags = (int) value; }
}
/// <summary>
/// Required if NotificationAction.Dialog is set, ignored otherwise
/// </summary>
public string Title
{
get { return pwszDialogTitle; }
set { pwszDialogTitle = value; }
}
/// <summary>
/// Required if NotificationAction.Dialog is set, ignored otherwise.
/// </summary>
public string Text
{
get { return pwszDialogText; }
set { pwszDialogText = value; }
}
/// <summary>
/// Sound string as supplied to PlaySound.
/// </summary>
public string Sound
{
get { return pwszSound; }
set { pwszSound = value; }
}
public int MaxSound
{
get { return nMaxSound; }
set { nMaxSound = value; }
}
}
}
NativeMethods.cs:
using System;
using System.Runtime.InteropServices;
namespace Thunder.Lib.ThunderMethod1
{
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMillisecond;
public static SYSTEMTIME FromDateTime(DateTime dt)
{
return new SYSTEMTIME
{
wYear = (short) dt.Year,
wMonth = (short) dt.Month,
wDayOfWeek = (short) dt.DayOfWeek,
wDay = (short) dt.Day,
wHour = (short) dt.Hour,
wMinute = (short) dt.Minute,
wSecond = (short) dt.Second,
wMillisecond = (short) dt.Millisecond
};
}
public DateTime ToDateTime()
{
if ((((wYear == 0) && (wMonth == 0)) && ((wDay == 0) && (wHour == 0))) && ((wMinute == 0) && (wSecond == 0)))
return DateTime.MinValue;
return new DateTime(wYear, wMonth, wDay, wHour, wMinute, wSecond, wMillisecond);
}
}
/// <summary>
/// Specifies the action to take when a notification event occurs.
/// </summary>
[Flags]
public enum NotificationAction
{
/// <summary>
/// Displays the user notification dialog box.
/// </summary>
Dialog = 4,
/// <summary>
/// Flashes the LED.
/// </summary>
Led = 1,
/// <summary>
/// Dialog box z-order flag.
/// Set if the notification dialog box should come up behind the password.
/// </summary>
Private = 32,
/// <summary>
/// Repeats the sound for 10–15 seconds.
/// </summary>
Repeat = 16,
/// <summary>
/// Plays the sound specified.
/// </summary>
Sound = 8,
/// <summary>
/// Vibrates the device.
/// </summary>
Vibrate = 2
}
internal class NativeMethods
{
[DllImport("coredll.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode,
SetLastError = true)]
internal static extern int CeSetUserNotificationEx(int hNotification, UserNotificationTrigger lpTrigger,
UserNotification lpUserNotification);
}
}
NotificationTools.cs:
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Thunder.Lib.ThunderMethod1
{
public static class NotificationTools
{
/// <summary>
/// This function modifies an existing user notification.
/// </summary>
/// <param name="handle">Handle of the Notification to be modified</param>
/// <param name="trigger">A UserNotificationTrigger that defines what event activates a notification.</param>
/// <param name="notification">A UserNotification that defines how the system should respond when a notification occurs.</param>
/// <returns>Handle to the notification event if successful.</returns>
public static int SetUserNotification(int handle, UserNotificationTrigger trigger, UserNotification notification)
{
int num = NativeMethods.CeSetUserNotificationEx(handle, trigger, notification);
if (num == 0)
throw new Win32Exception(Marshal.GetLastWin32Error(), "Error setting UserNotification");
return num;
}
}
}