为了更好地理解这个问题,请参阅我之前的问题:
C++ MSAPI 5: SetNotifyCallbackFunction not working
在Microsoft SAPI中,为了在您使用SetNotifyCallbackFunction
创建消息泵时提供文本转语音事件,下面是代码。
现在我的问题是我需要异步完成消息泵。我尝试了std::thread,pthread和boost库。但每当我把消息泵放在另一个线程中。泵失灵了。每当我尝试在另一个线程中调用Speak
时也是如此。我怎么解决这个问题?我的目标再次是让MSAPI与事件异步说话。
调用消息泵:
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;
}
答案 0 :(得分:3)
我怀疑你需要在调用WaitAndPumpMessagesWithTimeout之前创建消息队列。
有几种方法可以做到这一点:
::PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE)
当你在一个单独的线程上调用Speak()
时,你也应该在该线程上创建SAPI对象。
答案 1 :(得分:1)
我昨天忘了回答自己的问题。但我会赞扬Eric Brow
首先,我执行asynch事件的目的是将它用作其他语言的库。
我昨天研究的内容与Eric所说的一样,所有SAPI交互都必须在同一个线程上进行。因此,我通过创建一个派生自CWinThread的类来解决这个问题,该类也具有SAPI功能。然后我让包装器函数与派生的CWinThread类进行交互。
来源:http://www.codeproject.com/Articles/551/Using-User-Interface-Threads