home *** CD-ROM | disk | FTP | other *** search
- //--------------------------------------------------------------------------------------------
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Copyright (c) Microsoft Corporation, 1997 All Rights Reserved
- //
- // Description:
- //
- // Contains the base application level code and classes for a simple Apollo application
- //
- //--------------------------------------------------------------------------------------------
- #include <Windows.h> // standard windows header file
- #include <asfc.h> // form and control interfaces
- #include <ascmnctl.h> // common controls
- #include <keypad.h> // so we can use the keypad (WM_REMOTE_KEYDOWN messages)
- #include <asstyles.h>
-
- // App specific header files
- #include "resource.h" // resource IDs
- #include "app.h" // TTSApp definition
-
- //------------------------------------------------------------------------------
- //
- // Main application Class
- //
- //--------------------------------------------------------------------------
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::CTTSApp
- //
- // Synopsis: Contructor for CTTSApp
- //
- // Arguments: hInst - Instance handle
- //
- //---------------------------------------------------------------------------
- CTTSApp::CTTSApp( HINSTANCE hInst)
- {
- //initialize COM
- CoInitializeEx( NULL, COINIT_MULTITHREADED );
-
- //Thread and instance handle
- m_idThread = GetCurrentThreadId(); // save the id of the main thread
- m_hInst = hInst;
-
- //Sinks
- m_pFormEventSink = NULL;
- m_pAppMessageSink = NULL;
- m_pAppEventSink = NULL;
-
- //Strings
- m_bszAppName = NULL;
- m_bszMenuName = NULL;
- m_bszKeyFeedback = NULL;
- m_bszVoiceFeedback = NULL;
- m_bszMore = NULL;
- m_bszLess = NULL;
-
- //Forms, form manager, and controls
- m_pManage = NULL;
- m_pForm = NULL;
- m_pListBox = NULL;
-
- m_hFC = NULL;
- m_xres = NULL;
- m_yres = NULL;
- m_pSpeech = NULL;
- m_dwKeyFeedback = NULL;
- m_dwVoiceFeedback = NULL;
- m_bExiting = FALSE;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::~CTTSApp
- //
- // Synopsis: Destructor for CTTSApp
- // Releases all interfaces and frees all strings. Deregisters app with
- // forms manager as well.
- //
- // Arguments: void
- //
- //---------------------------------------------------------------------------
- CTTSApp::~CTTSApp()
- {
- //Tell the forms manager to deregister the application
- if (m_pManage) {
- m_pManage->DeregisterStartedApplication(m_hFC, m_bszAppName);
- }
-
- //Delete all the form controls
- DeleteFormControls();
-
- //Close and release the form
- if (m_pForm) {
- m_pForm->Close();
- m_pForm->Release();
- }
-
- //Free app name string
- if(m_bszAppName) SysFreeString(m_bszAppName);
- if(m_bszMenuName) SysFreeString(m_bszMenuName);
- if(m_bszKeyFeedback) SysFreeString(m_bszKeyFeedback);
- if(m_bszVoiceFeedback) SysFreeString(m_bszVoiceFeedback);
- if(m_bszMore) SysFreeString(m_bszMore);
- if(m_bszLess) SysFreeString(m_bszLess);
-
-
- //Release other interfaces we used
- //Forms manager
- if (m_pManage) m_pManage->Release();
-
- //Event sink attatched to form
- if (m_pFormEventSink) m_pFormEventSink->Release();
-
- //Class msg sink attatched to forms manager
- if (m_pAppMessageSink) m_pAppMessageSink->Release();
-
- //Event sink attatched to forms manager
- if (m_pAppEventSink) m_pAppEventSink->Release();
-
- //Speech interface, thanks for the hard work!
- if (m_pSpeech) m_pSpeech->Release();
-
- UnInitASFormsManager(); // uninitialize the forms manager
- CoUninitialize(); // uninitialize COM
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::Init
- //
- // Synopsis: Initialization for CTTSApp
- //
- // Arguments: void
- //
- // Returns: TRUE on success
- //
- //---------------------------------------------------------------------------
- BOOL CTTSApp::Init(VOID)
- {
- HRESULT hr;
-
- if( g_pApp == NULL ) return FALSE;
-
- // Allocate strings
- if(!LoadBSTR(STR_APP_SHELL_NAME, &m_bszAppName)) return FALSE;
- if(!LoadBSTR(IDS_MENUNAME, &m_bszMenuName)) return FALSE;
- if(!LoadBSTR(IDS_KEYFEEDBACK, &m_bszKeyFeedback)) return FALSE;
- if(!LoadBSTR(IDS_VOICEFEEDBACK, &m_bszVoiceFeedback)) return FALSE;
- if(!LoadBSTR(IDS_MORE, &m_bszMore)) return FALSE;
- if(!LoadBSTR(IDS_LESS, &m_bszLess)) return FALSE;
-
- // Initialize the forms manager
- hr = InitASFormsManager();
- if(FAILED(hr)) return FALSE;
-
- hr = CreateSinks();
- if(FAILED(hr)) return FALSE;
-
- hr = GetFormsManager();
- if(FAILED(hr)) return FALSE;
-
- hr = CreateMainForm();
- if(FAILED(hr)) return FALSE;
-
- hr = SpeechInit();
- if(FAILED(hr)) return FALSE;
-
- // Register the application with the forms manager.
- hr = m_pManage->RegisterStartedApplication(m_hFC, m_bszAppName, 0, 0);
- if(FAILED(hr)) return FALSE;
-
- //Bring it to foreground (if it isn't brought up from shell)
- hr = m_pManage->MoveAppToForeground(GetCurrentProcessId(), 0, 0);
- if(FAILED(hr)) return FALSE;
-
- return TRUE;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::CreateMainForm
- //
- // Synopsis: Create the main form of this application
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT CTTSApp::CreateMainForm( VOID)
- {
- HRESULT hr;
-
- // Create the form
- hr = CoCreateInstance(CLSID_ASFORM, NULL, CLSCTX_INPROC_SERVER,
- IID_ASFORM, (PVOID *) &m_pForm);
- if (FAILED(hr)) goto LReturn;
-
- // initialize the newly created form, attatch m_pFormEventSink
- hr = m_pForm->Init(ID_MAINFORM, NULL, m_pFormEventSink);
- if (FAILED(hr)) goto LReturn;
-
- hr = m_pForm->put_Caption(m_bszAppName); //add a caption (for titlebar)
- if (FAILED(hr)) goto LReturn;
-
- m_pForm->put_Visible(TRUE); // make it visible
-
- // create the forms controls
- hr = CreateFormControls();
- if (FAILED(hr)) goto LReturn;
-
- hr = m_pManage->Start(m_pForm); // start the form
- if (FAILED(hr)) goto LReturn;
-
- LReturn:
- if (FAILED(hr))
- {
- // there was an error. Cleanup
- if (m_pForm)
- {
- m_pForm->Close(); // close the form
- m_pForm->Release();
- m_pForm = NULL;
- }
- }
-
- return(hr);
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::SpeechInit
- //
- // Synopsis: Initialize the speech for the CApp object
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT CTTSApp::SpeechInit(void)
- {
- HRESULT hr;
-
- //grab the speech interface from the form
- hr = m_pForm->get_Speech(&m_pSpeech);
- if(FAILED(hr)) return E_FAIL;
-
- hr = GetFeedbackLevels();
- if(FAILED(hr)) return E_FAIL;
-
- //Make sure we get notifications when Speakdone and on Speak progress
- hr = m_pSpeech->SetMsgOptions(NULL, NULL, VTXTF_SPEAKDONE | VTXTF_SPEAK);
- if(FAILED(hr)) return E_FAIL;
-
- return( S_OK);
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::GetFeedbackLevels
- //
- // Synopsis: Queries the speech interface and gets the current feedback
- // level for Key and Voice
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
-
- HRESULT CTTSApp::GetFeedbackLevels(void)
- {
- HRESULT hr;
- hr = m_pSpeech->QueryFeedbackLevel(&m_dwKeyFeedback, &m_dwVoiceFeedback, NULL, 0);
- return hr;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::SpeakStop
- //
- // Synopsis: Stops the speech output
- //
- // Arguments: void
- //
- // Returns: void
- //
- //---------------------------------------------------------------------------
- void CTTSApp::SpeakStop(VOID)
- {
- //Stop speech output
- if (m_pSpeech)
- {
- m_pSpeech->Speak(NULL,0);
- }
- }
-
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::SetFocusOnId
- //
- // Synopsis: Puts the power list box's focus on specified ID
- //
- // Arguments: long - ID of list box item to give focus
- //
- // Returns: void
- //
- //---------------------------------------------------------------------------
-
- void CTTSApp::SetFocusOnId(long lId)
- {
- m_pListBox->put_FocusId(lId);
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::LoadBSTR
- //
- // Synopsis: Load a string and and put it into BSTR
- // Only handles strings < 128 chars
- //
- // Arguments: uId - Resource id of string to load
- // pBStr - Where to return the BSTR
- //
- // Returns: TRUE for success
- //
- //---------------------------------------------------------------------------
- BOOL CTTSApp::LoadBSTR(UINT uID, BSTR* pBStr)
- {
- if(!pBStr)
- return FALSE;
-
- WCHAR wszTemp[128]; //Buffer for resource string
- int iStringLen = 127;
-
- 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: CTTSApp::CreateSinks
- //
- // Synopsis: Creates Event and Class MSG sink for forms manager, and Even sink
- // for the Form itself.
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT CTTSApp::CreateSinks( VOID)
- {
- HRESULT hr = S_OK;
- CFormEventSink * pFormEventSink = NULL;
- CAppMessageSink * pMessageSink = NULL;
-
- pFormEventSink = new CFormEventSink(); // create an event sink object
- if (!pFormEventSink)
- return E_OUTOFMEMORY;
-
- //Get its IASEventSink interface (Form's Event Sink)
- hr = pFormEventSink->QueryInterface(IID_ASEVENTSINK, (PVOID *) &m_pFormEventSink);
- if (FAILED(hr)) {
- delete pFormEventSink;
- return E_FAIL;
- }
-
- pMessageSink = new CAppMessageSink(); // create a message sink object
- if (!pMessageSink)
- return E_OUTOFMEMORY;
-
- //Get its IASClassMsgSink interface (Form Manager(App)'s Class Msg Sink)
- hr = pMessageSink->QueryInterface(IID_ASCLASSMSGSINK, (PVOID *) &m_pAppMessageSink);
- if (FAILED(hr)) {
- delete pMessageSink;
- return E_FAIL;
- }
-
- //Get its IASEventSink interface (Form Manager(App)'s Event Sink)
- hr = pMessageSink->QueryInterface(IID_ASEVENTSINK, (PVOID *) &m_pAppEventSink);
- if (FAILED(hr)) {
- delete pMessageSink;
- return E_FAIL;
- }
-
- return(hr);
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::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 CTTSApp::GetFormsManager( VOID)
- {
- HRESULT hr;
-
- // Create the forms manager
- hr = CoCreateInstance(
- CLSID_FMMANAGE, // Class ID
- NULL, // Object NOT part of an aggregate
- CLSCTX_INPROC_SERVER, // Run object in process
- IID_FMMANAGE, // Get the IfmManage interface
- (PVOID *) &m_pManage); // Target
- if(FAILED(hr)) return E_FAIL;
-
- // get a context handle (used to RegisterStartedApp, etc.)
- hr = m_pManage->GetFormsContextHandle(&m_hFC);
- if(FAILED(hr)) return E_FAIL;
-
- // Get IfmSystem interface (so we can get some system metrics)
- IfmSystem * pFmSys;
- hr = m_pManage->QueryInterface(IID_FMSYSTEM, (PVOID *) &pFmSys);
- if(FAILED(hr)) return E_FAIL;
-
- hr = pFmSys->GetFormDisplayCaps(m_hFC, VERTRES, &m_yres);
- if(FAILED(hr)) return E_FAIL;
-
- hr = pFmSys->GetFormDisplayCaps(m_hFC, HORZRES, &m_xres);
- if(FAILED(hr)) return E_FAIL;
-
- if(pFmSys) pFmSys->Release();
-
- // attatched our Class Msg Sink to the form manager
- hr = m_pManage->put_ClassMsgSink(m_pAppMessageSink);
- if(FAILED(hr)) return E_FAIL;
-
- // attatched our Event sink to the form manager
- hr = m_pManage->put_EventSink(m_pAppEventSink);
- if(FAILED(hr)) return E_FAIL;
-
- return(hr);
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::DeleteFormControls
- //
- // Synopsis:Delete all the correct controls for the app form.
- // Our form only has 1 control
- //
- // Arguments: void
- //
- // Returns: void
- //
- //---------------------------------------------------------------------------
- VOID CTTSApp::DeleteFormControls( VOID)
- {
- if (m_pListBox){
- m_pListBox->Release();
- m_pListBox=NULL;
- }
-
- return;
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::CreateFormControls
- //
- // Synopsis: Create all the correct controls for the app form.
- //
- // Arguments: void
- //
- // Returns: S_OK on success
- //
- //---------------------------------------------------------------------------
- HRESULT CTTSApp::CreateFormControls(VOID)
- {
- HRESULT hr;
-
- // Create the power list box
- hr=CoCreateInstance(
- CLSID_ASPOWERLISTBOX, // Class ID
- NULL, // Object NOT part of an aggergate
- CLSCTX_INPROC_SERVER, // Load in process
- IID_ASPOWERLISTBOX, // We want this interface
- (PVOID *)&m_pListBox); // put it here
- if (FAILED(hr)) return hr;
-
- int iCY = 18;
- //APCGetSystemMetrics(m_hFC, ASM_CYTITLEBAR);
- m_pListBox->SetBounds(0, iCY, m_xres, m_yres - iCY);
-
- m_pListBox->put_Caption(m_bszMenuName); // give the power list box a name
-
- m_pForm->Add(m_pListBox, IDC_LISTBOX); // add it to the form
- m_pListBox->put_Sorted(FALSE); // don't sort the list box
-
- BSTR bStr = NULL;
-
-
- // Create each menu item. For each, tell the list box to create the item, add the caption.
- // Then free the string and release the interface.
- // Create ReadMenu item:
- IASPowerListBoxItem *pReadMenuPLB = NULL;
- hr = m_pListBox->CreateItem((IASPowerListBoxItem**)(&pReadMenuPLB), IDM_READMENU, ASFC_PWRLB_TYPE_COMMAND);
- if (SUCCEEDED(hr))
- {
- if(LoadBSTR(IDS_READMENU, &bStr))
- {
- pReadMenuPLB->put_Caption(bStr);
- SysFreeString(bStr);
- pReadMenuPLB->Release();
- }
- }
-
- // Create HelloWorld item:
- IASPowerListBoxItem *pHelloWorldPLB = NULL;
- hr = m_pListBox->CreateItem((IASPowerListBoxItem**)(&pHelloWorldPLB), IDM_HELLOWORLD, ASFC_PWRLB_TYPE_COMMAND);
- if (SUCCEEDED(hr))
- {
- if(LoadBSTR(IDS_HELLOWORLD, &bStr))
- {
- pHelloWorldPLB->put_Caption(bStr);
- SysFreeString(bStr);
- pHelloWorldPLB->Release();
- }
- }
-
- // Create Welcome item:
- IASPowerListBoxItem *pWelcomePLB = NULL;
- hr = m_pListBox->CreateItem((IASPowerListBoxItem**)(&pWelcomePLB), IDM_WELCOME, ASFC_PWRLB_TYPE_COMMAND);
- if (SUCCEEDED(hr))
- {
- if(LoadBSTR(IDS_WELCOME, &bStr))
- {
- pWelcomePLB->put_Caption(bStr);
- SysFreeString(bStr);
- pWelcomePLB->Release();
- }
- }
-
- // Create SpeakForm item:
- IASPowerListBoxItem *pSpeakFormPLB = NULL;
- hr = m_pListBox->CreateItem((IASPowerListBoxItem**)(&pSpeakFormPLB), IDM_SPEAKFORM, ASFC_PWRLB_TYPE_COMMAND);
- if (SUCCEEDED(hr))
- {
- if(LoadBSTR(IDS_SPEAKFORM, &bStr))
- {
- pSpeakFormPLB->put_Caption(bStr);
- SysFreeString(bStr);
- pSpeakFormPLB->Release();
- }
- }
-
- // Create Feedback item:
- IASPowerListBoxItem *pFeedbackPLB = NULL;
- hr = m_pListBox->CreateItem((IASPowerListBoxItem**)(&pFeedbackPLB), IDM_FEEDBACK, ASFC_PWRLB_TYPE_COMMAND);
- if (SUCCEEDED(hr))
- {
- if(LoadBSTR(IDS_FEEDBACK, &bStr))
- {
- pFeedbackPLB->put_Caption(bStr);
- SysFreeString(bStr);
- pFeedbackPLB->Release();
- }
- }
-
- // Create Exit item:
- IASPowerListBoxItem *pExitPLB = NULL;
- hr = m_pListBox->CreateItem((IASPowerListBoxItem**)(&pExitPLB), IDM_EXIT, ASFC_PWRLB_TYPE_COMMAND);
- if (SUCCEEDED(hr))
- {
- if(LoadBSTR(IDS_EXIT, &bStr))
- {
- pExitPLB->put_Caption(bStr);
- SysFreeString(bStr);
- pExitPLB->Release();
- }
- }
-
- return(hr);
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::ProcessMessage
- //
- // Synopsis: Process a message received on the app main thread message queue
- // This function is called by the Form's event sink.
- //
- // Arguments: uMsg - The message received
- // wParam - The wParam for the received message
- // lParam - The lParam for the received message
- //
- // Returns: void
- //
- //---------------------------------------------------------------------------
-
- VOID CTTSApp::ProcessMessage(LONG uMsg, LONG wParam, LONG lParam)
- {
- long lCurSel = 0;
- long lCount = 0;
- long lId = 0;
- int i;
- BSTR bstr;
- IASPowerListBoxItem* pItem = NULL;
- long lItemData = NULL;
- IDispatch* pDisp = NULL;
-
- if(uMsg == WM_COMMAND && LOWORD(wParam) == IDC_LISTBOX && HIWORD(wParam) == LBN_DBLCLK) // Some option on menu selected
- {
- switch (HIWORD(lParam)) // ID of item selected in HIWORD(lParam)
- {
- // When the user selects the Read Menu option, section pass each of the
- // Menu items and its ID to the Speak function. When the Speak function is about to
- // say each section, it fires a VTXTF_SPEAK message with the bookmark ID in the
- // lParam.
- case IDM_READMENU:
- m_pListBox->get_Count(&lCount);
- for(i=0; i<lCount; i++)
- {
- pDisp = NULL;
- m_pListBox->ItemAt(i, (IDispatch **)&pDisp);
- pDisp->QueryInterface(IID_ASPOWERLISTBOXITEM, (PVOID *)&pItem);
- pDisp->Release();
- pItem->get_Caption(&bstr);
- pItem->get_ItemId(&lId);
- pItem->Release();
- m_pSpeech->Speak(bstr, lId);
- }
- break;
-
- // When the Exit menu item is selected, we set a flag so we can exit
- // after we get the VTXTF_SPEAKDONE messasge.
- case IDM_EXIT:
- m_bExiting = TRUE;
-
- case IDM_HELLOWORLD:
- case IDM_WELCOME:
- // read the list box item that has focus
- pDisp = NULL;
- m_pListBox->get_FocusIndex(&lCurSel); // Gives us the index of the item in focus
- m_pListBox->ItemAt(lCurSel,(IDispatch **)&pDisp); // returns an IDispatch interface to the
- // item at our requested index
- pDisp->QueryInterface(IID_ASPOWERLISTBOXITEM, (PVOID *)&pItem);
- pDisp->Release();
- pItem->get_Caption(&bstr); // gets text of that item
- pItem->Release(); // release the item pointer
- m_pSpeech->Speak(bstr,0); // Speak it
- break;
-
- // Reads the feedback level for voice and key. Feedback variables filled
- // during SpeechInit, and whenever we receive a WM_SETTINGCHANGE(wParam=SPI_SETAPCFEEDBACK)
- // message.
- case IDM_FEEDBACK:
- m_pSpeech->Speak(m_bszKeyFeedback, 0); // Say "The key feedback level is"
- if(m_dwKeyFeedback == APCSPCH_FB_MORE) // Check our Key Feedback variable
- m_pSpeech->Speak(m_bszMore, 0); // Say "More"
- else m_pSpeech->Speak(m_bszLess, 0); // Say "Less"
-
- m_pSpeech->Speak(m_bszVoiceFeedback, 0);// Say "The voice feedback level is"
- if(m_dwVoiceFeedback == APCSPCH_FB_MORE)// Check out Voice Feedback variable
- m_pSpeech->Speak(m_bszMore, 0); // Say "More"
- else m_pSpeech->Speak(m_bszLess, 0); // Say "Less"
- break;
-
- // This tells the Form and the one and only control to Speak.
- case IDM_SPEAKFORM:
- m_pForm->Speak(NULL, ASFC_SPEAK_ALLITEMS, NULL);
- // m_pListBox->Speak(ASFC_SPEAK_ALLITEMS, NULL, NULL);
- break;
-
- default:
- break;
- } // end switch
- } //end if command directed towards listbox
- }
-
- //+-------------------------------------------------------------------------
- //
- // Function: CTTSApp::OnSpeakDone
- //
- // Synopsis: Called when a WM_SPCH_NOTIFY, wParam = VTXTF_SPEAKDONE message is received.
- // Exits if m_bExiting flag is set to true.
- //
- // Arguments: none
- //
- // Returns: void
- //
- //---------------------------------------------------------------------------
-
- void
- CTTSApp::OnSpeakDone()
- {
-
- if(m_bExiting)
- PostThreadMessage(m_idThread, WM_QUIT, 0, 0);
- }