2014-01-30 3 views
2

Мне нужно воспроизвести звук при нажатии кнопки. Я нашел эту dll, которая находится в C++. Поэтому я использую p invoke, но ошибка выскочит:PlaySound WinCE

ошибки 2 лучшие перегруженный матч метода для 'WinCE.Sound.PlaySound (строка, System.IntPtr, INT)' имеют некоторые недопустимые аргументы C: \ Пользователи \ Феро \ Documents \ маршрутный загрузчик-рекордер \ WinCE \ Sound.cs 44 17 WinCE

А также это:

Ошибка 3 Аргумент '3': не удается преобразовать из «WinCE.PlaySoundFlags 'to ' int 'C: \ Users \ Fero \ Do cuments \ 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()); 
      } 
     } 
    } 
} 
+0

@ctacke Это чистый вопрос P/Invoke, и вы не должны удалять этот тег –

ответ

1

Ваше заявление PlaySound неверно по-разному.

Прежде всего, не устанавливайте SetLastError на true. В документации PlaySound не упоминается GetLastError, а это означает, что PlaySound не дает никаких обязательств по телефону SetLastError. Единственная ошибка, сообщающая об этом, - это возвращаемое значение.

Легче объявить тип возврата bool, что лучше подходит для C++ BOOL.

Наконец, перейдя к проблеме объявления этого хорошего перечисления, вы также можете использовать его в своем p/invoke. Объедините это следующим образом:

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

Также обратите внимание, что функции API Win32 не генерируют исключений. Эти функции 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 в качестве базового типа.

+0

спасибо, что он работает. – franzp

+0

Вы ищете дополнительную помощь? –

+0

не сейчас, но наверняка позже xD – franzp

1

брось в целое, как это:

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

Кроме того, не исключение никогда не будет выброшен на P/Запускает в целом. Вам нужно проверить, какая функция возвращает, а затем значение Marshal.GetLastWin32Error(), но в этом случае PlaySound не возвращает значение в GetLastWin32Error.

+0

Пожалуйста, не советуйте использовать «Marshal.GetLastWin32Error» без особой осторожности. Прежде всего, вам нужно будет проверить возвращаемое значение 'PlaySound' для ошибки. Как бы то ни было, эта функция не вызывает «SetLastError», поэтому ваш совет вдвойне ошибочен. –

+0

Нет, не вызывайте 'GetLastWin32Error()'. Прочтите документы для 'PlaySound'. Они не говорят вам называть 'GetLastError'. Не все функции Win32 устанавливают последнее значение ошибки. Это один такой. –

+0

Я проголосовал за то, что ответ по-прежнему представляет собой запутанную картину относительно обработки ошибок. Обработка ошибок Win32 - беспорядок, и он заслуживает очень точного обращения на мой взгляд. Если вы исправите ответ, я уберу голосующий голос. –