PlaySound WinCE

时间:2014-01-30 16:53:37

标签: c# compact-framework pinvoke windows-ce

单击按钮时我需要播放声音。我发现这个dll是用c ++编写的。所以我使用p invoke,但会弹出一个错误:

  

错误2最佳重载方法匹配   'WinCE.Sound.PlaySound(string,System.IntPtr,int)'有一些无效   参数C:\ Users \ Fero \ Documents \ route-loader-recorder \ WinCE \ Sound.cs 44 17 WinCE

还有这个:

  

错误3参数'3':无法从'WinCE.PlaySoundFlags'转换为   'int'C:\ Users \ Fero \ Documents \ route-loader-recorder \ WinCE \ Sound.cs 44 51 WinCE

有什么想法吗?

我的代码是:

namespace Sound
{
    public enum PlaySoundFlags : int {
        SND_SYNC = 0x0,     // play synchronously (default)
        SND_ASYNC = 0x1,    // play asynchronously
        SND_NODEFAULT = 0x2,    // silence (!default) if sound not found
        SND_MEMORY = 0x4,       // pszSound points to a memory file
        SND_LOOP = 0x8,     // loop the sound until next sndPlaySound
        SND_NOSTOP = 0x10,      // don't stop any currently playing sound
        SND_NOWAIT = 0x2000,    // don't wait if the driver is busy
        SND_ALIAS = 0x10000,    // name is a registry alias
        SND_ALIAS_ID = 0x110000,// alias is a predefined ID
        SND_FILENAME = 0x20000, // name is file name
        SND_RESOURCE = 0x40004, // name is resource name or atom
    };

    public class Sound
    {
        [DllImport("winmm.dll", SetLastError = true)]
        public static extern int PlaySound(
            string szSound,
            IntPtr hModule,
            int flags);

        public static void Beep() {
            Play(@"\Windows\Voicbeep");
        }

        public static void Play(string fileName) {
            try {
                PlaySound(fileName, IntPtr.Zero, (PlaySoundFlags.SND_FILENAME | PlaySoundFlags.SND_SYNC));
            } catch (Exception ex) {
                MessageBox.Show("Can't play sound file. " + ex.ToString());
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

将它转换为int,如下所示:

PlaySound(fileName, IntPtr.Zero, (int)(PlaySoundFlags.SND_FILENAME | PlaySoundFlags.SND_SYNC));

此外,P / Invokes一般不会抛出任何异常。您需要检查返回的函数,然后检查Marshal.GetLastWin32Error()值,但在这种情况下,PlaySound不会在GetLastWin32Error中返回值。

答案 1 :(得分:1)

您对PlaySound的声明有多种不同之处。

首先,请勿将SetLastError设置为truePlaySound的文档未提及GetLastError,这意味着PlaySound无法致电SetLastError。报告它的唯一错误是通过其返回值。

将返回类型声明为bool更容易,这更适合C ++ BOOL

最后,为了解决这个好的枚举问题,你可以在你的p / invoke中使用它。把它放在一起就像这样:

[DllImport("winmm.dll")]
public static extern bool PlaySound(
    string szSound,
    IntPtr hModule,
    PlaySoundFlags flags
);

另请注意,Win32 API函数不会抛出异常。这些API函数是为互操作而设计的,并非所有语言都支持SEH异常处理。所以它不会抛出,只用布尔返回值表示错误。

您的主叫代码应为:

public static void Play(string fileName) 
{
    if (!PlaySound(fileName, IntPtr.Zero,
        PlaySoundFlags.SND_FILENAME | PlaySoundFlags.SND_SYNC))
    {
        MessageBox.Show("Can't play sound file.");
    }
}

请注意,PlaySound的最终参数的类型为DWORD。这是一个无符号的32位整数,严格来说你的枚举应该使用uint作为基类型。