Как получить список слов, используя ISpLexicon :: GetWords? - PullRequest
1 голос
/ 25 марта 2019

Я разрабатываю приложение для преобразования текста в речь, используя Microsoft SAPI. Я обнаружил, что в словарь можно добавлять индивидуальные произношения слов (поправьте меня, если я ошибаюсь). Я реализовал функцию, которая позволяет добавлять слова в этот словарь. Вот мой код:

int addPrononciation( const char* addPron, const char* phon )
{
   hr = cpLexicon.CoCreateInstance( CLSID_SpLexicon );
   hr = cpContainerLexicon.CoCreateInstance( CLSID_SpLexicon );

   hr = SpEnumTokens( SPCAT_VOICES, NULL, NULL, &cpEnum );
   cpEnum->Item( saveVoice, &cpVoiceToken ); //get saveVoice token defined at line 136
   cpVoice->SetVoice( cpVoiceToken ); //Initialization of the voice

   hr = cpContainerLexicon->AddLexicon( cpLexicon, eLEXTYPE_APP );
   langId = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
   hr = SpCreatePhoneConverter( langId, NULL, NULL, &cpPhoneConv );

   int wchars_num = MultiByteToWideChar( CP_ACP, 0, addPron, -1, NULL, 0 );
   wchar_t* pronWstr = new wchar_t[ wchars_num ];
   MultiByteToWideChar( CP_ACP, 0, addPron, -1, pronWstr, wchars_num );

   int phonWchars_num = MultiByteToWideChar( CP_ACP, 0, phon, -1, NULL, 0 );
   wchar_t* phonWstr = new wchar_t[ phonWchars_num ];
   MultiByteToWideChar( CP_ACP, 0, phon, -1, phonWstr, phonWchars_num );

   if(SUCCEEDED( hr ))
   {
      hr = cpPhoneConv->PhoneToId( phonWstr, wszId );
      hr = cpVoice->Speak( phonWstr, SPF_DEFAULT, NULL );
      hr = cpLexicon->AddPronunciation( pronWstr, langId, SPPS_Noun, wszId );
      hr = cpVoice->Speak( pronWstr, SPF_DEFAULT, NULL );
      if( SUCCEEDED( hr ) )
      {
         printf( "Success\n" );
      }
      else
      {
         printf( "Failed\n" );
      }
   }

   cpEnum.Release();
   cpVoiceToken.Release();
   cpContainerLexicon.Release();
   cpLexicon.Release();
   cpPhoneConv.Release();
   delete new wchar_t[ wchars_num ];
   delete new wchar_t[ phonWchars_num ];

   return true;
}

Теперь я хотел бы перечислить эти слова, используя ISpLexicon :: GetWords .

Я уже прочитал документацию на веб-сайте Microsoft и попытался реализовать функцию, но не могу понять, как инициализировать переменную spWordList.

Вот мой код:

 ZeroMemory( &spWordList, sizeof( spWordList ) );
 if( SUCCEEDED( hr ) )
 {
     hr = cpLexicon->GetWords( eLEXTYPE_APP, &dwGeneration, &dwCookie, &spWordList );
     printf( "Words: %ls\n", spWordList ); //print words but the output is null
 }
 CoTaskMemFree( spWordList.pvBuffer );

Я пытаюсь напечатать слова, но вывод нулевой. Я думаю, что переменная spWordList не инициализирована. Вот скриншот значений переменных.

Variable values

Как я могу его инициализировать?

1 Ответ

0 голосов
/ 25 марта 2019

Я узнал, как инициализировать spWordList. Вы должны заменить eLEXTYPE_APP на eLEXTYPE_USER. Тем не менее, вы можете оставить их обоих, как я. Ниже вы найдете пример того, как в нем перечислены слова.

ZeroMemory( &spWordList, sizeof( spWordList ) );
hr = S_FALSE;
if( hr == S_FALSE )
{
  hr = cpLexicon->GetWords( eLEXTYPE_USER | eLEXTYPE_APP, &dwGeneration, &dwCookie, &spWordList );
  for( spWord = spWordList.pFirstWord; spWord != NULL; spWord = spWord->pNextWord )
  {
     for( spWordPron = spWord->pFirstWordPronunciation; spWordPron != NULL; spWordPron = spWordPron->pNextWordPronunciation )
     {
        printf( "Words in dictionnary: %i\n", dwGeneration );
        printf( "Word: %ls\n", spWord->pszWord );
        //you can also display the pronunciation of words if you wish
     }
  }
}
CoTaskMemFree( spWordList.pvBuffer );

В коде я перебираю весь словарь. Обратите внимание, что перечисленные слова отображаются случайным образом. Я обновлю свой ответ, если найду другую важную информацию о ISpLexicon :: GetWords

...