#include "stdafx.h" #include "RemoteTest.h" #include "TTSDlg.h" #include "RemoteTestDlg.h" #include #include "VAIBOTTS.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTTSDlg dialog CTTSDlg::CTTSDlg(CVAIBO* vaibo, CWnd* pParent) : CDialog(CTTSDlg::IDD, pParent) { //{{AFX_DATA_INIT(CTTSDlg) //}}AFX_DATA_INIT m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_vaibo = vaibo; m_pDlgLexicon = NULL; m_isSendFTP = false; m_isPlayWave = false; } bool asp = true; void CTTSDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTTSDlg) DDX_Control(pDX, IDC_COMBO_ENGINE, m_ComboEngine); DDX_Control(pDX, IDC_COMBO_FORMAT, m_ComboFormat); DDX_Control(pDX, IDC_SLIDER_VOLUME, m_sliderVolume); DDX_Control(pDX, IDC_SLIDER_SPEED, m_sliderSpeed); DDX_Control(pDX, IDC_SLIDER_PITCH, m_sliderPitch); DDX_Control(pDX, IDC_SLIDER_ACCENT, m_sliderAccent); DDX_Control(pDX, IDC_EDIT_TEXT, m_editText); DDX_Control(pDX, IDC_EDIT_TEXT2, m_editText2); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CTTSDlg, CDialog) //{{AFX_MSG_MAP(CTTSDlg) ON_WM_DESTROY() ON_BN_CLICKED(IDC_BUTTON_SPEAK, OnButtonSpeak) ON_BN_CLICKED(IDC_BUTTON_SPEAK2, OnButtonSpeak2) ON_BN_CLICKED(IDC_BUTTON_SAVE, OnButtonSave) ON_BN_CLICKED(IDC_BUTTON_SAVE2, OnButtonSave2) ON_BN_CLICKED(IDC_BUTTON_AIBO_SPEAK, OnButtonAiboSpeak) ON_BN_CLICKED(IDC_BUTTON_AIBO_SPEAK2, OnButtonAiboSpeak2) ON_BN_CLICKED(IDC_BUTTON_LEXICON_SONYTTS, OnButtonLexiconSonyTTS) ON_BN_CLICKED(IDC_BUTTON_LEXICON_SAPI_J, OnButtonLexiconSAPI_J) ON_BN_CLICKED(IDC_BUTTON_LEXICON_SAPI_E, OnButtonLexiconSAPI_E) ON_WM_HSCROLL() ON_CBN_SELCHANGE(IDC_COMBO_ENGINE, OnSelchangeComboEngine) ON_CBN_SELCHANGE(IDC_COMBO_FORMAT, OnSelchangeComboFormat) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTTSDlg message handlers BOOL CTTSDlg::OnInitDialog() { CDialog::OnInitDialog(); m_sliderSpeed.SetRange( 0, VOICE_PARAM_MAX ); m_sliderSpeed.SetPos( VOICE_PARAM_DEFAULT ); m_sliderSpeed.SetTicFreq( 5 ); // Interval m_sliderPitch.SetRange( 0, VOICE_PARAM_MAX ); m_sliderPitch.SetPos( VOICE_PARAM_DEFAULT ); m_sliderPitch.SetTicFreq( 5 ); m_sliderAccent.SetRange( 0, VOICE_PARAM_MAX ); m_sliderAccent.SetPos( VOICE_PARAM_DEFAULT ); m_sliderAccent.SetTicFreq( 5 ); m_sliderVolume.SetRange( 0, VOICE_PARAM_MAX ); m_sliderVolume.SetPos( VOICE_PARAM_DEFAULT ); m_sliderVolume.SetTicFreq( 5 ); CString msg; msg.LoadString( IDS_TTS_MSG1_JAPANESE ); m_editText.SetWindowText( msg ); msg.LoadString( IDS_TTS_MSG2_ENGLISH ); m_editText2.SetWindowText( msg ); m_pTTS = new ( CVAIBOTTS ); if ( m_pTTS->Init() != E_VAIBOTTS_NOERROR ) { delete m_pTTS; m_pTTS = NULL; } // Get the TTS engine list if ( m_pTTS ) { // Get the number of engines int nEngineNum; m_pTTS->GetTTSEngineNum( nEngineNum ); for ( int i = 0; i < nEngineNum; i++ ) { char strEngineName[ 256 ]; m_pTTS->GetTTSEngineName( i, strEngineName ); m_ComboEngine.InsertString( -1, strEngineName ); } // Specify the current engine. m_ComboEngine.SetCurSel( 0 ); m_pTTS->SetVoiceEngine( m_ComboEngine.GetCurSel() ); if ( m_pTTS->GetTTSEngineKind( m_ComboEngine.GetCurSel() ) == E_VAIBOTTS_ENGINE_SAPI ) { m_pTTS->SetVoiceVolume( VOICE_PARAM_MAX ); // Because the volume of SAPI is low. m_sliderVolume.SetPos( VOICE_PARAM_MAX ); } m_ComboFormat.SetCurSel( m_pTTS->GetOutputFormat() ); } return TRUE; } void CTTSDlg::OnDestroy() { CDialog::OnDestroy(); if ( m_pDlgLexicon != NULL ) { m_pDlgLexicon->DestroyWindow(); delete m_pDlgLexicon; m_pDlgLexicon = NULL; } if ( m_pTTS ) { m_pTTS->End(); delete m_pTTS; } } void SplitString( CString& strSrc, CString& strDst, int nSplitStringLen ) { if ( strSrc.GetLength() < nSplitStringLen ) { strDst = strSrc; strSrc.Empty(); return; } // Terminating characters of a string. #define STREND_NUM ( 6 ) CString strEnd[ STREND_NUM ]; CString msg; msg.LoadString( IDS_TTS_STREND_1 ); strEnd[0] = msg; msg.LoadString( IDS_TTS_STREND_2 ); strEnd[1] = msg; msg.LoadString( IDS_TTS_STREND_3 ); strEnd[2] = msg; msg.LoadString( IDS_TTS_STREND_4 ); strEnd[3] = msg; msg.LoadString( IDS_TTS_STREND_5 ); strEnd[4] = msg; msg.LoadString( IDS_TTS_STREND_6 ); strEnd[5] = msg; int nSplitIdx = -1; for ( int i = 0; i < STREND_NUM; i++ ) { int nFindIdx = -1; int nIdx = 0; while ( 1 ) { nIdx = strSrc.Find( strEnd[ i ], nIdx + 1 ); // Terminating character wasn't found. if ( nIdx < 0 ) { break; } // Exceeded maximum range. if ( nIdx >= nSplitStringLen ) { break; } nFindIdx = nIdx; } // Terminating character was found. if ( nFindIdx >= 0 ) { if ( nFindIdx > nSplitIdx ) { nSplitIdx = nFindIdx; // The largest one } } } // Terminating character was found. if ( nSplitIdx >= 0 ) { // double-byte character? if ( IsDBCSLeadByte( strSrc.GetAt( nSplitIdx ) ) ) { // Include the following character. strDst = strSrc.Left( nSplitIdx + 2 ); strDst += '\0'; strSrc = strSrc.Mid( nSplitIdx + 2 ); } else { // Do not included the following character. strDst = strSrc.Left( nSplitIdx + 1 ); strDst += '\0'; strSrc = strSrc.Mid( nSplitIdx + 1 ); } } // Terminating character wasn't found. else { // Cut string in the middle (unavoidable). // double-byte character? if ( IsDBCSLeadByte( strSrc.GetAt( nSplitStringLen - 1 ) ) ) { // Include the following character. strDst = strSrc.Left( nSplitStringLen + 1 ); strDst += '\0'; strSrc = strSrc.Mid( nSplitStringLen + 1 ); } else { // Do not included the following character. strDst = strSrc.Left( nSplitStringLen ); strDst += '\0'; strSrc = strSrc.Mid( nSplitStringLen ); } } } void CTTSDlg::OnButtonSpeak() { if ( !m_pTTS ) { return; } CString strEdit; m_editText.GetWindowText( strEdit ); if ( strEdit.IsEmpty() ) { return; } CString strReadText = strEdit; for ( int i = 0; ; i++ ) { CString strText; SplitString( strReadText, strText, 60 ); char strTempPath[ 1024 ]; ::GetTempPath( 1024, strTempPath ); CString strFile; strFile.Format( "%s_VAIBOTTS%02d.wav", strTempPath, i ); CFile fileTest; if ( fileTest.Open( strFile, CFile::modeRead | CFile::shareDenyNone ) ) { fileTest.Close(); CFile::Remove( strFile ); } // Create wave file if ( m_pTTS->MakeWaveFile( strText, strFile ) ) { AfxMessageBox( "Wave file creation error\n" ); return; } // Play while ( !PlaySound( strFile, NULL, SND_FILENAME | SND_ASYNC | SND_NOSTOP ) ) { Sleep( 100 ); // Wait for the previous sound production. } // Short wait. Sleep( 10 ); // String to say is now empty if ( strReadText.IsEmpty() ) { break; } } } void CTTSDlg::OnButtonSpeak2() { if ( !m_pTTS ) { return; } CString strEdit; m_editText2.GetWindowText( strEdit ); if ( strEdit.IsEmpty() ) { return; } m_pTTS->Speak( strEdit ); } void CTTSDlg::OnButtonSave() { if ( !m_pTTS ) { return; } CString strEdit; m_editText.GetWindowText( strEdit ); if ( strEdit.IsEmpty() ) { return; } CFileDialog dlg( FALSE, "wav", "TTS.wav", 0, NULL, this ); if ( dlg.DoModal() != IDOK ) { return; } CString strFile; strFile = dlg.GetPathName(); // Save if ( m_pTTS->MakeWaveFile( strEdit, strFile ) ) { AfxMessageBox( "Wave file creation error\n" ); } } void CTTSDlg::OnButtonSave2() { if ( !m_pTTS ) { return; } CString strEdit; m_editText2.GetWindowText( strEdit ); if ( strEdit.IsEmpty() ) { return; } CFileDialog dlg( FALSE, "wav", "TTS.wav", 0, NULL, this ); if ( dlg.DoModal() != IDOK ) { return; } CString strFile; strFile = dlg.GetPathName(); // Save if ( m_pTTS->MakeWaveFile( strEdit, strFile ) ) { AfxMessageBox( "Wave file creation error\n" ); } } void CTTSDlg::AiboSpeak( CString strEdit ) { if ( m_pTTS == NULL ) { AfxMessageBox( "TTS Engine not initialized\n" ); return; } // VAIBO OK ? if ( m_vaibo == NULL ) { AfxMessageBox( "Not Connected to AIBO\n" ); return; } if ( !m_vaibo->IsConnect() ) { AfxMessageBox( "Not Connected to AIBO\n" ); return; } if ( ( ( CRemoteTestDlg* )AfxGetMainWnd() )->IsAiboControl() == false ) { AfxMessageBox( "Can't remotely control AIBO\n" ); return; } // NetAudio Preparation int nState = m_vaibo->GetStateNetAudio(); switch (nState) { case AUDIOTP_STATE_SERVICE: case AUDIOTP_STATE_PAUSE: break; case AUDIOTP_STATE_PLAY: AfxMessageBox( "The NetAudio Service is busy\n" ); return; default: AfxMessageBox( "Start the NetAudio Service, nitwit\n" ); return; } // Split the string. CString strReadText = strEdit; for ( int i = 0; ; i++ ) { // Split the string. CString strText; SplitString( strReadText, strText, 60 ); // Get TEMP directory char strTempPath[ 1024 ]; ::GetTempPath( 1024, strTempPath ); // TEMP filename CString strFile; strFile.Format( "%s_VAIBOTTS%02d.wav", strTempPath, i ); // Confirm the existence of the file. CFile fileTest; if ( fileTest.Open( strFile, CFile::modeRead | CFile::shareDenyNone ) ) { // It exists. fileTest.Close(); // Delete CFile::Remove( strFile ); } // Preparation of the wave file if ( m_pTTS->MakeWaveFile( strText, strFile ) ) { AfxMessageBox( "Wave file creation error\n" ); return; } // Check the size of the transfer CFile* pFile = new CFile( strFile, CFile::modeRead | CFile::shareDenyNone ); if ( pFile != NULL ) { int nSize; bool isError = false; if ( ( nSize = pFile->GetLength() ) >= 1 * 1000 * 1000/*1MB*/ ) { isError = true; AfxMessageBox( "Wave file is too large\n" ); } pFile->Close(); delete pFile; if ( isError ) { return; } } else { AfxMessageBox( "Wave file open error\n" ); return; } // AudioSendWAV int nRet; if ( ( nRet = m_vaibo->AudioSendWAVFile( strFile ) ) == VAIBO_NOERROR ) { m_isSendFTP = true; } else { // Failure CString strDebug; strDebug.Format( "Wave file transfer error %d\n", nRet ); AfxMessageBox( strDebug ); return; } // String to say is now empty. if ( strReadText.IsEmpty() ) { break; } } } void CTTSDlg::OnButtonAiboSpeak() { if ( !m_pTTS ) { return; } CString strEdit; m_editText.GetWindowText( strEdit ); if ( strEdit.IsEmpty() ) { return; } AiboSpeak( strEdit ); } // SpeakLoop to constantly check if myfile is modified CString strLoop = "Hello. I am robot"; void CTTSDlg::SpeakLoop() { if ( !m_pTTS ) { return; } AfxMessageBox("necessary. why?"); char buf[80]; FILE *fp; char c; int j; j=0; if((fp=fopen("n:\\myfile.txt","r"))!=NULL) { while(!feof(fp) && (c=fgetc(fp))!='\n' && j<78) { buf[j]=c; j++; } buf[j-1]='\0'; if (strLoop != buf){strLoop=buf; AiboSpeak( strLoop );} } if(asp) SpeakLoop(); } void CTTSDlg::OnButtonAiboSpeak2() { if ( !m_pTTS ) { return; } m_editText2.GetWindowText( strLoop ); if ( strLoop.IsEmpty() ) { return; } if(asp){asp = false;} if(!asp){asp = true;} char buf[80]; FILE *fp; char c; int j; if((fp=fopen("n:\\myfile.txt","r"))==NULL) { AfxMessageBox("Error opening file."); strLoop="test"; } else { j=0; while(!feof(fp) && (c=fgetc(fp))!='\n' && j<78) { buf[j]=c; j++; } buf[j-1]='\0'; strLoop=buf; } AiboSpeak( strLoop ); SpeakLoop(); } void CTTSDlg::DisplayLexicon( int eLexicon ) { if ( m_pDlgLexicon == NULL ) { m_pDlgLexicon = new CTTSLexiconDlg( m_pTTS ); m_pDlgLexicon->Create( IDD_DIALOG_LEXICON ); } m_pDlgLexicon->SetLexicon( eLexicon ); m_pDlgLexicon->ShowWindow( SW_SHOW ); } void CTTSDlg::OnButtonLexiconSonyTTS() { DisplayLexicon( E_VAIBOTTS_LEXICON_SONYTTS_J ); } void CTTSDlg::OnButtonLexiconSAPI_J() { DisplayLexicon( E_VAIBOTTS_LEXICON_SAPI_J ); } void CTTSDlg::OnButtonLexiconSAPI_E() { DisplayLexicon( E_VAIBOTTS_LEXICON_SAPI_E ); } void CTTSDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { if ( ( CSliderCtrl* )pScrollBar == &m_sliderSpeed ) { unsigned int unPos = m_sliderSpeed.GetPos(); if ( m_pTTS ) { m_pTTS->SetVoiceSpeed( unPos ); } } else if ( ( CSliderCtrl* )pScrollBar == &m_sliderPitch ) { unsigned int unPos = m_sliderPitch.GetPos(); if ( m_pTTS ) { m_pTTS->SetVoicePitch( unPos ); } } else if ( ( CSliderCtrl* )pScrollBar == &m_sliderAccent ) { unsigned int unPos = m_sliderAccent.GetPos(); if ( m_pTTS ) { m_pTTS->SetVoiceAccent( unPos ); } } else if ( ( CSliderCtrl* )pScrollBar == &m_sliderVolume ) { unsigned int unPos = m_sliderVolume.GetPos(); if ( m_pTTS ) { m_pTTS->SetVoiceVolume( unPos ); } } CDialog::OnHScroll(nSBCode, nPos, pScrollBar); } void CTTSDlg::OnSelchangeComboEngine() { if ( m_pTTS ) { m_pTTS->SetVoiceEngine( m_ComboEngine.GetCurSel() ); if ( m_pTTS->GetTTSEngineKind( m_ComboEngine.GetCurSel() ) == E_VAIBOTTS_ENGINE_SAPI ) { m_pTTS->SetVoiceVolume( VOICE_PARAM_MAX ); // Because the volume of SAPI is low. m_sliderVolume.SetPos( VOICE_PARAM_MAX ); } } } void CTTSDlg::OnSelchangeComboFormat() { if ( m_pTTS ) { if ( m_ComboFormat.GetCurSel() == 0 ) { m_pTTS->SetOutputFormat( E_TTS_WAVE_FORMAT_16K_16BIT ); } else { m_pTTS->SetOutputFormat( E_TTS_WAVE_FORMAT_8K_8BIT ); } } } // Wait for the end of the produced voice. void CTTSDlg::NotifyPlayWave( int status ) { if ( status == DONE_PLAY_WAV ) { m_isPlayWave = false; if ( m_isSendFTP ) { m_vaibo->SendCmd( APPCMD_PLAY_WAV, false ); m_isPlayWave = true; m_isSendFTP = false; } // There is no transfer. if ( !m_isSendFTP ) { ( CButton* )( GetDlgItem( IDC_BUTTON_AIBO_SPEAK ) )->EnableWindow( true ); ( CButton* )( GetDlgItem( IDC_BUTTON_AIBO_SPEAK2 ) )->EnableWindow( true ); } } } ///////////////////////////////////////////////////////////////////////////////// //////// TTSLexicon Dialog ///////////////////////////////////////////////////////////////////////////////// void CTTSLexiconDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTTSLexiconDlg) DDX_Control(pDX, IDC_LISTVIEW_WORD, m_listViewWord); DDX_Control(pDX, IDC_EDIT_WORD, m_editWord); DDX_Control(pDX, IDC_EDIT_KANA, m_editPhone); DDX_Control(pDX, IDC_COMBO_PART, m_comboPart); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CTTSLexiconDlg, CDialog) //{{AFX_MSG_MAP(CTTSDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED( IDC_BUTTON_ADD, OnButtonAdd ) ON_BN_CLICKED( IDC_BUTTON_DELETE, OnButtonDelete ) //}}AFX_MSG_MAP END_MESSAGE_MAP() CTTSLexiconDlg::CTTSLexiconDlg( CVAIBOTTS* pTTS ) { m_pTTS = pTTS; m_eLexicon = -1/*E_VAIBOTTS_LEXICON_SONYTTS_J*/; } BOOL CTTSLexiconDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon ListView_SetExtendedListViewStyle( ( HWND )m_listViewWord.m_hWnd, LVS_EX_FULLROWSELECT ); m_listViewWord.InsertColumn( 0, "Word", LVCFMT_LEFT, 90, -1 ); m_listViewWord.InsertColumn( 1, "Pronounce", LVCFMT_LEFT, 90, -1 ); m_listViewWord.InsertColumn( 2, "Part", LVCFMT_LEFT, 80, -1 ); return TRUE; } void CTTSLexiconDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CTTSLexiconDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } // Setup the dictionary void CTTSLexiconDlg::SetLexicon( int eLexicon ) { // Change the title name. switch ( eLexicon ) { case E_VAIBOTTS_LEXICON_SONYTTS_J: // SONY TTS SetWindowText( "SONY TTS" ); break; case E_VAIBOTTS_LEXICON_SAPI_J: // SAPI Japanese SetWindowText( "SAPI TTS Japanese" ); break; case E_VAIBOTTS_LEXICON_SAPI_E: // SAPI English SetWindowText( "SAPI TTS English" ); break; default: return; // Error check } // Empty list m_listViewWord.DeleteAllItems(); // Get the dictionary list. if ( m_pTTS ) { int nWord; m_pTTS->GetWordNumInLexicon( ( E_VAIBOTTS_LEXICON )eLexicon, nWord ); for ( int i = 0; i < nWord; i++ ) { char strWord[ 256 ]; char strPronunciation[ 256 ]; char strPart[ 256 ]; m_pTTS->GetWordInLexicon( ( E_VAIBOTTS_LEXICON )eLexicon, i, strWord ); m_pTTS->GetPronunciationInLexicon( ( E_VAIBOTTS_LEXICON )eLexicon, i, strPronunciation ); m_pTTS->GetPartInLexicon( ( E_VAIBOTTS_LEXICON )eLexicon, i, strPart ); CString strTemp; strTemp.Format( "%s, \"%s\", %s\r\n", strWord, strPronunciation, strPart ); m_listViewWord.InsertItem( i, "" ); m_listViewWord.SetItemText( i, 0, strWord ); m_listViewWord.SetItemText( i, 1, strPronunciation ); m_listViewWord.SetItemText( i, 2, strPart ); } } // Register parts of speech. if ( m_eLexicon != eLexicon ) { int i; int nIdx; switch ( eLexicon ) { case E_VAIBOTTS_LEXICON_SONYTTS_J: // SONY TTS m_comboPart.ResetContent(); for ( i = 0; i < NUM_E_VAIBOTTS_PART_SONYTTS; i++ ) { nIdx = m_comboPart.InsertString( -1, strSonyTTSParts[ i ] ); m_comboPart.SetItemData( nIdx, E_VAIBOTTS_PART_SONYTTS_HEAD + i ); } m_comboPart.SetCurSel( 0 ); break; case E_VAIBOTTS_LEXICON_SAPI_J: // SAPI Japanese case E_VAIBOTTS_LEXICON_SAPI_E: // SAPI English m_comboPart.ResetContent(); nIdx = m_comboPart.InsertString( -1, "Noun" ); m_comboPart.SetItemData( nIdx, E_VAIBOTTS_PART_SAPI_NOUN ); nIdx = m_comboPart.InsertString( -1, "Verb" ); m_comboPart.SetItemData( nIdx, E_VAIBOTTS_PART_SAPI_VERB ); nIdx = m_comboPart.InsertString( -1, "Modifier" ); m_comboPart.SetItemData( nIdx, E_VAIBOTTS_PART_SAPI_MODIFIER ); nIdx = m_comboPart.InsertString( -1, "Function" ); m_comboPart.SetItemData( nIdx, E_VAIBOTTS_PART_SAPI_FUNCTION ); nIdx = m_comboPart.InsertString( -1, "Interjection" ); m_comboPart.SetItemData( nIdx, E_VAIBOTTS_PART_SAPI_INTERJECTION ); m_comboPart.SetCurSel( 0 ); break; default: break; } } m_eLexicon = eLexicon; } void CTTSLexiconDlg::OnButtonAdd() { char strWord[ 256 ]; char strPhone[ 256 ]; E_VAIBOTTS_PART ePart; // Get a string. m_editWord.GetWindowText( strWord, 256 ); m_editPhone.GetWindowText( strPhone, 256 ); if ( !strlen( strWord ) || !strlen( strPhone ) ) { return; // Invalid. } // Get the part of speech int nIdx; if ( ( nIdx = m_comboPart.GetCurSel() ) < 0 ) { return; // Invalid. } else { ePart = ( E_VAIBOTTS_PART )m_comboPart.GetItemData( nIdx ); } // Registration if ( m_pTTS ) { if ( m_pTTS->AddWordInLexicon( ( E_VAIBOTTS_LEXICON )m_eLexicon, strWord, strPhone, ePart ) == E_VAIBOTTS_NOERROR ) { // Rebuild the list SetLexicon( m_eLexicon ); } } } void CTTSLexiconDlg::OnButtonDelete() { // Get the word to delete. int nIdx; POSITION pos = m_listViewWord.GetFirstSelectedItemPosition(); if ( pos == NULL ) { // Nothing is chosen. return; } nIdx = m_listViewWord.GetNextSelectedItem( pos ); // Deletion if ( m_pTTS ) { if ( m_pTTS->DeleteWordInLexicon( ( E_VAIBOTTS_LEXICON )m_eLexicon, nIdx ) == E_VAIBOTTS_NOERROR ) { // The reconstruction of the list SetLexicon( m_eLexicon ); } } }