события — C ++ MSAPI 5: функция SetNotifyCallback не работает

Итак, я попробовал MSAPI 5.4 TTS с примером события. Теперь я создаю приложение подсказки cmd, которое использует SetNotifyCallbackFunction, но функция, которую я пропустил, не вызывается. Я не являюсь экспертом в C ++, поэтому мне трудно решить эту проблему. Может ли кто-нибудь указать мне верное направление или хотя бы дать хороший пример SetNotifyCallbackFunction?

Вот упрощенная версия моего кода:

typedef void __stdcall SPNOTIFYCALLBACK(WPARAM wParam, LPARAM lParam);

void __stdcall outsideeventFunction(WPARAM, LPARAM);

void __stdcall outsideeventFunction(WPARAM wParam, LPARAM lParam){
std::cout << "Event called::wParam: " << wParam << " lParam: " << lParam << std::endl;
SPEVENT eventItem;
memset(&eventItem, 0, sizeof(SPEVENT));
while (SUCCEEDED(pV->GetEvents(1, &eventItem, NULL)))
{
bool exitNa = false;
switch (eventItem.eEventId)
{
case SPEI_WORD_BOUNDARY:
SPVOICESTATUS eventStatus;
pV->GetStatus(&eventStatus, NULL);
ULONG start, end;
start = eventStatus.ulInputWordPos;
end = eventStatus.ulInputWordLen;
std::cout << "From event Test: " << start << ", " << end << std::endl;
std::cout << "From event Length: " << theString.length() - 1 << ", " << start + end << std::endl;
if (theString.length() - 1 <= start + end){
std::cout << "From event Exit!" << std::endl;
exitNa = true;
}
break;
}

SpClearEvent(&eventItem);
if (exitNa){
break;
}
}
return;
}

int _tmain(int argc, TCHAR* argv [], TCHAR* envp [])
{
pV = NULL;
std::string nativeString("Hello world, this is a test! For the purpose of a longer message, I'll add another sentence. And here comes the new sentence.");
SPNOTIFYCALLBACK *cb = &outsideeventFunction;
if (FAILED(::CoInitialize(NULL)))
return FALSE;

HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **) &pV);
if (SUCCEEDED(hr))
{
if (SUCCEEDED(pV->SetNotifyCallbackFunction(cb, 0, 0))){
std::cout << "Success adding callback" << std::endl;
}

ULONGLONG ullMyEvents = SPFEI(SPEI_WORD_BOUNDARY);
pV->SetInterest(ullMyEvents, ullMyEvents);
}

theString = std::wstring(nativeString.begin(), nativeString.end());

printf("Speak: %s\n", nativeString.c_str());
hr = pV->Speak(theString.c_str(), SPF_ASYNC, NULL);
pV->WaitUntilDone(INFINITE);

std::system("pause");
pV->Release();
pV = NULL;
::CoUninitialize();
return TRUE;
}

Результатом этого приложения является то, что синтез слов происходит плавно, но функция outsideevent никогда не вызывается. Как видите, SetInterest настроен правильно. Как я могу это исправить?

4

Решение

Две проблемы:

1) SAPI не позволяет переназначать цели событий, поэтому строка

pV->SetNotifyWin32Event();

всегда потерпит неудачу

2) Вам нужно прокачать сообщения, чтобы получать события. Так что вместо звонка

pV->WaitUntilDone(INFINITE);

вам нужно получить дескриптор и прокачать сообщения, пока не будет установлено событие:

HANDLE hWait = pV->SpeakCompleteEvent();
WaitAndPumpMessagesWithTimeout(hWait, INFINITE);

HRESULT WaitAndPumpMessagesWithTimeout(HANDLE hWaitHandle, DWORD dwMilliseconds)
{
HRESULT hr = S_OK;
BOOL fContinue = TRUE;

while (fContinue)
{
DWORD dwWaitId = ::MsgWaitForMultipleObjectsEx(1, &hWaitHandle, dwMilliseconds, QS_ALLINPUT, MWMO_INPUTAVAILABLE);
switch (dwWaitId)
{
case WAIT_OBJECT_0:
{
fContinue = FALSE;
}
break;

case WAIT_OBJECT_0 + 1:
{
MSG Msg;
while (::PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&Msg);
::DispatchMessage(&Msg);
}
}
break;

case WAIT_TIMEOUT:
{
hr = S_FALSE;
fContinue = FALSE;
}
break;

default:// Unexpected error
{
fContinue = FALSE;
hr = E_FAIL;
}
break;
}
}
return hr;
}
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]