Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SetNotifyWindowMessage not sending message WindProc

Status
Not open for further replies.

Leibniz

Programmer
Dec 22, 2007
25
CA
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
Code:
#define WM_RECOEVENT	WM_USER+190
Code:
cpRecoCtx->SetNotifyWindowMessage( hWnd, WM_RECOEVENT, 0, 0 );
Code:
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;
....

WM_RECOEVENT never get called
 
Where are you setting the WndProc for the hWnd in cpRecoCtx->SetNotifyWindowMessage( hWnd, WM_RECOEVENT, 0, 0 );

Just wondering whether you are looking at the wrong WndProc.

Also your 2nd SetDlgItemText in your case statement will overwrite the first one.
 
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;
}
 
OK I think I understand now - SetNotifyWindowMessage just sets up the instance to send window messages to the specified window. It doesn't actually send them. You either need a SendMessage or PostMessage or SendDlgItemMessage to send them.

How you get that to activate on speech recognition is beyond me. It is probably some call in the API that activates it.
 
well, after calling SetNotifyWindowMessage, it was suppose to append automatically. So when ever i launch speech recognition, the api should have send a WM_RECOEVENT message but it is not doing it.
 
I can't figure out where you are launching speech recognition. When you call LaunchRecognition (which is currently commented out in WM_CREATE), all it does is set up cpRecoCtx. Where are you activating the speech recognition which uses either cpRecoEngine or cpRecoCtx.

 
Well, it is exactly when i call LaunchRecognition. At that moment, SAPI should have send the WM_RECOEVENT message. Then i would have been able to get the text that was spoken by the user.
 
problem solved, i had to introduce more selections in SetInterest:

Code:
SPFEI(SPEI_SOUND_START) | SPFEI(SPEI_SOUND_END) |
SPFEI(SPEI_PHRASE_START) | SPFEI(SPEI_RECOGNITION) |
SPFEI(SPEI_FALSE_RECOGNITION) | SPFEI(SPEI_HYPOTHESIS) |
SPFEI(SPEI_INTERFERENCE) | SPFEI(SPEI_RECO_OTHER_CONTEXT) |
SPFEI(SPEI_REQUEST_UI) | SPFEI(SPEI_RECO_STATE_CHANGE) |
SPFEI(SPEI_PROPERTY_NUM_CHANGE) | SPFEI(SPEI_PROPERTY_STRING_CHANGE);

webiste: [link ][/url]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top