1
votes

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;
        }
    }
}
1
Intag, you have a lot of code here but what's the problem we're supposed to look at? Is your trigger not firing and therefore no sound or is the code that is supposed to play the sound not working? Please trim back a little to what doesn't work.Paul Sasik
I have just edited my question, read again.Lessneek

1 Answers

0
votes

Instead of defining the pwszSound variable in you UserNotification class as a string, try using StringBuilder, as according to the documentation it should be a pointer to a buffer with the sound's file name.