|
|
#include "stdafx.h"
#include <stdio.h>
#include "comp.h"
#include "StreamHlp.h"
//#define INPROC
/****************************************************************************
* CCompiler::~CCompiler * *---------------------------* * Description: * Releases objects created by CCompiler **************************************************************** Leonro *****/ CCompiler::~CCompiler() { m_cpRichEdit.Release(); m_cpTextDoc.Release(); m_cpTextSel.Release(); m_cpRecognizer.Release(); m_cpRecoContext.Release(); m_cpCompiler.Release(); m_cpRecoGrammar.Release(); if( m_hMod ) { FreeLibrary( m_hMod ); } }
/****************************************************************************
* CCompiler::Initialize * *---------------------------* * Description: * Set up the windows, as well as the RichEdit objects. * Also it initializes some SAPI objects. ************************************************************** Leonro *******/ HRESULT CCompiler::Initialize( int nCmdShow ) { TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // Window class
HRESULT hr = S_OK; WNDCLASSEX wcex; // Initialize global strings
LoadString( m_hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING ); LoadString( m_hInstance, IDC_GRAMCOMP, szWindowClass, MAX_LOADSTRING ); // Register the windows class
wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = m_hInstance; wcex.hIcon = LoadIcon(m_hInstance, (LPCTSTR)IDI_GRAMCOMP); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_GRAMCOMP; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
// Register window and create the sapi grammar compiler
if( RegisterClassEx(&wcex) ) { hr = m_cpCompiler.CoCreateInstance( CLSID_SpGrammarCompiler ); if( FAILED( hr ) ) { MessageBox( NULL, _T("Error initializing speech objects. Shutting down.\n\n" " Please make sure SAPI5 is installed!"), _T("Error"), MB_OK ); } } else { MessageBox( NULL, _T("Error initializing application. Shutting down."), _T("Error"), MB_OK ); hr = E_FAIL; }
// Load DLL for Rich Edit 3.0
if( SUCCEEDED( hr ) ) { m_hMod = LoadLibrary( "RICHED20.DLL" ); if( !m_hMod ) { MessageBox( NULL, "Couldn't find required riched32.dll. Shutting down!", "Error - Missing dll", MB_OK ); hr = E_FAIL; } }
if( SUCCEEDED( hr ) ) { // Perform application initialization:
m_hWnd = CreateWindow( szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, m_hInstance, this );
if( m_hWnd && m_hWndStatus && m_hWndEdit ) { // Get TOM interfaces
SendMessage( m_hWndEdit, EM_GETOLEINTERFACE, 0, (LPARAM)(LPVOID FAR *)&m_cpRichEdit ); SendMessage( m_hWndEdit, EM_SETEVENTMASK, 0, ENM_CHANGE | ENM_KEYEVENTS );
if( !m_cpRichEdit ) { hr = E_NOINTERFACE; }
if( SUCCEEDED( hr ) ) { hr = m_cpRichEdit->QueryInterface( IID_ITextDocument, (void**)&m_cpTextDoc ); if( SUCCEEDED( hr ) ) { hr = m_cpTextDoc->GetSelection( &m_cpTextSel ); } } if( SUCCEEDED( hr ) ) { // Load Accelerators
m_hAccelTable = LoadAccelerators( m_hInstance, MAKEINTRESOURCE(IDR_GRAMACCEL) );
::ShowWindow( m_hWnd, nCmdShow ); ::UpdateWindow( m_hWnd ); } else { MessageBox( m_hWnd, _T("Error initializing edit control. Shutting down!"), _T("Error"), MB_OK ); } } }
return hr; }
/****************************************************************************************
* CCompiler::Run() * *----------------------* * Description: * Contains the message loop for the application **************************************************************************** Leonro *****/ int CCompiler::Run() { MSG msg;
// Main message loop:
while( ::GetMessage(&msg, NULL, 0, 0) ) { if( !::TranslateAccelerator(m_hWnd, m_hAccelTable, &msg) ) { ::TranslateMessage( &msg ); ::DispatchMessage( &msg ); } }
return msg.wParam; } /* CCompiler::Run */
/****************************************************************************
* CCompiler::WndProc * *---------------------------* * Description: * Processes messages for the main window. ***************************************************************** Leonro ****/ LRESULT CALLBACK CCompiler::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; static BOOL bFileOpened = FALSE; PAINTSTRUCT psMain, psStatus; HDC hMainDC=0, hStatusDC=0; long lSaved = 0; HRESULT hr = S_OK; static TCHAR szTitle[NORM_SIZE] = _T(""); TCHAR szFileName[NORM_SIZE] = _T(""); static TCHAR szSaveFileName[NORM_SIZE] = _T(""); HMENU hMenu=0; static int iNumUndos=0; long lStart, lEnd;
CCompiler* pThis = (CCompiler *)GetWindowLong(hWnd, GWL_USERDATA);
// get the handle to the menu
hMenu = GetMenu( hWnd ); switch (message) { case WM_SETFOCUS: SetFocus (pThis->m_hWndEdit); break;
case WM_CREATE: pThis = (CCompiler *)(((CREATESTRUCT *) lParam)->lpCreateParams); SetWindowLong(hWnd, GWL_USERDATA, (LPARAM)pThis); pThis->m_hWnd = hWnd; // Create the compile status window
pThis->m_hWndStatus = CreateWindowEx ( WS_EX_CLIENTEDGE, _T("LISTBOX"), NULL, WS_CHILD | WS_VISIBLE | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL | WS_HSCROLL, 1, 1, 1, 1, hWnd, NULL, pThis->m_hInstance, NULL); // Create the actual rich edit window
pThis->m_hWndEdit = CreateWindowEx( WS_EX_CLIENTEDGE, RICHEDIT_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_NOHIDESEL | ES_WANTRETURN, 1, 1, 1, 1, hWnd, (HMENU)IDC_RICHEDITWND, pThis->m_hInstance, NULL ); break;
case WM_ERASEBKGND: return TRUE;
case WM_SIZE: { // move the editor and compiler window
LONG lListBoxHeight = (HIWORD(lParam) / 4); LONG lCodeHeight = HIWORD(lParam) - lListBoxHeight; MoveWindow (pThis->m_hWndEdit, 0, 0, LOWORD(lParam), lCodeHeight , FALSE); MoveWindow (pThis->m_hWndStatus, 0, lCodeHeight, LOWORD(lParam), lListBoxHeight, FALSE); // repaint
InvalidateRect( hWnd, NULL, FALSE ); } break;
case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam);
// Update available menu items
pThis->m_cpTextSel->GetStart( &lStart ); pThis->m_cpTextSel->GetStoryLength( &lEnd ); if( lEnd-lStart > 1 ) { EnableMenuItem( hMenu, IDM_EDIT_CUT, MF_ENABLED ); EnableMenuItem( hMenu, IDM_EDIT_COPY, MF_ENABLED ); } else { EnableMenuItem( hMenu, IDM_EDIT_CUT, MF_GRAYED ); EnableMenuItem( hMenu, IDM_EDIT_COPY, MF_GRAYED ); }
// Parse the menu selections:
switch( wmId ) { case IDM_FILE_NEW: // Check if the file has been changed and save if necessary
hr = pThis->m_cpTextDoc->GetSaved( &lSaved ); if( lSaved == tomFalse && SUCCEEDED( hr ) ) { int iRetVal = MessageBox( pThis->m_hWndEdit, _T("Do you want to save your changes?"), _T("Grammar Compiler"), MB_YESNO ); if( iRetVal == IDYES ) { BOOL bRetVal = TRUE;
// No need to call save file dialog if there's already a file name
if( !_tcscmp( szSaveFileName, "" ) ) { bRetVal = pThis->CallSaveFileDialog( hWnd, szSaveFileName ); }
// TOM save file
if( bRetVal ) { // TOM save file
pThis->FileSave( hWnd, pThis, szSaveFileName ); } } else { pThis->m_cpTextDoc->SetSaved( tomTrue ); } } // call TOM new
pThis->m_cpTextDoc->New(); pThis->m_cpTextDoc->SetSaved( tomTrue );
// Add the file name to the title bar
LoadString( pThis->m_hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING ); _tcscat( szTitle, _T(" - []") ); SetWindowText( hWnd, szTitle );
// reset defaults
::SendMessage( pThis->m_hWndStatus, LB_RESETCONTENT, 0, 0 ); ::SendMessage( pThis->m_hWndStatus, LB_SETHORIZONTALEXTENT, 0, 0 ); pThis->m_szCFGDestFile[0] = 0; pThis->m_szHeaderDestFile[0] = 0; pThis->m_szXMLSrcFile[0] = 0; pThis->m_fNeedStartCompile = TRUE; pThis->m_hrWorstError = 0; _tcscpy( szSaveFileName, _T("") ); InvalidateRect( hWnd, NULL, FALSE ); break;
case IDM_FILE_OPEN: // Save old file first if one exists and it has not been saved
hr = pThis->m_cpTextDoc->GetSaved( &lSaved ); if( lSaved == tomFalse && SUCCEEDED( hr ) ) { int iRetVal = MessageBox( pThis->m_hWndEdit, _T("Do you want to save your changes?"), _T("Grammar Compiler"), MB_YESNO ); if( iRetVal == IDYES ) { // reset errors
pThis->m_hrWorstError = 0;
// TOM save file
hr = pThis->FileSave( hWnd, pThis, szSaveFileName ); if( hr == STG_E_ACCESSDENIED ) // Handle read only files
{ MessageBox( pThis->m_hWndEdit, _T("This file exists with Read Only attributes.\n Please use a different file name."), _T("File Save"), MB_OK ); // Call FileSave again but this time pop the save file dialog box
pThis->FileSave( hWnd, pThis, szSaveFileName ); } } else { pThis->m_cpTextDoc->SetSaved( tomTrue ); } }
bFileOpened = pThis->CallOpenFileDialog( hWnd, szFileName, _T("XML (*.xml)\0*.xml\0TXT (*.txt)\0*.txt\0All Files (*.*)\0*.*\0") ); // Copy the open file name to the Save file name for use later
_tcscpy( szSaveFileName, szFileName ); if( bFileOpened ) { HRESULT hr = S_OK; VARIANT Var; USES_CONVERSION;
// reset text in windows
_tcscpy(pThis->m_szXMLSrcFile, szFileName); ::SendMessage( pThis->m_hWndStatus, LB_RESETCONTENT, 0, 0 ); ::SendMessage( pThis->m_hWndStatus, LB_SETHORIZONTALEXTENT, 0, 0 );
InvalidateRect( hWnd, NULL, FALSE );
// Open the file in the rich edit control
VariantInit( &Var ); Var.vt = VT_BSTR; Var.bstrVal = SysAllocString( T2W(szFileName) ); // Will use Win32 file command
hr = pThis->m_cpTextDoc->Open( &Var, tomOpenExisting, 0 ); hr &= ~0x40000; // Mask off bit 18
if( hr == STG_E_ACCESSDENIED ) // Handle read only files
{ pThis->m_cpTextDoc->Open( &Var, tomReadOnly | tomOpenExisting, 0 ); } SysFreeString( Var.bstrVal ); // reset defaults
pThis->m_szCFGDestFile[0] = 0; pThis->m_szHeaderDestFile[0] = 0; pThis->m_fNeedStartCompile = TRUE; pThis->m_hrWorstError = 0; // no changes to the file yet so set SetSaved to true
pThis->m_cpTextDoc->SetSaved( tomTrue );
// Add the file name to the title bar
LoadString( pThis->m_hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING ); _tcscat( szTitle, _T(" - [") ); _tcscat( szTitle, szFileName ); _tcscat( szTitle, _T("]") ); SetWindowText( hWnd, szTitle ); } break;
case IDM_FILE_SAVEAS: // Remove old save file name if one exists
_tcscpy( szSaveFileName, _T("") ); // no break here
case IDM_FILE_SAVE: // TOM save file
hr = pThis->FileSave( hWnd, pThis, szSaveFileName ); if( hr == STG_E_ACCESSDENIED ) // Handle read only files
{ MessageBox( pThis->m_hWndEdit, _T("This file exists with Read Only attributes.\n Please use a different file name."), _T("File Save"), MB_OK ); // Call FileSave again but this time pop the save file dialog box
hr = pThis->FileSave( hWnd, pThis, szSaveFileName ); }
// Add the file name to the title bar
if( SUCCEEDED( hr ) ) { LoadString( pThis->m_hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING ); _tcscat( szTitle, _T(" - [") ); _tcscat( szTitle, szSaveFileName ); _tcscat( szTitle, _T("]") ); SetWindowText( hWnd, szTitle ); } break;
case IDM_BUILD_COMPILE: if( pThis->m_fNeedStartCompile ) { pThis->Compile( hWnd, szSaveFileName, szTitle, pThis ); } break;
case IDC_RICHEDITWND: // When user changes contents of edit control update status bar on top
if( wmEvent == EN_CHANGE ) { TCHAR szTitleNotSaved[NORM_SIZE] = _T("");
if( !_tcscmp( szTitle, _T("") ) ) { LoadString( pThis->m_hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING ); _tcscat( szTitle, _T(" - []") ); }
_tcscpy( szTitleNotSaved, szTitle ); _tcscat( szTitleNotSaved, _T("*") ); SetWindowText( hWnd, szTitleNotSaved );
pThis->m_fNeedStartCompile = TRUE;
//Update edit menu items
EnableMenuItem( hMenu, IDM_EDIT_UNDO, MF_ENABLED ); } break;
case IDM_EDIT_UNDO: // Undo
pThis->m_cpTextDoc->Undo( 1, NULL ); EnableMenuItem( hMenu, IDM_EDIT_REDO, MF_ENABLED ); iNumUndos++; break;
case IDM_EDIT_REDO: // Redo
pThis->m_cpTextDoc->Redo( 1, NULL ); if( --iNumUndos < 1 ) { EnableMenuItem( hMenu, IDM_EDIT_REDO, MF_GRAYED ); iNumUndos = 0; } break;
case IDM_EDIT_COPY: // Copy
pThis->m_cpTextSel->Copy( NULL ); EnableMenuItem( hMenu, IDM_EDIT_PASTE, MF_ENABLED ); break;
case IDM_EDIT_CUT: // Cut
pThis->m_cpTextSel->Cut( NULL ); EnableMenuItem( hMenu, IDM_EDIT_PASTE, MF_ENABLED ); break;
case IDM_EDIT_PASTE: // Paste
pThis->m_cpTextSel->Paste( NULL, 0 ); break;
case IDM_EDIT_DELETE: // Delete
pThis->m_cpTextSel->Delete( tomCharacter, 1, NULL ); break;
case IDM_EDIT_SELECTALL: // Select all
{ pThis->m_cpTextSel->GetStart( &lStart ); pThis->m_cpTextSel->GetStoryLength( &lEnd ); pThis->m_cpTextSel->MoveStart( tomCharacter, -lStart, NULL ); pThis->m_cpTextSel->MoveEnd( tomCharacter, lEnd-lStart, NULL ); } break;
case IDM_EDIT_FIND: // Find
DialogBoxParam( pThis->m_hInstance, (LPCTSTR)IDD_FIND, hWnd, Find, (LPARAM)pThis); break;
case IDM_EDIT_GOTO: // Find
DialogBoxParam( pThis->m_hInstance, (LPCTSTR)IDD_GOTO, hWnd, Goto, (LPARAM)pThis); break;
case IDM_TESTGRAMMAR: // Only compile if necessary
if( pThis->m_fNeedStartCompile ) { hr = pThis->Compile( hWnd, szSaveFileName, szTitle, pThis ); } // Create new dialog box
if( SUCCEEDED( hr ) ) { DialogBoxParam( pThis->m_hInstance, (LPCTSTR)IDD_TESTGRAMMAR, hWnd, TestGrammar, (LPARAM)pThis); } else if( hr == E_INVALIDARG ) { MessageBox( pThis->m_hWndEdit, _T("Please enter text or open an xml file first."), _T("Compile Error"), MB_OK ); } else if( hr == E_FAIL ) { MessageBox( pThis->m_hWndEdit, _T("Please save file first."), _T("Compile Error"), MB_OK ); } else { MessageBox( pThis->m_hWndEdit, _T("Error compiling xml file."), _T("Compile Error"), MB_OK ); } break;
case IDM_ABOUT: // About box
DialogBox( pThis->m_hInstance, (LPCTSTR)IDD_ABOUTBOX, hWnd, About ); break;
case IDM_EXIT: SendMessage( hWnd, WM_CLOSE, 0, 0 ); break;
default: return DefWindowProc(hWnd, message, wParam, lParam); } break;
case WM_CLOSE: { int iRetVal = 0; // Check if the file has been changed and save if necessary
hr = pThis->m_cpTextDoc->GetSaved( &lSaved ); if( lSaved == tomFalse && SUCCEEDED( hr ) ) { iRetVal = MessageBox( pThis->m_hWndEdit, _T("Do you want to save your changes?"), _T("Grammar Compiler"), MB_YESNOCANCEL ); if( iRetVal == IDYES ) { // No need to call save file dialog if there's already a file name
if( !_tcscmp( szSaveFileName, "" ) ) { pThis->CallSaveFileDialog( hWnd, szSaveFileName ); }
// TOM save file
pThis->FileSave( hWnd, pThis, szSaveFileName ); } else { pThis->m_cpTextDoc->SetSaved( tomTrue ); } } if( iRetVal != IDCANCEL ) { DestroyWindow( hWnd ); } } break;
case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0; }
/****************************************************************************
* CCompiler::About * *---------------------------* * Description: * Message handler for About box. ***************************************************************** Leonro ****/ INT_PTR CALLBACK CCompiler::About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE;
case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; }
/****************************************************************************
* CCompiler::Find * *---------------------------* * Description: * Message handler for Find box. ***************************************************************** Leonro ****/ INT_PTR CALLBACK CCompiler::Find(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { TCHAR szFindText[NORM_SIZE]=_T(""); CComBSTR bStr( _T("Grammar") ); long lUpDown = tomForward; long lFlags=0;
CCompiler* pThis = (CCompiler *)GetWindowLong( hDlg, GWL_USERDATA ); switch (message) { case WM_INITDIALOG: SetWindowLong( hDlg, GWL_USERDATA, lParam ); SendDlgItemMessage( hDlg, IDB_DOWN, BM_SETCHECK, BST_CHECKED, 0 ); return TRUE;
case WM_COMMAND: { switch( LOWORD( wParam ) ) { case IDB_FINDNEXT: // Get text string
GetDlgItemText( hDlg, IDE_FINDTEXT, szFindText, NORM_SIZE ); bStr = szFindText;
// Search up or down?
SendDlgItemMessage( hDlg, IDB_DOWN, BM_GETCHECK, 0, 0 )? lUpDown = tomForward : lUpDown = tomBackward; // Match case?
SendDlgItemMessage( hDlg, IDB_MATCHCASE, BM_GETCHECK, 0, 0 )? lFlags=tomMatchCase : lFlags=0; pThis->m_cpTextSel->FindText( bStr, lUpDown, lFlags, NULL );
return TRUE;
case IDB_CANCEL: case IDCANCEL: EndDialog( hDlg, LOWORD(wParam) ); return TRUE; } } break;
case WM_CLOSE: EndDialog( hDlg, LOWORD(wParam) ); return TRUE; } return FALSE; }
/****************************************************************************
* CCompiler::Goto * *---------------------------* * Description: * Message handler for Goto box. **************************************************************** Leonro *****/ INT_PTR CALLBACK CCompiler::Goto( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { TCHAR szGotoLine[NORM_SIZE]=_T(""); TCHAR szCurrLine[NORM_SIZE]=_T(""); long iGotoLine, iCurrLine, iLinesToMove; CCompiler* pThis = (CCompiler *)GetWindowLong( hDlg, GWL_USERDATA );
switch (message) { case WM_INITDIALOG: SetWindowLong( hDlg, GWL_USERDATA, lParam ); pThis = (CCompiler *)lParam; pThis->m_cpTextSel->GetIndex( tomLine, &iCurrLine ); _itoa( iCurrLine, szCurrLine, 10 ); SetDlgItemText( hDlg, IDE_LINE, szCurrLine ); return TRUE;
case WM_COMMAND: { switch( LOWORD( wParam ) ) { case IDB_OK: // Get current line
pThis->m_cpTextSel->GetIndex( tomLine, &iCurrLine ); // Get goto line
GetDlgItemText( hDlg, IDE_LINE, szGotoLine, NORM_SIZE ); iGotoLine = atoi( szGotoLine ); EndDialog( hDlg, LOWORD(wParam) ); // Calculate number of lines to move
iLinesToMove = iGotoLine - iCurrLine; // Move
pThis->m_cpTextSel->MoveDown( tomLine, iLinesToMove, tomMove, NULL ); return TRUE;
case IDB_CANCEL: case IDCANCEL: EndDialog( hDlg, LOWORD(wParam) ); return TRUE; } } break;
case WM_CLOSE: EndDialog( hDlg, LOWORD(wParam) ); return TRUE; } return FALSE; }
/****************************************************************************
* CCompiler::TestGrammar * *---------------------------* * Description: * Message handler for TestGrammar box. **************************************************************** Leonro *****/ LRESULT CALLBACK CCompiler::TestGrammar(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HRESULT hr = S_OK; CCompiler* pThis = (CCompiler *)GetWindowLong( hDlg, GWL_USERDATA );
switch (message) { case WM_RECOEVENT: { pThis->RecoEvent( hDlg, pThis ); } return TRUE;
case WM_INITDIALOG: { SetWindowLong( hDlg, GWL_USERDATA, lParam ); pThis = (CCompiler *)lParam;
// Create the shared sapi reco instance if the app hasn't already done so
if( !pThis->m_cpRecognizer ) { #ifdef INPROC
// Create the inproc engine
hr = pThis->m_cpRecognizer.CoCreateInstance( CLSID_SpInprocRecognizer );
// Create default audio input
CComPtr<ISpObjectToken> cpAudioToken; if (SUCCEEDED(hr)) { hr = SpGetDefaultTokenFromCategoryId(SPCAT_AUDIOIN, &cpAudioToken); } if (SUCCEEDED(hr)) { pThis->m_cpRecognizer->SetInput(cpAudioToken, TRUE); } #else
// Create the shared engine
hr = pThis->m_cpRecognizer.CoCreateInstance( CLSID_SpSharedRecognizer );
#endif
// Create the Reco context
if( SUCCEEDED( hr ) ) { hr = pThis->m_cpRecognizer->CreateRecoContext( &pThis->m_cpRecoContext ); } }
// Set up windows messageing for recognition events
if( SUCCEEDED( hr ) ) { hr = pThis->m_cpRecoContext->SetNotifyWindowMessage( hDlg, WM_RECOEVENT, 0, 0); } if( SUCCEEDED( hr ) ) { const ULONGLONG ullInterest = SPFEI(SPEI_SOUND_END) | SPFEI(SPEI_SOUND_START) | SPFEI(SPEI_HYPOTHESIS) | SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_FALSE_RECOGNITION); hr = pThis->m_cpRecoContext->SetInterest( ullInterest, ullInterest ); }
// Get locale/font settings
if( SUCCEEDED( hr ) ) { LCID lcid = GetUserDefaultLCID();
// Pick an appropriate font. On Windows 2000, let the system fontlink.
DWORD dwVersion = GetVersion();
if ( dwVersion >= 0x80000000 || LOBYTE(LOWORD(dwVersion)) < 5 || LANGIDFROMLCID(lcid) != MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)) { TCHAR achCodePage[6]; UINT uiCodePage;
if( 0 != GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, achCodePage, 6) ) { uiCodePage = atoi(achCodePage); } else { uiCodePage = GetACP(); }
CComPtr<IMultiLanguage> cpMultiLanguage; MIMECPINFO MimeCpInfo;
if ( SUCCEEDED(cpMultiLanguage.CoCreateInstance(CLSID_CMultiLanguage)) && SUCCEEDED(cpMultiLanguage->GetCodePageInfo(uiCodePage, &MimeCpInfo))) { USES_CONVERSION;
HFONT hfont = CreateFont( 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, MimeCpInfo.bGDICharset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, W2T(MimeCpInfo.wszProportionalFont ));
} } }
// Update status edit box
if( SUCCEEDED( hr ) ) { const static TCHAR szPrefixText[] = _T("Current C&&C Grammar: "); TCHAR szDesc[sp_countof(pThis->m_szCFGDestFile) + sp_countof(szPrefixText) + 4]; _tcscpy( szDesc, szPrefixText ); if( *pThis->m_szCFGDestFile ) { _tcscat( szDesc, pThis->m_szCFGDestFile ); } else { _tcscat( szDesc, _T("none") ); } SendDlgItemMessage( hDlg, IDC_GRAMMAR_STATUS, WM_SETTEXT, 0, (LPARAM)szDesc ); }
if( FAILED( hr ) ) { MessageBox( hDlg, _T("Error initializing Speech Recognizer."), _T("Error"), MB_OK ); EndDialog( hDlg, LOWORD(wParam) ); } }
return TRUE;
case WM_COMMAND: { switch( LOWORD( wParam ) ) { case IDC_BEGINRECO: // Load the grammar
if( SendDlgItemMessage( hDlg, IDC_BEGINRECO, BM_GETCHECK, 0, 0 ) ) { // Enable Emulate Recognition feature
EnableWindow( GetDlgItem(hDlg, IDC_EDIT_PARSETEXT), TRUE ); TCHAR* szPath = pThis->m_szCFGDestFile; hr = pThis->LoadGrammar( szPath ); if( FAILED( hr ) ) { MessageBox( hDlg, _T("Error loading grammar. Make sure") _T(" a file is loaded, saved, and compiled."), _T("Error"), MB_OK ); }
// Activate the grammar
if( SUCCEEDED( hr ) ) { hr = pThis->m_cpRecoGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE); }
if( FAILED( hr ) ) { // Release grammar
pThis->m_cpRecoGrammar.Release(); MessageBox( NULL, _T("Error loading grammar."), _T("Error"), MB_OK ); EndDialog( hDlg, LOWORD(wParam) ); return FALSE; } } else { // Disable Emulate Recognition
EnableWindow( GetDlgItem(hDlg, IDC_EDIT_PARSETEXT), FALSE );
// Release grammar
pThis->m_cpRecoGrammar.Release(); } return TRUE; case IDB_MUTE: { // Check if the user has selected mute
if( SendDlgItemMessage( hDlg, IDB_MUTE, BM_GETCHECK, 0, 0 ) ) { pThis->m_cpRecognizer->SetRecoState( SPRST_INACTIVE ); } else { pThis->m_cpRecognizer->SetRecoState( SPRST_ACTIVE ); } } return TRUE;
case IDC_BUTTON_SUBMIT: { CSpDynamicString dstrText; int iStrLen = 0; TCHAR szEmulateRecoText[NORM_SIZE]; USES_CONVERSION;
UINT numChar = GetDlgItemText( hDlg, IDC_EDIT_PARSETEXT, szEmulateRecoText, NORM_SIZE ); if( pThis->m_cpRecoGrammar ) { pThis->m_dstr = L""; HRESULT hr = pThis->EmulateRecognition(T2W(szEmulateRecoText)); if( SP_NO_PARSE_FOUND == hr ) { ::SendMessage( GetDlgItem(hDlg, IDC_LIST_PHRASES), WM_SETTEXT, 0, (LPARAM)"<Unrecognized phrase>"); } } } return TRUE; } } return TRUE;
case WM_CLOSE: { // Release grammar
pThis->m_cpRecoGrammar.Release(); EndDialog( hDlg, LOWORD(wParam) ); } return TRUE; } return FALSE; }
/****************************************************************************
* CCompiler::AddStatus * *---------------------------* * Description: * Writes compile output to the status window. *****************************************************************************/ void CCompiler::AddStatus(HRESULT hr, UINT uID, const TCHAR * pFmtString) { USES_CONVERSION; TCHAR sz[MAX_PATH]; ::LoadString(m_hInstance, uID, sz, sp_countof(sz)); if (pFmtString) { TCHAR szFormatted[MAX_PATH]; ::wsprintf(szFormatted, sz, pFmtString); AddError(-1, hr, T2W(szFormatted), NULL, 0); } else { AddError(-1, hr, T2W(sz), NULL, 0); } }
/****************************************************************************
* CCompiler::AddError * *---------------------------* * Description: * Writes compile error messages to the status window. *****************************************************************************/ STDMETHODIMP CCompiler::AddError(const long lLine, HRESULT hr, const WCHAR * pszDescription, const WCHAR * pszHelpFile, DWORD dwHelpContext) { if (FAILED(hr) && SUCCEEDED(m_hrWorstError)) { m_hrWorstError = hr; } USES_CONVERSION; TCHAR *pszText = NULL; TCHAR *pszFinalOutput = NULL; if (hr == S_OK) { pszFinalOutput = W2T(pszDescription); } else { pszText = new TCHAR[ MAX_PATH + _tcslen( m_szXMLSrcFile ) + _tcslen( W2T(pszDescription) ) ]; if ( pszText ) { if (lLine >= 0) { wsprintf(pszText, SUCCEEDED(hr) ? _T("%s(%d) Warning: %s\n") : _T("%s(%d) Error: %s\n"), m_szXMLSrcFile, lLine, W2T(pszDescription)); } else { wsprintf(pszText, SUCCEEDED(hr) ? _T("%s Warning: %s\n") : _T("%s Error: %s\n"), m_szXMLSrcFile, W2T(pszDescription)); }
pszFinalOutput = pszText; } else { // out of memory: just give the description
pszFinalOutput = W2T(pszDescription); } }
bool fNeedToUpdateWidth = false; // Might need to tell the listbox to show the hscroll
HWND hwndList = NULL; if( m_hDlg ) // dialog
{ if( m_fCommandLine ) { int iRet = ::SendDlgItemMessage(m_hDlg, IDC_LIST_STATUS, LB_ADDSTRING, 0, (LPARAM)pszFinalOutput); hwndList = ::GetDlgItem( m_hDlg, IDC_LIST_STATUS ); fNeedToUpdateWidth = (LB_ERR != iRet); } else { _tprintf( pszFinalOutput ); } } else // window
{ int iRet = ::SendMessage( m_hWndStatus, LB_ADDSTRING, 0, (LPARAM) pszFinalOutput ); hwndList = m_hWndStatus; fNeedToUpdateWidth = (LB_ERR != iRet); }
if ( fNeedToUpdateWidth ) { // Listboxes do not update their horizontal extent dynamically,
// so we need to do so here.
HDC hdc = ::GetDC( hwndList ); SIZE size; ::GetTextExtentPoint32( hdc, pszFinalOutput, _tcslen( pszFinalOutput ), &size ); ::ReleaseDC( hwndList, hdc );
int iCurrentWidth = (int) ::SendMessage( hwndList, LB_GETHORIZONTALEXTENT, 0, 0 ); if ( size.cx > iCurrentWidth ) { ::SendMessage( hwndList, LB_SETHORIZONTALEXTENT, size.cx, 0 ); }
}
if ( pszText ) { delete[] pszText; }
return S_OK; }
/****************************************************************************
* CCompiler::EnterIdle * *---------------------------* * Description: * Calls the SAPI grammar compiler to compile the xml file. *****************************************************************************/ HRESULT CCompiler::EnterIdle() { HRESULT hr = S_OK;
if (m_fNeedStartCompile) { BOOL bWorked = FALSE; m_fNeedStartCompile = FALSE; CSpFileStream Source(&hr, m_szXMLSrcFile); AddInternalError(hr, IDS_CANTOPENSOURCE, m_szXMLSrcFile); if (SUCCEEDED(hr)) { CSpFileStream Dest(&hr, m_szCFGDestFile, GENERIC_WRITE, 0, CREATE_ALWAYS); AddInternalError(hr, IDS_CANTOPENDEST, m_szCFGDestFile); if (SUCCEEDED(hr) && strlen(m_szHeaderDestFile)) { CSpFileStream Header(&hr, m_szHeaderDestFile, GENERIC_WRITE, 0, CREATE_ALWAYS); AddInternalError(hr, IDS_CANTOPENDEST, m_szHeaderDestFile); WriteStream(&Header, "#ifndef __"); StripWrite(&Header, m_szHeaderDestFile); WriteStream(&Header, "_IDs__\n"); WriteStream(&Header, "#define __"); StripWrite(&Header, m_szHeaderDestFile); WriteStream(&Header, "_IDs__\n\n");
if (SUCCEEDED(hr)) { if( !m_fSilent ) { hr = m_cpCompiler->CompileStream(&Source, &Dest, &Header, NULL, this, 0); } else { hr = m_cpCompiler->CompileStream(&Source, &Dest, &Header, NULL, m_cpError, 0); } } if (SUCCEEDED(hr)) { WriteStream(&Header, "\n#endif\n"); } } else { if (SUCCEEDED(hr)) { if( !m_fSilent ) { hr = m_cpCompiler->CompileStream(&Source, &Dest, NULL, NULL, this, 0); } else { hr = m_cpCompiler->CompileStream(&Source, &Dest, NULL, NULL, m_cpError, 0); } } }
if (SUCCEEDED(hr) && SUCCEEDED(m_hrWorstError)) { AddStatus(S_OK, IDS_COMPILESUCCESS); bWorked = TRUE; if (m_fSilent) { ::EndDialog(m_hDlg, S_OK); } } else { AddStatus(hr, IDS_COMPILEFAILURE); bWorked = FALSE; if (m_fSilent) { ::EndDialog(m_hDlg, S_OK); } } } if (!bWorked) { ::DeleteFile(m_szCFGDestFile); } }
return hr; }
/****************************************************************************
* CCompiler::LoadGrammar * *---------------------------* * Description: * Loads and activates the Grammar ***************************************************************** Leonro ****/ HRESULT CCompiler::LoadGrammar( TCHAR* szPath ) { HRESULT hr = S_OK;
// load grammar
hr = m_cpRecoContext->CreateGrammar(GRAM_ID, &m_cpRecoGrammar); if (SUCCEEDED(hr)) { USES_CONVERSION; hr = m_cpRecoGrammar->LoadCmdFromFile( T2W(szPath), SPLO_STATIC ); if (FAILED(hr)) { m_cpRecoGrammar.Release(); } } return hr; }
/****************************************************************************
* CCompiler::WriteStream * *---------------------------* * Description: * Calls write on the output stream *****************************************************************************/ HRESULT CCompiler::WriteStream(IStream * pStream, const char * pszText) { ULONG cch = strlen(pszText); return pStream->Write(pszText, cch, NULL); }
/****************************************************************************
* CCompiler::StripWrite * *---------------------------* * Description: * Strips characters off strings *****************************************************************************/ HRESULT CCompiler::StripWrite(IStream * pStream, const char * pszText) { ULONG cch = strlen(pszText); char * psz = (char *)_alloca((cch + 1) * sizeof(char)); char c; char * pszWork = psz; do { c = *pszText++; *pszWork++ = ((c == 0) || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) ? c : '_'; } while (c); return pStream->Write(psz, cch, NULL); }
/****************************************************************************
* CCompiler::CallOpenFileDialog * *---------------------------* * Description: * Displays the open dialog box to retrieve the * user-selected .txt or .xml file for synthisizing *************************************************************** Leonro ******/ BOOL CCompiler::CallOpenFileDialog( HWND hWnd, LPSTR szFileName, TCHAR* szFilter ) { OPENFILENAME ofn; BOOL bRetVal = TRUE; LONG lRetVal; HKEY hkResult; TCHAR szPath[NORM_SIZE] = _T(""); DWORD size = NORM_SIZE;
// Open the last directory used by this app (stored in registry)
lRetVal = RegCreateKeyEx( HKEY_CURRENT_USER, _T("SOFTWARE\\Microsoft\\Speech\\AppData\\PathToGrammarFiles"), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkResult, NULL );
if( lRetVal == ERROR_SUCCESS ) { RegQueryValueEx( hkResult, _T("GramCompFiles"), NULL, NULL, (PBYTE)szPath, &size ); }
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = hWnd; ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = NULL; ofn.nFilterIndex = 1; ofn.lpstrInitialDir = szPath; ofn.lpstrFile = szFileName; ofn.nMaxFile = NORM_SIZE; ofn.lpstrTitle = NULL; ofn.lpstrFileTitle = NULL; ofn.lpstrDefExt = _T("xml"); ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
// Pop the dialog
bRetVal = GetOpenFileName( &ofn ); // Write the directory path you're in to the registry
TCHAR pathstr[NORM_SIZE] = _T(""); strcpy( pathstr, szFileName );
int i=0; while( pathstr[i] != NULL ) { i++; } while( pathstr[i] != '\\' ) { i --; } pathstr[i] = NULL;
RegSetValueEx( hkResult, _T("GramCompFiles"), NULL, REG_EXPAND_SZ, (PBYTE)pathstr, strlen(pathstr)+1 );
RegCloseKey( hkResult );
return bRetVal; }
/****************************************************************************
* CCompiler::CallSaveFileDialog * *---------------------------* * Description: * Displays the save file dialog box and retrieves * the user-selected save file name. *************************************************************** Leonro ******/ BOOL CCompiler::CallSaveFileDialog( HWND hWnd, TCHAR* szSaveFile ) { TCHAR pszFileName[MAX_PATH] = _T(""); BOOL bSuccess = TRUE; static TCHAR pszFilter[MAX_PATH] = _T("leon");
OPENFILENAME ofn; ZeroMemory( &ofn, OPENFILENAME_SIZE_VERSION_400 ); ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = hWnd; ofn.hInstance = m_hInstance; ofn.lpstrFilter = "XML Files (*.xml)\0*.xml\0Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0"; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = szSaveFile; ofn.nMaxFile = MAX_PATH; ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrFileTitle = NULL; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = NULL; ofn.Flags = OFN_CREATEPROMPT; ofn.lpstrDefExt = "xml";
bSuccess = GetSaveFileName( &ofn ); return bSuccess; }
/****************************************************************************
* CCompiler::FileSave * *---------------------------* * Description: * Saves the TOM file to disk **************************************************************** Leonro *****/ HRESULT CCompiler::FileSave( HWND hWnd, CCompiler* pComp, TCHAR* szSaveFile ) //
{ VARIANT Var; HRESULT hr = S_OK; BOOL bRetVal = TRUE; USES_CONVERSION;
// Call save file dialog if there's no file name already
if( !_tcscmp( szSaveFile, "" ) ) { bRetVal = CallSaveFileDialog( hWnd, szSaveFile ); }
// TOM save file
if( bRetVal ) { // Save it
VariantInit( &Var ); Var.vt = VT_BSTR; Var.bstrVal = SysAllocString( T2W(szSaveFile) ); // Will use Win32 file command
hr = pComp->m_cpTextDoc->Save( &Var, tomCreateAlways, 1200 ); hr &= ~0x40000; // Mask off bit 18
SysFreeString( Var.bstrVal );
if( SUCCEEDED( hr ) ) { // Set the compiler source file to the newly saved file
_tcscpy( pComp->m_szXMLSrcFile, szSaveFile ); } else { _tcscpy( szSaveFile, _T("") ); }
// If the text document has been saved
if( SUCCEEDED( hr ) ) { pComp->m_cpTextDoc->SetSaved( tomTrue ); } } else { hr = E_FAIL; }
return hr; }
/****************************************************************************
* CCompiler::Compile * *---------------------------* * Description: * Handles compiling the text in the editor. This function calls CCompiler::EnterIdle * to do the actual compiling. ***************************************************************** Leonro ****/ HRESULT CCompiler::Compile( HWND hWnd, TCHAR* szSaveFileName, TCHAR* szTitle, CCompiler* pComp ) { HRESULT hr = S_OK; long lSaved = 0;
// reset errors
pComp->m_hrWorstError = 0;
// Save file first if it has not been saved
hr = pComp->m_cpTextDoc->GetSaved( &lSaved ); if( lSaved == tomFalse && SUCCEEDED( hr ) ) { // TOM save file
hr = FileSave( hWnd, pComp, szSaveFileName ); if( hr == STG_E_ACCESSDENIED ) // Handle read only files
{ MessageBox( pComp->m_hWndEdit, _T("This file exists with Read Only attributes.\n Please use a different file name."), _T("File Save"), MB_OK ); // Call FileSave again but this time pop the save file dialog box
hr = FileSave( hWnd, pComp, szSaveFileName ); } // Add the file name to the title bar
if( SUCCEEDED( hr ) ) { LoadString( pComp->m_hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING ); _tcscat( szTitle, _T(" - [") ); _tcscat( szTitle, szSaveFileName ); _tcscat( szTitle, _T("]") ); SetWindowText( hWnd, szTitle ); } }
// If everything has succeeded but there is no source text in the editor
// set hr to InvalidArg
if( SUCCEEDED( hr ) && !*pComp->m_szXMLSrcFile ) { hr = E_INVALIDARG; }
// Clear out the listbox of any previous errors
::SendMessage( m_hWndStatus, LB_RESETCONTENT, 0, 0 );
// Set up the compiler and do it
if( SUCCEEDED( hr ) ) { // construct name from m_szXMLSrcFile
_tcscpy(pComp->m_szCFGDestFile, pComp->m_szXMLSrcFile); _tcscpy(&pComp->m_szCFGDestFile[strlen(pComp->m_szCFGDestFile) -3], _T("cfg")); // update text in Status Window
TCHAR sz[MAX_PATH]; TCHAR *pszOutput = new TCHAR[ sp_countof(sz) + _tcslen( pComp->m_szXMLSrcFile ) ]; if ( pszOutput ) { LoadString( m_hInstance, IDS_COMPFILE, sz, sp_countof(sz) ); wsprintf( pszOutput, sz, pComp->m_szXMLSrcFile ); ::SendMessage( m_hWndStatus, LB_INSERTSTRING, 0, (LPARAM) pszOutput );
// Size the listbox
HDC hdc = ::GetDC( m_hWndStatus ); SIZE size; ::GetTextExtentPoint32( hdc, pszOutput, _tcslen( pszOutput ), &size ); ::ReleaseDC( m_hWndStatus, hdc ); ::SendMessage( m_hWndStatus, LB_SETHORIZONTALEXTENT, size.cx, 0 ); delete[] pszOutput; }
// call the actual compile step
pComp->EnterIdle(); // repaint
InvalidateRect( hWnd, NULL, FALSE ); // Check for compile errors
hr = pComp->m_hrWorstError; if( FAILED( hr ) ) { pComp->m_fNeedStartCompile = TRUE; } else { pComp->m_fNeedStartCompile = FALSE; } } return hr; }
/****************************************************************************
* CCompiler::RecoEvent * *---------------------------* * Description: * Helper function that handles speech events **************************************************************** Leonro *****/ void CCompiler::RecoEvent( HWND hDlg, CCompiler* pComp ) { USES_CONVERSION; HRESULT hr=S_OK; CSpEvent event; long iNewPhrase=0; static BOOL fStartSound = FALSE;
if( pComp->m_cpRecoContext ) { while( event.GetFrom(pComp->m_cpRecoContext) == S_OK ) { // Switch on recognition event
switch( event.eEventId ) { case SPEI_SOUND_START: fStartSound = TRUE; m_dstr = L""; break;
case SPEI_SOUND_END: if( fStartSound ) { fStartSound = FALSE; if( !pComp->m_fGotReco ) { CSpDynamicString dstrText = L"<noise>"; TCHAR* szUnRecoString = W2T( dstrText.m_psz ); iNewPhrase = SendDlgItemMessage( hDlg, IDC_LIST_PHRASES, LB_ADDSTRING, 0, (LPARAM)szUnRecoString ); SendDlgItemMessage( hDlg, IDC_LIST_PHRASES, LB_SETCURSEL, iNewPhrase, 0); } pComp->m_fGotReco = FALSE; } break;
case SPEI_FALSE_RECOGNITION: ::SendMessage( GetDlgItem(hDlg, IDC_LIST_PHRASES), WM_SETTEXT, 0, (LPARAM)"<Unrecognized>"); break;
case SPEI_RECOGNITION: case SPEI_HYPOTHESIS: Recognize( hDlg, *pComp, event ); break; } } } }
/****************************************************************************
* CCompiler::Recognize * *----------------------* * Description: * Helper function that handles recognition events *************************************************************** MarkNik *****/ void CCompiler::Recognize( HWND hDlg, CCompiler &rComp, CSpEvent &rEvent ) { USES_CONVERSION; CComPtr<ISpRecoResult> cpResult; cpResult = rEvent.RecoResult(); HRESULT hr = S_OK; long iNewPhrase=0;
rComp.m_fGotReco = TRUE;
CSpDynamicString dstrText;
SPPHRASE *pElements; if( SUCCEEDED( cpResult->GetPhrase( &pElements ) ) ) { _ASSERT(pElements->ullGrammarID == GRAM_ID); TCHAR szText[256];
HWND hwndEdit = GetDlgItem(hDlg, IDC_LIST_PHRASES); ULONG CurrentLen = ::SendMessage( hwndEdit, WM_GETTEXTLENGTH, 0, 0 );
if( SPEI_RECOGNITION == rEvent.eEventId ) { m_dstr.Append( L"------------- Recognition Event: ------------- \r\n\r\n" ); } else if ( SPEI_HYPOTHESIS == rEvent.eEventId ) { m_dstr.Append( L"------------- Hypothesis Event: ------------- \r\n\r\n" ); } else { m_dstr.Append( L"Unknown Event...:\r\n\r\n" ); }
if (pElements->Rule.pszName || pElements->Rule.ulId) { wsprintf(szText, "RULE=\"%s\" (%05d)\r\n", W2T(pElements->Rule.pszName), pElements->Rule.ulId); m_dstr.Append( T2W(szText) ); hr = cpResult->GetText( SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL ); if( SUCCEEDED( hr ) ) { m_dstr.Append( dstrText ); } else { m_dstr.Append( L"<Unrecognized phrase>" ); } } else { m_dstr = L"DICTATION\r\n"; CSpDynamicString dstrText; hr = cpResult->GetText( SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL ); if( SUCCEEDED( hr ) ) { m_dstr.Append( dstrText ); } else { m_dstr.Append( L"<Unrecognized DICTATION>" ); } }
m_dstr.Append(L"\r\n"); if (pElements->pProperties) { m_dstr.Append(L"\r\nPROPERTIES:\r\n"); ConstructPropertyDisplay(pElements->pElements, pElements->pProperties, m_dstr, 0); }
m_dstr.Append(L"\r\nPARSE TREE:\r\n"); ConstructRuleDisplay(&pElements->Rule, m_dstr, 0);
m_dstr.Append(L"\r\nELEMENTS:\r\n"); for (ULONG i = 0; i < pElements->Rule.ulCountOfElements; i++) { wsprintf(szText, " <%u - %u> \"%s\" %c(%c)\r\n", pElements->pElements[i].ulAudioStreamOffset, pElements->pElements[i].ulAudioStreamOffset + pElements->pElements[i].ulAudioSizeBytes, W2T(pElements->pElements[i].pszDisplayText), ConfidenceGroupChar(pElements->pElements[i].ActualConfidence), ConfidenceGroupChar(pElements->pElements[i].RequiredConfidence)); m_dstr.Append(T2W(szText)); }
m_dstr.Append( L"\r\n\r\n" ); ::SendMessage( hwndEdit, WM_SETTEXT, 0, (LPARAM)W2T(m_dstr));
::CoTaskMemFree(pElements); } else { ::SendMessage( GetDlgItem(hDlg, IDC_LIST_PHRASES), WM_SETTEXT, 0, (LPARAM)"<Unrecognized>"); } }
/****************************************************************************
* CCompiler::EmulateRecognition * *-----------------------------------* * Description: * Allows users to input text to emmulate recognition * ***************************************************************** PhilSch ***/ HRESULT CCompiler::EmulateRecognition(WCHAR *pszText) { HRESULT hr = S_OK;
// Get local info
SPRECOGNIZERSTATUS stat; LANGID LangID; ZeroMemory(&stat, sizeof(stat)); m_cpRecognizer->GetStatus(&stat); LangID = stat.aLangID[0];
CComPtr<ISpPhraseBuilder> cpPhrase; if (SUCCEEDED(CreatePhraseFromText(pszText, &cpPhrase, LangID)) && m_cpRecognizer) { return( m_cpRecognizer->EmulateRecognition(cpPhrase) ); }
return S_FALSE; }
/* MEMBER FUNCTIONS FOR THE COMMAND LINE VERSION OF THE APPLICATION ONLY*/ /****************************************************************************
* CCompiler::InitDialog * *---------------------------* * Description: * Initializes the command line version of the compile status dialog box *****************************************************************************/ BOOL CCompiler::InitDialog(HWND hDlg) { m_hDlg = hDlg; TCHAR sz[MAX_PATH]; ::LoadString(m_hInstance, IDS_COMPFILE, sz, sp_countof(sz)); TCHAR szTitle[MAX_PATH]; wsprintf(szTitle, sz, m_szXMLSrcFile); ::SendDlgItemMessage(hDlg, IDC_STATUS, WM_SETTEXT, 0, (LPARAM)szTitle); return TRUE; }
/****************************************************************************
* CCompiler::DialogProc * *---------------------------* * Description: * Message handler for command line version of dialog box *****************************************************************************/ int CALLBACK CCompiler::DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { CCompiler * pThis = (CCompiler *)::GetWindowLong(hDlg, GWL_USERDATA); switch (message) { case WM_INITDIALOG: ::SetWindowLong(hDlg, GWL_USERDATA, lParam); pThis = (CCompiler *)lParam; return pThis->InitDialog(hDlg); //1
case WM_PAINT: if (pThis->m_fNeedStartCompile) { ::PostMessage(hDlg, WM_APP, 0, 0); } break;
case WM_APP: pThis->EnterIdle(); return TRUE;
case WM_COMMAND: { if (LOWORD(wParam) == IDOK) { EndDialog(hDlg, 0); return TRUE; } } break; } return FALSE; }
/****************************************************************************
* CError::AddError * *------------------* * Description: * * Returns: * ***************************************************************** PhilSch ***/
HRESULT CError::AddError(const long lLine, HRESULT hr, const WCHAR * pszDescription, const WCHAR * pszHelpFile, DWORD dwHelpContext) { SPDBG_FUNC("CError::AddError"); USES_CONVERSION; ATLTRACE(L"%s(%d) : %s\n", T2W(m_pszFileName), lLine, pszDescription); return S_OK; } /****************************************************************************
* CError::Init * *--------------* * Description: * * Returns: * ***************************************************************** PhilSch ***/
HRESULT CError::Init(const char *pszFileName) { SPDBG_FUNC("CError::Init"); m_pszFileName = pszFileName; return S_OK; }
/****************************************************************************
* CRecoDlgClass::ConstructPropertyDisplay * *-----------------------------------------* * Description: * * Returns: * ***************************************************************** PhilSch ***/
HRESULT CCompiler::ConstructPropertyDisplay(const SPPHRASEELEMENT *pElem, const SPPHRASEPROPERTY *pProp, CSpDynamicString & dstr, ULONG ulLevel) { SPDBG_FUNC("CRecoDlgClass::ConstructPropertyDisplay"); HRESULT hr = S_OK; USES_CONVERSION; TCHAR szText[256];
// constrcut indent
while(SUCCEEDED(hr) && pProp) { wsprintf(szText, " [%2d, %2d] ", pProp->ulFirstElement, pProp->ulFirstElement + pProp->ulCountOfElements); for (ULONG i = 0; i < ulLevel; i++) { dstr.Append(L"\t"); } if (pProp->pszName) { if (wcslen(pProp->pszName) > 240) { dstr.Append(L"\"(Rule name too long)\" = \""); } else { wsprintf(szText, "\"%s\" = \"", W2T(pProp->pszName)); dstr.Append(T2W(szText)); } } else { dstr.Append(L"\"(UNK)\" = \""); } if (!pProp->pszValue) { // construct the value from the elements!
ULONG ulEndElement = pProp->ulFirstElement + pProp->ulCountOfElements; for (ULONG j = pProp->ulFirstElement; j < ulEndElement; j++) { if (j+1 < ulEndElement) { dstr.Append2(pElem[j].pszDisplayText, L" "); } else { dstr.Append(pElem[j].pszDisplayText); } } } else { dstr.Append(pProp->pszValue); }
if (pProp->vValue.vt != VT_EMPTY) { CComVariant cv = pProp->vValue; cv.ChangeType(VT_BSTR); wsprintf(szText, "\" (%d = %s)", pProp->ulId, W2T(cv.bstrVal)); } else { wsprintf(szText, "\" (%d)", pProp->ulId); } dstr.Append2(T2W(szText), L"\r\n"); if (pProp->pFirstChild) { hr = ConstructPropertyDisplay(pElem, pProp->pFirstChild, dstr, ulLevel + 1); } pProp = pProp->pNextSibling; } return hr; }
/****************************************************************************
* CRecoDlgClass::ConstructRuleDisplay * *-------------------------------------* * Description: * * Returns: * ***************************************************************** PhilSch ***/
HRESULT CCompiler::ConstructRuleDisplay(const SPPHRASERULE *pRule, CSpDynamicString &dstr, ULONG ulLevel) { SPDBG_FUNC("CRecoDlgClass::ConstructRuleDisplay"); HRESULT hr = S_OK;
USES_CONVERSION; TCHAR szText[256];
// constrcut indent
while(SUCCEEDED(hr) && pRule) { wsprintf(szText, " [%2d, %2d] ", pRule->ulFirstElement, pRule->ulFirstElement + pRule->ulCountOfElements); for (ULONG i = 0; i < ulLevel; i++) { dstr.Append(L"\t"); } if (pRule->pszName) { if (wcslen(pRule->pszName) > 240) { dstr.Append(L"\"(Rule name too long)\" = \""); } else { wsprintf(szText, "%s \"%s\" (%d)", szText, W2T(pRule->pszName), pRule->ulId); dstr.Append(T2W(szText)); } } else { dstr.Append(L"\"(UNK)\" = \""); } dstr.Append(L"\r\n"); if (pRule->pFirstChild) { hr = ConstructRuleDisplay(pRule->pFirstChild, dstr, ulLevel + 1); } pRule = pRule->pNextSibling; } return hr; }
|