我正在编写一个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的访问冲突。发生。
最终目标是该程序仅在音乐在后台播放时才响应。
答案 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;
}