First off, CComPtr is a smart pointer abstraction over COM interfaces, not an enumerator.
To list all the voices, you need to enumerate the tokens in the SPCAT_VOICES category.
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();
}
}
}
If you want to pick a specific voice, you need to specify an attribute that's unique to that voice. EnumTokens allows you to specify required and optional attributes. The attributes are actually defined by the creator of the voice, but some common attributes are
- Name (e.g., "Microsoft Anna")
- Language (specified by a numeric locale ID)
- Gender (male/female)
- Vendor (name of company that created the voice)
So to specify "Microsoft Anna" instead of any voice, you would use
if (SUCCEEDED(hr = cpSpCategory->EnumTokens(L"Name=Microsoft Anna", NULL, &cpSpEnumTokens)))
instead of
if (SUCCEEDED(hr = cpSpCategory->EnumTokens(NULL, NULL, &cpSpEnumTokens)))