Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1405 lines
37 KiB

  1. //
  2. // nui.cpp
  3. //
  4. #include "private.h"
  5. #include "immxutil.h"
  6. #include "sapilayr.h"
  7. #include "xstring.h"
  8. #include "nui.h"
  9. #include "ids.h"
  10. #include "cicspres.h"
  11. #include "cresstr.h"
  12. #include "slbarid.h"
  13. #include "ptrary.h"
  14. #include "ctffunc.h"
  15. /* ad8d338b-fb07-4e06-8d5b-911baad9eeb3 */
  16. const IID IID_PRIV_CSPEECHUISERVER = {
  17. 0xad8d338b,
  18. 0xfb07,
  19. 0x4e06,
  20. {0x8d, 0x5b, 0x91, 0x1b, 0xaa, 0xd9, 0xee, 0xb3}
  21. };
  22. /* e49d6ff3-1fff-43ba-b835-3a122e98a1c9 */
  23. const GUID GUID_LBI_SAPILAYR_MICROPHONE = {
  24. 0xe49d6ff3,
  25. 0x1fff,
  26. 0x43ba,
  27. {0xb8, 0x35, 0x3a, 0x12, 0x2e, 0x98, 0xa1, 0xc9}
  28. };
  29. /* 3f9ea2e3-75d6-4879-86c2-2bcc2b6fa46e */
  30. const GUID GUID_LBI_SAPILAYR_BALLOON = {
  31. 0x3f9ea2e3,
  32. 0x75d6,
  33. 0x4879,
  34. {0x86, 0xc2, 0x2b, 0xcc, 0x2b, 0x6f, 0xa4, 0x6e}
  35. };
  36. /* 17f9fa7f-a9ed-47b5-8bcd-eebb94b2e6ca */
  37. const GUID GUID_LBI_SAPILAYR_COMMANDING = {
  38. 0x17f9fa7f,
  39. 0xa9ed,
  40. 0x47b5,
  41. {0x8b, 0xcd, 0xee, 0xbb, 0x94, 0xb2, 0xe6, 0xca}
  42. };
  43. /* 49261a4a-87df-47fc-8a68-6ea07ba82a87 */
  44. const GUID GUID_LBI_SAPILAYR_DICTATION = {
  45. 0x49261a4a,
  46. 0x87df,
  47. 0x47fc,
  48. {0x8a, 0x68, 0x6e, 0xa0, 0x7b, 0xa8, 0x2a, 0x87}
  49. };
  50. /* 791b4403-0cda-4fe1-b748-517d049fde08 */
  51. const GUID GUID_LBI_SAPILAYR_TTS_PLAY_STOP = {
  52. 0x791b4403,
  53. 0x0cda,
  54. 0x4fe1,
  55. {0xb7, 0x48, 0x51, 0x7d, 0x04, 0x9f, 0xde, 0x08}
  56. };
  57. /* e6fbfc9d-a2e0-4203-a27b-af2353e6a44e */
  58. const GUID GUID_LBI_SAPILAYR_TTS_PAUSE_RESUME = {
  59. 0xe6fbfc9d,
  60. 0xa2e0,
  61. 0x4203,
  62. {0xa2, 0x7b, 0xaf, 0x23, 0x53, 0xe6, 0xa4, 0x4e}
  63. };
  64. CPtrArray<SPTIPTHREAD> *g_rgstt = NULL;
  65. //+---------------------------------------------------------------------------
  66. //
  67. // GetSPTIPTHREAD
  68. //
  69. //----------------------------------------------------------------------------
  70. SPTIPTHREAD *GetSPTIPTHREAD()
  71. {
  72. SPTIPTHREAD *pstt;
  73. if (g_dwTlsIndex == (DWORD)-1)
  74. return NULL;
  75. pstt = (SPTIPTHREAD *)TlsGetValue(g_dwTlsIndex);
  76. if (!pstt)
  77. {
  78. pstt = (SPTIPTHREAD *)cicMemAllocClear(sizeof(SPTIPTHREAD));
  79. if (!TlsSetValue(g_dwTlsIndex, pstt))
  80. {
  81. cicMemFree(pstt);
  82. pstt = NULL;
  83. }
  84. EnterCriticalSection(g_cs);
  85. if (!g_rgstt)
  86. g_rgstt = new CPtrArray<SPTIPTHREAD>;
  87. if (g_rgstt)
  88. {
  89. if (g_rgstt->Insert(0, 1))
  90. {
  91. g_rgstt->Set(0, pstt);
  92. }
  93. else
  94. {
  95. TlsSetValue(g_dwTlsIndex, NULL);
  96. cicMemFree(pstt);
  97. pstt = NULL;
  98. }
  99. }
  100. LeaveCriticalSection(g_cs);
  101. }
  102. return pstt;
  103. }
  104. //+---------------------------------------------------------------------------
  105. //
  106. // FreeSPTIPTHREAD
  107. //
  108. //----------------------------------------------------------------------------
  109. void FreeSPTIPTHREAD()
  110. {
  111. SPTIPTHREAD *pstt;
  112. if (g_dwTlsIndex == (DWORD)-1)
  113. return;
  114. pstt = (SPTIPTHREAD *)TlsGetValue(g_dwTlsIndex);
  115. if (pstt)
  116. {
  117. EnterCriticalSection(g_cs);
  118. if (g_rgstt)
  119. {
  120. int nCnt = g_rgstt->Count();
  121. while (nCnt)
  122. {
  123. nCnt--;
  124. if (g_rgstt->Get(nCnt) == pstt)
  125. {
  126. g_rgstt->Remove(nCnt, 1);
  127. break;
  128. }
  129. }
  130. }
  131. LeaveCriticalSection(g_cs);
  132. cicMemFree(pstt);
  133. TlsSetValue(g_dwTlsIndex, NULL);
  134. }
  135. return;
  136. }
  137. //+---------------------------------------------------------------------------
  138. //
  139. // UninitProcess()
  140. //
  141. //+---------------------------------------------------------------------------
  142. void UninitProcess()
  143. {
  144. //
  145. // FreeSPTIPTHREAD2() removes psfn from PtrArray.
  146. //
  147. if (g_rgstt)
  148. {
  149. while(g_rgstt->Count())
  150. {
  151. SPTIPTHREAD *pstt = g_rgstt->Get(0);
  152. g_rgstt->Remove(0, 1);
  153. cicMemFree(pstt);
  154. }
  155. delete g_rgstt;
  156. g_rgstt = NULL;
  157. }
  158. //
  159. // Free speech grammar resource module(SPGRMR.DLL)
  160. //
  161. if (g_hInstSpgrmr)
  162. {
  163. FreeLibrary(g_hInstSpgrmr);
  164. }
  165. //
  166. // Free XP SP1 resource module(XPSP1RES.DLL) if it is loaded.
  167. //
  168. FreeCicResInstance();
  169. }
  170. //+---------------------------------------------------------------------------
  171. //
  172. // LoadSpgrmrModule()
  173. //
  174. //+---------------------------------------------------------------------------
  175. void LoadSpgrmrModule()
  176. {
  177. if (!g_hInstSpgrmr)
  178. {
  179. TCHAR szSpgrmrPath[MAX_PATH + 32];
  180. if (GetWindowsDirectory(szSpgrmrPath, MAX_PATH))
  181. {
  182. StringCchCat(szSpgrmrPath,
  183. ARRAYSIZE(szSpgrmrPath),
  184. TEXT("\\IME\\SPGRMR.DLL"));
  185. g_hInstSpgrmr = LoadLibrary(szSpgrmrPath);
  186. }
  187. }
  188. }
  189. //////////////////////////////////////////////////////////////////////////////
  190. //
  191. // CSpeechUIServer
  192. //
  193. //////////////////////////////////////////////////////////////////////////////
  194. //+---------------------------------------------------------------------------
  195. //
  196. // PostCreateInstance
  197. //
  198. //----------------------------------------------------------------------------
  199. void CSpeechUIServer::PostCreateInstance(REFIID riid, void *pvObj)
  200. {
  201. if (IsEqualGUID(riid, IID_ITfSpeechUIServer))
  202. {
  203. ((CSpeechUIServer *)pvObj)->_EnsureSpeechProfile();
  204. }
  205. }
  206. //+---------------------------------------------------------------------------
  207. //
  208. // ctor
  209. //
  210. //----------------------------------------------------------------------------
  211. CSpeechUIServer::CSpeechUIServer()
  212. {
  213. _SetThis(this);
  214. _tim = NULL;
  215. _lbim = NULL;
  216. _fShown = FALSE;
  217. m_fCommandingReady = FALSE;
  218. }
  219. //+---------------------------------------------------------------------------
  220. //
  221. // dtor
  222. //
  223. //----------------------------------------------------------------------------
  224. CSpeechUIServer::~CSpeechUIServer()
  225. {
  226. if (_fShown)
  227. ShowUI(FALSE);
  228. if (_pCes)
  229. {
  230. _pCes->_Unadvise();
  231. SafeReleaseClear(_pCes);
  232. }
  233. SafeRelease(_plbiMicrophone);
  234. SafeRelease(_plbiCfgMenuButton);
  235. SafeRelease(_plbiBalloon);
  236. SafeRelease(_plbiDictation);
  237. SafeRelease(_plbiCommanding);
  238. SafeRelease(_plbiTtsPlayStop);
  239. SafeRelease(_plbiTtsPauseResume);
  240. SafeRelease(_tim);
  241. SafeRelease(_lbim);
  242. GlobalDeleteAtom(m_hAtom);
  243. _SetThis(NULL);
  244. }
  245. //+---------------------------------------------------------------------------
  246. //
  247. // Initialize
  248. //
  249. //----------------------------------------------------------------------------
  250. STDAPI CSpeechUIServer::Initialize()
  251. {
  252. HRESULT hr;
  253. if (_tim)
  254. return S_OK;
  255. if (FAILED(hr = TF_CreateThreadMgr(&_tim)))
  256. return hr;
  257. if (FAILED(hr = GetService(_tim,
  258. IID_ITfLangBarItemMgr,
  259. (IUnknown **)&_lbim)))
  260. return hr;
  261. if (!(_pCes = new CCompartmentEventSink(_CompEventSinkCallback, this)))
  262. {
  263. return E_OUTOFMEMORY;
  264. }
  265. _pCes->_Advise(_tim, GUID_COMPARTMENT_SPEECH_OPENCLOSE, TRUE);
  266. _pCes->_Advise(_tim, GUID_COMPARTMENT_SPEECH_DISABLED, FALSE);
  267. _pCes->_Advise(_tim, GUID_COMPARTMENT_SPEECH_GLOBALSTATE, TRUE);
  268. _pCes->_Advise(_tim, GUID_COMPARTMENT_SPEECH_UI_STATUS, TRUE);
  269. _pCes->_Advise(_tim, GUID_COMPARTMENT_SHARED_BLN_TEXT, TRUE);
  270. _pCes->_Advise(_tim, GUID_COMPARTMENT_TTS_STATUS, FALSE);
  271. //TABLETPC
  272. _pCes->_Advise(_tim, GUID_COMPARTMENT_SPEECH_STAGE, FALSE);
  273. _pCes->_Advise(_tim, GUID_COMPARTMENT_SPEECH_STAGECHANGE, TRUE);
  274. // SetCompartmentDWORD(0, _tim, GUID_COMPARTMENT_SPEECH_UI_STATUS, 7, TRUE);
  275. // this is for TABLET
  276. DWORD dw = 0;
  277. GetCompartmentDWORD(_tim, GUID_COMPARTMENT_SPEECH_STAGECHANGE, &dw, TRUE);
  278. m_fStageVisible = dw ? TRUE : FALSE;
  279. m_fStageTip = FALSE;
  280. return S_OK;
  281. }
  282. // internal API specially added for ctfmon
  283. extern "C"
  284. HRESULT WINAPI TF_CreateLangProfileUtil(ITfFnLangProfileUtil **ppFnLangUtil);
  285. extern "C" HRESULT WINAPI TF_InvalidAssemblyListCacheIfExist();
  286. void CSpeechUIServer::_EnsureSpeechProfile()
  287. {
  288. CLangProfileUtil *pCLangUtil = NULL;
  289. CSapiIMX *pimx;
  290. if (pimx = GetIMX())
  291. {
  292. pCLangUtil = SAFECAST(pimx, CLangProfileUtil *);
  293. pCLangUtil->AddRef();
  294. }
  295. else
  296. {
  297. // ref gets added by the API
  298. TF_CreateLangProfileUtil((ITfFnLangProfileUtil **)&pCLangUtil);
  299. }
  300. if (pCLangUtil)
  301. {
  302. // do this only once when profiles are not populated for the user
  303. if(!pCLangUtil->_fUserInitializedProfile())
  304. {
  305. if (S_OK == pCLangUtil->RegisterActiveProfiles())
  306. TF_InvalidAssemblyListCacheIfExist();
  307. }
  308. }
  309. SafeRelease(pCLangUtil);
  310. }
  311. //+---------------------------------------------------------------------------
  312. //
  313. // ShowUI
  314. //
  315. //----------------------------------------------------------------------------
  316. STDAPI CSpeechUIServer::ShowUI(BOOL fShow)
  317. {
  318. DWORD dwDictState = GetDictStatus();
  319. if (fShow)
  320. {
  321. BOOL fOn = GetOnOff();
  322. BOOL fDisabled = GetDisabled();
  323. #ifdef TF_DISABLE_SPEECH
  324. BOOL fDictationDisabled = GetDictationDisabled();
  325. BOOL fCommandingDisabled = GetCommandingDisabled();
  326. #endif
  327. SetCompartmentDWORD(0, _tim,
  328. GUID_COMPARTMENT_SPEECHUISHOWN,
  329. TF_SPEECHUI_SHOWN,
  330. FALSE);
  331. AddItemMicrophone();
  332. DisableItemMicrophone(fDisabled);
  333. if (_pimx)
  334. {
  335. AddItemCfgMenuButton();
  336. DisableItemCfgMenuButton(fDisabled);
  337. if (!fDisabled)
  338. {
  339. SetCfgMenu(TRUE);
  340. }
  341. }
  342. if (fOn)
  343. {
  344. DWORD dwUIState = GetUIStatus();
  345. if (!(dwUIState & TF_DISABLE_BALLOON))
  346. {
  347. AddItemBalloon();
  348. DisableItemBalloon(fDisabled);
  349. }
  350. else
  351. RemoveItemBalloon();
  352. AddItemCommanding();
  353. AddItemDictation();
  354. DisableItemCommanding(fDisabled || fCommandingDisabled);
  355. DisableItemDictation(fDisabled || fDictationDisabled || !(dwDictState & TF_DICTATION_ENABLED));
  356. ToggleItemCommanding((dwDictState & TF_COMMANDING_ON) ? TRUE : FALSE);
  357. ToggleItemDictation((dwDictState & TF_DICTATION_ON) ? TRUE : FALSE);
  358. }
  359. else
  360. {
  361. RemoveItemBalloon();
  362. RemoveItemCommanding();
  363. RemoveItemDictation();
  364. }
  365. #ifdef CHANGE_MIC_TOOLTIP_ONTHEFLY
  366. _ToggleMicrophone(fOn);
  367. #else
  368. ToggleItemMicrophone(fOn);
  369. #endif
  370. // Handle TTS Play & Stop Buttons
  371. BOOL fTTSButtonEnable;
  372. AddItemTtsPlayStop( );
  373. AddItemTtsPauseResume( );
  374. fTTSButtonEnable = GetTtsButtonStatus();
  375. DisableItemTtsPlayStop( !fTTSButtonEnable );
  376. DisableItemTtsPauseResume( !fTTSButtonEnable );
  377. if ( fTTSButtonEnable )
  378. {
  379. BOOL fTTSPlayOn;
  380. BOOL fTTSPauseOn;
  381. fTTSPlayOn = GetTtsPlayOnOff( );
  382. ToggleItemTtsPlayStop(fTTSPlayOn);
  383. fTTSPauseOn = GetTtsPauseOnOff( );
  384. ToggleItemTtsPauseResume(fTTSPauseOn);
  385. }
  386. }
  387. else
  388. {
  389. RemoveItemMicrophone();
  390. SetCfgMenu(FALSE);
  391. RemoveItemCfgMenuButton();
  392. RemoveItemBalloon();
  393. RemoveItemCommanding();
  394. RemoveItemDictation();
  395. RemoveItemTtsPlayStop( );
  396. RemoveItemTtsPauseResume( );
  397. SetCompartmentDWORD(0, _tim,
  398. GUID_COMPARTMENT_SPEECHUISHOWN,
  399. 0, FALSE);
  400. }
  401. _fShown = fShow;
  402. return S_OK;
  403. }
  404. //+---------------------------------------------------------------------------
  405. //
  406. // UpdateBalloon
  407. //
  408. //----------------------------------------------------------------------------
  409. STDAPI CSpeechUIServer::UpdateBalloon(TfLBBalloonStyle style,
  410. const WCHAR *pch,
  411. ULONG cch)
  412. {
  413. UpdateBalloonAndTooltip(style, pch, cch, NULL, 0);
  414. return S_OK;
  415. }
  416. //
  417. // UpdateBalloonAndTooltip (internal method)
  418. //
  419. //
  420. //
  421. HRESULT CSpeechUIServer::UpdateBalloonAndTooltip
  422. (
  423. TfLBBalloonStyle style,
  424. const WCHAR *pch,
  425. ULONG cch,
  426. const WCHAR *pchTooltip,
  427. ULONG cchTooltip
  428. )
  429. {
  430. // check if it has same style and string already
  431. if ((_plbiBalloon && _plbiBalloon->NeedUpdate(style, pch)) || GetSystemMetrics(SM_TABLETPC) > 0)
  432. {
  433. // we don't pick up out proc tooltip
  434. if (pchTooltip && _plbiBalloon)
  435. _plbiBalloon->SetToolTip((WCHAR *)pchTooltip);
  436. // this is a private channel for non-cicero UI plugin
  437. // they pick up this global compartment notification,
  438. // and store the string for displaying what's set to
  439. // any of the balloon objects in the system by Cicero apps.
  440. // it should be deleted right after sent to non-cicero threads
  441. // to avoid ref count management
  442. //
  443. if (m_hAtom)
  444. {
  445. GlobalDeleteAtom(m_hAtom);
  446. }
  447. m_hAtom = GlobalAddAtomW(pch);
  448. if (m_hAtom && _tim)
  449. {
  450. DWORD dw;
  451. dw = m_hAtom + (style << 16);
  452. SetCompartmentDWORD(0, _tim, GUID_COMPARTMENT_SHARED_BLN_TEXT, dw, TRUE);
  453. }
  454. }
  455. return S_OK;
  456. }
  457. HRESULT CSpeechUIServer::SetBalloonSAPIInitFlag(BOOL fSet)
  458. {
  459. HRESULT hr = E_FAIL;
  460. if (_plbiBalloon)
  461. {
  462. _plbiBalloon->SetToFireInitializeSAPI(fSet);
  463. hr = S_OK;
  464. }
  465. return hr;
  466. }
  467. #ifdef CHANGE_MIC_TOOLTIP_ONTHEFLY
  468. //
  469. // ToggleMicrophone (internal method)
  470. //
  471. // synopsis: toggle microphone button and set tooltip accordingly
  472. //
  473. HRESULT CSpeechUIServer::_ToggleMicrophone(BOOL fOn)
  474. {
  475. if (!_plbiMicrophone)
  476. return E_FAIL;
  477. static WCHAR s_szTooltipOff[MAX_PATH] = {0};
  478. static WCHAR s_szTooltipOn[MAX_PATH] = {0};
  479. if (!s_szTooltipOff[0])
  480. {
  481. CicLoadStringWrapW(g_hInst, IDS_NUI_MICROPHONE_ON_TOOLTIP,
  482. s_szTooltipOff,
  483. ARRAYSIZE(s_szTooltipOff));
  484. }
  485. if (!s_szTooltipOn[0])
  486. {
  487. CicLoadStringWrapW(g_hInst, IDS_NUI_MICROPHONE_OFF_TOOLTIP,
  488. s_szTooltipOn,
  489. ARRAYSIZE(s_szTooltipOn));
  490. }
  491. WCHAR szMicTooltip[MAX_PATH];
  492. StringCchCopyW(szMicTooltip, ARRAYSIZE(szMicTooltip), fOn ? s_szTooltipOn : s_szTooltipOff);
  493. _plbiMicrophone->SetToolTip((WCHAR *)szMicTooltip);
  494. _plbiMicrophone->SetOrClearStatus(TF_LBI_STATUS_BTN_TOGGLED, fOn);
  495. if (_plbiMicrophone->GetSink())
  496. _plbiMicrophone->GetSink()->OnUpdate(TF_LBI_STATUS);
  497. return S_OK;
  498. }
  499. #endif
  500. //----------------------------------------------------------------------------
  501. //
  502. // _CompEventSinkCallback (static)
  503. //
  504. //----------------------------------------------------------------------------
  505. HRESULT CSpeechUIServer::_CompEventSinkCallback(void *pv, REFGUID rguid)
  506. {
  507. CSpeechUIServer *_this = (CSpeechUIServer *)pv;
  508. if ((IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_OPENCLOSE)) ||
  509. (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_DISABLED)) ||
  510. (IsEqualGUID(rguid, GUID_COMPARTMENT_TTS_STATUS)))
  511. {
  512. if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_OPENCLOSE))
  513. {
  514. TraceMsg(TF_SAPI_PERF, "GUID_COMPARTMENT_SPEECH_OPENCLOSE to be handled in NUI");
  515. }
  516. _this->ShowUI(_this->_fShown);
  517. if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_OPENCLOSE))
  518. {
  519. TraceMsg(TF_SAPI_PERF, "GUID_COMPARTMENT_SPEECH_OPENCLOSE is handled in NUI ::ShowUI");
  520. }
  521. return S_OK;
  522. }
  523. else if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_GLOBALSTATE))
  524. {
  525. HRESULT hr = S_OK;
  526. BOOL fFocus;
  527. if ( (S_OK == _this->_tim->IsThreadFocus(&fFocus) && fFocus) ||
  528. S_OK == _this->IsActiveThread())
  529. {
  530. // We switch states immediately if we have focus or we are the active thread.
  531. // This allows the stage speech tip instance to turn on/off dictation at the correct time
  532. // and allows other speech tip instances to turn on C&C only if they have focus (since the
  533. // stage application does not care about focus-based C&C).
  534. DWORD dwLocal, dwGlobal;
  535. GetCompartmentDWORD(_this->_tim, GUID_COMPARTMENT_SPEECH_DICTATIONSTAT, &dwLocal, FALSE);
  536. GetCompartmentDWORD(_this->_tim, GUID_COMPARTMENT_SPEECH_GLOBALSTATE, &dwGlobal, TRUE);
  537. dwGlobal = dwGlobal & (TF_DICTATION_ON + TF_COMMANDING_ON);
  538. if ( (dwLocal&(TF_DICTATION_ON + TF_COMMANDING_ON)) != dwGlobal)
  539. {
  540. dwLocal = (dwLocal & ~(TF_DICTATION_ON + TF_COMMANDING_ON)) + dwGlobal;
  541. SetCompartmentDWORD(0, _this->_tim, GUID_COMPARTMENT_SPEECH_DICTATIONSTAT, dwLocal, FALSE);
  542. }
  543. }
  544. _this->ShowUI(_this->_fShown);
  545. return hr;
  546. }
  547. else if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_UI_STATUS))
  548. {
  549. DWORD dwDictState = _this->GetDictStatus();
  550. BOOL fOn = _this->GetOnOff();
  551. DWORD dwUIState = _this->GetUIStatus();
  552. if (fOn &&
  553. (dwDictState & (TF_DICTATION_ENABLED | TF_COMMANDING_ENABLED)) &&
  554. !(dwUIState & TF_DISABLE_BALLOON))
  555. {
  556. BOOL fDisabled = _this->GetDisabled();
  557. _this->AddItemBalloon();
  558. _this->DisableItemBalloon(fDisabled);
  559. }
  560. else
  561. _this->RemoveItemBalloon();
  562. if (fOn && !(dwUIState & TF_DISABLE_BALLOON))
  563. {
  564. // when balloon is shown and
  565. // for the first time commanding is set on,
  566. // we show "Begin Voice Command" as a hint
  567. // that now user can start speaking
  568. //
  569. if (!_this->m_fCommandingReady &&
  570. (dwDictState & TF_COMMANDING_ON))
  571. {
  572. WCHAR sz[128];
  573. sz[0] = '\0';
  574. CicLoadStringWrapW(g_hInst, IDS_NUI_BEGINVOICECMD, sz, ARRAYSIZE(sz));
  575. _this->UpdateBalloon(TF_LB_BALLOON_RECO, sz , -1);
  576. _this->m_fCommandingReady = TRUE;
  577. }
  578. }
  579. }
  580. else if (IsEqualGUID(rguid, GUID_COMPARTMENT_SHARED_BLN_TEXT))
  581. {
  582. if (_this->_plbiBalloon&&
  583. !(TF_LBI_STATUS_HIDDEN & _this->_plbiBalloon->GetStatusInternal()))
  584. {
  585. DWORD dw;
  586. if (SUCCEEDED(GetCompartmentDWORD(_this->_tim, rguid, &dw, TRUE)))
  587. {
  588. ATOM hAtom = (WORD)dw & 0xffff;
  589. WCHAR szAtom[MAX_PATH] = {0};
  590. TfLBBalloonStyle style;
  591. style = (TfLBBalloonStyle) (dw >> 16);
  592. GlobalGetAtomNameW(hAtom, szAtom, ARRAYSIZE(szAtom));
  593. _this->_plbiBalloon->Set(style, szAtom);
  594. if (_this->_plbiBalloon->GetSink())
  595. {
  596. _this->_plbiBalloon->GetSink()->OnUpdate(TF_LBI_BALLOON);
  597. }
  598. }
  599. }
  600. }
  601. // TABLETPC
  602. else if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_STAGE))
  603. {
  604. _this->m_fStageTip = TRUE;
  605. }
  606. else if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_STAGECHANGE))
  607. {
  608. HRESULT hr = S_OK;
  609. DWORD dw;
  610. GetCompartmentDWORD(_this->_tim, GUID_COMPARTMENT_SPEECH_STAGECHANGE, &dw, TRUE);
  611. _this->m_fStageVisible = dw ? TRUE:FALSE;
  612. }
  613. // TABLETPC
  614. return S_FALSE;
  615. }
  616. //////////////////////////////////////////////////////////////////////////////
  617. //
  618. // CLBarItemMicrophone
  619. //
  620. //////////////////////////////////////////////////////////////////////////////
  621. //+---------------------------------------------------------------------------
  622. //
  623. // ctor
  624. //
  625. //----------------------------------------------------------------------------
  626. CLBarItemMicrophone::CLBarItemMicrophone(CSpeechUIServer *psus)
  627. {
  628. Dbg_MemSetThisName(TEXT("CLBarItemMicrophone"));
  629. _psus = psus;
  630. InitNuiInfo(CLSID_SYSTEMLANGBARITEM_SPEECH,
  631. GUID_LBI_SAPILAYR_MICROPHONE,
  632. TF_LBI_STYLE_HIDDENSTATUSCONTROL
  633. | TF_LBI_STYLE_BTN_TOGGLE
  634. | TF_LBI_STYLE_SHOWNINTRAY,
  635. SORT_MICROPHONE,
  636. CRStr(IDS_NUI_MICROPHONE_TOOLTIP));
  637. SetToolTip(CRStr(IDS_NUI_MICROPHONE_TOOLTIP));
  638. SetText(CRStr(IDS_NUI_MICROPHONE_TEXT));
  639. }
  640. //+---------------------------------------------------------------------------
  641. //
  642. // dtor
  643. //
  644. //----------------------------------------------------------------------------
  645. CLBarItemMicrophone::~CLBarItemMicrophone()
  646. {
  647. }
  648. //+---------------------------------------------------------------------------
  649. //
  650. // GetIcon
  651. //
  652. //----------------------------------------------------------------------------
  653. STDAPI CLBarItemMicrophone::GetIcon(HICON *phIcon)
  654. {
  655. if (!phIcon)
  656. return E_INVALIDARG;
  657. TraceMsg(TF_SAPI_PERF, "Microphone::GetIcon is called");
  658. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_MICROPHONE));
  659. return S_OK;
  660. }
  661. //+---------------------------------------------------------------------------
  662. //
  663. // OnLButtonUp
  664. //
  665. //----------------------------------------------------------------------------
  666. HRESULT CLBarItemMicrophone::OnLButtonUp(const POINT pt, const RECT *prcArea)
  667. {
  668. TraceMsg(TF_SAPI_PERF, "Microphone button is hit");
  669. return ToggleCompartmentDWORD(0,
  670. _psus->GetTIM(),
  671. GUID_COMPARTMENT_SPEECH_OPENCLOSE,
  672. TRUE);
  673. }
  674. //////////////////////////////////////////////////////////////////////////////
  675. //
  676. // CLBarItemCfgmenuButton
  677. //
  678. //////////////////////////////////////////////////////////////////////////////
  679. //+---------------------------------------------------------------------------
  680. //
  681. // ctor
  682. //
  683. //----------------------------------------------------------------------------
  684. CLBarItemCfgMenuButton::CLBarItemCfgMenuButton(CSpeechUIServer *psus)
  685. {
  686. Dbg_MemSetThisName(TEXT("CLBarItemCfgMenuButton"));
  687. _psus = psus;
  688. InitNuiInfo(CLSID_SYSTEMLANGBARITEM_SPEECH,
  689. GUID_LBI_SAPILAYR_CFGMENUBUTTON,
  690. TF_LBI_STYLE_BTN_MENU,
  691. SORT_CFGMENUBUTTON,
  692. CRStr(IDS_NUI_CFGMENU_TOOLTIP));
  693. SetToolTip(CRStr(IDS_NUI_CFGMENU_TOOLTIP));
  694. SetText(CRStr(IDS_NUI_CFGMENU_TEXT));
  695. }
  696. //+---------------------------------------------------------------------------
  697. //
  698. // dtor
  699. //
  700. //----------------------------------------------------------------------------
  701. CLBarItemCfgMenuButton::~CLBarItemCfgMenuButton()
  702. {
  703. }
  704. //+---------------------------------------------------------------------------
  705. //
  706. // GetIcon
  707. //
  708. //----------------------------------------------------------------------------
  709. STDAPI CLBarItemCfgMenuButton::GetIcon(HICON *phIcon)
  710. {
  711. if (!phIcon)
  712. return E_INVALIDARG;
  713. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_CFGMENU));
  714. return S_OK;
  715. }
  716. //+---------------------------------------------------------------------------
  717. //
  718. // InitMenu
  719. //
  720. //----------------------------------------------------------------------------
  721. STDAPI CLBarItemCfgMenuButton::InitMenu(ITfMenu *pMenu)
  722. {
  723. UINT nTipCurMenuID = IDM_CUSTOM_MENU_START;
  724. _InsertCustomMenus(pMenu, &nTipCurMenuID);
  725. CSapiIMX::_SysLBarCallback(IDSLB_INITMENU, _psus->GetIMX(), pMenu, 0);
  726. return S_OK;
  727. }
  728. //+---------------------------------------------------------------------------
  729. //
  730. // OnMenuSelect
  731. //
  732. //----------------------------------------------------------------------------
  733. STDAPI CLBarItemCfgMenuButton::OnMenuSelect(UINT uID)
  734. {
  735. HRESULT hr;
  736. if (uID >= IDM_CUSTOM_MENU_START)
  737. hr = CLBarItemSystemButtonBase::OnMenuSelect(uID);
  738. else
  739. hr = CSapiIMX::_SysLBarCallback(IDSLB_ONMENUSELECT, _psus->GetIMX(), NULL, uID);
  740. return hr;
  741. }
  742. //////////////////////////////////////////////////////////////////////////////
  743. //
  744. // CLBarItemBalloon
  745. //
  746. //////////////////////////////////////////////////////////////////////////////
  747. //+---------------------------------------------------------------------------
  748. //
  749. // ctor
  750. //
  751. //----------------------------------------------------------------------------
  752. CLBarItemBalloon::CLBarItemBalloon(CSpeechUIServer *psus)
  753. {
  754. Dbg_MemSetThisName(TEXT("CLBarItemBalloon"));
  755. _psus = psus;
  756. InitNuiInfo(CLSID_SYSTEMLANGBARITEM_SPEECH,
  757. GUID_LBI_SAPILAYR_BALLOON,
  758. 0,
  759. SORT_BALLOON,
  760. CRStr(IDS_NUI_BALLOON_TEXT));
  761. SIZE size;
  762. size.cx = 100;
  763. size.cy = 16;
  764. SetPreferedSize(&size);
  765. SetToolTip(CRStr(IDS_NUI_BALLOON_TOOLTIP));
  766. // by default Balloon is hidden.
  767. // SetStatusInternal(TF_LBI_STATUS_HIDDEN);
  768. m_fFireInitializeSapi = FALSE;
  769. }
  770. //+---------------------------------------------------------------------------
  771. //
  772. // dtor
  773. //
  774. //----------------------------------------------------------------------------
  775. CLBarItemBalloon::~CLBarItemBalloon()
  776. {
  777. if (_bstrText)
  778. SysFreeString(_bstrText);
  779. }
  780. //+---------------------------------------------------------------------------
  781. //
  782. // GetBalloonInfo
  783. //
  784. //----------------------------------------------------------------------------
  785. STDAPI CLBarItemBalloon::GetBalloonInfo(TF_LBBALLOONINFO *pInfo)
  786. {
  787. pInfo->style = _style;
  788. pInfo->bstrText = SysAllocString(_bstrText);
  789. //
  790. // If the flag is set, we're asked to fire an event to set
  791. // a timer to start SAPI intialization
  792. //
  793. if (m_fFireInitializeSapi)
  794. {
  795. // turns the flag off
  796. SetToFireInitializeSAPI(FALSE);
  797. TraceMsg(TF_SAPI_PERF, "GetBalloonInfo is called");
  798. CSapiIMX *pimx = _psus->GetIMX();
  799. if (pimx)
  800. {
  801. pimx->_EnsureWorkerWnd();
  802. SetTimer(pimx->_GetWorkerWnd(), TIMER_ID_OPENCLOSE, 100, NULL);
  803. }
  804. }
  805. return S_OK;
  806. }
  807. //+---------------------------------------------------------------------------
  808. //
  809. // Set
  810. //
  811. //----------------------------------------------------------------------------
  812. void CLBarItemBalloon::Set(TfLBBalloonStyle style, const WCHAR *psz)
  813. {
  814. if (_bstrText)
  815. SysFreeString(_bstrText);
  816. _bstrText = SysAllocString(psz);
  817. if (_bstrText)
  818. {
  819. SetToolTip(_bstrText);
  820. }
  821. _style = style;
  822. }
  823. //////////////////////////////////////////////////////////////////////////////
  824. //
  825. // CLBarItemDictation
  826. //
  827. //////////////////////////////////////////////////////////////////////////////
  828. //+---------------------------------------------------------------------------
  829. //
  830. // ctor
  831. //
  832. //----------------------------------------------------------------------------
  833. CLBarItemDictation::CLBarItemDictation(CSpeechUIServer *psus)
  834. {
  835. Dbg_MemSetThisName(TEXT("CLBarItemDictation"));
  836. _psus = psus;
  837. InitNuiInfo(CLSID_SYSTEMLANGBARITEM_SPEECH,
  838. GUID_LBI_SAPILAYR_DICTATION,
  839. TF_LBI_STYLE_BTN_TOGGLE,
  840. SORT_DICTATION,
  841. CRStr(IDS_NUI_DICTATION_TOOLTIP));
  842. SetToolTip(CRStr(IDS_NUI_DICTATION_TOOLTIP));
  843. SetText(CRStr(IDS_NUI_DICTATION_TEXT));
  844. }
  845. //+---------------------------------------------------------------------------
  846. //
  847. // dtor
  848. //
  849. //----------------------------------------------------------------------------
  850. CLBarItemDictation::~CLBarItemDictation()
  851. {
  852. }
  853. //+---------------------------------------------------------------------------
  854. //
  855. // GetIcon
  856. //
  857. //----------------------------------------------------------------------------
  858. STDAPI CLBarItemDictation::GetIcon(HICON *phIcon)
  859. {
  860. if (!phIcon)
  861. return E_INVALIDARG;
  862. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_DICTATION));
  863. return S_OK;
  864. }
  865. //+---------------------------------------------------------------------------
  866. //
  867. // OnLButtonUp
  868. //
  869. //----------------------------------------------------------------------------
  870. HRESULT CLBarItemDictation::OnLButtonUp(const POINT pt, const RECT *prcArea)
  871. {
  872. _psus->SetDictStatus();
  873. return S_OK;
  874. }
  875. //////////////////////////////////////////////////////////////////////////////
  876. //
  877. // CLBarItemCommanding
  878. //
  879. //////////////////////////////////////////////////////////////////////////////
  880. //+---------------------------------------------------------------------------
  881. //
  882. // ctor
  883. //
  884. //----------------------------------------------------------------------------
  885. CLBarItemCommanding::CLBarItemCommanding(CSpeechUIServer *psus)
  886. {
  887. Dbg_MemSetThisName(TEXT("CLBarItemCommanding"));
  888. _psus = psus;
  889. InitNuiInfo(CLSID_SYSTEMLANGBARITEM_SPEECH,
  890. GUID_LBI_SAPILAYR_COMMANDING,
  891. TF_LBI_STYLE_BTN_TOGGLE,
  892. SORT_COMMANDING,
  893. CRStr(IDS_NUI_COMMANDING_TOOLTIP));
  894. SetToolTip(CRStr(IDS_NUI_COMMANDING_TOOLTIP));
  895. SetText(CRStr(IDS_NUI_COMMANDING_TEXT));
  896. }
  897. //+---------------------------------------------------------------------------
  898. //
  899. // dtor
  900. //
  901. //----------------------------------------------------------------------------
  902. CLBarItemCommanding::~CLBarItemCommanding()
  903. {
  904. }
  905. //+---------------------------------------------------------------------------
  906. //
  907. // GetIcon
  908. //
  909. //----------------------------------------------------------------------------
  910. STDAPI CLBarItemCommanding::GetIcon(HICON *phIcon)
  911. {
  912. if (!phIcon)
  913. return E_INVALIDARG;
  914. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_COMMANDING));
  915. return S_OK;
  916. }
  917. //+---------------------------------------------------------------------------
  918. //
  919. // OnLButtonUp
  920. //
  921. //----------------------------------------------------------------------------
  922. HRESULT CLBarItemCommanding::OnLButtonUp(const POINT pt, const RECT *prcArea)
  923. {
  924. _psus->SetCmdStatus();
  925. return S_OK;
  926. }
  927. //////////////////////////////////////////////////////////////////////////////
  928. //
  929. // CLBarItemTtsPlayStop
  930. //
  931. //////////////////////////////////////////////////////////////////////////////
  932. //+---------------------------------------------------------------------------
  933. //
  934. // ctor
  935. //
  936. //----------------------------------------------------------------------------
  937. CLBarItemTtsPlayStop::CLBarItemTtsPlayStop(CSpeechUIServer *psus)
  938. {
  939. Dbg_MemSetThisName(TEXT("CLBarItemTtsPlayStop"));
  940. _psus = psus;
  941. InitNuiInfo(CLSID_SYSTEMLANGBARITEM_SPEECH,
  942. GUID_LBI_SAPILAYR_TTS_PLAY_STOP,
  943. TF_LBI_STYLE_BTN_TOGGLE | TF_LBI_STYLE_HIDDENBYDEFAULT,
  944. SORT_TTSPLAYSTOP,
  945. CRStr(IDS_NUI_TTSPLAY_TOOLTIP));
  946. SetToolTip(CRStr(IDS_NUI_TTSPLAY_TOOLTIP));
  947. SetText(CRStr(IDS_NUI_TTSPLAY_TEXT));
  948. }
  949. //+---------------------------------------------------------------------------
  950. //
  951. // dtor
  952. //
  953. //----------------------------------------------------------------------------
  954. CLBarItemTtsPlayStop::~CLBarItemTtsPlayStop()
  955. {
  956. }
  957. //+---------------------------------------------------------------------------
  958. //
  959. // GetIcon
  960. //
  961. //----------------------------------------------------------------------------
  962. STDAPI CLBarItemTtsPlayStop::GetIcon(HICON *phIcon)
  963. {
  964. BOOL fTTSPlayOn;
  965. if (!phIcon)
  966. return E_INVALIDARG;
  967. if (!_psus) return E_FAIL;
  968. fTTSPlayOn = _psus->GetTtsPlayOnOff( );
  969. if ( fTTSPlayOn )
  970. {
  971. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_TTSSTOP));
  972. }
  973. else
  974. {
  975. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_TTSPLAY));
  976. }
  977. return S_OK;
  978. }
  979. //+---------------------------------------------------------------------------
  980. //
  981. // OnLButtonUp
  982. //
  983. //----------------------------------------------------------------------------
  984. HRESULT CLBarItemTtsPlayStop::OnLButtonUp(const POINT pt, const RECT *prcArea)
  985. {
  986. HRESULT hr = S_OK;
  987. CSapiIMX *pimx;
  988. if ( _psus == NULL) return E_FAIL;
  989. pimx = _psus->GetIMX();
  990. if ( pimx )
  991. {
  992. hr = pimx->_HandleEventOnPlayButton( );
  993. }
  994. return hr;
  995. }
  996. // +-------------------------------------------------------------------------
  997. //
  998. // UpdateStatus
  999. //
  1000. // Update the text, tooltips, and icons based on current Play/Stop
  1001. // button's status.
  1002. // +-------------------------------------------------------------------------
  1003. HRESULT CLBarItemTtsPlayStop::UpdateStatus( )
  1004. {
  1005. HRESULT hr = S_OK;
  1006. BOOL fTTSPlayOn;
  1007. if (!_psus) return E_FAIL;
  1008. fTTSPlayOn = _psus->GetTtsPlayOnOff( );
  1009. if ( fTTSPlayOn ) // Toggled status
  1010. {
  1011. SetToolTip(CRStr(IDS_NUI_TTSSTOP_TOOLTIP));
  1012. SetText(CRStr(IDS_NUI_TTSSTOP_TEXT));
  1013. }
  1014. else
  1015. {
  1016. SetToolTip(CRStr(IDS_NUI_TTSPLAY_TOOLTIP));
  1017. SetText(CRStr(IDS_NUI_TTSPLAY_TEXT));
  1018. }
  1019. if ( GetSink( ) )
  1020. GetSink( )->OnUpdate(TF_LBI_ICON | TF_LBI_TEXT | TF_LBI_TOOLTIP);
  1021. // Update the toolbar command grammar to use the new tooltip text
  1022. // Speak Text or Stop speaking
  1023. CSapiIMX *pImx;
  1024. pImx = _psus->GetIMX( );
  1025. if ( pImx)
  1026. {
  1027. CSpTask *psp;
  1028. pImx->GetSpeechTask(&psp);
  1029. if (psp)
  1030. {
  1031. if ( psp->m_pLangBarSink )
  1032. (psp->m_pLangBarSink)->OnThreadItemChange(0);
  1033. psp->Release();
  1034. }
  1035. }
  1036. return hr;
  1037. }
  1038. //////////////////////////////////////////////////////////////////////////////
  1039. //
  1040. // CLBarItemTtsPauseResume
  1041. //
  1042. //////////////////////////////////////////////////////////////////////////////
  1043. //+---------------------------------------------------------------------------
  1044. //
  1045. // ctor
  1046. //
  1047. //----------------------------------------------------------------------------
  1048. CLBarItemTtsPauseResume::CLBarItemTtsPauseResume(CSpeechUIServer *psus)
  1049. {
  1050. Dbg_MemSetThisName(TEXT("CLBarItemTtsPauseResume"));
  1051. _psus = psus;
  1052. InitNuiInfo(CLSID_SYSTEMLANGBARITEM_SPEECH,
  1053. GUID_LBI_SAPILAYR_TTS_PAUSE_RESUME,
  1054. TF_LBI_STYLE_BTN_TOGGLE | TF_LBI_STYLE_HIDDENBYDEFAULT,
  1055. SORT_TTSPAUSERESUME,
  1056. CRStr(IDS_NUI_TTSPAUSE_TOOLTIP));
  1057. SetToolTip(CRStr(IDS_NUI_TTSPAUSE_TOOLTIP));
  1058. SetText(CRStr(IDS_NUI_TTSPAUSE_TEXT));
  1059. }
  1060. //+---------------------------------------------------------------------------
  1061. //
  1062. // dtor
  1063. //
  1064. //----------------------------------------------------------------------------
  1065. CLBarItemTtsPauseResume::~CLBarItemTtsPauseResume()
  1066. {
  1067. }
  1068. //+---------------------------------------------------------------------------
  1069. //
  1070. // GetIcon
  1071. //
  1072. //----------------------------------------------------------------------------
  1073. STDAPI CLBarItemTtsPauseResume::GetIcon(HICON *phIcon)
  1074. {
  1075. if (!phIcon)
  1076. return E_INVALIDARG;
  1077. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_TTSPAUSE));
  1078. return S_OK;
  1079. }
  1080. //+---------------------------------------------------------------------------
  1081. //
  1082. // OnLButtonUp
  1083. //
  1084. //----------------------------------------------------------------------------
  1085. HRESULT CLBarItemTtsPauseResume::OnLButtonUp(const POINT pt, const RECT *prcArea)
  1086. {
  1087. HRESULT hr = S_OK;
  1088. CSapiIMX *pimx;
  1089. if ( _psus == NULL) return E_FAIL;
  1090. pimx = _psus->GetIMX();
  1091. if (pimx)
  1092. {
  1093. hr = pimx->_HandleEventOnPauseButton( );
  1094. }
  1095. return hr;
  1096. }
  1097. // +-------------------------------------------------------------------------
  1098. //
  1099. // UpdateStatus
  1100. //
  1101. // Update text, tooltips, icons for Pause/Resume buttons
  1102. // based on current status.
  1103. // +-------------------------------------------------------------------------
  1104. HRESULT CLBarItemTtsPauseResume::UpdateStatus( )
  1105. {
  1106. HRESULT hr = S_OK;
  1107. BOOL fTTSPauseOn;
  1108. if (!_psus) return E_FAIL;
  1109. fTTSPauseOn = _psus->GetTtsPauseOnOff( );
  1110. if ( fTTSPauseOn ) // Toggled status
  1111. {
  1112. SetToolTip(CRStr(IDS_NUI_TTSRESUME_TOOLTIP));
  1113. SetText(CRStr(IDS_NUI_TTSRESUME_TEXT));
  1114. }
  1115. else
  1116. {
  1117. SetToolTip(CRStr(IDS_NUI_TTSPAUSE_TOOLTIP));
  1118. SetText(CRStr(IDS_NUI_TTSPAUSE_TEXT));
  1119. }
  1120. if ( GetSink( ) )
  1121. GetSink( )->OnUpdate(TF_LBI_TEXT | TF_LBI_TOOLTIP);
  1122. // Update the toolbar command grammar to use the new tooltip text
  1123. // Pause Speaking or Resume speaking
  1124. CSapiIMX *pImx;
  1125. pImx = _psus->GetIMX( );
  1126. if ( pImx)
  1127. {
  1128. CSpTask *psp;
  1129. pImx->GetSpeechTask(&psp);
  1130. if (psp)
  1131. {
  1132. if ( psp->m_pLangBarSink )
  1133. (psp->m_pLangBarSink)->OnThreadItemChange(0);
  1134. psp->Release();
  1135. }
  1136. }
  1137. return hr;
  1138. }