home *** CD-ROM | disk | FTP | other *** search
- /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- Copyright (c) 1998 Microsoft Corporation
-
- Module Name:
-
- app.cpp
-
- Abstract:
-
- SR App sample main application class implementation.
-
- Environment:
-
- AutoPC
-
- -------------------------------------------------------------------*/
- #include <Windows.h>
- #include <asfc.h>
- #include <ascmnctl.h>
- #include <keypad.h>
- #include <apcdebug.h>
-
- #include "resource.h"
- #include "appsink.h"
- #include "app.h"
-
- // macro to release an interface pointer and set it to zero
- #define RELEASE_IF(i)\
- if(i){\
- i->Release();\
- i=NULL; }
-
- //------------------------------------------------------------------------------
- //
- // Main application Class
- //
- //--------------------------------------------------------------------------
-
- //+-------------------------------------------------------------------------
- //
- // Function: CSRApp::CSRApp
- //
- // Synopsis: Contructor for CSRApp
- //
- // Arguments: hInst - Instance handle
- //
- //---------------------------------------------------------------------------
- CSRApp::CSRApp( HINSTANCE hInst)
- {
-
- // Sinks
- m_pFormEventSink = NULL;
- m_pAppMessageSink = NULL;
- m_pAppEventSink = NULL;
-
- m_bstrAppName = NULL;
-
- // Forms Manager/etc.
- m_pManage = NULL;
- m_pActiveForms = NULL;
- m_pFmSys = NULL;
-
- m_hInst = hInst;
- m_hFC = NULL;
- m_xres = NULL;
- m_yres = NULL;
-
- // Forms
- m_pMainForm = NULL;
- m_pColorsForm = NULL;
- m_pNumbersForm = NULL;
-
- // Controls
- m_pPLBMainFormMenu = NULL;
- m_pNumbersLabel = NULL;
-
- // Speech and voice menus
- m_pSpeech = NULL;
- m_pVMNumbersForm = NULL;
- m_pVMColorsForm = NULL;
-
- // Init COM
- CoInitializeEx( NULL, COINIT_MULTITHREADED );
- m_idThread = GetCurrentThreadId(); // save the id of the main thread
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CSRApp::~CSRApp
- //
- // Synopsis: Destructor for CSRApp
- //
- // Arguments: void
- //
- //---------------------------------------------------------------------------
- CSRApp::~CSRApp()
- {
- if (m_pManage){
- m_pManage->DeregisterStartedApplication(m_hFC, m_bstrAppName);
- }
-
- // Release forms (uses macro defined at top of file)
-
- if(m_pMainForm) m_pMainForm->Close();
- RELEASE_IF(m_pMainForm)
-
- if(m_pColorsForm) m_pColorsForm->Close();
- RELEASE_IF(m_pColorsForm)
-
- if(m_pNumbersForm) m_pNumbersForm->Close();
- RELEASE_IF(m_pNumbersForm)
-
- // Release controls
- RELEASE_IF(m_pPLBMainFormMenu)
- RELEASE_IF(m_pNumbersLabel)
-
- RELEASE_IF(m_pVMNumbersForm)
- RELEASE_IF(m_pVMColorsForm)
- RELEASE_IF(m_pSpeech)
-
- RELEASE_IF(m_pFmSys)
- RELEASE_IF(m_pActiveForms)
- RELEASE_IF(m_pManage)
-
- RELEASE_IF(m_pFormEventSink)
- RELEASE_IF(m_pAppMessageSink)
- RELEASE_IF(m_pAppEventSink)
-
- if(m_bstrAppName)
- {
- SysFreeString(m_bstrAppName);
- m_bstrAppName = NULL;
- }
-
- if(m_bstrNoColors)
- {
- SysFreeString(m_bstrNoColors);
- m_bstrNoColors = NULL;
- }
-
- if(m_bstrNoColorsTitle)
- {
- SysFreeString(m_bstrNoColorsTitle);
- m_bstrNoColorsTitle = NULL;
- }
-
- UnInitASFormsManager(); // uninitialize the forms manager
- CoUninitialize(); // uninitialize COM
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CSRApp::Init
- //
- // Synopsis: Initialization for CSRApp
- //
- // Arguments: void
- //
- // Returns: TRUE on success
- //
- //---------------------------------------------------------------------------
- BOOL
- CSRApp::Init()
- {
- HRESULT hr;
-
- DEBUGCHK(g_pApp);
-
- // get the app name from the resource script
- if(!LoadBSTR(STR_APP_SHELL_NAME, &m_bstrAppName))
- return FALSE;
-
- // Allocate BSTRs for other strings we use in program
- if(!LoadBSTR(IDS_NOCOLORS, &m_bstrNoColors))
- return FALSE;
-
- if(!LoadBSTR(IDS_NOCOLORS_TITLE, &m_bstrNoColorsTitle))
- return FALSE;
-
- m_bstrNumbers = SysAllocStringLen(NULL, 50);
- if(!m_bstrNumbers)
- return FALSE;
-
- InitASFormsManager(); // Initialize the forms manager
-
- hr = CreateSinks();
- if(FAILED(hr))
- return FALSE;
- DEBUGMSG(ZONE_VERBOSE, (L"SRApp: Sinks Created.\n"));
-
- hr = GetFormsManager();
- if(FAILED(hr))
- return FALSE;
- DEBUGMSG(ZONE_VERBOSE, (L"SRApp: Got Forms manager.\n"));
-
- hr = CreateForms();
- if(FAILED(hr))
- return FALSE;
- DEBUGMSG(ZONE_VERBOSE, (L"SRApp: Created forms.\n"));
-
- // Register the application with the forms manager.
- hr = m_pManage->RegisterStartedApplication(m_hFC, m_bstrAppName, 0, 0);
- if(FAILED(hr))
- return FALSE;
- DEBUGMSG(ZONE_VERBOSE, (L"SRApp: Application registered.\n"));
-
- // move app to foreground
- hr = m_pManage->MoveAppToForeground(GetCurrentProcessId(), 0, 0);
- if(FAILED(hr))
- return FALSE;
- DEBUGMSG(ZONE_VERBOSE, (L"SRApp: Application brought to foreground.\n"));
-
- // Create the voice menu that will be used for or "Listen to Numbers" form
- // Don't try and create the colors voice menu until the user selects that option
- // from the main form menu
- hr = CreateNumbersVoiceMenu();
- if(FAILED(hr))
- return FALSE;
-
- // Make the class message sink and the event sink for the app.
- // This is so we can take direct key presses and process them.
- hr = m_pManage->put_ClassMsgSink(m_pAppMessageSink);
- if(FAILED(hr))
- return FALSE;
- DEBUGMSG(ZONE_VERBOSE, (L"SRApp: App message sink attached to Forms Manager.\n"));
-
- hr = m_pManage->put_EventSink(m_pAppEventSink);
- if(FAILED(hr))
- return FALSE;
- DEBUGMSG(ZONE_VERBOSE, (L"SRApp: Event sink attached to Forms Manager.\n"));
-
- if (m_pActiveForms && m_pMainForm)
- m_pActiveForms->SetFocus(m_pMainForm);
-
- return TRUE;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CSRApp::CreateMainForm
- //
- // Synopsis: Create the main form of this application
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT
- CSRApp::CreateForms()
- {
- BSTR bstr;
- HRESULT hr;
-
- bstr = NULL;
-
- //
- // Create Main Menu form
- //
- DEBUGCHK(!m_pMainForm);
- DEBUGCHK(m_pFormEventSink);
-
- // Load our form from a Dialog resource. LoadFormResource CoCreates
- // the form for us, and returns an IDispatch interface to it.
- IDispatch* pDispMainForm = NULL;
- hr = m_pManage->LoadFormResource(
- (OLE_HANDLE)m_hInst, // Application's instance handle
- IDF_MAIN, // Forms ID
- (IDispatch **)&pDispMainForm, // Interface target
- m_pFormEventSink); // Event sink to attach to form
-
- if(FAILED(hr))
- return E_FAIL;
-
- // Get the IASForm interface from our new form
- hr = pDispMainForm->QueryInterface(IID_ASFORM, (PVOID *)&m_pMainForm);
- if(FAILED(hr))
- return E_FAIL;
-
- // Get a pointer to the menu Power List Box on the main form
- IDispatch* pDispMainFormMenu = NULL;
- hr = m_pMainForm->ItemFromID(IDC_PLB_MENU, (IDispatch **)&pDispMainFormMenu);
- if(FAILED(hr))
- return E_FAIL;
-
- // Ask for the IASPowerListBox interface
- hr = pDispMainFormMenu->QueryInterface(IID_ASPOWERLISTBOX, (PVOID *)&m_pPLBMainFormMenu);
- if(FAILED(hr))
- return E_FAIL;
-
- // Release the IDispatch interface we got from ItemFromID
- pDispMainFormMenu->Release();
-
- // Add items from our menu resource to our main PLB menu
- hr = m_pPLBMainFormMenu->AddItemsFromResource(
- m_hInst, // Application's instance
- MAKEINTRESOURCE(IDM_MAIN), // menu resource
- NULL); // menu state (not used)
-
- if(FAILED(hr))
- return E_FAIL;
-
- // We have to Start our form after everything is set up
- hr = m_pManage->Start(pDispMainForm);
- if(FAILED(hr))
- return E_FAIL;
-
- // Release our main form's IDispatch (we release the main form's IASForm
- // In the app class destructor)
- pDispMainForm->Release();
-
- //
- // Create Listen to Colors form
- //
- DEBUGCHK(!m_pColorsForm);
- DEBUGCHK(m_pFormEventSink);
-
- IDispatch* pDispColorsForm = NULL;
- hr = m_pManage->LoadFormResource(
- (OLE_HANDLE)m_hInst, // Application's instance handle
- IDF_COLORS, // Form ID
- (IDispatch **)&pDispColorsForm, // Interface target
- m_pFormEventSink); // Sink to attach on creation
-
- if(FAILED(hr))
- return E_FAIL;
-
- // Get the IASForm interface for our new form
- hr = pDispColorsForm->QueryInterface(IID_ASFORM, (PVOID *)&m_pColorsForm);
- if(FAILED(hr))
- return E_FAIL;
-
- // Have to start the form after everything is set up
- hr = m_pManage->Start(pDispColorsForm);
- if(FAILED(hr))
- return E_FAIL;
-
- // Release Colors form's IDispatch (release IASForm interface to Colors Form
- // in app class' destructor)
- pDispColorsForm->Release();
-
- //
- // Create Listen to Numbers form
- //
- DEBUGCHK(!m_pNumbersForm);
- DEBUGCHK(m_pFormEventSink);
-
- IDispatch* pDispNumbersForm = NULL;
- hr = m_pManage->LoadFormResource(
- (OLE_HANDLE)m_hInst, // Application's instance handle
- IDF_NUMBERS, // Form ID
- (IDispatch **)&pDispNumbersForm,// Interface target
- m_pFormEventSink); // Sink to attach to new form
-
- if(FAILED(hr))
- return E_FAIL;
-
- // Get the IASForm interface to our ListenToNumbers form
- hr = pDispNumbersForm->QueryInterface(IID_ASFORM, (PVOID *)&m_pNumbersForm);
- if(FAILED(hr))
- return E_FAIL;
-
- // Get an interface to the Label(static text) control on the Listen to numbers
- // form
- IDispatch* pDispNumbersLabel = NULL;
- m_pNumbersForm->ItemFromID(IDC_LABEL_NUMBERS, (IDispatch **)&pDispNumbersLabel);
-
- // Get the ASLabel interface to the label control
- hr = pDispNumbersLabel->QueryInterface(IID_ASLABEL, (PVOID *)&m_pNumbersLabel);
- if(FAILED(hr))
- return E_FAIL;
-
- pDispNumbersLabel->Release();
-
- // Startup our numbers form
- hr = m_pManage->Start(pDispNumbersForm);
- if(FAILED(hr))
- return E_FAIL;
-
- pDispNumbersForm->Release();
-
- return NOERROR;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CSRApp::LoadBSTR
- //
- // Synopsis: Load a string and and put it into BSTR
- //
- // Arguments: uId - Resource id of string to load
- // pBStr - Where to return the BSTR
- //
- // Returns: TRUE for success
- //
- //---------------------------------------------------------------------------
- BOOL CSRApp::LoadBSTR(UINT uID, BSTR* pBStr)
- {
- if(!pBStr)
- return FALSE;
-
- WCHAR wszTemp[128];
- int iStringLen = 128;
-
- if((iStringLen = LoadStringW(m_hInst, uID, wszTemp, iStringLen)) == 0)
- {
- return(FALSE);
- }
-
- *pBStr = SysAllocString(wszTemp);
- // see if the string was allocated
- if (!(*pBStr))
- {
- return(FALSE);
- }
-
- return(TRUE);
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CSRApp::CreateSinks
- //
- // Synopsis: Create default event and message sinks for the application
- // (attached to the forms manager)
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT CSRApp::CreateSinks()
- {
- HRESULT hr;
- CFormEventSink* pFormEventSink;
- CAppMessageSink* pMessageSink;
- DWORD dwMainThreadId;
-
- pFormEventSink = NULL;
- pMessageSink = NULL;
- dwMainThreadId = GetCurrentThreadId();
-
- // Create an instance of our FormEventSink object, which implements IASEventSink,
- // that we will attach to each of the form's we create. (ref count = 0)
- pFormEventSink = new CFormEventSink(dwMainThreadId); // create an event sink object
-
- if(!pFormEventSink)
- return E_OUTOFMEMORY;
-
- // Get an IASEventSink pointer from our object (ref count = 1)
- hr = pFormEventSink->QueryInterface(IID_ASEVENTSINK, (PVOID *) &m_pFormEventSink);
- if(FAILED(hr))
- {
- delete pFormEventSink;
- return hr;
- }
-
- // Create an instance of our AppMessageSink object, which implements IASClassMsgSink
- // and IASEventSink, that we will attach to our forms manager. (ref count = 0)
- pMessageSink = new CAppMessageSink(dwMainThreadId); // create a message sink object
- if(!pMessageSink)
- return E_OUTOFMEMORY;
-
- // Get an IASClassMsgSink pointer from our AppMessageSink object (ref count = 1)
- hr = pMessageSink->QueryInterface(IID_ASCLASSMSGSINK, (PVOID *) &m_pAppMessageSink);
- if(FAILED(hr))
- {
- delete pMessageSink;
- return hr;
- }
-
- // Get an IASEventSink pointer from our AppMessageSink object (ref count = 2)
- hr = pMessageSink->QueryInterface(IID_ASEVENTSINK, (PVOID *) &m_pAppEventSink);
- if (FAILED(hr))
- return hr;
-
- return NOERROR;
- }
-
-
- //+-------------------------------------------------------------------------
- //
- // Function: CApp::CreateNumbersVoiceMenu
- //
- // Synopsis: Creates a voice menu containing 0-9 from a menu resource.
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT
- CSRApp::CreateNumbersVoiceMenu()
- {
- HRESULT hr;
-
- DEBUGCHK(m_pManage);
- DEBUGCHK(!m_pSpeech);
-
- // Get our speech object from the form's manager
- m_pManage->get_Speech(&m_pSpeech);
-
- if(!m_pSpeech)
- return E_NOTIMPL;
-
- // Declare and fill in the necessary fields of a VCMDNAME structure
- VCMDNAME vnNumbers;
- memset(&vnNumbers, NULL, sizeof(VCMDNAME)); // Clear structure
- lstrcpy(vnNumbers.szApplication, L"SR App"); // Put in our application name
- lstrcpy(vnNumbers.szState, L"SR App - Numbers"); // Put in voice menu name
-
- // First we create a voice menu, then we use AddVMenuCommandsFromResource to
- // to add items to it from a menu resource
- hr = m_pSpeech->CreateVMenu(
- NULL, // Null since we don't create a voice command
- &vnNumbers, // Pointer to our VCMDNAME structure
- m_hInst, // Application's instance handle
- 0, // Table size (0 since we aren't creating and words here
- NULL, // Pointer to GrammerID table
- 0, // Flags (not APCSPCH_VM_USEEXISTING since we want a fresh VMenu)
- &m_pVMNumbersForm); // Interface to our new voice menu
- if(FAILED(hr))
- return E_FAIL;
-
- // Add Voice Menu Commands from a resource script to our newly created, blank, VoiceMenu
- hr = m_pSpeech->AddVMenuCommandsFromResource(
- m_pVMNumbersForm, // Interface to our voice menu
- m_hInst, // App instance handle
- MAKEINTRESOURCE(IDVM_NUMBERS),//Resource ID
- NULL, // Menu State (not used in this case)
- 0); // Flags (could be APCSPCH_VM_USEEXISTING if we were making this
- if(FAILED(hr)) // call several times to "build" a menu)
- return E_FAIL;
-
- // Attach the voice menu to our Listen to Numbers form
- hr = m_pNumbersForm->put_VoiceMenu(m_pVMNumbersForm);
- if(FAILED(hr))
- return E_FAIL;
-
- return S_OK;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CApp::CreateColorsVoiceMenu
- //
- // Synopsis: Creates a voice menu containing the eight colors support by
- // the Auto PC v1 devices. First checks to see if all the words have
- // Speaker Dependent or Independent templates, if not, it returns E_FAIL.
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT
- CSRApp::CreateColorsVoiceMenu()
- {
- HRESULT hr;
-
- // Check to see if all the words have been trained already
- if(!IsColorWordsTrained()) return E_FAIL;
-
- // Declare and fill in the necessary fields of a VCMDNAME structure
- VCMDNAME vnColors;
- memset(&vnColors, NULL, sizeof(VCMDNAME)); // Clear the structure
- lstrcpy(vnColors.szApplication, L"SR App"); // Add the application name
- lstrcpy(vnColors.szState, L"SR App - Colors"); // Add the voice menu's name
-
- // Create a blank voice menu
- hr = m_pSpeech->CreateVMenu(
- NULL, // Null since we don't create a voice command
- &vnColors, // Pointer to our VCMDNAME structure
- m_hInst, // Application's instance handle
- 0, // Table size (0 since we aren't creating and words here
- NULL, // Pointer to GrammerID table
- 0, // Flags (not APCSPCH_VM_USEEXISTING since we want a fresh VMenu)
- &m_pVMColorsForm); // Interface to our new voice menu
- if(FAILED(hr))
- return E_FAIL;
-
- // Add Voice Menu Commands from a resource script to our newly created, blank, VoiceMenu
- hr = m_pSpeech->AddVMenuCommandsFromResource(
- m_pVMColorsForm, // Interface to our voice menu
- m_hInst, // App instance handle
- MAKEINTRESOURCE(IDVM_COLORS),//Resource ID
- NULL, // Menu State (not used in this case)
- 0); // Flags, 0 since we want a fresh menu
- if(FAILED(hr))
- return E_FAIL;
-
- // Add "End" to our voice menu
- hr = m_pSpeech->AddVMenuCommandsFromResource(
- m_pVMColorsForm, // Interface to our voice menu
- m_hInst, // App instance handle
- MAKEINTRESOURCE(IDVM_COLORS_END),//Resource ID
- 0, // Menu State (not used here)
- APCSPCH_VM_USEEXISTING); // Flags, USEEXISTING meands don't clear the voice menu, just add
- if(FAILED(hr)) // the items to it
- return E_FAIL;
-
- // Attach the voice menu to the colors form
- hr = m_pColorsForm->put_VoiceMenu(m_pVMColorsForm);
- if(FAILED(hr))
- return E_FAIL;
-
- return NOERROR;
-
- }
-
- BOOL
- CSRApp::IsColorWordsTrained()
- {
- IVCmdUserWord* pVCmdUserWord;
- DWORD dwQPFlags;
-
- // Get the SAPI (Speech Application Programming Interface) IVCmdUserWord
- // interface from our speech object so we can use its methods
- HRESULT hr = m_pSpeech->QuerySpeechInterface(IID_IVCmdUserWord, (PVOID *)&pVCmdUserWord);
- if(FAILED(hr))
- return FALSE;
-
- WCHAR* szColors[8] = { L"Black", L"Red", L"Green", L"Blue",
- L"Yellow", L"Violet", L"Cyan", L"White" };
-
- for(int i=0; i < 8; i++)
- {
- // QueryPhrase tells us what templates are installed on the system
- hr = pVCmdUserWord->QueryPhrase(szColors[i], &dwQPFlags);
-
- // If there is no enabled SpeakerIndependent or SpeakerDependent template,
- // return FALSE
- if( !((dwQPFlags & SRPHRASE_SI) && (dwQPFlags & SRPHRASE_SI_ENABLE)) &&
- !((dwQPFlags & SRPHRASE_SD) && (dwQPFlags & SRPHRASE_SD_ENABLE)) )
- {
- DEBUGMSG(ZONE_VERBOSE, (L"%s template not in system.\n", szColors[i]));
- pVCmdUserWord->Release();
- return FALSE;
- }
- }
-
- pVCmdUserWord->Release();
- return TRUE;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CSRApp::GetFormsManager
- //
- // Synopsis: Create a forms manager object and get display dimensions
- // also get the active forms object
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT
- CSRApp::GetFormsManager()
- {
- HRESULT hr;
-
- // Create the forms manager
- hr = CoCreateInstance(
- CLSID_FMMANAGE, // Forms Manager's class ID
- NULL, // Not using COM aggregation
- CLSCTX_INPROC_SERVER, // Create object in process
- IID_FMMANAGE, // Get us the IfmManage interface
- (PVOID *) &m_pManage); // Interface target
-
- if(FAILED(hr))
- return hr;
-
- // Get the FormsContextHandle, which is basically which faceplate the forms
- // manager will show it on (when we support multiple faceplates)
- hr = m_pManage->GetFormsContextHandle(&m_hFC);
- if(FAILED(hr))
- return hr;
-
- // Get IfmSystem interface
- hr = m_pManage->QueryInterface( IID_FMSYSTEM, (PVOID *) &m_pFmSys );
- if(FAILED(hr))
- return hr;
-
- // Get the X and Y resolution of the display we're on
- hr = m_pFmSys->GetFormDisplayCaps( m_hFC, VERTRES, &m_yres);
- if(FAILED(hr))
- return hr;
-
- hr = m_pFmSys->GetFormDisplayCaps( m_hFC, HORZRES, &m_xres);
- if(FAILED(hr))
- return hr;
-
- // Get IASActiveForms interface
- hr = m_pManage->QueryInterface(IID_ASACTIVEFORMS, (PVOID *) &m_pActiveForms);
- if(FAILED(hr))
- return hr;
-
- return NOERROR;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CSRApp::Quit
- //
- // Synopsis: Post a WM_QUIT to the main thread
- //
- // Arguments: void
- //
- // Returns: void
- //
- //---------------------------------------------------------------------------
-
- void
- CSRApp::Quit()
- {
- ::PostThreadMessage(m_idThread, WM_QUIT, 0, 0);
- return;
- }
-
- void
- CSRApp::AddNumber(int iNum)
- {
- WCHAR wszNewNumberBuffer[100];
-
- wszNewNumberBuffer[0] = '0';
- wszNewNumberBuffer[0] += iNum;
- wszNewNumberBuffer[1] = NULL;
-
- wcscat(m_bstrNumbers, wszNewNumberBuffer);
- m_pNumbersLabel->put_Caption(m_bstrNumbers);
- }
-
-
-