Я взял gander в github, указанный в комментариях выше в вашем вопросе, и это казалось немного сложнее, чем это действительно нужно было для простой одноразовой тестовой программы. Кроме того, если вы просто собираетесь реализовать класс, содержащий все указатели COM, вы, вероятно, не захотите использовать SetNotifyCallbackFunction, и вместо этого в вашем классе реализует SetNotifyCallbackInterface.
#include <sapi.h>
#include <sphelper.h>
#include <conio.h>
CComPtr<ISpRecognizer> g_cpEngine;
CComPtr<ISpRecoContext> g_cpContext;
CComPtr<ISpRecoGrammar> g_cpGrammar;
void __stdcall testCallback(WPARAM wParam, LPARAM lParam) {
CSpEvent evt;
ISpRecoResult* pPhrase;
LPWSTR *text;
bool exit = false;
//text = new LPWSTR(L"");
HANDLE waitHandle = NULL;
waitHandle = g_cpContext->GetNotifyEventHandle();
do{
WaitForSingleObject(waitHandle, INFINITE);
while (g_cpContext != NULL && evt.GetFrom(g_cpContext) == S_OK)
{
// Look at recognition event only
switch (evt.eEventId)
{
case SPEI_RECOGNITION:
pPhrase = evt.RecoResult();
text = new LPWSTR(L"");
pPhrase->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, text, NULL);
wprintf(L"%ls\n", *text);
if(wcscmp(L"Exit",*text) == 0){
exit = true;
}
delete[] text;
break;
case SPEI_FALSE_RECOGNITION:
wprintf(L"False Reco\n");
break;
}
}
}while(!exit && g_cpContext != NULL);
if(g_cpEngine)
g_cpEngine->SetRecoState(SPRECOSTATE::SPRST_INACTIVE);
}
int main(int argc, char* argv[]){
HRESULT hr = S_OK;
HANDLE waitHandle;
ULONGLONG ullEvents;
DWORD dwRetVal;
HANDLE thread;
ullEvents = SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_FALSE_RECOGNITION);
waitHandle = NULL;
dwRetVal = 0;
::CoInitialize(NULL);
hr = g_cpEngine.CoCreateInstance(CLSID_SpSharedRecognizer);
hr = g_cpEngine->CreateRecoContext(&g_cpContext);
hr = g_cpContext->SetAudioOptions(SPAO_NONE, NULL, NULL);
hr = g_cpContext->CreateGrammar(NULL,&g_cpGrammar);
hr = g_cpContext->SetInterest(ullEvents,ullEvents);
hr = g_cpContext->SetNotifyCallbackFunction(testCallback, NULL, NULL);
hr = g_cpGrammar->SetDictationState(SPRULESTATE::SPRS_ACTIVE);
hr = g_cpEngine->SetRecoState(SPRECOSTATE::SPRST_ACTIVE);
thread = ::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)testCallback,NULL,NULL,NULL);
puts("Press any key to continue...");
getch();
g_cpGrammar.Release();
g_cpContext.Release();
g_cpEngine.Release();
::CoUninitialize();
return 0;
}
Эта программа не имеет обработки ошибок, заметьте, и он использует Геч(), чтобы сохранить его от просто выхода и очистки. Вам нужно будет найти свой собственный способ держать вашу программу занятой, когда вы обрабатываете события от распознавателя.
Это может помочь: https://github.com/rpavlik/vrjuggler-2.2-debs/blob/0118f3fa3cd304f312fb84e717e1ecc091225496/modules/gadgeteer/drivers/Microsoft/SpeechRecognition/MSFTSpeechServerManager.cpp Глядя на заголовочный файл, вы можете увидеть это не пустое, но ожидает, что SPNOTITIFYCALLBACK будет возвращать тип – Tim
Копировать-вставить ссылку @ Tim: 'void __stdcall testCallback (WPARAM wParam, LPARAM lParam)' –