Lexicon Interfaces Overview (SAPI 5.3)
The ISpLexicon interface provides a uniform way for applications and engines to access the user lexicon, application lexicon, and engine private lexicons.
The following topics are covered in this section:
SpLexicon is the SAPI standard lexicon object which implements the ISpLexicon interface. It contains the user lexicon and all application lexicons registered in the system when the SpLexicon object was CoCreated. Engines can add their private lexicons through ISpContainerLexicon interface. However, if an application uses ISpContainerLexicon to add a lexicon to an instance of SpLexicon, the engine will not use the lexicon.
You can get pronunciations from both the user and application lexicons:
hr = cpLexicon->GetPronunciation(... eLEXTYPE_USER ...); hr = cpLexicon->GetPronunciation(... eLEXTYPE_APP ...); hr = cpLexicon->GetPronunciation(... eLEXTYPE_USER | eLEXTYPE_APP ...);
hr = SpCreateNewTokenEx(SPCAT_APPLEXICONS, pszLangIndependentName, &CLSID_YourLexicon, pszLangIndependentName, langid, pszLangDependentName, &cpToken, &cpDataKeyAttribs); // hr = cpDataKeyAttribs->SetStringValue(name1, value1); // optional. Can be used to find your lexicon later // hr = cpDataKeyAttribs->SetStringValue(name2, value2); // optional // ...
You can also use the SAPI-provided CLSID_SpUnCompressedLexicon to implement your application lexicon as follows (the CLSID_SpCompressedLexicon is intended for engine vendors):
hr = SpCreateNewTokenEx(SPCAT_APPLEXICONS, pszLangIndependentName, &CLSID_SpUnCompressedLexicon, pszLangIndependentName, langid, pszLangDependentName, &cpToken, &cpDataKeyAttribs); // hr = cpDataKeyAttribs->SetStringValue(name1, value1); // optional. Can be used to find your lexicon later // hr = cpDataKeyAttribs->SetStringValue(name2, value2); // optional // ... hr = SpCreateObjectFromToken(cpToken, &cpAppLexicon); cpAppLexicon->AddPronunciation(...); cpAppLexicon->AddPronunciation(...); cpAppLexicon.Release(); // the CLSID_SpUnCompressedLexicon object will be read-only after this point
To remove an application lexicon from the system:
- Locate your lexicon with the SpFindBestToken(..., &cpToken) function.
- Call cpToken->Remove (NULL) to remove the lexicon from the system.
When an application lexicon is added to the system, it is shared by all applications. Any SpLexicon object created afterward will automatically load the application lexicon. Application lexicons will override engine private lexicons.
ISpLexicon provides a uniform format to access user, application, and engine private lexicons. CLSID_SpLexicon implements ISpContainerLexicon, which is derived from ISpLexicon and has one more method, AddLexicon.
CComPtr<ISpContainerLexicon> cpLexicon; // load user lexicon and all application lexicons registered in the system automatically hr = cpLexicon.CoCreateInstance(CLSID_SpLexicon); // create your private lexicons implementing ISpLexicon, e.g. pMyLex1, pMyLex2 hr = cpLexicon->AddLexicon(pMyLex1, eLEXTYPE_PRIVATE1); hr = cpLexicon->AddLexicon(pMyLex2, eLEXTYPE_PRIVATE2); ...
Engines can can access lexicons in the following manner:
hr = cpLexicon->GetPronunciations(... eLEXTYPE_USER ...); hr = cpLexicon->GetPronunciations(... eLEXTYPE_APP ...); hr = cpLexicon->GetPronunciations(... eLEXTYPE_USER | eLEXTYPE_APP | eLEXTYPE_PRIVATE1 | eLEXTYPE_PRIVATE2 ...);
The lexicon pronunciation information is returned from GetPronunciations in the following order:
- Pronunciation from user lexicon (could have multiple pronunciations)
- Pronunciation from application lexicon(s) (could have multiple pronunciations)
- Pronunciation from the added lexicons in the same order the lexicons were added.
The expected order of priority is the same as what is returned from GetPronunciations in the above list.
The ISpLexicon interface can be used to add or remove words from the user lexicon. However, engine developers will not typically use ISpLexicon::AddPronunciation and ISpLexicon::RemovePronunciation to add or remove words from user lexicons.
When private lexicons are implemented through the ISpLexicon interface, SAPI will only call GetPronunciations and GetWords on the private lexicon. Implementing the AddPronunciation or RemovePronunciation methods to populate lexicons can modify private lexicons.
If you cache the pronunciations from user or application lexicons, you need to call GetGeneration periodically to determine if the pronunciation has been modified. For optimum efficiency, an engine should maintain synchronization with the user and application lexicons. The SAPI 5 compliance test can verify an engine's ability to detect changes in the user or application lexicons. For more information, please see the Compliance Tests White Paper.
When the call to GetGeneration returns a larger generation number than the previous call, the engine should call GetGenerationChange or GetWords to update the cache.
Private lexicons can be added to the ISpContainerLexicon interface, or engine developers can elect to create their own method of implementing a private lexicon. However, to ensure consistent performance among all applications, engines should always use the pronunciations from the user and application lexicons.