Pregunta

To better understand this question, refer to my earlier question:

C++ MSAPI 5: SetNotifyCallbackFunction not working

In Microsoft SAPI, in order to deliver the text-to-speech events when you are using the SetNotifyCallbackFunction you need to create a message pump, below is the code.

Now my problem is that I need the message pump to be done asynchronously. I have tried the std::thread, pthread and the boost library. But whenever I put the message pump in another thread. The pump failed. It is also the case whenever I tried calling the Speak in another thread. How can I solve this? Again my goal is to make the MSAPI speak asynchronously with events.

to call the message pump:

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

the actual message pump code:

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;
}
¿Fue útil?

Solución 2

I forgot to answer my own question yesterday. But I'll give credit to Eric Brow

First off, my purpose in doing the asynch event is it will be used as a library for other language.

What I have researched yesterday was like what Eric said, all SAPI interaction must occur on the same thread. Therefore, I solve this by creating a class that is derive from CWinThread which also has the SAPI functionalities. Then I let the wrapper functions interact with the derived CWinThread class.

Source: http://www.codeproject.com/Articles/551/Using-User-Interface-Threads

Otros consejos

I suspect you need to create the message queue before calling WaitAndPumpMessagesWithTimeout.

There are a couple of ways of doing this:

  1. call ::PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE)
  2. Create a window (message-only windows are useful here)

When you call Speak() on a separate thread, you should create the SAPI objects on that thread, as well.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top