c# - 玩声WinCE

标签 c# compact-framework pinvoke windows-ce

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

Error 2 The best overloaded method match for 'WinCE.Sound.PlaySound(string, System.IntPtr, int)' has some invalid arguments C:\Users\Fero\Documents\route-loader-recorder\WinCE\Sound.cs 44 17 WinCE

还有这个:

Error 3 Argument '3': cannot convert from 'WinCE.PlaySoundFlags' to '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());
            }
        }
    }
}

最佳答案

您的 PlaySound 声明在很多方面都是错误的。

首先,不要将 SetLastError 设置为 truePlaySound 的文档没有提及 GetLastError,这意味着 PlaySound 不 promise 调用 SetLastError。它报告的唯一错误是通过其返回值。

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

最后,在费尽心思声明这个漂亮的枚举之后,您不妨在您的 p/invoke 中使用它。像这样组合起来:

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

另请注意,Win32 API 函数不会引发异常。这些 API 函数是为互操作而设计的,并非所有语言都支持 SEH 异常处理。所以它不会抛出异常,并且仅通过 bool 返回值来指示错误。

您的调用代码应该是:

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 作为其基本类型。

关于c# - 玩声WinCE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21462601/

相关文章:

c# - System.Diagnostics.StackTrace 紧凑框架

c# - 如何将 HSM 加密与 C# 集成?

c# - NHibernate Linq Select Projection - 使用部分选择检索完整实体

timer - 在 Compact Framework 中使用 System.Threading.Timer

c# - 如何在未处理的异常后继续运行?

c# - 如何将窗口所有者设置为非托管窗口

c# - lineTranslateAddress c++ 到托管 c#

c# - volatile 用法的可重现示例

c# - 如何在C#(3.5框架)中编码和解码Base128字符串

c# - 如何调用 Windows API