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.

2352 lines
63 KiB

  1. //
  2. // nui.cpp
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "nuihkl.h"
  7. #include "xstring.h"
  8. #include "tim.h"
  9. #include "dim.h"
  10. #include "immxutil.h"
  11. #include "internat.h"
  12. #include "ctffunc.h"
  13. #include "imemenu.h"
  14. #include "ic.h"
  15. #include "imelist.h"
  16. #include "computil.h"
  17. #include "funcprv.h"
  18. #include "nuictrl.h"
  19. #include "profiles.h"
  20. #include "lbmenu.h"
  21. #include "slbarid.h"
  22. #include "cresstr.h"
  23. #include "fnrecon.h"
  24. DBG_ID_INSTANCE(CLBarItemWin32IME);
  25. DBG_ID_INSTANCE(CLBarItemReconv);
  26. DBG_ID_INSTANCE(CLBarItemDeviceType);
  27. extern "C" DWORD WINAPI TF_CheckThreadInputIdle(DWORD dwThreadId, DWORD dwTimeOut);
  28. #define LBBASE_NUM_CONNECTIONPTS 1
  29. //////////////////////////////////////////////////////////////////////////////
  30. //
  31. // utility functions
  32. //
  33. //////////////////////////////////////////////////////////////////////////////
  34. #ifndef WM_IME_SYSTEM
  35. #define WM_IME_SYSTEM 0x287
  36. #endif
  37. // wParam for WM_IME_SYSTEM
  38. #define TFS_DESTROYWINDOW 0x0001
  39. #define TFS_IME31COMPATIBLE 0x0002
  40. #define TFS_SETOPENSTATUS 0x0003
  41. #define TFS_SETACTIVECONTEXT 0x0004
  42. #define TFS_CHANGE_SHOWSTAT 0x0005
  43. #define TFS_WINDOWPOS 0x0006
  44. #define TFS_SENDIMEMSG 0x0007
  45. #define TFS_SENDIMEMSGEX 0x0008
  46. #define TFS_SETCANDIDATEPOS 0x0009
  47. #define TFS_SETCOMPOSITIONFONT 0x000A
  48. #define TFS_SETCOMPOSITIONWINDOW 0x000B
  49. #define TFS_CHECKENABLE 0x000C
  50. #define TFS_CONFIGUREIME 0x000D
  51. #define TFS_CONTROLIMEMSG 0x000E
  52. #define TFS_SETOPENCLOSE 0x000F
  53. #define TFS_ISACTIVATED 0x0010
  54. #define TFS_UNLOADTHREADLAYOUT 0x0011
  55. #define TFS_LCHGREQUEST 0x0012
  56. #define TFS_SETSOFTKBDONOFF 0x0013
  57. #define TFS_GETCONVERSIONMODE 0x0014
  58. #define TFS_IMEHELP 0x0015 // ;Internal
  59. //+---------------------------------------------------------------------------
  60. //
  61. // GetIMEShowStatus
  62. //
  63. //----------------------------------------------------------------------------
  64. static char szInputMethod[]="control panel\\input method" ;
  65. static TCHAR szInputMethodNT[] = TEXT("Control Panel\\Input Method");
  66. static char szValueName[]="show status";
  67. BOOL GetIMEShowStatus()
  68. {
  69. char szValueText[16];
  70. ULONG cb;
  71. HKEY hkey;
  72. BOOL fReturn = IsOnNT() ? TRUE : FALSE;
  73. if(RegOpenKey(HKEY_CURRENT_USER, IsOnNT() ? szInputMethodNT : szInputMethod,&hkey) == ERROR_SUCCESS)
  74. {
  75. cb = sizeof(szValueText);
  76. if(RegQueryValueEx(hkey, szValueName, NULL, NULL, (BYTE *)szValueText, &cb) != ERROR_SUCCESS)
  77. {
  78. szValueText[0] = '\0';
  79. }
  80. RegCloseKey(hkey);
  81. if(lstrcmp(szValueText, IsOnNT() ? "0" : "1") == 0)
  82. fReturn = !fReturn;
  83. }
  84. return fReturn;
  85. }
  86. //+---------------------------------------------------------------------------
  87. //
  88. // SetIMEShowStatus
  89. //
  90. //----------------------------------------------------------------------------
  91. BOOL SetIMEShowStatus(HWND hwnd, BOOL fShow)
  92. {
  93. char szValueText[16];
  94. ULONG cb;
  95. HKEY hkey;
  96. szValueText[0] = fShow ? '1' : '0';
  97. szValueText[1] = 0;
  98. if(RegOpenKey(HKEY_CURRENT_USER,szInputMethod,&hkey)==ERROR_SUCCESS)
  99. {
  100. cb = lstrlen(szValueText)+1;
  101. if(RegSetValueEx(hkey, szValueName, 0L, REG_SZ, (BYTE *)szValueText, cb) == ERROR_SUCCESS)
  102. {
  103. if (IsOnNT())
  104. {
  105. hwnd = ImmGetDefaultIMEWnd(hwnd);
  106. if (IsWindow(hwnd))
  107. goto SendShowMsg;
  108. }
  109. else
  110. {
  111. SendShowMsg:
  112. SendMessage(hwnd, WM_IME_SYSTEM, TFS_CHANGE_SHOWSTAT, (LPARAM)(DWORD)fShow);
  113. }
  114. }
  115. RegCloseKey(hkey);
  116. return TRUE;
  117. }
  118. return FALSE;
  119. }
  120. //+---------------------------------------------------------------------------
  121. //
  122. // CallIMEHelp
  123. //
  124. //----------------------------------------------------------------------------
  125. BOOL CallIMEHelp(HWND hwnd, BOOL fCallWinHelp)
  126. {
  127. if(hwnd)
  128. {
  129. return (BOOL)SendMessage(hwnd, WM_IME_SYSTEM, TFS_IMEHELP,
  130. (LPARAM)fCallWinHelp);
  131. }
  132. return FALSE;
  133. }
  134. //+---------------------------------------------------------------------------
  135. //
  136. // CallConfigureIME
  137. //
  138. //----------------------------------------------------------------------------
  139. void CallConfigureIME(HWND hwnd, HKL dwhkl)
  140. {
  141. if (IsWindow(hwnd))
  142. {
  143. hwnd = ImmGetDefaultIMEWnd(hwnd);
  144. if(IsWindow(hwnd))
  145. {
  146. SendMessage(hwnd, WM_IME_SYSTEM, TFS_CONFIGUREIME, (LPARAM)dwhkl);
  147. }
  148. }
  149. }
  150. //---------------------------------------------------------------------------
  151. //
  152. // GetFontSig()
  153. //
  154. //---------------------------------------------------------------------------
  155. BOOL GetFontSig(HWND hwnd, HKL hKL)
  156. {
  157. LOCALESIGNATURE ls;
  158. BOOL bFontSig = 0;
  159. //
  160. // 4th param is TCHAR count but we call GetLocaleInfoA()
  161. // ~
  162. // so we pass "sizeof(LOCALESIGNATURE) / sizeof(char)".
  163. //
  164. if( GetLocaleInfoA( (DWORD)(LOWORD(hKL)),
  165. LOCALE_FONTSIGNATURE,
  166. (LPSTR)&ls,
  167. sizeof(LOCALESIGNATURE) / sizeof(char)))
  168. {
  169. CHARSETINFO cs;
  170. HDC hdc = GetDC(hwnd);
  171. TranslateCharsetInfo((LPDWORD)UIntToPtr(GetTextCharsetInfo(hdc,NULL,0)),
  172. &cs, TCI_SRCCHARSET);
  173. DWORD fsShell = cs.fs.fsCsb[0];
  174. ReleaseDC(hwnd, hdc);
  175. if (fsShell & ls.lsCsbSupported[0])
  176. bFontSig = 1;
  177. }
  178. return bFontSig;
  179. }
  180. //+---------------------------------------------------------------------------
  181. //
  182. // CanActivateKeyboardLayout
  183. //
  184. //----------------------------------------------------------------------------
  185. BOOL CanActivateKeyboardLayout(HKL hkl)
  186. {
  187. if (!IsIMEHKL(hkl))
  188. return TRUE;
  189. //
  190. // ActivateKeyboardLayout() does not call ImeSelct() if default ime window
  191. // is destroyed.
  192. //
  193. HWND hDefImeWnd = ImmGetDefaultIMEWnd(NULL);
  194. if (!hDefImeWnd)
  195. return FALSE;
  196. if (!IsWindow(hDefImeWnd))
  197. return FALSE;
  198. return TRUE;
  199. }
  200. //+---------------------------------------------------------------------------
  201. //
  202. // PostInputLangRequest
  203. //
  204. //----------------------------------------------------------------------------
  205. void PostInputLangRequest(SYSTHREAD *psfn, HKL hkl, BOOL fUsePost)
  206. {
  207. if (!psfn->hklBeingActivated)
  208. {
  209. if (hkl == GetKeyboardLayout(0))
  210. return;
  211. }
  212. else if (psfn->hklBeingActivated == hkl)
  213. {
  214. return;
  215. }
  216. psfn->hklBeingActivated = hkl;
  217. //
  218. // Issue:
  219. //
  220. // we want to call ActivateKeybaordLayout() at the beginning of Thread
  221. // start. But is it safe to call it? There is no window created so
  222. // PostMessage() can not be used.
  223. //
  224. // We need to take care of rejecting WM_INPUTLANGAGEREQUEST.
  225. //
  226. if (!fUsePost)
  227. {
  228. //
  229. // make sure we already updated the current assmelby lang id.
  230. // If not, we will call ActivateAssembly() in ShellHook again
  231. // and may cause recursion call of ActivateAssembly().
  232. //
  233. Assert((LOWORD(hkl) == GetCurrentAssemblyLangId(psfn)));
  234. if (g_dwAppCompatibility & CIC_COMPAT_DELAYFIRSTACTIVATEKBDLAYOUT)
  235. {
  236. static s_fFirstPostInput = FALSE;
  237. if (!s_fFirstPostInput)
  238. {
  239. s_fFirstPostInput = TRUE;
  240. goto TryPostMessage;
  241. }
  242. }
  243. //
  244. // #613953
  245. //
  246. // ActivateKeyboardLayout() does SendMessage() to the focus window.
  247. // If the focus window is in another thread, we like to check
  248. // the thread is not busy.
  249. //
  250. HWND hwndFocus = GetFocus();
  251. DWORD dwFocusThread = 0;
  252. if (hwndFocus)
  253. dwFocusThread = GetWindowThreadProcessId(hwndFocus, NULL);
  254. if (dwFocusThread && (dwFocusThread != GetCurrentThreadId()))
  255. {
  256. if (TF_CheckThreadInputIdle(dwFocusThread, 0x100))
  257. {
  258. Assert(0);
  259. goto TryPostMessage;
  260. }
  261. }
  262. if (CanActivateKeyboardLayout(hkl))
  263. {
  264. if (!ActivateKeyboardLayout(hkl, 0))
  265. {
  266. psfn->hklDelayActive = hkl;
  267. }
  268. }
  269. else
  270. {
  271. //
  272. // There is no workaround here. The keyboard layout will be
  273. // restored correctly when this thread gets a visible window back.
  274. //
  275. Assert(0);
  276. }
  277. }
  278. else
  279. {
  280. TryPostMessage:
  281. HWND hwndForLang = GetFocus();
  282. if (hwndForLang != NULL)
  283. {
  284. BOOL bFontSig = GetFontSig(hwndForLang, hkl);
  285. PostMessage(hwndForLang,
  286. WM_INPUTLANGCHANGEREQUEST,
  287. (WPARAM)bFontSig,
  288. (LPARAM)hkl);
  289. }
  290. else
  291. {
  292. psfn->hklDelayActive = hkl;
  293. }
  294. }
  295. }
  296. //+---------------------------------------------------------------------------
  297. //
  298. // GetIconIndexFromhKL
  299. //
  300. //----------------------------------------------------------------------------
  301. ULONG GetIconIndexFromhKL(HKL hKL)
  302. {
  303. MLNGINFO mlInfo;
  304. BOOL bFound;
  305. int nCnt = TF_MlngInfoCount();
  306. int i;
  307. bFound = FALSE;
  308. for (i = 0; i < nCnt; i++)
  309. {
  310. if (!GetMlngInfo(i, &mlInfo))
  311. continue;
  312. if (mlInfo.hKL == hKL)
  313. {
  314. bFound = TRUE;
  315. break;
  316. }
  317. }
  318. if (!bFound)
  319. {
  320. if (!GetMlngInfo(0, &mlInfo))
  321. return -1;
  322. }
  323. return mlInfo.GetIconIndex();
  324. }
  325. //+---------------------------------------------------------------------------
  326. //
  327. // GetIconIndex
  328. //
  329. //----------------------------------------------------------------------------
  330. ULONG GetIconIndex(LANGID langid, ASSEMBLYITEM *pItem)
  331. {
  332. ULONG uIconIndex = -1;
  333. if ((pItem->uIconIndex != -1) || pItem->fInitIconIndex)
  334. return pItem->uIconIndex;
  335. if (!IsEqualGUID(pItem->clsid, GUID_NULL))
  336. {
  337. int cx, cy;
  338. ULONG uFileIconIndex;
  339. WCHAR szFileName[MAX_PATH];
  340. InatGetIconSize(&cx, &cy);
  341. //
  342. // Get Icon filename from registry.
  343. //
  344. // At first, we try the given langid's icon.
  345. // Then we try just primary language.
  346. // At last we try 0xffff complete neutral language.
  347. //
  348. TryAgain:
  349. if (SUCCEEDED(GetProfileIconInfo(pItem->clsid,
  350. langid,
  351. pItem->guidProfile,
  352. szFileName, ARRAYSIZE(szFileName),
  353. &uFileIconIndex)))
  354. {
  355. HICON hIcon = GetIconFromFile(cx, cy, szFileName, uFileIconIndex);
  356. if (hIcon)
  357. {
  358. uIconIndex = InatAddIcon(hIcon);
  359. DestroyIcon(hIcon);
  360. }
  361. }
  362. else if (langid != 0xffff)
  363. {
  364. if (langid & 0xfc00)
  365. {
  366. langid = PRIMARYLANGID(langid);
  367. }
  368. else
  369. {
  370. langid = 0xffff;
  371. }
  372. goto TryAgain;
  373. }
  374. }
  375. else
  376. {
  377. uIconIndex = GetIconIndexFromhKL(pItem->hkl);
  378. }
  379. pItem->fInitIconIndex = TRUE;
  380. pItem->uIconIndex = uIconIndex;
  381. return uIconIndex;
  382. }
  383. //+---------------------------------------------------------------------------
  384. //
  385. // FlushIconIndex
  386. //
  387. //----------------------------------------------------------------------------
  388. void FlushIconIndex(SYSTHREAD *psfn)
  389. {
  390. int i,j;
  391. CAssemblyList *pAsmList;
  392. int nAsmCnt;
  393. //
  394. // reset icon of Language Button
  395. //
  396. if (psfn->plbim && psfn->plbim->_GetLBarItemCtrl())
  397. psfn->plbim->_GetLBarItemCtrl()->OnSysColorChanged();
  398. //
  399. // clear icon list cache.
  400. //
  401. pAsmList = psfn->pAsmList;
  402. if (!pAsmList)
  403. return;
  404. nAsmCnt = pAsmList->Count();
  405. if (!nAsmCnt)
  406. return;
  407. for (i = 0; i < nAsmCnt; i++)
  408. {
  409. CAssembly *pAsm = pAsmList->GetAssembly(i);
  410. int nItemCnt = pAsm->Count();
  411. for (j = 0; j < nItemCnt; j++)
  412. {
  413. ASSEMBLYITEM *pItem;
  414. pItem= pAsm->GetItem(j);
  415. pItem->fInitIconIndex = FALSE;
  416. pItem->uIconIndex = (ULONG)(-1);
  417. }
  418. }
  419. //
  420. // check icon list
  421. // And clean up all icon list if there is the impage icon list.
  422. //
  423. if (InatGetImageCount())
  424. {
  425. ClearMlngIconIndex();
  426. InatRemoveAll();
  427. }
  428. }
  429. //////////////////////////////////////////////////////////////////////////////
  430. //
  431. // CLBarItemWin32IME
  432. //
  433. //////////////////////////////////////////////////////////////////////////////
  434. //+---------------------------------------------------------------------------
  435. //
  436. // ctor
  437. //
  438. //----------------------------------------------------------------------------
  439. static const TCHAR c_szNuiWin32IMEWndClass[] = "NuiWin32IMEDummyWndClass";
  440. CLBarItemWin32IME::CLBarItemWin32IME()
  441. {
  442. Dbg_MemSetThisNameID(TEXT("CLBarItemWin32IME"));
  443. InitNuiInfo(CLSID_SYSTEMLANGBARITEM_KEYBOARD,
  444. GUID_LBI_WIN32IME,
  445. TF_LBI_STYLE_BTN_BUTTON |
  446. TF_LBI_STYLE_HIDDENSTATUSCONTROL |
  447. TF_LBI_STYLE_SHOWNINTRAY |
  448. TF_LBI_STYLE_SHOWNINTRAYONLY,
  449. WIN32IME_ORDER,
  450. CRStr(IDS_NUI_IME_TEXT));
  451. WNDCLASSEX wc;
  452. memset(&wc, 0, sizeof(wc));
  453. wc.cbSize = sizeof(wc);
  454. wc.style = CS_HREDRAW | CS_VREDRAW ;
  455. wc.hInstance = g_hInst;
  456. wc.lpfnWndProc = _WndProc;
  457. wc.lpszClassName = c_szNuiWin32IMEWndClass;
  458. RegisterClassEx(&wc);
  459. UpdateIMEIcon();
  460. SetText(CRStr(IDS_NUI_IME_TEXT));
  461. SetToolTip(CRStr(IDS_NUI_IME_TOOLTIP));
  462. }
  463. //+---------------------------------------------------------------------------
  464. //
  465. // _WndProc
  466. //
  467. //----------------------------------------------------------------------------
  468. LRESULT CALLBACK CLBarItemWin32IME::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  469. {
  470. switch (uMsg)
  471. {
  472. case WM_CREATE:
  473. SetThis(hWnd, lParam);
  474. break;
  475. default:
  476. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  477. }
  478. return 0;
  479. }
  480. //+---------------------------------------------------------------------------
  481. //
  482. // OnLButtonUp
  483. //
  484. //----------------------------------------------------------------------------
  485. HRESULT CLBarItemWin32IME::OnLButtonUp(const POINT pt, const RECT *prcArea)
  486. {
  487. HWND hWnd;
  488. hWnd = CreateMyWnd();
  489. ShowIMELeftMenu(hWnd, pt.x, pt.y);
  490. DestroyWindow(hWnd);
  491. return S_OK;
  492. }
  493. //+---------------------------------------------------------------------------
  494. //
  495. // OnRButtonUp
  496. //
  497. //----------------------------------------------------------------------------
  498. HRESULT CLBarItemWin32IME::OnRButtonUp(const POINT pt, const RECT *prcArea)
  499. {
  500. HWND hWnd;
  501. hWnd = CreateMyWnd();
  502. ShowIMERightMenu(hWnd, pt.x, pt.y);
  503. DestroyWindow(hWnd);
  504. return S_OK;
  505. }
  506. //+---------------------------------------------------------------------------
  507. //
  508. // ShowIMELeftMenu
  509. //
  510. //----------------------------------------------------------------------------
  511. void CLBarItemWin32IME::ShowIMELeftMenu(HWND hWnd, LONG xPos, LONG yPos)
  512. {
  513. HKL hKL;
  514. HMENU hMenu;
  515. HIMC hIMC;
  516. HWND hFocusWnd;
  517. int cmd;
  518. int nIds;
  519. int nIdsSoftKbd;
  520. DWORD fdwConversion;
  521. DWORD fdwSentence;
  522. BOOL fShow;
  523. CWin32ImeMenu *pWin32Menu = NULL;
  524. hKL = GetKeyboardLayout(0);
  525. hMenu = CreatePopupMenu();
  526. if (!hMenu)
  527. return;
  528. hFocusWnd = GetFocus();
  529. hIMC = ImmGetContext(hFocusWnd);
  530. if (IsOn98orNT5())
  531. {
  532. if ((pWin32Menu = new CWin32ImeMenu) == NULL)
  533. goto Exit;
  534. pWin32Menu->GetIMEMenu(hFocusWnd, hIMC, FALSE);
  535. pWin32Menu->BuildIMEMenu(hMenu, FALSE);
  536. }
  537. else
  538. {
  539. nIds = 0;
  540. // If Korean TFE, don't show OPEN/CLOSE menu
  541. if (((DWORD)(UINT_PTR)hKL & 0xF000FFFF) != 0xE0000412)
  542. {
  543. BOOL bOpen = ImmGetOpenStatus(hIMC);
  544. nIds= (bOpen ? IDS_IMECLOSE : IDS_IMEOPEN);
  545. InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION,
  546. IDM_IME_OPENCLOSE, CRStr(nIds));
  547. }
  548. // open or close the soft keyboard
  549. nIdsSoftKbd = 0;
  550. if (ImmGetProperty(hKL, IGP_CONVERSION) & IME_CMODE_SOFTKBD)
  551. {
  552. ImmGetConversionStatus(hIMC, &fdwConversion, &fdwSentence);
  553. nIdsSoftKbd = ((fdwConversion & IME_CMODE_SOFTKBD)?
  554. IDS_SOFTKBDOFF:IDS_SOFTKBDON);
  555. InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION,
  556. IDM_IME_SOFTKBDONOFF, (LPCSTR)CRStr(nIdsSoftKbd));
  557. }
  558. if (nIds || nIdsSoftKbd)
  559. {
  560. InsertMenu(hMenu, (UINT)-1, MF_SEPARATOR, 0, 0);
  561. }
  562. InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION,
  563. IDM_IME_SHOWSTATUS, (LPCSTR)CRStr(IDS_IMESHOWSTATUS));
  564. if((fShow = GetIMEShowStatus()) == TRUE)
  565. CheckMenuItem(hMenu, IDM_IME_SHOWSTATUS, MF_CHECKED);
  566. }
  567. cmd = TrackPopupMenuEx(hMenu,
  568. TPM_VERTICAL | TPM_BOTTOMALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
  569. xPos, yPos, hWnd, NULL);
  570. switch (cmd)
  571. {
  572. case IDM_IME_OPENCLOSE:
  573. if (hIMC)
  574. ImmSetOpenStatus(hIMC, (nIds == IDS_IMEOPEN));
  575. break;
  576. case IDM_IME_SOFTKBDONOFF:
  577. ImmGetConversionStatus(hIMC, &fdwConversion, &fdwSentence);
  578. if (nIdsSoftKbd == IDS_SOFTKBDOFF)
  579. fdwConversion &= ~IME_CMODE_SOFTKBD;
  580. else
  581. fdwConversion |= IME_CMODE_SOFTKBD;
  582. ImmSetConversionStatus(hIMC, fdwConversion, fdwSentence);
  583. break;
  584. case IDM_IME_SHOWSTATUS:
  585. SetIMEShowStatus(GetFocus(), !fShow);
  586. break;
  587. default:
  588. if (IsOn98orNT5() &&
  589. pWin32Menu &&
  590. (cmd >= IDM_CUSTOM_MENU_START))
  591. {
  592. UINT uID = pWin32Menu->GetIMEMenuItemID(cmd);
  593. DWORD dwData = pWin32Menu->GetIMEMenuItemData(uID);
  594. ImmNotifyIME(hIMC, NI_IMEMENUSELECTED, uID, dwData);
  595. }
  596. break;
  597. }
  598. Exit:
  599. DestroyMenu(hMenu);
  600. ImmReleaseContext(hFocusWnd, hIMC);
  601. if (pWin32Menu)
  602. delete pWin32Menu;
  603. }
  604. //+---------------------------------------------------------------------------
  605. //
  606. // ShowIMERightMenu
  607. //
  608. //----------------------------------------------------------------------------
  609. void CLBarItemWin32IME::ShowIMERightMenu(HWND hWnd, LONG xPos, LONG yPos)
  610. {
  611. HMENU hMenu;
  612. int cmd;
  613. HKL hKL;
  614. HIMC hIMC;
  615. HWND hFocusWnd;
  616. CWin32ImeMenu *pWin32Menu = NULL;
  617. hFocusWnd = GetFocus();
  618. if (!(hIMC = ImmGetContext(hFocusWnd)))
  619. return;
  620. hMenu = CreatePopupMenu();
  621. if (hMenu == 0)
  622. goto ExitNoMenu;
  623. if (IsOn98orNT5())
  624. {
  625. if ((pWin32Menu = new CWin32ImeMenu) == NULL)
  626. goto Exit;
  627. pWin32Menu->GetIMEMenu(hFocusWnd, hIMC, TRUE);
  628. pWin32Menu->BuildIMEMenu(hMenu, TRUE);
  629. }
  630. else
  631. {
  632. InsertMenu(hMenu, (UINT)-1, MF_STRING | MF_BYPOSITION,
  633. IDM_RMENU_PROPERTIES, (LPCSTR)CRStr(IDS_CONFIGUREIME));
  634. }
  635. cmd = TrackPopupMenuEx(hMenu,
  636. TPM_VERTICAL | TPM_BOTTOMALIGN | TPM_RETURNCMD,
  637. xPos, yPos, hWnd, NULL);
  638. if (cmd && (cmd != -1))
  639. {
  640. switch (cmd)
  641. {
  642. case IDM_RMENU_PROPERTIES:
  643. hKL = GetKeyboardLayout(0);
  644. if ((HIWORD(hKL) & 0xF000) == 0xE000)
  645. CallConfigureIME(hFocusWnd, hKL);
  646. break;
  647. case IDM_RMENU_IMEHELP:
  648. CallIMEHelp(hFocusWnd, TRUE);
  649. break;
  650. default:
  651. if (IsOn98orNT5() &&
  652. pWin32Menu &&
  653. (cmd >= IDM_CUSTOM_MENU_START))
  654. {
  655. UINT uID = pWin32Menu->GetIMEMenuItemID(cmd);
  656. DWORD dwData = pWin32Menu->GetIMEMenuItemData(uID);
  657. ImmNotifyIME(hIMC, NI_IMEMENUSELECTED, uID, dwData);
  658. }
  659. break;
  660. }
  661. }
  662. Exit:
  663. DestroyMenu(hMenu);
  664. ExitNoMenu:
  665. ImmReleaseContext(hFocusWnd, hIMC);
  666. if (pWin32Menu)
  667. delete pWin32Menu;
  668. }
  669. //+---------------------------------------------------------------------------
  670. //
  671. // UpdateIMEIcon
  672. //
  673. //----------------------------------------------------------------------------
  674. void CLBarItemWin32IME::UpdateIMEIcon()
  675. {
  676. HWND hWnd;
  677. HIMC hIMC;
  678. DWORD fdwConversion;
  679. DWORD fdwSentence;
  680. BOOL bOpen;
  681. HKL hKL = GetKeyboardLayout(0);
  682. if (!IsPureIMEHKL(hKL))
  683. {
  684. _nIconId = 0;
  685. goto Exit;
  686. }
  687. hWnd = GetFocus();
  688. hIMC = ImmGetContext(hWnd);
  689. bOpen = ImmGetOpenStatus(hIMC);
  690. ImmGetConversionStatus(hIMC, &fdwConversion, &fdwSentence);
  691. if (((DWORD)(UINT_PTR)hKL & 0xF000FFFFL) == 0xE0000412L)
  692. {
  693. if (!hIMC)
  694. _nIconId = ID_ICON_IMEDISAB;
  695. else if (!bOpen)
  696. _nIconId = ID_ICON_IMEE_H;
  697. else
  698. {
  699. _nIconId = (fdwConversion & IME_CMODE_NATIVE) ?
  700. ID_ICON_IMEH_H : ID_ICON_IMEE_H;
  701. if (fdwConversion & IME_CMODE_FULLSHAPE)
  702. _nIconId++;
  703. }
  704. }
  705. else
  706. {
  707. if (!hIMC)
  708. _nIconId = ID_ICON_IMEDISAB;
  709. else
  710. _nIconId = bOpen ? ID_ICON_IMEOPEN : ID_ICON_IMECLOSE;
  711. }
  712. ImmReleaseContext(hWnd, hIMC);
  713. Exit:
  714. SetStatusInternal(_nIconId ? 0 : TF_LBI_STATUS_HIDDEN | TF_LBI_STATUS_DISABLED);
  715. if (_plbiSink)
  716. _plbiSink->OnUpdate(TF_LBI_ICON | TF_LBI_STATUS);
  717. }
  718. //+---------------------------------------------------------------------------
  719. //
  720. // GetIcon
  721. //
  722. //----------------------------------------------------------------------------
  723. STDAPI CLBarItemWin32IME::GetIcon(HICON *phIcon)
  724. {
  725. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(_nIconId));
  726. return S_OK;
  727. }
  728. //////////////////////////////////////////////////////////////////////////////
  729. //
  730. // CAsyncReconvQueueItem
  731. //
  732. //////////////////////////////////////////////////////////////////////////////
  733. class CAsyncReconvQueueItem : public CAsyncQueueItem
  734. {
  735. public:
  736. CAsyncReconvQueueItem() {}
  737. HRESULT DoDispatch(CInputContext *pic);
  738. };
  739. HRESULT CAsyncReconvQueueItem::DoDispatch(CInputContext *pic)
  740. {
  741. CThreadInputMgr *ptim;
  742. ITfRange *pRangeSel = NULL;
  743. ITfRange *pRangeReconv = NULL;
  744. ITfFunctionProvider *psysFuncPrv = NULL;
  745. ITfFnReconversion *psysReconv = NULL;
  746. HRESULT hr;
  747. GETSELECTIONQUEUEITEM qItemGS;
  748. BOOL fConvertable;
  749. CStructArray<GENERICSINK> *prgSinks;
  750. int i;
  751. if ((ptim = CThreadInputMgr::_GetThis()) == NULL)
  752. return E_FAIL;
  753. //
  754. // AIMM12 hack!
  755. //
  756. // If the target IC is aimm12, we mak a notifycation to AIMM
  757. //
  758. prgSinks = pic->_GetStartReconversionNotifySinks();
  759. for (i = 0; i < prgSinks->Count(); i++)
  760. ((ITfStartReconversionNotifySink *)prgSinks->GetPtr(i)->pSink)->StartReconversion();
  761. hr = S_OK;
  762. qItemGS.ppRange = &pRangeSel;
  763. if (pic->_DoPseudoSyncEditSession(TF_ES_READ, PSEUDO_ESCB_GETSELECTION, &qItemGS, &hr) != S_OK || hr != S_OK)
  764. {
  765. Assert(0);
  766. goto Exit;
  767. }
  768. psysFuncPrv = ptim->GetSystemFunctionProvider();
  769. if (!psysFuncPrv)
  770. goto Exit;
  771. if (FAILED(psysFuncPrv->GetFunction(GUID_NULL, IID_ITfFnReconversion,
  772. (IUnknown **)&psysReconv)))
  773. goto Exit;
  774. if (psysReconv->QueryRange(pRangeSel, &pRangeReconv, &fConvertable) != S_OK)
  775. goto Exit;
  776. if (fConvertable)
  777. psysReconv->Reconvert(pRangeReconv);
  778. SafeRelease(pRangeReconv);
  779. Exit:
  780. for (i = 0; i < prgSinks->Count(); i++)
  781. ((ITfStartReconversionNotifySink *)prgSinks->GetPtr(i)->pSink)->EndReconversion();
  782. SafeRelease(pRangeSel);
  783. SafeRelease(psysFuncPrv);
  784. SafeRelease(psysReconv);
  785. return S_OK;
  786. }
  787. //+---------------------------------------------------------------------------
  788. //
  789. // AsyncReconversion
  790. //
  791. //----------------------------------------------------------------------------
  792. HRESULT AsyncReconversion()
  793. {
  794. CThreadInputMgr *ptim;
  795. CDocumentInputManager *pdim;
  796. CInputContext *pic;
  797. CAsyncReconvQueueItem *paReconv;
  798. HRESULT hr = E_FAIL;
  799. TF_STATUS dcs;
  800. if ((ptim = CThreadInputMgr::_GetThis()) == NULL)
  801. goto Exit;
  802. if ((pdim = ptim->_GetFocusDocInputMgr()) == NULL)
  803. goto Exit;
  804. if (!(pic = pdim->_GetTopIC()))
  805. goto Exit;
  806. if (SUCCEEDED(pic->GetStatus(&dcs)))
  807. {
  808. //
  809. // Korean AIMM1.2 don't support the corrention button.
  810. //
  811. if ((dcs.dwStaticFlags & TF_SS_TRANSITORY) &&
  812. (PRIMARYLANGID(GetCurrentAssemblyLangId(GetSYSTHREAD()))) == LANG_KOREAN)
  813. {
  814. goto Exit;
  815. }
  816. }
  817. paReconv = new CAsyncReconvQueueItem();
  818. if (!paReconv)
  819. goto Exit;
  820. hr = S_OK;
  821. if ((pic->_QueueItem(paReconv->GetItem(), FALSE, &hr) != S_OK) || FAILED(hr))
  822. {
  823. Assert(0);
  824. }
  825. paReconv->_Release();
  826. Exit:
  827. return hr;
  828. }
  829. //////////////////////////////////////////////////////////////////////////////
  830. //
  831. // CLBarItemReconv
  832. //
  833. //////////////////////////////////////////////////////////////////////////////
  834. //+---------------------------------------------------------------------------
  835. //
  836. // ctor
  837. //
  838. //----------------------------------------------------------------------------
  839. CLBarItemReconv::CLBarItemReconv(SYSTHREAD *psfn) : CSysThreadRef(psfn)
  840. {
  841. Dbg_MemSetThisNameID(TEXT("CLBarItemReconv"));
  842. InitNuiInfo(CLSID_SYSTEMLANGBARITEM,
  843. GUID_LBI_RECONV,
  844. TF_LBI_STYLE_BTN_BUTTON | TF_LBI_STYLE_HIDDENBYDEFAULT,
  845. 0,
  846. CRStr(IDS_NUI_CORRECTION_TEXT));
  847. SetText(CRStr(IDS_NUI_CORRECTION_TEXT));
  848. SetToolTip(CRStr(IDS_NUI_CORRECTION_TOOLTIP));
  849. _fAddedBefore = FALSE;
  850. }
  851. //+---------------------------------------------------------------------------
  852. //
  853. // GetIcon
  854. //
  855. //----------------------------------------------------------------------------
  856. STDAPI CLBarItemReconv::GetIcon(HICON *phIcon)
  857. {
  858. *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_RECONVERSION));
  859. return S_OK;
  860. }
  861. //+---------------------------------------------------------------------------
  862. //
  863. // LButtonUpHandler
  864. //
  865. //----------------------------------------------------------------------------
  866. HRESULT CLBarItemReconv::OnLButtonUp(const POINT pt, const RECT *prcArea)
  867. {
  868. return AsyncReconversion();
  869. }
  870. //+---------------------------------------------------------------------------
  871. //
  872. // ShowOrHide
  873. //
  874. //----------------------------------------------------------------------------
  875. void CLBarItemReconv::ShowOrHide(BOOL fNotify)
  876. {
  877. CThreadInputMgr *ptim = _psfn->ptim;
  878. CDocumentInputManager *pdim;
  879. CInputContext *pic;
  880. BOOL bShow = FALSE;
  881. DWORD dwOldStatus = _dwStatus;
  882. //
  883. // If the real IME is running, we don't show the correction button.
  884. //
  885. if (!IsPureIMEHKL(GetKeyboardLayout(0)))
  886. {
  887. //
  888. // If there is no focus dim, we don't show the correction button.
  889. //
  890. if (ptim && (pdim = ptim->_GetFocusDocInputMgr()))
  891. {
  892. pic = pdim->_GetIC(0);
  893. if (pic)
  894. {
  895. LANGID langid = GetCurrentAssemblyLangId(_psfn);
  896. TF_STATUS dcs;
  897. CAssemblyList *pAsmList;
  898. CAssembly *pAsm;
  899. BOOL fTransitory = FALSE;
  900. BOOL fIsTipActive = FALSE;
  901. if (pAsmList = EnsureAssemblyList(_psfn))
  902. {
  903. if (pAsm = pAsmList->FindAssemblyByLangId(langid))
  904. {
  905. int i;
  906. for (i = 0; i < pAsm->Count(); i++)
  907. {
  908. ASSEMBLYITEM *pItem = pAsm->GetItem(i);
  909. if (!pItem)
  910. continue;
  911. if (!pItem->fEnabled)
  912. continue;
  913. if (!pItem->fActive)
  914. continue;
  915. if (!IsEqualGUID(pItem->clsid, GUID_NULL))
  916. {
  917. fIsTipActive = TRUE;
  918. break;
  919. }
  920. }
  921. }
  922. }
  923. //
  924. // if there is no Tip, we won't show correction button.
  925. //
  926. if (!fIsTipActive)
  927. goto Exit;
  928. if (SUCCEEDED(pic->GetStatus(&dcs)))
  929. {
  930. //
  931. // Don't show the corrention button on AIMM1.2 non EA.
  932. // And Korean AIMM1.2 also don't show the corrention button.
  933. //
  934. if (dcs.dwStaticFlags & TF_SS_TRANSITORY)
  935. fTransitory = TRUE;
  936. }
  937. if (!fTransitory || (IsFELangId(langid) && langid != 0x0412))
  938. {
  939. bShow = TRUE;
  940. SetOrClearStatus(TF_LBI_STATUS_DISABLED, FALSE);
  941. }
  942. }
  943. else
  944. {
  945. //
  946. // if it is shown, we don't remove it. Just disable it.
  947. //
  948. if (!(_dwStatus & TF_LBI_STATUS_HIDDEN))
  949. {
  950. bShow = TRUE;
  951. SetOrClearStatus(TF_LBI_STATUS_DISABLED, TRUE);
  952. }
  953. }
  954. }
  955. }
  956. Exit:
  957. if (bShow)
  958. {
  959. if (_fAddedBefore)
  960. {
  961. SetOrClearStatus(TF_LBI_STATUS_DISABLED, FALSE);
  962. if (fNotify && (dwOldStatus != _dwStatus) && _plbiSink)
  963. _plbiSink->OnUpdate(TF_LBI_STATUS);
  964. }
  965. else
  966. {
  967. _psfn->plbim->AddItem(this);
  968. SetOrClearStatus(TF_LBI_STATUS_HIDDEN, FALSE);
  969. if (fNotify && (dwOldStatus != _dwStatus) && _plbiSink)
  970. _plbiSink->OnUpdate(TF_LBI_STATUS);
  971. _fAddedBefore = TRUE;
  972. }
  973. }
  974. else
  975. {
  976. if (_fAddedBefore)
  977. {
  978. SetOrClearStatus(TF_LBI_STATUS_DISABLED, TRUE);
  979. if (fNotify && (dwOldStatus != _dwStatus) && _plbiSink)
  980. _plbiSink->OnUpdate(TF_LBI_STATUS);
  981. }
  982. else
  983. {
  984. SetOrClearStatus(TF_LBI_STATUS_HIDDEN, TRUE);
  985. if (fNotify && (dwOldStatus != _dwStatus) && _plbiSink)
  986. _plbiSink->OnUpdate(TF_LBI_STATUS);
  987. _psfn->plbim->RemoveItem(*this->GetGuidItem());
  988. }
  989. }
  990. }
  991. //////////////////////////////////////////////////////////////////////////////
  992. //
  993. // CLBarItemSystemButtonBase
  994. //
  995. //////////////////////////////////////////////////////////////////////////////
  996. //+---------------------------------------------------------------------------
  997. //
  998. // IUnknown
  999. //
  1000. //----------------------------------------------------------------------------
  1001. STDAPI CLBarItemSystemButtonBase::QueryInterface(REFIID riid, void **ppvObj)
  1002. {
  1003. *ppvObj = NULL;
  1004. if (IsEqualIID(riid, IID_IUnknown) ||
  1005. IsEqualIID(riid, IID_ITfLangBarItem))
  1006. {
  1007. *ppvObj = SAFECAST(this, ITfLangBarItem *);
  1008. }
  1009. else if (IsEqualIID(riid, IID_ITfLangBarItemButton))
  1010. {
  1011. *ppvObj = SAFECAST(this, ITfLangBarItemButton *);
  1012. }
  1013. else if (IsEqualIID(riid, IID_ITfSource))
  1014. {
  1015. *ppvObj = SAFECAST(this, ITfSource *);
  1016. }
  1017. else if (IsEqualIID(riid, IID_ITfSystemLangBarItem))
  1018. {
  1019. *ppvObj = SAFECAST(this, ITfSystemLangBarItem *);
  1020. }
  1021. else if (IsEqualIID(riid, IID_ITfSystemDeviceTypeLangBarItem))
  1022. {
  1023. *ppvObj = SAFECAST(this, ITfSystemDeviceTypeLangBarItem *);
  1024. }
  1025. if (*ppvObj)
  1026. {
  1027. AddRef();
  1028. return S_OK;
  1029. }
  1030. return E_NOINTERFACE;
  1031. }
  1032. STDAPI_(ULONG) CLBarItemSystemButtonBase::AddRef()
  1033. {
  1034. return CLBarItemButtonBase::AddRef();
  1035. }
  1036. STDAPI_(ULONG) CLBarItemSystemButtonBase::Release()
  1037. {
  1038. return CLBarItemButtonBase::Release();
  1039. }
  1040. //+---------------------------------------------------------------------------
  1041. //
  1042. // ctor
  1043. //
  1044. //----------------------------------------------------------------------------
  1045. CLBarItemSystemButtonBase::CLBarItemSystemButtonBase(SYSTHREAD *psfn) : CSysThreadRef(psfn)
  1046. {
  1047. _dwIconMode = 0;
  1048. }
  1049. //----------------------------------------------------------------------------
  1050. //
  1051. // dtor
  1052. //
  1053. //----------------------------------------------------------------------------
  1054. CLBarItemSystemButtonBase::~CLBarItemSystemButtonBase()
  1055. {
  1056. if (_pMenuMap)
  1057. delete _pMenuMap;
  1058. }
  1059. //+---------------------------------------------------------------------------
  1060. //
  1061. // AdviseSink
  1062. //
  1063. //----------------------------------------------------------------------------
  1064. STDAPI CLBarItemSystemButtonBase::AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie)
  1065. {
  1066. HRESULT hr = CLBarItemButtonBase::AdviseSink(riid, punk, pdwCookie);
  1067. if (hr == S_OK)
  1068. return hr;
  1069. const IID *rgiid = &IID_ITfSystemLangBarItemSink;
  1070. hr = GenericAdviseSink(riid, punk, &rgiid, &_rgEventSinks, 1, pdwCookie);
  1071. if (hr != S_OK)
  1072. return hr;
  1073. // adjust the cookie so we don't overlap with idle detector sinks
  1074. *pdwCookie = GenericChainToCookie(*pdwCookie, LBBASE_NUM_CONNECTIONPTS);
  1075. return hr;
  1076. }
  1077. //+---------------------------------------------------------------------------
  1078. //
  1079. // UnadviseSink
  1080. //
  1081. //----------------------------------------------------------------------------
  1082. STDAPI CLBarItemSystemButtonBase::UnadviseSink(DWORD dwCookie)
  1083. {
  1084. HRESULT hr = CLBarItemButtonBase::UnadviseSink(dwCookie);
  1085. if (hr == S_OK)
  1086. return hr;
  1087. dwCookie = GenericUnchainToCookie(dwCookie, LBBASE_NUM_CONNECTIONPTS);
  1088. return GenericUnadviseSink(&_rgEventSinks, 1, dwCookie);
  1089. }
  1090. //+---------------------------------------------------------------------------
  1091. //
  1092. // GetInfo
  1093. //
  1094. //----------------------------------------------------------------------------
  1095. STDAPI CLBarItemSystemButtonBase::GetInfo(TF_LANGBARITEMINFO *pInfo)
  1096. {
  1097. return CLBarItemButtonBase::GetInfo(pInfo);
  1098. }
  1099. //+---------------------------------------------------------------------------
  1100. //
  1101. // Show
  1102. //
  1103. //----------------------------------------------------------------------------
  1104. STDAPI CLBarItemSystemButtonBase::Show(BOOL fShow)
  1105. {
  1106. return CLBarItemButtonBase::Show(fShow);
  1107. }
  1108. //----------------------------------------------------------------------------
  1109. //
  1110. // SetIcon
  1111. //
  1112. //----------------------------------------------------------------------------
  1113. STDAPI CLBarItemSystemButtonBase::SetIcon(HICON hIcon)
  1114. {
  1115. CLBarItemButtonBase::SetIcon(hIcon);
  1116. return S_OK;
  1117. }
  1118. //----------------------------------------------------------------------------
  1119. //
  1120. // SetTooltipString
  1121. //
  1122. //----------------------------------------------------------------------------
  1123. STDAPI CLBarItemSystemButtonBase::SetTooltipString(WCHAR *pchToolTip, ULONG cch)
  1124. {
  1125. SetToolTip(pchToolTip, cch);
  1126. return S_OK;
  1127. }
  1128. //----------------------------------------------------------------------------
  1129. //
  1130. // SetIconMode()
  1131. //
  1132. //----------------------------------------------------------------------------
  1133. STDAPI CLBarItemSystemButtonBase::SetIconMode(DWORD dwFlags)
  1134. {
  1135. _dwIconMode = dwFlags;
  1136. if (_dwIconMode & TF_DTLBI_USEPROFILEICON)
  1137. SetBrandingIcon(NULL, TRUE);
  1138. else
  1139. SetDefaultIcon(TRUE);
  1140. return S_OK;
  1141. }
  1142. //----------------------------------------------------------------------------
  1143. //
  1144. // GetIconMode()
  1145. //
  1146. //----------------------------------------------------------------------------
  1147. STDAPI CLBarItemSystemButtonBase::GetIconMode(DWORD *pdwFlags)
  1148. {
  1149. if (!pdwFlags)
  1150. return E_INVALIDARG;
  1151. *pdwFlags = _dwIconMode;
  1152. return S_OK;
  1153. }
  1154. //+---------------------------------------------------------------------------
  1155. //
  1156. // _InsertCustomMenus
  1157. //
  1158. //----------------------------------------------------------------------------
  1159. BOOL CLBarItemSystemButtonBase::_InsertCustomMenus(ITfMenu *pMenu, UINT *pnTipCurMenuID)
  1160. {
  1161. int nCntEventSink;
  1162. int i;
  1163. BOOL bRet = FALSE;
  1164. //
  1165. // Insert Custom item to menu
  1166. //
  1167. ClearMenuMap();
  1168. nCntEventSink = _rgEventSinks.Count();
  1169. for (i = 0; i < nCntEventSink; i++)
  1170. {
  1171. CCicLibMenu *pMenuTmp;
  1172. GENERICSINK *pSink;
  1173. ITfSystemLangBarItemSink *plbSink;
  1174. if (i >= IDM_CUSTOM_MENU_START - IDM_ASM_MENU_START)
  1175. {
  1176. Assert(0);
  1177. break;
  1178. }
  1179. if (!_pMenuMap)
  1180. _pMenuMap = new CStructArray<TIPMENUITEMMAP>;
  1181. if (!_pMenuMap)
  1182. {
  1183. Assert(0);
  1184. goto Exit;
  1185. }
  1186. pMenuTmp = new CCicLibMenu;
  1187. if (!pMenuTmp)
  1188. {
  1189. goto Exit;
  1190. }
  1191. pSink = _rgEventSinks.GetPtr(i);
  1192. if (SUCCEEDED(pSink->pSink->QueryInterface(
  1193. IID_ITfSystemLangBarItemSink,
  1194. (void **)&plbSink)))
  1195. {
  1196. if (SUCCEEDED(plbSink->InitMenu(pMenuTmp)))
  1197. {
  1198. if (*pnTipCurMenuID > IDM_CUSTOM_MENU_START)
  1199. LangBarInsertSeparator(pMenu);
  1200. *pnTipCurMenuID = _MergeMenu(pMenu,
  1201. pMenuTmp,
  1202. plbSink,
  1203. _pMenuMap,
  1204. *pnTipCurMenuID);
  1205. }
  1206. plbSink->Release();
  1207. }
  1208. else
  1209. {
  1210. Assert(0);
  1211. }
  1212. pMenuTmp->Release();
  1213. }
  1214. bRet = TRUE;
  1215. Exit:
  1216. return bRet;
  1217. }
  1218. //+---------------------------------------------------------------------------
  1219. //
  1220. // _MergeMenu
  1221. //
  1222. //----------------------------------------------------------------------------
  1223. #define MIIM_ALL ( MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE )
  1224. UINT CLBarItemSystemButtonBase::_MergeMenu(ITfMenu *pMenu,
  1225. CCicLibMenu *pMenuTip,
  1226. ITfSystemLangBarItemSink *plbSink,
  1227. CStructArray<TIPMENUITEMMAP> *pMenuMap,
  1228. UINT &nCurID)
  1229. {
  1230. int i;
  1231. int nMenuCnt = pMenuTip->GetItemCount();
  1232. HRESULT hr;
  1233. if (nMenuCnt <= 0)
  1234. return nCurID;
  1235. for (i = 0; i < nMenuCnt; i++)
  1236. {
  1237. CCicLibMenuItem *pItem = pMenuTip->GetItem(i);
  1238. if (!pItem)
  1239. continue;
  1240. TIPMENUITEMMAP *ptmm;
  1241. ptmm = pMenuMap->Append(1);
  1242. if (!ptmm)
  1243. continue;
  1244. ptmm->plbSink = plbSink;
  1245. ptmm->nOrgID = pItem->GetId();
  1246. ptmm->nTmpID = nCurID++;
  1247. hr = E_FAIL;
  1248. if (pItem->GetSubMenu())
  1249. {
  1250. ITfMenu *pSubMenu = NULL;
  1251. hr = pMenu->AddMenuItem((UINT)-1,
  1252. pItem->GetFlags(),
  1253. pItem->GetBitmap(),
  1254. pItem->GetBitmapMask(),
  1255. pItem->GetText(),
  1256. wcslen(pItem->GetText()),
  1257. &pSubMenu);
  1258. if (SUCCEEDED(hr))
  1259. {
  1260. _MergeMenu(pSubMenu,
  1261. pItem->GetSubMenu(),
  1262. plbSink,
  1263. pMenuMap,
  1264. nCurID);
  1265. pSubMenu->Release();
  1266. }
  1267. }
  1268. else
  1269. {
  1270. hr = pMenu->AddMenuItem(ptmm->nTmpID,
  1271. pItem->GetFlags(),
  1272. pItem->GetBitmap(),
  1273. pItem->GetBitmapMask(),
  1274. pItem->GetText(),
  1275. wcslen(pItem->GetText()),
  1276. NULL);
  1277. }
  1278. if (SUCCEEDED(hr))
  1279. pItem->ClearBitmaps();
  1280. }
  1281. return nCurID;
  1282. }
  1283. //////////////////////////////////////////////////////////////////////////////
  1284. //
  1285. // CLBarItemDeviceType
  1286. //
  1287. //////////////////////////////////////////////////////////////////////////////
  1288. //+---------------------------------------------------------------------------
  1289. //
  1290. // ctor
  1291. //
  1292. //----------------------------------------------------------------------------
  1293. CLBarItemDeviceType::CLBarItemDeviceType(SYSTHREAD *psfn, REFGUID rguid) : CLBarItemSystemButtonBase(psfn)
  1294. {
  1295. Dbg_MemSetThisNameID(TEXT("CLBarItemDeviceType"));
  1296. DWORD dwNuiStyle = TF_LBI_STYLE_BTN_MENU |
  1297. TF_LBI_STYLE_HIDDENSTATUSCONTROL;
  1298. _guid = rguid;
  1299. _nType = -1;
  1300. _fHideOrder = FALSE;
  1301. if (IsEqualGUID(_guid, GUID_TFCAT_TIP_KEYBOARD))
  1302. {
  1303. _nType = ID_TYPE_KEYBOARD;
  1304. dwNuiStyle |= TF_LBI_STYLE_SHOWNINTRAY;
  1305. _dwIconMode = TF_DTLBI_USEPROFILEICON;
  1306. }
  1307. else if (IsEqualGUID(_guid, GUID_TFCAT_TIP_HANDWRITING))
  1308. {
  1309. _nType = ID_TYPE_HANDWRITING;
  1310. }
  1311. else if (IsEqualGUID(_guid, GUID_TFCAT_TIP_SPEECH))
  1312. {
  1313. _nType = ID_TYPE_SPEECH;
  1314. }
  1315. if (_nType != -1)
  1316. {
  1317. InitNuiInfo(CLSID_SYSTEMLANGBARITEM,
  1318. rguid,
  1319. dwNuiStyle,
  1320. 0,
  1321. CRStr(IDS_NUI_DEVICE_NAME_START + _nType));
  1322. }
  1323. else
  1324. {
  1325. BSTR bstr = NULL;
  1326. MyGetGUIDDescription(rguid, &bstr);
  1327. InitNuiInfo(CLSID_SYSTEMLANGBARITEM,
  1328. rguid,
  1329. dwNuiStyle,
  1330. 0,
  1331. bstr ? bstr : L"");
  1332. if (bstr)
  1333. SysFreeString(bstr);
  1334. }
  1335. _pif = NULL;
  1336. }
  1337. //----------------------------------------------------------------------------
  1338. //
  1339. // dtor
  1340. //
  1341. //----------------------------------------------------------------------------
  1342. CLBarItemDeviceType::~CLBarItemDeviceType()
  1343. {
  1344. if (_pif)
  1345. delete _pif;
  1346. if (_pces)
  1347. {
  1348. _pces->_Unadvise();
  1349. _pces->Release();
  1350. }
  1351. }
  1352. //+---------------------------------------------------------------------------
  1353. //
  1354. // Init
  1355. //
  1356. //----------------------------------------------------------------------------
  1357. static const TCHAR c_szNuiDeviceTypeWndClass[] = "NuiDeviceTypeDummyWndClass";
  1358. void CLBarItemDeviceType::Init()
  1359. {
  1360. if (_nType != -1)
  1361. {
  1362. SetText(CRStr(IDS_NUI_DEVICE_NAME_START + _nType));
  1363. SetToolTip(CRStr(IDS_NUI_DEVICE_TIP_START + _nType));
  1364. }
  1365. else
  1366. {
  1367. SetText(_lbiInfo.szDescription);
  1368. SetToolTip(_lbiInfo.szDescription);
  1369. }
  1370. ShowOrHide(FALSE);
  1371. }
  1372. //+---------------------------------------------------------------------------
  1373. //
  1374. // Uninit
  1375. //
  1376. //----------------------------------------------------------------------------
  1377. void CLBarItemDeviceType::Uninit()
  1378. {
  1379. if (_pces)
  1380. {
  1381. _pces->_Unadvise();
  1382. SafeReleaseClear(_pces);
  1383. }
  1384. }
  1385. //+---------------------------------------------------------------------------
  1386. //
  1387. // InitTipArray
  1388. //
  1389. //----------------------------------------------------------------------------
  1390. void CLBarItemDeviceType::InitTipArray(BOOL fInitIconIndex)
  1391. {
  1392. CAssembly *pAsm;
  1393. int i;
  1394. int nCnt;
  1395. LANGID langid = 0;
  1396. _rgGuidatomHkl.Clear();
  1397. pAsm = GetCurrentAssembly();
  1398. if (!pAsm)
  1399. goto Exit;
  1400. if (_psfn->plbim && _psfn->plbim->_GetLBarItemCtrl())
  1401. langid = GetCurrentAssemblyLangId(_psfn);
  1402. nCnt = pAsm->Count();
  1403. if (_psfn->ptim && _psfn->ptim->_GetFocusDocInputMgr())
  1404. pAsm->RebuildSubstitutedHKLList();
  1405. else
  1406. pAsm->ClearSubstitutedHKLList();
  1407. for (i = 0; i < nCnt; i++)
  1408. {
  1409. ASSEMBLYITEM *pItem = pAsm->GetItem(i);
  1410. if (!pItem->fEnabled)
  1411. continue;
  1412. if (IsEqualGUID(pItem->catid, _guid))
  1413. {
  1414. GUIDATOMHKL gahkl;
  1415. BOOL fInsert = FALSE;
  1416. if (!IsEqualGUID(pItem->clsid, GUID_NULL))
  1417. {
  1418. if (_psfn->ptim && _psfn->ptim->_GetFocusDocInputMgr())
  1419. {
  1420. TfGuidAtom guidatom;
  1421. MyRegisterGUID(pItem->clsid, &guidatom);
  1422. gahkl.guidatom = guidatom;
  1423. gahkl.hkl = pItem->hkl;
  1424. gahkl.pItem = pItem;
  1425. fInsert = TRUE;
  1426. }
  1427. }
  1428. else
  1429. {
  1430. Assert(pItem->hkl);
  1431. BOOL bSkip = FALSE;
  1432. if (pAsm->IsSubstitutedHKL(pItem->hkl) ||
  1433. ((!_psfn->ptim || !_psfn->ptim->_GetFocusDocInputMgr()) &&
  1434. CAssemblyList::IsFEDummyKL(pItem->hkl)))
  1435. {
  1436. bSkip = TRUE;
  1437. }
  1438. if (!bSkip)
  1439. {
  1440. gahkl.guidatom = TF_INVALID_GUIDATOM;
  1441. gahkl.hkl = pItem->hkl;
  1442. gahkl.pItem = pItem;
  1443. fInsert = TRUE;
  1444. }
  1445. }
  1446. if (fInsert)
  1447. {
  1448. GUIDATOMHKL *pgahkl;
  1449. int nCurId;
  1450. int nMaxId = _rgGuidatomHkl.Count();
  1451. for (nCurId = 0; nCurId < nMaxId; nCurId++)
  1452. {
  1453. GUIDATOMHKL *pgahklCur;
  1454. int nCmp;
  1455. pgahklCur = _rgGuidatomHkl.GetPtr(nCurId);
  1456. if (!pgahklCur)
  1457. continue;
  1458. nCmp = CompareGUIDs(pgahklCur->pItem->clsid,
  1459. gahkl.pItem->clsid);
  1460. if (nCmp > 0)
  1461. break;
  1462. if (nCmp < 0)
  1463. continue;
  1464. if (CompareGUIDs(pgahklCur->pItem->guidProfile,
  1465. gahkl.pItem->guidProfile) > 0)
  1466. break;
  1467. }
  1468. if (_rgGuidatomHkl.Insert(nCurId, 1) &&
  1469. (pgahkl = _rgGuidatomHkl.GetPtr(nCurId)))
  1470. {
  1471. gahkl.uIconIndex = fInitIconIndex ? GetIconIndex(langid, pItem) : (ULONG)-1;
  1472. *pgahkl = gahkl;
  1473. }
  1474. }
  1475. }
  1476. }
  1477. Exit:
  1478. return;
  1479. }
  1480. //+---------------------------------------------------------------------------
  1481. //
  1482. // ShowOrHide
  1483. //
  1484. //----------------------------------------------------------------------------
  1485. void CLBarItemDeviceType::ShowOrHide(BOOL fNotify)
  1486. {
  1487. BOOL bShow = TRUE;
  1488. int nCnt;
  1489. //
  1490. // if _fHideOrder is TRUE, someone asked not to show this category icon.
  1491. // we do nothing.
  1492. //
  1493. if (_fHideOrder)
  1494. {
  1495. Assert(_dwStatus & TF_LBI_STATUS_HIDDEN);
  1496. return;
  1497. }
  1498. InitTipArray(FALSE);
  1499. nCnt = _rgGuidatomHkl.Count();
  1500. if (_nType != ID_TYPE_KEYBOARD)
  1501. {
  1502. CAssembly *pAsm = GetCurrentAssembly();
  1503. if (pAsm && pAsm->IsFEIMEActive())
  1504. {
  1505. ShowInternal(FALSE, fNotify);
  1506. return;
  1507. }
  1508. }
  1509. if (!nCnt)
  1510. {
  1511. bShow = FALSE;
  1512. }
  1513. else if (nCnt == 1)
  1514. {
  1515. if (_nType == ID_TYPE_KEYBOARD)
  1516. {
  1517. GUIDATOMHKL *pgahkl;
  1518. pgahkl = _rgGuidatomHkl.GetPtr(0);
  1519. bShow = pgahkl->guidatom ? TRUE : FALSE;
  1520. }
  1521. else
  1522. {
  1523. bShow = FALSE;
  1524. }
  1525. }
  1526. ShowInternal(bShow, fNotify);
  1527. }
  1528. //+---------------------------------------------------------------------------
  1529. //
  1530. // Show
  1531. //
  1532. //----------------------------------------------------------------------------
  1533. STDAPI CLBarItemDeviceType::Show(BOOL fShow)
  1534. {
  1535. _fHideOrder = fShow ? FALSE : TRUE;
  1536. return CLBarItemSystemButtonBase::Show(fShow);
  1537. }
  1538. //+---------------------------------------------------------------------------
  1539. //
  1540. // InitMenu
  1541. //
  1542. //----------------------------------------------------------------------------
  1543. #if IDM_CUSTOM_MENU_START <= IDM_ASM_MENU_START
  1544. #erroe IDM_CUSTOM_MENU_START is smaller than IDM_ASM_MENU_START
  1545. #endif
  1546. #if IDM_ASM_MENU_START <= IDM_LANG_MENU_START
  1547. #erroe IDM_ASM_MENU_START is smaller than IDM_LANG_MENU_START
  1548. #endif
  1549. STDAPI CLBarItemDeviceType::InitMenu(ITfMenu *pMenu)
  1550. {
  1551. CThreadInputMgr *ptim = NULL;
  1552. CDocumentInputManager *pdim = NULL;
  1553. CInputContext *pic;
  1554. int nCntGuidatomHkl;
  1555. int i;
  1556. CLSID clsid;
  1557. UINT nTipCurMenuID = IDM_CUSTOM_MENU_START;
  1558. LANGID langid = 0;
  1559. BOOL bMenuChecked = FALSE;
  1560. GUIDATOMHKL *pgahkl;
  1561. BOOL fTransitory = FALSE;
  1562. ptim = _psfn->ptim;
  1563. InitTipArray(TRUE);
  1564. nCntGuidatomHkl = _rgGuidatomHkl.Count();
  1565. if (!ptim)
  1566. goto SetHKLMenu;
  1567. if (!(pdim = ptim->_GetFocusDocInputMgr()))
  1568. goto SetHKLMenu;
  1569. pic = pdim->_GetTopIC();
  1570. if (pic)
  1571. {
  1572. TF_STATUS dcs;
  1573. if (SUCCEEDED(pic->GetStatus(&dcs)) &&
  1574. (dcs.dwStaticFlags & TF_SS_TRANSITORY))
  1575. fTransitory = TRUE;
  1576. }
  1577. if (!_InsertCustomMenus(pMenu, &nTipCurMenuID))
  1578. goto Exit;
  1579. //
  1580. // Insert separator.
  1581. //
  1582. if (nCntGuidatomHkl && (nTipCurMenuID > IDM_CUSTOM_MENU_START))
  1583. LangBarInsertSeparator(pMenu);
  1584. if (_psfn->plbim && _psfn->plbim->_GetLBarItemCtrl())
  1585. langid = GetCurrentAssemblyLangId(_psfn);
  1586. //
  1587. // Insert TIPs to menu
  1588. //
  1589. for (i = 0; i < nCntGuidatomHkl; i++)
  1590. {
  1591. BOOL bCheckThis;
  1592. pgahkl = _rgGuidatomHkl.GetPtr(i);
  1593. if (i >= IDM_CUSTOM_MENU_START - IDM_ASM_MENU_START)
  1594. {
  1595. Assert(0);
  1596. break;
  1597. }
  1598. if (!pgahkl->guidatom)
  1599. continue;
  1600. MyGetGUID(pgahkl->guidatom, &clsid);
  1601. if (!CAssemblyList::CheckLangSupport(clsid, langid))
  1602. continue;
  1603. bCheckThis = (pgahkl->pItem->fActive) ? TRUE : FALSE;
  1604. if (fTransitory && pgahkl->pItem->fDisabledOnTransitory)
  1605. LangBarInsertGrayedMenu(pMenu,
  1606. pgahkl->pItem->szProfile,
  1607. TF_InatExtractIcon(pgahkl->uIconIndex));
  1608. else
  1609. LangBarInsertMenu(pMenu,
  1610. IDM_ASM_MENU_START + i,
  1611. pgahkl->pItem->szProfile,
  1612. bCheckThis,
  1613. TF_InatExtractIcon(pgahkl->uIconIndex));
  1614. if (bCheckThis)
  1615. {
  1616. bMenuChecked = TRUE;
  1617. }
  1618. }
  1619. SetHKLMenu:
  1620. //
  1621. // Insert HKLs to menu
  1622. //
  1623. for (i = 0; i < nCntGuidatomHkl; i++)
  1624. {
  1625. BOOL bCheckIt = FALSE;
  1626. pgahkl = _rgGuidatomHkl.GetPtr(i);
  1627. if (i >= IDM_CUSTOM_MENU_START - IDM_ASM_MENU_START)
  1628. {
  1629. Assert(0);
  1630. break;
  1631. }
  1632. if (pgahkl->guidatom)
  1633. continue;
  1634. if (!bMenuChecked && pgahkl->hkl == GetKeyboardLayout(0))
  1635. {
  1636. if (pdim)
  1637. bCheckIt = (pgahkl->pItem->fActive) ? TRUE : FALSE;
  1638. else
  1639. bCheckIt = TRUE;
  1640. }
  1641. LangBarInsertMenu(pMenu,
  1642. IDM_LANG_MENU_START + i,
  1643. pgahkl->pItem->szProfile,
  1644. bCheckIt,
  1645. IsPureIMEHKL(pgahkl->hkl) ? TF_InatExtractIcon(pgahkl->uIconIndex) : NULL);
  1646. if (bCheckIt)
  1647. {
  1648. bMenuChecked = TRUE;
  1649. }
  1650. }
  1651. //
  1652. // If the lbiCtrl is hidden (there is only one language available) and
  1653. // the floating toolbar is minimized, the keyboard langbar item
  1654. // has a "Show Langbar" menu item.
  1655. //
  1656. if ((_nType == ID_TYPE_KEYBOARD) && _psfn->plbim)
  1657. {
  1658. CLBarItemCtrl *plbiCtrl = _psfn->plbim->_GetLBarItemCtrl();
  1659. if (plbiCtrl)
  1660. {
  1661. DWORD dwFlags;
  1662. DWORD dwStatus;
  1663. dwStatus = plbiCtrl->GetStatusInternal();
  1664. if ((dwStatus & TF_LBI_STATUS_HIDDEN) &&
  1665. SUCCEEDED(CLangBarMgr::s_GetShowFloatingStatus(&dwFlags)) &&
  1666. (dwFlags & (TF_SFT_MINIMIZED | TF_SFT_DESKBAND)))
  1667. {
  1668. LangBarInsertSeparator(pMenu);
  1669. LangBarInsertMenu(pMenu,
  1670. IDM_SHOWLANGBAR,
  1671. CRStr(IDS_SHOWLANGBAR));
  1672. }
  1673. }
  1674. }
  1675. Exit:
  1676. return S_OK;
  1677. }
  1678. //+---------------------------------------------------------------------------
  1679. //
  1680. // OnMenuSelect
  1681. //
  1682. //----------------------------------------------------------------------------
  1683. STDAPI CLBarItemDeviceType::OnMenuSelect(UINT uID)
  1684. {
  1685. CThreadInputMgr *ptim;
  1686. int i;
  1687. GUIDATOMHKL *pgahkl;
  1688. ptim = _psfn->ptim;
  1689. if (uID == IDM_SHOWLANGBAR)
  1690. {
  1691. CLangBarMgr::s_ShowFloating(TF_SFT_SHOWNORMAL);
  1692. }
  1693. else if (uID >= IDM_CUSTOM_MENU_START)
  1694. {
  1695. Assert(ptim);
  1696. int nMenuMapoCnt = _pMenuMap->Count();
  1697. for (i = 0; i < nMenuMapoCnt; i++)
  1698. {
  1699. TIPMENUITEMMAP *ptmm;
  1700. ptmm = _pMenuMap->GetPtr(i);
  1701. if (ptmm->nTmpID == (UINT)uID)
  1702. {
  1703. ptmm->plbSink->OnMenuSelect(ptmm->nOrgID);
  1704. break;
  1705. }
  1706. }
  1707. }
  1708. else if (uID >= IDM_ASM_MENU_START)
  1709. {
  1710. Assert(ptim);
  1711. pgahkl = _rgGuidatomHkl.GetPtr(uID - IDM_ASM_MENU_START);
  1712. Assert(pgahkl);
  1713. Assert(pgahkl->guidatom);
  1714. ASSEMBLYITEM *pItem = pgahkl->pItem;
  1715. if (!pgahkl->pItem->fActive)
  1716. {
  1717. LANGID langid = GetCurrentAssemblyLangId(_psfn);
  1718. ActivateAssemblyItem(_psfn,
  1719. langid,
  1720. pItem,
  1721. AAIF_CHANGEDEFAULT);
  1722. CAssemblyList *pAsmList = EnsureAssemblyList(_psfn);
  1723. if (pAsmList)
  1724. {
  1725. CAssembly *pAsm = pAsmList->FindAssemblyByLangId(langid);
  1726. if (pAsm)
  1727. {
  1728. pAsmList->SetDefaultTIPInAssemblyInternal(pAsm,
  1729. pItem,
  1730. TRUE);
  1731. }
  1732. }
  1733. }
  1734. // #ifdef HANDWRITINGAUTOSHOW
  1735. if (_nType == ID_TYPE_HANDWRITING)
  1736. {
  1737. MySetCompartmentDWORD(g_gaSystem,
  1738. ptim,
  1739. GUID_COMPARTMENT_HANDWRITING_OPENCLOSE,
  1740. TRUE);
  1741. }
  1742. // #endif
  1743. }
  1744. else if (uID >= IDM_LANG_MENU_START)
  1745. {
  1746. pgahkl = _rgGuidatomHkl.GetPtr(uID - IDM_LANG_MENU_START);
  1747. Assert(pgahkl);
  1748. Assert(pgahkl->hkl);
  1749. ActivateAssemblyItem(_psfn,
  1750. GetCurrentAssemblyLangId(_psfn),
  1751. pgahkl->pItem,
  1752. AAIF_CHANGEDEFAULT);
  1753. }
  1754. ClearMenuMap();
  1755. return S_OK;
  1756. }
  1757. //----------------------------------------------------------------------------
  1758. //
  1759. // CompEventSinkCallback (static)
  1760. //
  1761. //----------------------------------------------------------------------------
  1762. HRESULT CLBarItemDeviceType::CompEventSinkCallback(void *pv, REFGUID rguid)
  1763. {
  1764. CLBarItemDeviceType *_this = (CLBarItemDeviceType *)pv;
  1765. if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_OPENCLOSE))
  1766. {
  1767. _this->SetSpeechButtonState(_this->_psfn->ptim);
  1768. }
  1769. return S_FALSE;
  1770. }
  1771. //----------------------------------------------------------------------------
  1772. //
  1773. // SetSpeechButtonState
  1774. //
  1775. //----------------------------------------------------------------------------
  1776. HRESULT CLBarItemDeviceType::SetSpeechButtonState(CThreadInputMgr *ptim)
  1777. {
  1778. DWORD dw = 0;
  1779. MyGetCompartmentDWORD(ptim->GetGlobalComp(), GUID_COMPARTMENT_SPEECH_OPENCLOSE, &dw);
  1780. SetOrClearStatus(TF_LBI_STATUS_BTN_TOGGLED, dw);
  1781. if (_plbiSink)
  1782. _plbiSink->OnUpdate(TF_LBI_STATUS);
  1783. return S_OK;
  1784. }
  1785. //----------------------------------------------------------------------------
  1786. //
  1787. // SetIcon
  1788. //
  1789. //----------------------------------------------------------------------------
  1790. STDAPI CLBarItemDeviceType::SetIcon(HICON hIcon)
  1791. {
  1792. CLBarItemButtonBase::SetIcon(hIcon);
  1793. return S_OK;
  1794. }
  1795. //----------------------------------------------------------------------------
  1796. //
  1797. // GetIcon
  1798. //
  1799. //----------------------------------------------------------------------------
  1800. STDAPI CLBarItemDeviceType::GetIcon(HICON *phIcon)
  1801. {
  1802. if (CLBarItemButtonBase::GetIcon())
  1803. {
  1804. return CLBarItemButtonBase::GetIcon(phIcon);
  1805. }
  1806. HICON hIcon = NULL;
  1807. if (_nType != -1)
  1808. {
  1809. hIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_DEVICE_START + _nType));
  1810. }
  1811. else
  1812. {
  1813. int cx, cy;
  1814. InatGetIconSize(&cx, &cy);
  1815. if (!_pif)
  1816. {
  1817. BSTR bstr;
  1818. HRESULT hr;
  1819. ICONFILE *pif;
  1820. pif = new ICONFILE;
  1821. if (!pif)
  1822. goto Exit;
  1823. if (FAILED(hr = MyGetGUIDValue(_guid, c_szIconIndexW, &bstr)))
  1824. {
  1825. delete pif;
  1826. goto Exit;
  1827. }
  1828. pif->uIconIndex = WToNum(bstr);
  1829. SysFreeString(bstr);
  1830. if (FAILED(hr = MyGetGUIDValue(_guid, c_szIconFileW, &bstr)))
  1831. {
  1832. delete pif;
  1833. goto Exit;
  1834. }
  1835. wcsncpy(pif->szFile, bstr, ARRAYSIZE(pif->szFile));
  1836. SysFreeString(bstr);
  1837. _pif = pif;
  1838. }
  1839. hIcon = GetIconFromFile(cx, cy, _pif->szFile, _pif->uIconIndex);
  1840. }
  1841. Exit:
  1842. *phIcon = hIcon;
  1843. return S_OK;
  1844. }
  1845. //----------------------------------------------------------------------------
  1846. //
  1847. // SetTooltipString
  1848. //
  1849. //----------------------------------------------------------------------------
  1850. STDAPI CLBarItemDeviceType::SetTooltipString(WCHAR *pchToolTip, ULONG cch)
  1851. {
  1852. if (!pchToolTip)
  1853. {
  1854. SetToolTip(CRStr(IDS_NUI_DEVICE_TIP_START + _nType));
  1855. }
  1856. else
  1857. SetToolTip(pchToolTip, cch);
  1858. return S_OK;
  1859. }
  1860. //+---------------------------------------------------------------------------
  1861. //
  1862. // UpdateLangIcon
  1863. //
  1864. //----------------------------------------------------------------------------
  1865. void CLBarItemDeviceType::SetBrandingIcon(HKL hKL, BOOL fNotify)
  1866. {
  1867. CThreadInputMgr *ptim;
  1868. HICON hIcon;
  1869. ULONG uIconIndex = -1;
  1870. ASSEMBLYITEM *pItem = NULL;
  1871. CAssembly *pAsm;
  1872. WCHAR szDesc[128];
  1873. if (!hKL)
  1874. hKL = GetKeyboardLayout(0);
  1875. if (!(_dwIconMode & TF_DTLBI_USEPROFILEICON))
  1876. return;
  1877. ptim = CThreadInputMgr::_GetThisFromSYSTHREAD(_psfn);
  1878. pAsm = GetCurrentAssembly(_psfn);
  1879. if (!pAsm)
  1880. return;
  1881. #ifdef USE_ASM_ISFEIMEACTIVE
  1882. BOOL fIsPureIME = FALSE;
  1883. if (_nType == ID_TYPE_KEYBOARD)
  1884. {
  1885. if (ptim && ptim->_GetFocusDocInputMgr())
  1886. {
  1887. fIsPureIME = pAsm->IsFEIMEActive();
  1888. }
  1889. else
  1890. {
  1891. fIsPureIME = IsPureIMEHKL(hKL);
  1892. }
  1893. }
  1894. #endif USE_ASM_ISFEIMEACTIVE
  1895. hIcon = NULL;
  1896. szDesc[0] = L'\0';
  1897. #ifdef USE_ASM_ISFEIMEACTIVE
  1898. if (fIsPureIMEHKL)
  1899. #else
  1900. if (IsPureIMEHKL(hKL))
  1901. #endif USE_ASM_ISFEIMEACTIVE
  1902. {
  1903. pItem = pAsm->FindKeyboardLayoutItem(hKL);
  1904. uIconIndex = GetIconIndexFromhKL(hKL);
  1905. if (uIconIndex != -1)
  1906. hIcon = TF_InatExtractIcon(uIconIndex);
  1907. }
  1908. else if (ptim && ptim->_GetFocusDocInputMgr())
  1909. {
  1910. pItem = pAsm->FindActiveKeyboardItem();
  1911. //
  1912. // if it is Cicero item, we will show the branding Icon.
  1913. //
  1914. if (pItem && !IsEqualGUID(pItem->clsid, GUID_NULL))
  1915. {
  1916. uIconIndex = GetIconIndex(LOWORD(HandleToLong(hKL)), pItem);
  1917. if (uIconIndex != -1)
  1918. hIcon = TF_InatExtractIcon(uIconIndex);
  1919. }
  1920. }
  1921. else
  1922. {
  1923. MLNGINFO mlInfo;
  1924. if (GetMlngInfoByhKL(hKL, &mlInfo) != -1)
  1925. {
  1926. wcsncpy(szDesc, mlInfo.GetDesc(), ARRAYSIZE(szDesc));
  1927. }
  1928. }
  1929. HICON hIconOld = GetIcon();
  1930. SetIcon(hIcon);
  1931. if (hIconOld)
  1932. DestroyIcon(hIconOld);
  1933. if (pItem)
  1934. {
  1935. SetText(pItem->szProfile);
  1936. SetToolTip(pItem->szProfile);
  1937. }
  1938. else if (szDesc[0])
  1939. {
  1940. SetText(szDesc);
  1941. SetToolTip(szDesc);
  1942. }
  1943. else if (_nType != -1)
  1944. {
  1945. SetText(CRStr(IDS_NUI_DEVICE_NAME_START + _nType));
  1946. SetToolTip(CRStr(IDS_NUI_DEVICE_TIP_START + _nType));
  1947. }
  1948. if (fNotify && _plbiSink)
  1949. _plbiSink->OnUpdate(TF_LBI_ICON | TF_LBI_TEXT | TF_LBI_TOOLTIP);
  1950. }
  1951. //+---------------------------------------------------------------------------
  1952. //
  1953. // SetDefaultIcon
  1954. //
  1955. //----------------------------------------------------------------------------
  1956. void CLBarItemDeviceType::SetDefaultIcon(BOOL fNotify)
  1957. {
  1958. HICON hIconOld = GetIcon();
  1959. SetIcon(NULL);
  1960. if (hIconOld)
  1961. DestroyIcon(hIconOld);
  1962. if (_nType != -1)
  1963. {
  1964. SetToolTip(CRStr(IDS_NUI_DEVICE_NAME_START + _nType));
  1965. SetText(_szToolTip);
  1966. }
  1967. if (fNotify && _plbiSink)
  1968. _plbiSink->OnUpdate(TF_LBI_ICON | TF_LBI_TEXT | TF_LBI_TOOLTIP);
  1969. }