如何与PlaySound同时执行其他功能? 我写了一个C++的Windows应用程序,需要从数组中播放一个随机选择的歌曲,用户需要能够在单击按钮时在列表上播放另一首歌曲。你会如何停止第一首歌的声音而播放第二首歌

如何与PlaySound同时执行其他功能? 我写了一个C++的Windows应用程序,需要从数组中播放一个随机选择的歌曲,用户需要能够在单击按钮时在列表上播放另一首歌曲。你会如何停止第一首歌的声音而播放第二首歌,c++,windows,C++,Windows,通过按下播放第一首歌曲的“我的”按钮,音频资源将被播放,但我的程序不再响应任何单击,代码也不会继续,直到歌曲完成。我尝试使用CreateThread,但是没有用,因为我的程序仍然处于无响应状态 包含播放声音的函数: LPTHREAD_START_ROUTINE WINAPI PlayWavFile(int resource) { PlaySound(MAKEINTRESOURCE(resource), hInst, SND_RESOURCE | SND_SYNC); return

通过按下播放第一首歌曲的“我的”按钮,音频资源将被播放,但我的程序不再响应任何单击,代码也不会继续,直到歌曲完成。我尝试使用CreateThread,但是没有用,因为我的程序仍然处于无响应状态

包含播放声音的函数:

LPTHREAD_START_ROUTINE WINAPI PlayWavFile(int resource) {
    PlaySound(MAKEINTRESOURCE(resource), hInst, SND_RESOURCE | SND_SYNC);
    return 0;
}
WndProc函数中确定按钮按下结果的情况:

case WM_COMMAND:
        if (LOWORD(wParam) == 1) {
            HANDLE hThread = CreateThread(
                NULL,
                0,
                PlayWavFile(i),
                NULL,
                NULL,
                NULL
            );
        }
        else if (LOWORD(wParam) == 2) {
            HANDLE hPlaySecond = CreateThread(
                NULL,
                0,
                PlayWavFile(j),
                NULL,
                NULL,
                NULL
            );
        }
        else if (LOWORD(wParam) == 3) {
            HANDLE hStop = CreateThread(
                NULL,
                0,
                PlayWavFile(NULL),
                NULL,
                NULL,
                NULL
            );
        }
        break;
此外,如果我尝试单击我的按钮,该按钮应给出wParam值3,则程序会出现异常,该异常状态为:

在Audio Player.exe的0x00000000处引发异常:0xC0000005:访问冲突执行位置0x00000000。发生了

最终的目标是,当音乐在后台播放时,程序将只是响应。只需使用SND_ASYNC而不是SND_SYNC直接调用PlaySound即可。这将导致PlaySound立即返回并在背景中播放声音

没有必要为了这个而乱搞线程。

只需使用SND\u ASYNC而不是SND\u SYNC直接调用PlaySound即可。这将导致PlaySound立即返回并在背景中播放声音

没有必要为此而乱搞线程。

当您这样做时

HANDLE hThread = CreateThread(
    NULL,
    0,
    PlayWavFile(i),
    NULL,
    NULL,
    NULL
);
您正在调用函数PlayWavFile,并使用它返回的值作为要调用的线程函数。由于函数总是返回0,这是一个空指针,它相当于

HANDLE hThread = CreateThread(
    NULL,
    0,
    nullptr,
    NULL,
    NULL,
    NULL
);
线程函数参数的类型为,它是指向函数的指针,该函数接受LPVOID参数并返回DWORD

您需要相应地更改线程函数,然后调用

当你这样做的时候

HANDLE hThread = CreateThread(
    NULL,
    0,
    PlayWavFile(i),
    NULL,
    NULL,
    NULL
);
您正在调用函数PlayWavFile,并使用它返回的值作为要调用的线程函数。由于函数总是返回0,这是一个空指针,它相当于

HANDLE hThread = CreateThread(
    NULL,
    0,
    nullptr,
    NULL,
    NULL,
    NULL
);
线程函数参数的类型为,它是指向函数的指针,该函数接受LPVOID参数并返回DWORD

您需要相应地更改线程函数,然后调用


与基本问题无关,但肯定与您的解决方案尝试有关,您正在泄漏创建的每个线程的线程句柄。如果您不打算通过waitforsingleobject或类似工具等待线程,则应关闭CreateThread返回的线程句柄。与基本问题无关,但肯定与解决方案尝试有关,您正在泄漏创建的每个线程的线程句柄。如果您不打算通过waitforsingleobject或类似工具等待线程,您应该关闭CreateThread返回的线程句柄。我完全按照您所说的做了,并收到了以下错误:DWORD*LPVOID arg类型的参数与LPTHREAD\u START类型的参数不兼容_ROUTINE@SiggersLPTHREAD_START_例程是线程进程的函数指针类型。它不是线程进程的正确返回值类型,因为您似乎正在使用它。您的函数应该a返回DWORD,b使用WINAPI调用约定,c使用单个LPVOID参数。请注意我在您的问题下面的一般评论中所说的关于泄漏螺纹手柄的内容;这很重要。我完全按照你说的做了,收到了这个错误:DWORD*LPVOID arg类型的参数与LPTHREAD\u START类型的参数不兼容_ROUTINE@SiggersLPTHREAD_START_例程是线程进程的函数指针类型。它不是线程进程的正确返回值类型,因为您似乎正在使用它。您的函数应该a返回DWORD,b使用WINAPI调用约定,c使用单个LPVOID参数。请注意我在您的问题下面的一般评论中所说的关于泄漏螺纹手柄的内容;这很重要。谢谢,这很快就奏效了。真不敢相信我居然没想到。谢谢,这马上就奏效了。真不敢相信我没想到。