如何使用PlaySound同时执行其他功能?

时间:2019-06-13 11:05:39

标签: c++ windows

我正在编写一个C ++ Windows应用程序,该程序需要播放从数组中随机选择的歌曲,并且用户需要能够单击按钮才能播放列表中的另一首歌曲。您将如何停止播放第一首歌曲的声音而播放第二首歌曲?

通过按播放第一首歌曲的按钮,将播放音频资源,但是我的程序不再响应任何单击,并且直到歌曲完成后代码才继续。我尝试使用CreateThread(),但是由于我的程序仍处于无响应状态,因此无济于事。

包含PlaySound的函数:

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的访问冲突。发生。

最终目标是该程序仅在音乐在后台播放时才响应。

2 个答案:

答案 0 :(得分:3)

只需直接使用PlaySound而不是SND_ASYNC来调用SND_SYNC。这将导致PlaySound立即返回并在后台播放声音。

无需为此烦恼。

答案 1 :(得分:2)

这样做的时候

HANDLE hThread = CreateThread(
    NULL,
    0,
    PlayWavFile(i),
    NULL,
    NULL,
    NULL
);

您正在 调用 函数PlayWavFile,并且正在使用它返回的值作为要调用的线程函数。并且由于该函数始终返回0(这是一个空指针),因此等效于

HANDLE hThread = CreateThread(
    NULL,
    0,
    nullptr,
    NULL,
    NULL,
    NULL
);

线程函数参数的类型为LPTHREAD_START_ROUTINE,它是指向一个函数的指针,该函数接受一个LPVOID参数,并返回一个DWORD

您需要相应地更改线程函数,然后以以下方式调用CreateThread

HANDLE hThread = CreateThread(
    NULL,
    0,
    &PlayWavFile,  // Pass a pointer to the function
    reinterpret_cast<LPVOID>(i),    // The argument to pass
    NULL,
    NULL
);

PlayWavFile可能看起来像

DWORD PlayWavFile(LPVOID argument) {
    int resource = reinterpret_cast<int>(argument);
    PlaySound(MAKEINTRESOURCE(resource), hInst, SND_RESOURCE | SND_SYNC);
    return 0;
}