2010-01-16 104 views
1

萬事俱備! 我想在我的Windows Mobile 5/6設備上顯示通知並播放自定義聲音。 我嘗試過類似的東西,但是我的自定義聲音不播放,儘管消息以非標準聲音顯示。自定義聲音的通知CeSetUserNotificationEx

如果我在[HKEY_CURRENT_USER \ ControlPanel \ Notifications {15F11F90-8A5F-454c-89FC-BA9B7AAB0CAD}]中編輯Wave密鑰到我需要的聲音文件,那麼它會播放好的。 但爲什麼有標誌NotificationAction.Sound和屬性UserNotification.Sound?它不起作用。如果我使用這種標誌,振動和LED也不起作用。

(您可以從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,你在這裏有很多代碼,但是我們應該看到什麼問題?您的觸發器是否沒有觸發,因此沒有聲音或是應該播放聲音的代碼不工作?請稍微修改一下不起作用的內容。 – 2010-01-16 18:33:12

+0

我剛剛編輯我的問題,再讀一遍。 – 2010-01-16 18:40:35

回答

0

而是在你定義pwszSound變量UserNotification類作爲一個字符串,請嘗試使用StringBuilder的,如根據documentation它應該是一個指向緩衝區與聲音的文件名稱。

+0

但是如何? 而且還有其他類型的變量: [MarshalAs(UnmanagedType.LPWStr)] private string pwszDialogText; [MarshalAs(UnmanagedType.LPWStr)] private string pwszSound; 和TCHAR * pwszDialogText; TCHAR * pwszSound; 它運作良好。 – 2010-01-19 10:50:00

+0

像這樣:[MarshalAs(UnmanagedType.LPWStr)] private StringBuilder pwszSound; 但根據pinvoke.net它應該與字符串類型一起工作,所以我可能會錯在那裏:http://pinvoke.net/default.aspx/coredll/CE_USER_NOTIFICATION.html – 2010-01-19 11:36:36

+0

我已經嘗試過它,它doesn沒有工作。 NotSupportedException異常。 – 2010-01-19 13:00:02