Как вы можете выполнять другие функции одновременно с PlaySound? - PullRequest
1 голос
/ 13 июня 2019

Я пишу программу на 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, программа достигнет исключения, в котором говорится:

Исключение, выданное в 0x00000000 вAudio Player.exe: 0xC0000005: нарушение прав доступа, местоположение выполнения 0x00000000.произошло.

Конечная цель заключается в том, чтобы программа просто реагировала, а музыка играла в фоновом режиме.

Ответы [ 2 ]

3 голосов
/ 13 июня 2019

Просто позвоните PlaySound напрямую с SND_ASYNC вместо SND_SYNC.Это приведет к немедленному возвращению PlaySound и воспроизведению звука в фоновом режиме.

Для этого не нужно возиться с потоками.

2 голосов
/ 13 июня 2019

Когда вы делаете

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...