C ++ MSAPI 5:SetNotifyCallbackFunction不工作 [英] C++ MSAPI 5: SetNotifyCallbackFunction not working

查看:550
本文介绍了C ++ MSAPI 5:SetNotifyCallbackFunction不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试过了 MSAPI 5.4 TTS与事件示例。现在我创建一个使用SetNotifyCallbackFunction的cmd提示应用程序,但我已经通过的函数没有被调用。我不是C ++的专家,所以我有困难解决这一个,任何人可以指向我正确的方向,或至少给我一个很好的例子SetNotifyCallbackFunction?

So I've tried the MSAPI 5.4 TTS with event example. Now I create an cmd prompt app that utilize the SetNotifyCallbackFunction but the function that I've pass is not being called. I'm not an expert in C++ so I am having difficulty in solving this one, can anyone point me in the right direction or at least give me a good example of SetNotifyCallbackFunction?

这里是我的代码的简化版本:

Here is a simplified version of my code:

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;
}

这个应用程序的结果是单词的合成顺利完成, outsideeventFunction从未被调用。正如你可以看到SetInterest正确设置。如何解决这个问题?

The result of this app is that the synthesizing of words are done smoothly, but the outsideeventFunction is never been called. As you can see the SetInterest is properly set. How I can fix this?

1

推荐答案

)SAPI不允许您重新分配事件目标,因此

1) SAPI doesn't let you reassign event targets, so the line

pV->SetNotifyWin32Event();

总是会失败。

您需要泵送消息以获取事件。而不是调用

2) You need to pump messages to get events delivered. So instead of calling

pV->WaitUntilDone(INFINITE);

您需要获取句柄和泵消息,直到设置事件:

you need to get the handle and pump messages until the event is set:

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;
}

这篇关于C ++ MSAPI 5:SetNotifyCallbackFunction不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆