I'am developping a speech recognition application, all the code has been written correctly. However, SetNotifyWindowMessage would not send any message to the windows procedure
-WM_RECOEVENT never get called
here is the full code:
-WM_RECOEVENT never get called
here is the full code:
Code:
#include "resource.h"
#include "grammar.h"
#include <windows.h>
#include <sphelper.h>
#include <string>
#define IDC_EDIT1 1001
#define ID_START_RECOG 1002
#define WM_RECOEVENT WM_USER+190
void CreateWnd(const char *title, int x = 200, int y = 100, int width = 640, int height = 490);
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void LaunchRecognition(HWND hWnd);
WCHAR *HandleEvent();
WCHAR *ExtractInput(CSpEvent event);
void Register(WNDCLASS &wc);
const char *szClassName = "win32App";
CComPtr<ISpRecognizer> cpEngine;
CComPtr<ISpRecoContext> cpRecoCtx;
CComPtr<ISpRecoGrammar> cpRecoGrammar;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASS wc;
Register(wc);
CreateWnd("Speech Recognition");
return 0;
}
void CreateWnd(const char *title, int x, int y, int width, int height) {
HWND hWnd = CreateWindow(szClassName, title, WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, GetModuleHandle(NULL), NULL);
if(hWnd == NULL) {
MessageBox(NULL, "Unable to create window", "creating window", MB_ICONERROR);
}
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
MSG msg;
while(GetMessage(&msg, 0, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void Register(WNDCLASS &wc) {
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hCursor = NULL;
wc.hIcon = NULL;
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = WndProc;
wc.lpszClassName = szClassName;
wc.lpszMenuName = NULL;
wc.style = 0;
if(!RegisterClass(&wc)) {
MessageBox(NULL, "Unable to register class", "registering class", MB_ICONERROR);
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
static HWND hEdit;
switch(uMsg) {
case WM_CREATE:
{
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_VISIBLE | WS_CHILD , 0, 0, 640, 400, hWnd, (HMENU)IDC_EDIT1, GetModuleHandle(NULL), NULL);
HWND bButton = CreateWindowEx(0, "BUTTON", "Start Speech Recognition", WS_VISIBLE | WS_CHILD, 0, 410, 640, 30, hWnd, (HMENU)ID_START_RECOG, GetModuleHandle(NULL), NULL);
//LaunchRecognition(hWnd);
}
break;
case WM_RECOEVENT:
{
WCHAR *pwszText = HandleEvent();
SetDlgItemText(hWnd, IDC_EDIT1, (char*)pwszText);
//SetDlgItemText(hWnd, IDC_EDIT1, "\r\n");
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_START_RECOG:
LaunchRecognition(hWnd);
break;
}
break;
case WM_CLOSE:
cpRecoGrammar.Release();
cpRecoCtx.Release();
cpEngine.Release();
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return FALSE;
}
void LaunchRecognition(HWND hWnd)
{
HRESULT hr = ::CoInitialize(NULL);
if(FAILED(hr))
{
throw std::string("Unable to initialise COM objects");
}
hr = cpEngine.CoCreateInstance(CLSID_SpSharedRecognizer);
if(FAILED(hr))
{
throw std::string("Unable to create recognition engine");
}
hr = cpEngine->CreateRecoContext(&cpRecoCtx);
if(FAILED(hr))
{
throw std::string("Failed command recognition");
}
hr = cpRecoCtx->SetNotifyWindowMessage( hWnd, WM_RECOEVENT, 0, 0 );
if(FAILED(hr))
{
throw std::string("Unable to select notification window");
}
hr = cpRecoCtx->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION));
if(FAILED(hr))
{
throw std::string("Failed to create interest");
}
hr = cpRecoCtx->CreateGrammar(0, &cpRecoGrammar);
if(FAILED(hr))
{
throw std::string("Unable to create grammar");
}
hr = cpRecoGrammar->LoadCmdFromResource(
NULL,
MAKEINTRESOURCEW(IDR_SAPI0),
L"SRGRAMMAR",
MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL), SPLO_DYNAMIC);
if(FAILED(hr))
{
throw std::string("Error loading grammar");
}
hr = cpRecoGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE );
if(FAILED(hr))
{
throw std::string("Error activating the rules");
}
}
WCHAR *HandleEvent()
{
CSpEvent event;
HRESULT hr = event.GetFrom(cpRecoCtx);
if(hr == S_FALSE)
{
throw std::string("event failed");
}
// Loop processing events while there are any in the queue
while (event.GetFrom(cpRecoCtx) == S_OK)
{
// Look at recognition event only
switch (event.eEventId)
{
case SPEI_RECOGNITION:
return ExtractInput(event);
}
}
return (WCHAR *)"";
}
WCHAR *ExtractInput(CSpEvent event)
{
// Declare local identifiers:
HRESULT hr = S_OK;
CComPtr<ISpRecoResult> cpRecoResult;
SPPHRASE *pPhrase;
WCHAR *pwszText;
cpRecoResult = event.RecoResult();
// ... Obtain a recognition result object from the recognizer ...
// Get the recognized phrase object.
hr = cpRecoResult->GetPhrase(&pPhrase);
if (SUCCEEDED (hr))
{
// Get the phrase's entire text string, including replacements.
hr = cpRecoResult->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &pwszText, NULL);
}
return pwszText;
}