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.

570 lines
13 KiB

  1. //
  2. // mslbui.cpp
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "mslbui.h"
  7. #include "helpers.h"
  8. /* 2dc1cc1f-3e09-49c5-9cf0-bf67154dc827 */
  9. const GUID GUID_COMPARTMENT_CICPAD = {
  10. 0x2dc1cc1f,
  11. 0x3e09,
  12. 0x49c5,
  13. {0x9c, 0xf0, 0xbf, 0x67, 0x15, 0x4d, 0xc8, 0x27}
  14. };
  15. // Issue: we should add this to private header
  16. /* c1a1554f-b715-48e1-921f-716fd7332ce9 */
  17. const GUID GUID_COMPARTMENT_SHARED_BLN_TEXT = {
  18. 0xc1a1554f,
  19. 0xb715,
  20. 0x48e1,
  21. {0x92, 0x1f, 0x71, 0x6f, 0xd7, 0x33, 0x2c, 0xe9}
  22. };
  23. /* 574e41bb-1bf4-4630-95dd-b143372ac8d0 */
  24. const GUID GUID_COMPARTMENT_SPEECHUISHOWN = {
  25. 0x574e41bb,
  26. 0x1bf4,
  27. 0x4630,
  28. {0x95, 0xdd, 0xb1, 0x43, 0x37, 0x2a, 0xc8, 0xd0}
  29. };
  30. //////////////////////////////////////////////////////////////////////////////
  31. //
  32. // CTFGetLangBarAddIn
  33. //
  34. //////////////////////////////////////////////////////////////////////////////
  35. HRESULT CTFGetLangBarAddIn(ITfLangBarAddIn **ppAddIn)
  36. {
  37. CUnCicAppLangBarAddIn *pAddIn;
  38. *ppAddIn = NULL;
  39. pAddIn = new CUnCicAppLangBarAddIn;
  40. if (!pAddIn)
  41. return E_OUTOFMEMORY;
  42. *ppAddIn = pAddIn;
  43. return S_OK;
  44. }
  45. //////////////////////////////////////////////////////////////////////////////
  46. //
  47. // CUnCicAppLangBarAddIn
  48. //
  49. //////////////////////////////////////////////////////////////////////////////
  50. //+---------------------------------------------------------------------------
  51. //
  52. // IUnknown
  53. //
  54. //----------------------------------------------------------------------------
  55. STDAPI CUnCicAppLangBarAddIn::QueryInterface(REFIID riid, void **ppvObj)
  56. {
  57. *ppvObj = NULL;
  58. if (IsEqualIID(riid, IID_IUnknown) ||
  59. IsEqualIID(riid, IID_ITfLangBarAddIn))
  60. {
  61. *ppvObj = SAFECAST(this, ITfLangBarAddIn *);
  62. }
  63. if (*ppvObj)
  64. {
  65. AddRef();
  66. return S_OK;
  67. }
  68. return E_NOINTERFACE;
  69. }
  70. STDAPI_(ULONG) CUnCicAppLangBarAddIn::AddRef()
  71. {
  72. return ++_cRef;
  73. }
  74. STDAPI_(ULONG) CUnCicAppLangBarAddIn::Release()
  75. {
  76. long cr;
  77. cr = --_cRef;
  78. Assert(cr >= 0);
  79. if (cr == 0)
  80. {
  81. delete this;
  82. }
  83. return cr;
  84. }
  85. //+---------------------------------------------------------------------------
  86. //
  87. // ctor
  88. //
  89. //----------------------------------------------------------------------------
  90. CUnCicAppLangBarAddIn::CUnCicAppLangBarAddIn()
  91. {
  92. _cRef = 1;
  93. }
  94. //+---------------------------------------------------------------------------
  95. //
  96. // dtor
  97. //
  98. //----------------------------------------------------------------------------
  99. CUnCicAppLangBarAddIn::~CUnCicAppLangBarAddIn()
  100. {
  101. }
  102. //+---------------------------------------------------------------------------
  103. //
  104. // OnStart
  105. //
  106. //----------------------------------------------------------------------------
  107. STDAPI CUnCicAppLangBarAddIn::OnStart(CLSID *pclsid)
  108. {
  109. ITfLangBarItemMgr *plbim = NULL;
  110. HRESULT hr;
  111. Assert(!_plbim);
  112. Assert(!_pCicPadItem);
  113. hr = TF_CreateLangBarItemMgr(&plbim);
  114. if (FAILED(hr))
  115. return hr;
  116. if (!plbim)
  117. return E_FAIL;
  118. _plbim = plbim;
  119. #ifdef _DEBUG_
  120. CLBarTestItem *pTestItem;
  121. pTestItem = new CLBarTestItem;
  122. if (pTestItem)
  123. {
  124. if (SUCCEEDED(plbim->AddItem(pTestItem)))
  125. _pTestItem = pTestItem;
  126. else
  127. Assert(0);
  128. }
  129. #endif
  130. *pclsid = CLSID_MSLBUI;
  131. return S_OK;
  132. }
  133. //+---------------------------------------------------------------------------
  134. //
  135. // OnUpdate()
  136. //
  137. //----------------------------------------------------------------------------
  138. STDAPI CUnCicAppLangBarAddIn::OnUpdate(DWORD dwFlags)
  139. {
  140. HRESULT hr = S_OK;
  141. #if 1
  142. if (!_pces &&
  143. (_pces = new CGlobalCompartmentEventSink(_CompEventSinkCallback,this)))
  144. {
  145. hr =_pces->_Advise(GUID_COMPARTMENT_CICPAD);
  146. if (S_OK == hr)
  147. hr = _pces->_Advise(GUID_COMPARTMENT_SPEECH_OPENCLOSE);
  148. if (S_OK == hr)
  149. hr = _pces->_Advise(GUID_COMPARTMENT_SHARED_BLN_TEXT);
  150. if (S_OK != hr)
  151. {
  152. _pces->_Unadvise();
  153. delete _pces;
  154. _pces = NULL;
  155. }
  156. }
  157. #endif
  158. // let's assume language bar item manager is initialized already
  159. if (!_plbim)
  160. return E_FAIL;
  161. DWORD dwMicOn = 0;
  162. hr = GetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, &dwMicOn);
  163. if ( FAILED(hr))
  164. return hr;
  165. if (_pCicPadItem)
  166. {
  167. _pCicPadItem->SetOrClearStatus(TF_LBI_STATUS_HIDDEN,
  168. dwFlags ? TRUE : FALSE);
  169. if (_pCicPadItem->GetSink())
  170. _pCicPadItem->GetSink()->OnUpdate(TF_LBI_STATUS);
  171. }
  172. #if 0
  173. else if (!dwFlags) // non-Cicero case
  174. {
  175. CLBarCicPadItem *pCicPadItem = NULL;
  176. // create cicpad item
  177. pCicPadItem = new CLBarCicPadItem;
  178. if (!pCicPadItem)
  179. return E_OUTOFMEMORY;
  180. hr = _plbim->AddItem(pCicPadItem);
  181. if (FAILED(hr))
  182. {
  183. pCicPadItem->Release();
  184. return hr;
  185. }
  186. _pCicPadItem = pCicPadItem;
  187. }
  188. #endif
  189. // We don't need to create Mic, Balloon or Cfg menu
  190. // when the thread has speech UI server running already
  191. // *OR* the speech isn't installed on the system
  192. //
  193. if (!_IsSREnabledForLangInReg(LANGIDFROMHKL(GetSystemDefaultHKL()))
  194. ||( GetUIStatus() & TF_SPEECHUI_SHOWN ))
  195. {
  196. dwFlags |= 1;
  197. _DeleteSpeechUIItems();
  198. }
  199. if (_pMicrophoneItem)
  200. {
  201. _pMicrophoneItem->SetOrClearStatus(TF_LBI_STATUS_HIDDEN,
  202. dwFlags ? TRUE : FALSE);
  203. if (_pMicrophoneItem->GetSink())
  204. _pMicrophoneItem->GetSink()->OnUpdate(TF_LBI_STATUS);
  205. }
  206. else if (!dwFlags) // non-Cicero case
  207. {
  208. CLBarItemMicrophone *pMicrophoneItem = NULL;
  209. // create microphone item
  210. pMicrophoneItem = new CLBarItemMicrophone;
  211. if (!pMicrophoneItem)
  212. return E_OUTOFMEMORY;
  213. hr = _plbim->AddItem(pMicrophoneItem);
  214. if (FAILED(hr))
  215. {
  216. pMicrophoneItem->Release();
  217. return hr;
  218. }
  219. _pMicrophoneItem = pMicrophoneItem;
  220. }
  221. if ( _pMicrophoneItem && !dwFlags )
  222. {
  223. // For Non-Cicero application, we want to show the Mic button
  224. // as pressed if the MIC status is ON.
  225. ToggleMicrophoneBtn(dwMicOn ? TRUE : FALSE);
  226. }
  227. if (_pBalloonItem)
  228. {
  229. _pBalloonItem->SetOrClearStatus(TF_LBI_STATUS_HIDDEN,
  230. dwFlags ? TRUE : FALSE);
  231. if (_pBalloonItem->GetSink())
  232. _pBalloonItem->GetSink()->OnUpdate(TF_LBI_STATUS);
  233. }
  234. else // when balloon isn't initialized
  235. {
  236. if (dwFlags)
  237. {
  238. // this is the case you are on Cicero app
  239. RemoveItemBalloon();
  240. }
  241. else if (dwMicOn)
  242. {
  243. // this is the case you are on non-Cicero app
  244. AddItemBalloon();
  245. }
  246. }
  247. if ( _pBalloonItem && !dwFlags && dwMicOn && GetBalloonStatus())
  248. {
  249. // Display "Mic is On" on the balloon for Non-Cicero Aware Application.
  250. if (!(TF_LBI_STATUS_HIDDEN &
  251. _pMicrophoneItem->GetStatusInternal()))
  252. {
  253. SetBalloonText(CRStr(IDS_MIC_ON));
  254. }
  255. }
  256. if (_pCfgMenuItem)
  257. {
  258. _pCfgMenuItem->SetOrClearStatus(TF_LBI_STATUS_HIDDEN,
  259. dwFlags ? TRUE : FALSE);
  260. if (_pCfgMenuItem->GetSink())
  261. _pCfgMenuItem->GetSink()->OnUpdate(TF_LBI_STATUS);
  262. }
  263. else if (!dwFlags) // non-Cicero case
  264. {
  265. CLBarItemCfgMenuButton *pCfgMenuItem = NULL;
  266. // create tool menu item
  267. pCfgMenuItem = new CLBarItemCfgMenuButton;
  268. if (!pCfgMenuItem)
  269. return E_OUTOFMEMORY;
  270. hr = _plbim->AddItem(pCfgMenuItem);
  271. if (FAILED(hr))
  272. {
  273. pCfgMenuItem->Release();
  274. return hr;
  275. }
  276. _pCfgMenuItem = pCfgMenuItem;
  277. }
  278. return S_OK;
  279. }
  280. //+---------------------------------------------------------------------------
  281. //
  282. // dtor
  283. //
  284. //----------------------------------------------------------------------------
  285. STDAPI CUnCicAppLangBarAddIn::OnTerminate()
  286. {
  287. if (g_fProcessDetached)
  288. return S_OK;
  289. if (_pces)
  290. {
  291. _pces->_Unadvise();
  292. _pces->Release();
  293. _pces = NULL;
  294. }
  295. if (_pCicPadItem)
  296. {
  297. _plbim->RemoveItem(_pCicPadItem);
  298. _pCicPadItem->Release();
  299. _pCicPadItem = NULL;
  300. }
  301. _DeleteSpeechUIItems();
  302. if (_ptim)
  303. {
  304. _ptim->Release();
  305. _ptim = NULL;
  306. }
  307. #ifdef _DEBUG_
  308. if (_pTestItem)
  309. {
  310. _plbim->RemoveItem(_pTestItem);
  311. _pTestItem->Release();
  312. _pTestItem = NULL;
  313. }
  314. #endif
  315. SafeReleaseClear(_plbim);
  316. SafeReleaseClear(_pCompMgr);
  317. return S_OK;
  318. }
  319. void CUnCicAppLangBarAddIn::_DeleteSpeechUIItems()
  320. {
  321. if (_pMicrophoneItem)
  322. {
  323. _plbim->RemoveItem(_pMicrophoneItem);
  324. _pMicrophoneItem->Release();
  325. _pMicrophoneItem = NULL;
  326. }
  327. if (_pBalloonItem)
  328. {
  329. _plbim->RemoveItem(_pBalloonItem);
  330. _pBalloonItem->Release();
  331. _pBalloonItem = NULL;
  332. }
  333. if (_pCfgMenuItem)
  334. {
  335. _plbim->RemoveItem(_pCfgMenuItem);
  336. _pCfgMenuItem->Release();
  337. _pCfgMenuItem = NULL;
  338. }
  339. }
  340. //+---------------------------------------------------------------------------
  341. //
  342. // _CompEventSinkCallback
  343. //
  344. //----------------------------------------------------------------------------
  345. HRESULT CUnCicAppLangBarAddIn::_CompEventSinkCallback(void *pv, REFGUID rguid)
  346. {
  347. CUnCicAppLangBarAddIn *_this = (CUnCicAppLangBarAddIn *)pv;
  348. if (!_this)
  349. return E_FAIL;
  350. if (IsEqualGUID(rguid, GUID_COMPARTMENT_CICPAD))
  351. {
  352. if (!_this->_pCicPadItem)
  353. return E_FAIL;
  354. DWORD dw;
  355. if (SUCCEEDED(GetGlobalCompartmentDWORD(rguid, &dw)))
  356. {
  357. _this->_pCicPadItem->SetOrClearStatus(TF_LBI_STATUS_BTN_TOGGLED,
  358. dw ? TRUE : FALSE);
  359. if (_this->_pCicPadItem->GetSink())
  360. _this->_pCicPadItem->GetSink()->OnUpdate(TF_LBI_STATUS);
  361. }
  362. }
  363. else if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_OPENCLOSE))
  364. {
  365. if (!_this->_pMicrophoneItem)
  366. return E_FAIL;
  367. DWORD dwMicOn;
  368. if (SUCCEEDED(GetGlobalCompartmentDWORD(rguid, &dwMicOn)))
  369. {
  370. _this->ToggleMicrophoneBtn(dwMicOn ? TRUE : FALSE);
  371. }
  372. if (!(TF_LBI_STATUS_HIDDEN &
  373. _this->_pMicrophoneItem->GetStatusInternal()))
  374. {
  375. if (GetBalloonStatus() && dwMicOn)
  376. {
  377. _this->AddItemBalloon();
  378. if (_this->_pBalloonItem)
  379. {
  380. _this->SetBalloonText(CRStr(IDS_MIC_ON));
  381. }
  382. }
  383. else
  384. {
  385. _this->RemoveItemBalloon();
  386. }
  387. }
  388. }
  389. else if (IsEqualGUID(rguid, GUID_COMPARTMENT_SHARED_BLN_TEXT))
  390. {
  391. if (_this->_pBalloonItem &&
  392. !(TF_LBI_STATUS_HIDDEN & _this->_pBalloonItem->GetStatusInternal()))
  393. {
  394. DWORD dw;
  395. if (SUCCEEDED(GetGlobalCompartmentDWORD(rguid, &dw)))
  396. {
  397. ATOM hAtom = (WORD)dw;
  398. WCHAR szAtom[MAX_PATH] = {0};
  399. GlobalGetAtomNameW(hAtom, szAtom, ARRAYSIZE(szAtom));
  400. _this->SetBalloonText(szAtom);
  401. }
  402. }
  403. }
  404. return S_OK;
  405. }
  406. //
  407. // Toggle the Microphone Button
  408. //
  409. void CUnCicAppLangBarAddIn::ToggleMicrophoneBtn( BOOL fOn)
  410. {
  411. _pMicrophoneItem->SetOrClearStatus(TF_LBI_STATUS_BTN_TOGGLED, fOn);
  412. if (_pMicrophoneItem->GetSink())
  413. _pMicrophoneItem->GetSink()->OnUpdate(TF_LBI_STATUS);
  414. }
  415. //
  416. // Show the Balloon Text for non-cicero Aware Application.
  417. //
  418. void CUnCicAppLangBarAddIn::SetBalloonText(WCHAR *pwszText )
  419. {
  420. if (_pBalloonItem && pwszText)
  421. {
  422. _pBalloonItem->Set(TF_LB_BALLOON_RECO, pwszText);
  423. if (_pBalloonItem->GetSink())
  424. {
  425. _pBalloonItem->GetSink()->OnUpdate(TF_LBI_BALLOON);
  426. }
  427. }
  428. }
  429. //
  430. // Add/Remove ballon item
  431. //
  432. void CUnCicAppLangBarAddIn::AddItemBalloon()
  433. {
  434. if (!_pBalloonItem)
  435. {
  436. _pBalloonItem = new CLBarItemBalloon();
  437. }
  438. if (_plbim && _pBalloonItem)
  439. {
  440. _plbim->AddItem(_pBalloonItem);
  441. }
  442. }
  443. void CUnCicAppLangBarAddIn::RemoveItemBalloon()
  444. {
  445. if (_plbim && _pBalloonItem)
  446. _plbim->RemoveItem(_pBalloonItem);
  447. }
  448. //
  449. // global functions
  450. //
  451. BOOL GetBalloonStatus()
  452. {
  453. DWORD dw;
  454. GetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_UI_STATUS, &dw);
  455. return (dw & TF_DISABLE_BALLOON) ? FALSE : TRUE;
  456. }
  457. void SetBalloonStatus(BOOL fShow, BOOL fForce = FALSE)
  458. {
  459. if (!fForce && fShow == GetBalloonStatus())
  460. return;
  461. DWORD dw;
  462. GetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_UI_STATUS, &dw);
  463. dw &= ~TF_DISABLE_BALLOON;
  464. dw |= fShow ? 0: TF_DISABLE_BALLOON;
  465. SetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_UI_STATUS, dw);
  466. }