If you’ve done any development with the shared recognizer, you’ve probably had problems determining when the shared recognizer is in sleep mode.

Determining when the shared recognizer is OFF is easy enough; ISpRecognizer::GetRecoState will return SPRST_INACTIVE.

But figuring out the sleep state is much harder.  That’s because the shared recognizer is active (SPRST_ACTIVE_ALWAYS), but it’s not listening for all commands.

In Windows 7, there is a new interface that expose ‘categories’ (ISpRecognizer3). 

When WSR is sleeping, ISpRecognizer3::GetActiveCategory will return a non-null ISpRecoCategory of type SPCT_SLEEP

When WSR is listening, ISpRecognizer3::GetActiveCategory will return a null ISpRecoCategory

NOTE WELL:  This is only guaranteed to work on Windows 7.  It is not guaranteed to work on future versions of Windows.

Some sample code to get an ISpRecognizer3 interface from a shared recognizer stored in m_cpReco:

ISpRecognizer3 snippet
  1. CComPtr<ISpRecognizer3> cpReco3;
  2. hr = m_cpReco.QueryInterface<ISpRecognizer3>(&cpReco3);
  3. if (SUCCEEDED(hr))
  4. {
  5.     CComPtr<ISpRecoCategory> cpCategory;
  6.     hr = cpReco3->GetActiveCategory(&cpCategory);
  7.     if (SUCCEEDED(hr) && cpCategory != NULL)
  8.     {
  9.         SPCATEGORYTYPE spct;
  10.         hr = cpCategory->GetType(&spct);
  11.         if (SUCCEEDED(hr)
  12.         {
  13.             fIsSleeping = spct = SPCT_SLEEP;
  14.         }
  15.     }
  16. }

In order to make this work, you’ll need to have the Windows 7 SDK installed and set as default in Visual Studio.

Also, you’ll need to make sure that you have the following version numbers defined (typically in targetver.h):

#define WINVER 0x0601

#define _WIN32_WINNT 0x0601

This will enable the Windows-7 only interfaces like ISpRecognizer3.