Прежде всего, C ++ не мой язык (я программист Java).
Я видел примеры Microsoft SAPI 5.1, и мне нужен способ распечатать все доступные голоса на машине. Я видел Токен объекта SAPI, и я не совсем понимаю, как использовать CComPtr для итерации. Кто-нибудь может мне с этим помочь. Кроме того, как я могу выбрать определенный голос вместо использования по умолчанию.
Основываясь на примерах, вы можете получить голос по умолчанию, вызвав следующие коды:
ISpVoice * pVoice = NULL;
if (FAILED(::CoInitialize(NULL)))
return FALSE;
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
Итак, вкратце: Как я могу перечислить все доступные голоса и как я могу выбрать голос?
// PS: я не Мне нужно поместить его в поле со списком (как и все примеры, которые я видел), я реализую это для библиотеки DLL JNI, поэтому пример итерации гораздо предпочтительнее.
Прежде всего, CComPtr — это интеллектуальная абстракция указателя над интерфейсами COM, а не перечислитель.
Чтобы перечислить все голоса, вам нужно перечислить токены в SPCAT_VOICES категория.
HRESULT hr = S_OK;
CComPtr<ISpObjectTokenCategory> cpSpCategory = NULL;
if (SUCCEEDED(hr = SpGetCategoryFromId(SPCAT_VOICES, &cpSpCategory)))
{
CComPtr<IEnumSpObjectTokens> cpSpEnumTokens;
if (SUCCEEDED(hr = cpSpCategory->EnumTokens(NULL, NULL, &cpSpEnumTokens)))
{
CComPtr<ISpObjectToken> pSpTok;
while (SUCCEEDED(hr = cpSpEnumTokens->Next(1,&pSpTok, NULL))))
{
// do something with the token here; for example, set the voice
pVoice->SetVoice(pSpTok,FALSE);
// NOTE: IEnumSpObjectTokens::Next will *overwrite* the pointer; must manually release
pSpTok.Release();
}
}
}
Если вы хотите выбрать определенный голос, вам нужно указать атрибут, который уникален для этого голоса. EnumTokens позволяет указать обязательные и дополнительные атрибуты. Атрибуты фактически определяются создателем голоса, но некоторые общие атрибуты
Таким образом, чтобы указать «Microsoft Anna» вместо любого голоса, вы бы использовали
if (SUCCEEDED(hr = cpSpCategory->EnumTokens(L"Name=Microsoft Anna", NULL, &cpSpEnumTokens)))
вместо
if (SUCCEEDED(hr = cpSpCategory->EnumTokens(NULL, NULL, &cpSpEnumTokens)))
Метод enum работает, но немного неуклюже. Лучший способ — открыть реестр и просмотреть ключи и их атрибуты. Вы можете найти больше информации здесь:
msdn: токены SAPI, категории и реестр
Опять же, это немного трудоемко, поэтому я создал интерфейс, делая что-то еще, и это может помочь вам или кому-то еще: