首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PlaySound WinCE

PlaySound WinCE
EN

Stack Overflow用户
提问于 2014-01-30 16:53:37
回答 2查看 2.3K关注 0票数 2

我需要播放声音时,点击按钮。我在c++中找到了这个dll。所以我使用p invoke,但是会弹出一个错误:

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

此外,这也是:

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

有什么想法吗?

我的代码是:

代码语言:javascript
复制
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());
            }
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-30 17:34:16

您对PlaySound的声明在各种方面都是错误的。

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

更容易将返回类型声明为bool,这是与C++ BOOL更好的匹配。

最后,在声明了这个很好的枚举之后,您还可以在p/invoke中使用它。把它像这样组合起来:

代码语言:javascript
复制
[DllImport("winmm.dll")]
public static extern bool PlaySound(
    string szSound,
    IntPtr hModule,
    PlaySoundFlags flags
);

还请注意,Win32 API函数不会抛出异常。这些API函数是为互操作而设计的,并不是所有语言都支持SEH异常处理。因此,它将不会抛出,并且仅通过布尔返回值指示错误。

您的呼叫代码应该是:

代码语言:javascript
复制
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作为它的基类型。

票数 1
EN

Stack Overflow用户

发布于 2014-01-30 17:09:34

将其转换为如下所示:

代码语言:javascript
复制
PlaySound(fileName, IntPtr.Zero, (int)(PlaySoundFlags.SND_FILENAME | PlaySoundFlags.SND_SYNC));

而且,在一般情况下,对P/调用都不会抛出任何异常。您需要检查哪些函数返回,然后检查Marshal.GetLastWin32Error()值,但在本例中,PlaySound不返回GetLastWin32Error中的值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21462601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档