// // nui.cpp // #include "private.h" #include "globals.h" #include "nuihkl.h" #include "xstring.h" #include "tim.h" #include "dim.h" #include "immxutil.h" #include "internat.h" #include "ctffunc.h" #include "imemenu.h" #include "ic.h" #include "imelist.h" #include "computil.h" #include "funcprv.h" #include "nuictrl.h" #include "profiles.h" #include "lbmenu.h" #include "slbarid.h" #include "cresstr.h" #include "fnrecon.h" DBG_ID_INSTANCE(CLBarItemWin32IME); DBG_ID_INSTANCE(CLBarItemReconv); DBG_ID_INSTANCE(CLBarItemDeviceType); extern "C" DWORD WINAPI TF_CheckThreadInputIdle(DWORD dwThreadId, DWORD dwTimeOut); #define LBBASE_NUM_CONNECTIONPTS 1 ////////////////////////////////////////////////////////////////////////////// // // utility functions // ////////////////////////////////////////////////////////////////////////////// #ifndef WM_IME_SYSTEM #define WM_IME_SYSTEM 0x287 #endif // wParam for WM_IME_SYSTEM #define TFS_DESTROYWINDOW 0x0001 #define TFS_IME31COMPATIBLE 0x0002 #define TFS_SETOPENSTATUS 0x0003 #define TFS_SETACTIVECONTEXT 0x0004 #define TFS_CHANGE_SHOWSTAT 0x0005 #define TFS_WINDOWPOS 0x0006 #define TFS_SENDIMEMSG 0x0007 #define TFS_SENDIMEMSGEX 0x0008 #define TFS_SETCANDIDATEPOS 0x0009 #define TFS_SETCOMPOSITIONFONT 0x000A #define TFS_SETCOMPOSITIONWINDOW 0x000B #define TFS_CHECKENABLE 0x000C #define TFS_CONFIGUREIME 0x000D #define TFS_CONTROLIMEMSG 0x000E #define TFS_SETOPENCLOSE 0x000F #define TFS_ISACTIVATED 0x0010 #define TFS_UNLOADTHREADLAYOUT 0x0011 #define TFS_LCHGREQUEST 0x0012 #define TFS_SETSOFTKBDONOFF 0x0013 #define TFS_GETCONVERSIONMODE 0x0014 #define TFS_IMEHELP 0x0015 // ;Internal //+--------------------------------------------------------------------------- // // GetIMEShowStatus // //---------------------------------------------------------------------------- static char szInputMethod[]="control panel\\input method" ; static TCHAR szInputMethodNT[] = TEXT("Control Panel\\Input Method"); static char szValueName[]="show status"; BOOL GetIMEShowStatus() { char szValueText[16]; ULONG cb; HKEY hkey; BOOL fReturn = IsOnNT() ? TRUE : FALSE; if(RegOpenKey(HKEY_CURRENT_USER, IsOnNT() ? szInputMethodNT : szInputMethod,&hkey) == ERROR_SUCCESS) { cb = sizeof(szValueText); if(RegQueryValueEx(hkey, szValueName, NULL, NULL, (BYTE *)szValueText, &cb) != ERROR_SUCCESS) { szValueText[0] = '\0'; } RegCloseKey(hkey); if(lstrcmp(szValueText, IsOnNT() ? "0" : "1") == 0) fReturn = !fReturn; } return fReturn; } //+--------------------------------------------------------------------------- // // SetIMEShowStatus // //---------------------------------------------------------------------------- BOOL SetIMEShowStatus(HWND hwnd, BOOL fShow) { char szValueText[16]; ULONG cb; HKEY hkey; szValueText[0] = fShow ? '1' : '0'; szValueText[1] = 0; if(RegOpenKey(HKEY_CURRENT_USER,szInputMethod,&hkey)==ERROR_SUCCESS) { cb = lstrlen(szValueText)+1; if(RegSetValueEx(hkey, szValueName, 0L, REG_SZ, (BYTE *)szValueText, cb) == ERROR_SUCCESS) { if (IsOnNT()) { hwnd = ImmGetDefaultIMEWnd(hwnd); if (IsWindow(hwnd)) goto SendShowMsg; } else { SendShowMsg: SendMessage(hwnd, WM_IME_SYSTEM, TFS_CHANGE_SHOWSTAT, (LPARAM)(DWORD)fShow); } } RegCloseKey(hkey); return TRUE; } return FALSE; } //+--------------------------------------------------------------------------- // // CallIMEHelp // //---------------------------------------------------------------------------- BOOL CallIMEHelp(HWND hwnd, BOOL fCallWinHelp) { if(hwnd) { return (BOOL)SendMessage(hwnd, WM_IME_SYSTEM, TFS_IMEHELP, (LPARAM)fCallWinHelp); } return FALSE; } //+--------------------------------------------------------------------------- // // CallConfigureIME // //---------------------------------------------------------------------------- void CallConfigureIME(HWND hwnd, HKL dwhkl) { if (IsWindow(hwnd)) { hwnd = ImmGetDefaultIMEWnd(hwnd); if(IsWindow(hwnd)) { SendMessage(hwnd, WM_IME_SYSTEM, TFS_CONFIGUREIME, (LPARAM)dwhkl); } } } //--------------------------------------------------------------------------- // // GetFontSig() // //--------------------------------------------------------------------------- BOOL GetFontSig(HWND hwnd, HKL hKL) { LOCALESIGNATURE ls; BOOL bFontSig = 0; // // 4th param is TCHAR count but we call GetLocaleInfoA() // ~ // so we pass "sizeof(LOCALESIGNATURE) / sizeof(char)". // if( GetLocaleInfoA( (DWORD)(LOWORD(hKL)), LOCALE_FONTSIGNATURE, (LPSTR)&ls, sizeof(LOCALESIGNATURE) / sizeof(char))) { CHARSETINFO cs; HDC hdc = GetDC(hwnd); TranslateCharsetInfo((LPDWORD)UIntToPtr(GetTextCharsetInfo(hdc,NULL,0)), &cs, TCI_SRCCHARSET); DWORD fsShell = cs.fs.fsCsb[0]; ReleaseDC(hwnd, hdc); if (fsShell & ls.lsCsbSupported[0]) bFontSig = 1; } return bFontSig; } //+--------------------------------------------------------------------------- // // CanActivateKeyboardLayout // //---------------------------------------------------------------------------- BOOL CanActivateKeyboardLayout(HKL hkl) { if (!IsIMEHKL(hkl)) return TRUE; // // ActivateKeyboardLayout() does not call ImeSelct() if default ime window // is destroyed. // HWND hDefImeWnd = ImmGetDefaultIMEWnd(NULL); if (!hDefImeWnd) return FALSE; if (!IsWindow(hDefImeWnd)) return FALSE; return TRUE; } //+--------------------------------------------------------------------------- // // PostInputLangRequest // //---------------------------------------------------------------------------- void PostInputLangRequest(SYSTHREAD *psfn, HKL hkl, BOOL fUsePost) { if (!psfn->hklBeingActivated) { if (hkl == GetKeyboardLayout(0)) return; } else if (psfn->hklBeingActivated == hkl) { return; } psfn->hklBeingActivated = hkl; // // Issue: // // we want to call ActivateKeybaordLayout() at the beginning of Thread // start. But is it safe to call it? There is no window created so // PostMessage() can not be used. // // We need to take care of rejecting WM_INPUTLANGAGEREQUEST. // if (!fUsePost) { // // make sure we already updated the current assmelby lang id. // If not, we will call ActivateAssembly() in ShellHook again // and may cause recursion call of ActivateAssembly(). // Assert((LOWORD(hkl) == GetCurrentAssemblyLangId(psfn))); if (g_dwAppCompatibility & CIC_COMPAT_DELAYFIRSTACTIVATEKBDLAYOUT) { static s_fFirstPostInput = FALSE; if (!s_fFirstPostInput) { s_fFirstPostInput = TRUE; goto TryPostMessage; } } // // #613953 // // ActivateKeyboardLayout() does SendMessage() to the focus window. // If the focus window is in another thread, we like to check // the thread is not busy. // HWND hwndFocus = GetFocus(); DWORD dwFocusThread = 0; if (hwndFocus) dwFocusThread = GetWindowThreadProcessId(hwndFocus, NULL); if (dwFocusThread && (dwFocusThread != GetCurrentThreadId())) { if (TF_CheckThreadInputIdle(dwFocusThread, 0x100)) { Assert(0); goto TryPostMessage; } } if (CanActivateKeyboardLayout(hkl)) { if (!ActivateKeyboardLayout(hkl, 0)) { psfn->hklDelayActive = hkl; } } else { // // There is no workaround here. The keyboard layout will be // restored correctly when this thread gets a visible window back. // Assert(0); } } else { TryPostMessage: HWND hwndForLang = GetFocus(); if (hwndForLang != NULL) { BOOL bFontSig = GetFontSig(hwndForLang, hkl); PostMessage(hwndForLang, WM_INPUTLANGCHANGEREQUEST, (WPARAM)bFontSig, (LPARAM)hkl); } else { psfn->hklDelayActive = hkl; } } } //+--------------------------------------------------------------------------- // // GetIconIndexFromhKL // //---------------------------------------------------------------------------- ULONG GetIconIndexFromhKL(HKL hKL) { MLNGINFO mlInfo; BOOL bFound; int nCnt = TF_MlngInfoCount(); int i; bFound = FALSE; for (i = 0; i < nCnt; i++) { if (!GetMlngInfo(i, &mlInfo)) continue; if (mlInfo.hKL == hKL) { bFound = TRUE; break; } } if (!bFound) { if (!GetMlngInfo(0, &mlInfo)) return -1; } return mlInfo.GetIconIndex(); } //+--------------------------------------------------------------------------- // // GetIconIndex // //---------------------------------------------------------------------------- ULONG GetIconIndex(LANGID langid, ASSEMBLYITEM *pItem) { ULONG uIconIndex = -1; if ((pItem->uIconIndex != -1) || pItem->fInitIconIndex) return pItem->uIconIndex; if (!IsEqualGUID(pItem->clsid, GUID_NULL)) { int cx, cy; ULONG uFileIconIndex; WCHAR szFileName[MAX_PATH]; InatGetIconSize(&cx, &cy); // // Get Icon filename from registry. // // At first, we try the given langid's icon. // Then we try just primary language. // At last we try 0xffff complete neutral language. // TryAgain: if (SUCCEEDED(GetProfileIconInfo(pItem->clsid, langid, pItem->guidProfile, szFileName, ARRAYSIZE(szFileName), &uFileIconIndex))) { HICON hIcon = GetIconFromFile(cx, cy, szFileName, uFileIconIndex); if (hIcon) { uIconIndex = InatAddIcon(hIcon); DestroyIcon(hIcon); } } else if (langid != 0xffff) { if (langid & 0xfc00) { langid = PRIMARYLANGID(langid); } else { langid = 0xffff; } goto TryAgain; } } else { uIconIndex = GetIconIndexFromhKL(pItem->hkl); } pItem->fInitIconIndex = TRUE; pItem->uIconIndex = uIconIndex; return uIconIndex; } //+--------------------------------------------------------------------------- // // FlushIconIndex // //---------------------------------------------------------------------------- void FlushIconIndex(SYSTHREAD *psfn) { int i,j; CAssemblyList *pAsmList; int nAsmCnt; // // reset icon of Language Button // if (psfn->plbim && psfn->plbim->_GetLBarItemCtrl()) psfn->plbim->_GetLBarItemCtrl()->OnSysColorChanged(); // // clear icon list cache. // pAsmList = psfn->pAsmList; if (!pAsmList) return; nAsmCnt = pAsmList->Count(); if (!nAsmCnt) return; for (i = 0; i < nAsmCnt; i++) { CAssembly *pAsm = pAsmList->GetAssembly(i); int nItemCnt = pAsm->Count(); for (j = 0; j < nItemCnt; j++) { ASSEMBLYITEM *pItem; pItem= pAsm->GetItem(j); pItem->fInitIconIndex = FALSE; pItem->uIconIndex = (ULONG)(-1); } } // // check icon list // And clean up all icon list if there is the impage icon list. // if (InatGetImageCount()) { ClearMlngIconIndex(); InatRemoveAll(); } } ////////////////////////////////////////////////////////////////////////////// // // CLBarItemWin32IME // ////////////////////////////////////////////////////////////////////////////// //+--------------------------------------------------------------------------- // // ctor // //---------------------------------------------------------------------------- static const TCHAR c_szNuiWin32IMEWndClass[] = "NuiWin32IMEDummyWndClass"; CLBarItemWin32IME::CLBarItemWin32IME() { Dbg_MemSetThisNameID(TEXT("CLBarItemWin32IME")); InitNuiInfo(CLSID_SYSTEMLANGBARITEM_KEYBOARD, GUID_LBI_WIN32IME, TF_LBI_STYLE_BTN_BUTTON | TF_LBI_STYLE_HIDDENSTATUSCONTROL | TF_LBI_STYLE_SHOWNINTRAY | TF_LBI_STYLE_SHOWNINTRAYONLY, WIN32IME_ORDER, CRStr(IDS_NUI_IME_TEXT)); WNDCLASSEX wc; memset(&wc, 0, sizeof(wc)); wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW ; wc.hInstance = g_hInst; wc.lpfnWndProc = _WndProc; wc.lpszClassName = c_szNuiWin32IMEWndClass; RegisterClassEx(&wc); UpdateIMEIcon(); SetText(CRStr(IDS_NUI_IME_TEXT)); SetToolTip(CRStr(IDS_NUI_IME_TOOLTIP)); } //+--------------------------------------------------------------------------- // // _WndProc // //---------------------------------------------------------------------------- LRESULT CALLBACK CLBarItemWin32IME::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: SetThis(hWnd, lParam); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } //+--------------------------------------------------------------------------- // // OnLButtonUp // //---------------------------------------------------------------------------- HRESULT CLBarItemWin32IME::OnLButtonUp(const POINT pt, const RECT *prcArea) { HWND hWnd; hWnd = CreateMyWnd(); ShowIMELeftMenu(hWnd, pt.x, pt.y); DestroyWindow(hWnd); return S_OK; } //+--------------------------------------------------------------------------- // // OnRButtonUp // //---------------------------------------------------------------------------- HRESULT CLBarItemWin32IME::OnRButtonUp(const POINT pt, const RECT *prcArea) { HWND hWnd; hWnd = CreateMyWnd(); ShowIMERightMenu(hWnd, pt.x, pt.y); DestroyWindow(hWnd); return S_OK; } //+--------------------------------------------------------------------------- // // ShowIMELeftMenu // //---------------------------------------------------------------------------- void CLBarItemWin32IME::ShowIMELeftMenu(HWND hWnd, LONG xPos, LONG yPos) { HKL hKL; HMENU hMenu; HIMC hIMC; HWND hFocusWnd; int cmd; int nIds; int nIdsSoftKbd; DWORD fdwConversion; DWORD fdwSentence; BOOL fShow; CWin32ImeMenu *pWin32Menu = NULL; hKL = GetKeyboardLayout(0); hMenu = CreatePopupMenu(); if (!hMenu) return; hFocusWnd = GetFocus(); hIMC = ImmGetContext(hFocusWnd); if (IsOn98orNT5()) { if ((pWin32Menu = new CWin32ImeMenu) == NULL) goto Exit; pWin32Menu->GetIMEMenu(hFocusWnd, hIMC, FALSE); pWin32Menu->BuildIMEMenu(hMenu, FALSE); } else { nIds = 0; // If Korean TFE, don't show OPEN/CLOSE menu if (((DWORD)(UINT_PTR)hKL & 0xF000FFFF) != 0xE0000412) { BOOL bOpen = ImmGetOpenStatus(hIMC); nIds= (bOpen ? IDS_IMECLOSE : IDS_IMEOPEN); InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION, IDM_IME_OPENCLOSE, CRStr(nIds)); } // open or close the soft keyboard nIdsSoftKbd = 0; if (ImmGetProperty(hKL, IGP_CONVERSION) & IME_CMODE_SOFTKBD) { ImmGetConversionStatus(hIMC, &fdwConversion, &fdwSentence); nIdsSoftKbd = ((fdwConversion & IME_CMODE_SOFTKBD)? IDS_SOFTKBDOFF:IDS_SOFTKBDON); InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION, IDM_IME_SOFTKBDONOFF, (LPCSTR)CRStr(nIdsSoftKbd)); } if (nIds || nIdsSoftKbd) { InsertMenu(hMenu, (UINT)-1, MF_SEPARATOR, 0, 0); } InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION, IDM_IME_SHOWSTATUS, (LPCSTR)CRStr(IDS_IMESHOWSTATUS)); if((fShow = GetIMEShowStatus()) == TRUE) CheckMenuItem(hMenu, IDM_IME_SHOWSTATUS, MF_CHECKED); } cmd = TrackPopupMenuEx(hMenu, TPM_VERTICAL | TPM_BOTTOMALIGN | TPM_NONOTIFY | TPM_RETURNCMD, xPos, yPos, hWnd, NULL); switch (cmd) { case IDM_IME_OPENCLOSE: if (hIMC) ImmSetOpenStatus(hIMC, (nIds == IDS_IMEOPEN)); break; case IDM_IME_SOFTKBDONOFF: ImmGetConversionStatus(hIMC, &fdwConversion, &fdwSentence); if (nIdsSoftKbd == IDS_SOFTKBDOFF) fdwConversion &= ~IME_CMODE_SOFTKBD; else fdwConversion |= IME_CMODE_SOFTKBD; ImmSetConversionStatus(hIMC, fdwConversion, fdwSentence); break; case IDM_IME_SHOWSTATUS: SetIMEShowStatus(GetFocus(), !fShow); break; default: if (IsOn98orNT5() && pWin32Menu && (cmd >= IDM_CUSTOM_MENU_START)) { UINT uID = pWin32Menu->GetIMEMenuItemID(cmd); DWORD dwData = pWin32Menu->GetIMEMenuItemData(uID); ImmNotifyIME(hIMC, NI_IMEMENUSELECTED, uID, dwData); } break; } Exit: DestroyMenu(hMenu); ImmReleaseContext(hFocusWnd, hIMC); if (pWin32Menu) delete pWin32Menu; } //+--------------------------------------------------------------------------- // // ShowIMERightMenu // //---------------------------------------------------------------------------- void CLBarItemWin32IME::ShowIMERightMenu(HWND hWnd, LONG xPos, LONG yPos) { HMENU hMenu; int cmd; HKL hKL; HIMC hIMC; HWND hFocusWnd; CWin32ImeMenu *pWin32Menu = NULL; hFocusWnd = GetFocus(); if (!(hIMC = ImmGetContext(hFocusWnd))) return; hMenu = CreatePopupMenu(); if (hMenu == 0) goto ExitNoMenu; if (IsOn98orNT5()) { if ((pWin32Menu = new CWin32ImeMenu) == NULL) goto Exit; pWin32Menu->GetIMEMenu(hFocusWnd, hIMC, TRUE); pWin32Menu->BuildIMEMenu(hMenu, TRUE); } else { InsertMenu(hMenu, (UINT)-1, MF_STRING | MF_BYPOSITION, IDM_RMENU_PROPERTIES, (LPCSTR)CRStr(IDS_CONFIGUREIME)); } cmd = TrackPopupMenuEx(hMenu, TPM_VERTICAL | TPM_BOTTOMALIGN | TPM_RETURNCMD, xPos, yPos, hWnd, NULL); if (cmd && (cmd != -1)) { switch (cmd) { case IDM_RMENU_PROPERTIES: hKL = GetKeyboardLayout(0); if ((HIWORD(hKL) & 0xF000) == 0xE000) CallConfigureIME(hFocusWnd, hKL); break; case IDM_RMENU_IMEHELP: CallIMEHelp(hFocusWnd, TRUE); break; default: if (IsOn98orNT5() && pWin32Menu && (cmd >= IDM_CUSTOM_MENU_START)) { UINT uID = pWin32Menu->GetIMEMenuItemID(cmd); DWORD dwData = pWin32Menu->GetIMEMenuItemData(uID); ImmNotifyIME(hIMC, NI_IMEMENUSELECTED, uID, dwData); } break; } } Exit: DestroyMenu(hMenu); ExitNoMenu: ImmReleaseContext(hFocusWnd, hIMC); if (pWin32Menu) delete pWin32Menu; } //+--------------------------------------------------------------------------- // // UpdateIMEIcon // //---------------------------------------------------------------------------- void CLBarItemWin32IME::UpdateIMEIcon() { HWND hWnd; HIMC hIMC; DWORD fdwConversion; DWORD fdwSentence; BOOL bOpen; HKL hKL = GetKeyboardLayout(0); if (!IsPureIMEHKL(hKL)) { _nIconId = 0; goto Exit; } hWnd = GetFocus(); hIMC = ImmGetContext(hWnd); bOpen = ImmGetOpenStatus(hIMC); ImmGetConversionStatus(hIMC, &fdwConversion, &fdwSentence); if (((DWORD)(UINT_PTR)hKL & 0xF000FFFFL) == 0xE0000412L) { if (!hIMC) _nIconId = ID_ICON_IMEDISAB; else if (!bOpen) _nIconId = ID_ICON_IMEE_H; else { _nIconId = (fdwConversion & IME_CMODE_NATIVE) ? ID_ICON_IMEH_H : ID_ICON_IMEE_H; if (fdwConversion & IME_CMODE_FULLSHAPE) _nIconId++; } } else { if (!hIMC) _nIconId = ID_ICON_IMEDISAB; else _nIconId = bOpen ? ID_ICON_IMEOPEN : ID_ICON_IMECLOSE; } ImmReleaseContext(hWnd, hIMC); Exit: SetStatusInternal(_nIconId ? 0 : TF_LBI_STATUS_HIDDEN | TF_LBI_STATUS_DISABLED); if (_plbiSink) _plbiSink->OnUpdate(TF_LBI_ICON | TF_LBI_STATUS); } //+--------------------------------------------------------------------------- // // GetIcon // //---------------------------------------------------------------------------- STDAPI CLBarItemWin32IME::GetIcon(HICON *phIcon) { *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(_nIconId)); return S_OK; } ////////////////////////////////////////////////////////////////////////////// // // CAsyncReconvQueueItem // ////////////////////////////////////////////////////////////////////////////// class CAsyncReconvQueueItem : public CAsyncQueueItem { public: CAsyncReconvQueueItem() {} HRESULT DoDispatch(CInputContext *pic); }; HRESULT CAsyncReconvQueueItem::DoDispatch(CInputContext *pic) { CThreadInputMgr *ptim; ITfRange *pRangeSel = NULL; ITfRange *pRangeReconv = NULL; ITfFunctionProvider *psysFuncPrv = NULL; ITfFnReconversion *psysReconv = NULL; HRESULT hr; GETSELECTIONQUEUEITEM qItemGS; BOOL fConvertable; CStructArray *prgSinks; int i; if ((ptim = CThreadInputMgr::_GetThis()) == NULL) return E_FAIL; // // AIMM12 hack! // // If the target IC is aimm12, we mak a notifycation to AIMM // prgSinks = pic->_GetStartReconversionNotifySinks(); for (i = 0; i < prgSinks->Count(); i++) ((ITfStartReconversionNotifySink *)prgSinks->GetPtr(i)->pSink)->StartReconversion(); hr = S_OK; qItemGS.ppRange = &pRangeSel; if (pic->_DoPseudoSyncEditSession(TF_ES_READ, PSEUDO_ESCB_GETSELECTION, &qItemGS, &hr) != S_OK || hr != S_OK) { Assert(0); goto Exit; } psysFuncPrv = ptim->GetSystemFunctionProvider(); if (!psysFuncPrv) goto Exit; if (FAILED(psysFuncPrv->GetFunction(GUID_NULL, IID_ITfFnReconversion, (IUnknown **)&psysReconv))) goto Exit; if (psysReconv->QueryRange(pRangeSel, &pRangeReconv, &fConvertable) != S_OK) goto Exit; if (fConvertable) psysReconv->Reconvert(pRangeReconv); SafeRelease(pRangeReconv); Exit: for (i = 0; i < prgSinks->Count(); i++) ((ITfStartReconversionNotifySink *)prgSinks->GetPtr(i)->pSink)->EndReconversion(); SafeRelease(pRangeSel); SafeRelease(psysFuncPrv); SafeRelease(psysReconv); return S_OK; } //+--------------------------------------------------------------------------- // // AsyncReconversion // //---------------------------------------------------------------------------- HRESULT AsyncReconversion() { CThreadInputMgr *ptim; CDocumentInputManager *pdim; CInputContext *pic; CAsyncReconvQueueItem *paReconv; HRESULT hr = E_FAIL; TF_STATUS dcs; if ((ptim = CThreadInputMgr::_GetThis()) == NULL) goto Exit; if ((pdim = ptim->_GetFocusDocInputMgr()) == NULL) goto Exit; if (!(pic = pdim->_GetTopIC())) goto Exit; if (SUCCEEDED(pic->GetStatus(&dcs))) { // // Korean AIMM1.2 don't support the corrention button. // if ((dcs.dwStaticFlags & TF_SS_TRANSITORY) && (PRIMARYLANGID(GetCurrentAssemblyLangId(GetSYSTHREAD()))) == LANG_KOREAN) { goto Exit; } } paReconv = new CAsyncReconvQueueItem(); if (!paReconv) goto Exit; hr = S_OK; if ((pic->_QueueItem(paReconv->GetItem(), FALSE, &hr) != S_OK) || FAILED(hr)) { Assert(0); } paReconv->_Release(); Exit: return hr; } ////////////////////////////////////////////////////////////////////////////// // // CLBarItemReconv // ////////////////////////////////////////////////////////////////////////////// //+--------------------------------------------------------------------------- // // ctor // //---------------------------------------------------------------------------- CLBarItemReconv::CLBarItemReconv(SYSTHREAD *psfn) : CSysThreadRef(psfn) { Dbg_MemSetThisNameID(TEXT("CLBarItemReconv")); InitNuiInfo(CLSID_SYSTEMLANGBARITEM, GUID_LBI_RECONV, TF_LBI_STYLE_BTN_BUTTON | TF_LBI_STYLE_HIDDENBYDEFAULT, 0, CRStr(IDS_NUI_CORRECTION_TEXT)); SetText(CRStr(IDS_NUI_CORRECTION_TEXT)); SetToolTip(CRStr(IDS_NUI_CORRECTION_TOOLTIP)); _fAddedBefore = FALSE; } //+--------------------------------------------------------------------------- // // GetIcon // //---------------------------------------------------------------------------- STDAPI CLBarItemReconv::GetIcon(HICON *phIcon) { *phIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_RECONVERSION)); return S_OK; } //+--------------------------------------------------------------------------- // // LButtonUpHandler // //---------------------------------------------------------------------------- HRESULT CLBarItemReconv::OnLButtonUp(const POINT pt, const RECT *prcArea) { return AsyncReconversion(); } //+--------------------------------------------------------------------------- // // ShowOrHide // //---------------------------------------------------------------------------- void CLBarItemReconv::ShowOrHide(BOOL fNotify) { CThreadInputMgr *ptim = _psfn->ptim; CDocumentInputManager *pdim; CInputContext *pic; BOOL bShow = FALSE; DWORD dwOldStatus = _dwStatus; // // If the real IME is running, we don't show the correction button. // if (!IsPureIMEHKL(GetKeyboardLayout(0))) { // // If there is no focus dim, we don't show the correction button. // if (ptim && (pdim = ptim->_GetFocusDocInputMgr())) { pic = pdim->_GetIC(0); if (pic) { LANGID langid = GetCurrentAssemblyLangId(_psfn); TF_STATUS dcs; CAssemblyList *pAsmList; CAssembly *pAsm; BOOL fTransitory = FALSE; BOOL fIsTipActive = FALSE; if (pAsmList = EnsureAssemblyList(_psfn)) { if (pAsm = pAsmList->FindAssemblyByLangId(langid)) { int i; for (i = 0; i < pAsm->Count(); i++) { ASSEMBLYITEM *pItem = pAsm->GetItem(i); if (!pItem) continue; if (!pItem->fEnabled) continue; if (!pItem->fActive) continue; if (!IsEqualGUID(pItem->clsid, GUID_NULL)) { fIsTipActive = TRUE; break; } } } } // // if there is no Tip, we won't show correction button. // if (!fIsTipActive) goto Exit; if (SUCCEEDED(pic->GetStatus(&dcs))) { // // Don't show the corrention button on AIMM1.2 non EA. // And Korean AIMM1.2 also don't show the corrention button. // if (dcs.dwStaticFlags & TF_SS_TRANSITORY) fTransitory = TRUE; } if (!fTransitory || (IsFELangId(langid) && langid != 0x0412)) { bShow = TRUE; SetOrClearStatus(TF_LBI_STATUS_DISABLED, FALSE); } } else { // // if it is shown, we don't remove it. Just disable it. // if (!(_dwStatus & TF_LBI_STATUS_HIDDEN)) { bShow = TRUE; SetOrClearStatus(TF_LBI_STATUS_DISABLED, TRUE); } } } } Exit: if (bShow) { if (_fAddedBefore) { SetOrClearStatus(TF_LBI_STATUS_DISABLED, FALSE); if (fNotify && (dwOldStatus != _dwStatus) && _plbiSink) _plbiSink->OnUpdate(TF_LBI_STATUS); } else { _psfn->plbim->AddItem(this); SetOrClearStatus(TF_LBI_STATUS_HIDDEN, FALSE); if (fNotify && (dwOldStatus != _dwStatus) && _plbiSink) _plbiSink->OnUpdate(TF_LBI_STATUS); _fAddedBefore = TRUE; } } else { if (_fAddedBefore) { SetOrClearStatus(TF_LBI_STATUS_DISABLED, TRUE); if (fNotify && (dwOldStatus != _dwStatus) && _plbiSink) _plbiSink->OnUpdate(TF_LBI_STATUS); } else { SetOrClearStatus(TF_LBI_STATUS_HIDDEN, TRUE); if (fNotify && (dwOldStatus != _dwStatus) && _plbiSink) _plbiSink->OnUpdate(TF_LBI_STATUS); _psfn->plbim->RemoveItem(*this->GetGuidItem()); } } } ////////////////////////////////////////////////////////////////////////////// // // CLBarItemSystemButtonBase // ////////////////////////////////////////////////////////////////////////////// //+--------------------------------------------------------------------------- // // IUnknown // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::QueryInterface(REFIID riid, void **ppvObj) { *ppvObj = NULL; if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfLangBarItem)) { *ppvObj = SAFECAST(this, ITfLangBarItem *); } else if (IsEqualIID(riid, IID_ITfLangBarItemButton)) { *ppvObj = SAFECAST(this, ITfLangBarItemButton *); } else if (IsEqualIID(riid, IID_ITfSource)) { *ppvObj = SAFECAST(this, ITfSource *); } else if (IsEqualIID(riid, IID_ITfSystemLangBarItem)) { *ppvObj = SAFECAST(this, ITfSystemLangBarItem *); } else if (IsEqualIID(riid, IID_ITfSystemDeviceTypeLangBarItem)) { *ppvObj = SAFECAST(this, ITfSystemDeviceTypeLangBarItem *); } if (*ppvObj) { AddRef(); return S_OK; } return E_NOINTERFACE; } STDAPI_(ULONG) CLBarItemSystemButtonBase::AddRef() { return CLBarItemButtonBase::AddRef(); } STDAPI_(ULONG) CLBarItemSystemButtonBase::Release() { return CLBarItemButtonBase::Release(); } //+--------------------------------------------------------------------------- // // ctor // //---------------------------------------------------------------------------- CLBarItemSystemButtonBase::CLBarItemSystemButtonBase(SYSTHREAD *psfn) : CSysThreadRef(psfn) { _dwIconMode = 0; } //---------------------------------------------------------------------------- // // dtor // //---------------------------------------------------------------------------- CLBarItemSystemButtonBase::~CLBarItemSystemButtonBase() { if (_pMenuMap) delete _pMenuMap; } //+--------------------------------------------------------------------------- // // AdviseSink // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie) { HRESULT hr = CLBarItemButtonBase::AdviseSink(riid, punk, pdwCookie); if (hr == S_OK) return hr; const IID *rgiid = &IID_ITfSystemLangBarItemSink; hr = GenericAdviseSink(riid, punk, &rgiid, &_rgEventSinks, 1, pdwCookie); if (hr != S_OK) return hr; // adjust the cookie so we don't overlap with idle detector sinks *pdwCookie = GenericChainToCookie(*pdwCookie, LBBASE_NUM_CONNECTIONPTS); return hr; } //+--------------------------------------------------------------------------- // // UnadviseSink // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::UnadviseSink(DWORD dwCookie) { HRESULT hr = CLBarItemButtonBase::UnadviseSink(dwCookie); if (hr == S_OK) return hr; dwCookie = GenericUnchainToCookie(dwCookie, LBBASE_NUM_CONNECTIONPTS); return GenericUnadviseSink(&_rgEventSinks, 1, dwCookie); } //+--------------------------------------------------------------------------- // // GetInfo // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::GetInfo(TF_LANGBARITEMINFO *pInfo) { return CLBarItemButtonBase::GetInfo(pInfo); } //+--------------------------------------------------------------------------- // // Show // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::Show(BOOL fShow) { return CLBarItemButtonBase::Show(fShow); } //---------------------------------------------------------------------------- // // SetIcon // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::SetIcon(HICON hIcon) { CLBarItemButtonBase::SetIcon(hIcon); return S_OK; } //---------------------------------------------------------------------------- // // SetTooltipString // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::SetTooltipString(WCHAR *pchToolTip, ULONG cch) { SetToolTip(pchToolTip, cch); return S_OK; } //---------------------------------------------------------------------------- // // SetIconMode() // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::SetIconMode(DWORD dwFlags) { _dwIconMode = dwFlags; if (_dwIconMode & TF_DTLBI_USEPROFILEICON) SetBrandingIcon(NULL, TRUE); else SetDefaultIcon(TRUE); return S_OK; } //---------------------------------------------------------------------------- // // GetIconMode() // //---------------------------------------------------------------------------- STDAPI CLBarItemSystemButtonBase::GetIconMode(DWORD *pdwFlags) { if (!pdwFlags) return E_INVALIDARG; *pdwFlags = _dwIconMode; return S_OK; } //+--------------------------------------------------------------------------- // // _InsertCustomMenus // //---------------------------------------------------------------------------- BOOL CLBarItemSystemButtonBase::_InsertCustomMenus(ITfMenu *pMenu, UINT *pnTipCurMenuID) { int nCntEventSink; int i; BOOL bRet = FALSE; // // Insert Custom item to menu // ClearMenuMap(); nCntEventSink = _rgEventSinks.Count(); for (i = 0; i < nCntEventSink; i++) { CCicLibMenu *pMenuTmp; GENERICSINK *pSink; ITfSystemLangBarItemSink *plbSink; if (i >= IDM_CUSTOM_MENU_START - IDM_ASM_MENU_START) { Assert(0); break; } if (!_pMenuMap) _pMenuMap = new CStructArray; if (!_pMenuMap) { Assert(0); goto Exit; } pMenuTmp = new CCicLibMenu; if (!pMenuTmp) { goto Exit; } pSink = _rgEventSinks.GetPtr(i); if (SUCCEEDED(pSink->pSink->QueryInterface( IID_ITfSystemLangBarItemSink, (void **)&plbSink))) { if (SUCCEEDED(plbSink->InitMenu(pMenuTmp))) { if (*pnTipCurMenuID > IDM_CUSTOM_MENU_START) LangBarInsertSeparator(pMenu); *pnTipCurMenuID = _MergeMenu(pMenu, pMenuTmp, plbSink, _pMenuMap, *pnTipCurMenuID); } plbSink->Release(); } else { Assert(0); } pMenuTmp->Release(); } bRet = TRUE; Exit: return bRet; } //+--------------------------------------------------------------------------- // // _MergeMenu // //---------------------------------------------------------------------------- #define MIIM_ALL ( MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE ) UINT CLBarItemSystemButtonBase::_MergeMenu(ITfMenu *pMenu, CCicLibMenu *pMenuTip, ITfSystemLangBarItemSink *plbSink, CStructArray *pMenuMap, UINT &nCurID) { int i; int nMenuCnt = pMenuTip->GetItemCount(); HRESULT hr; if (nMenuCnt <= 0) return nCurID; for (i = 0; i < nMenuCnt; i++) { CCicLibMenuItem *pItem = pMenuTip->GetItem(i); if (!pItem) continue; TIPMENUITEMMAP *ptmm; ptmm = pMenuMap->Append(1); if (!ptmm) continue; ptmm->plbSink = plbSink; ptmm->nOrgID = pItem->GetId(); ptmm->nTmpID = nCurID++; hr = E_FAIL; if (pItem->GetSubMenu()) { ITfMenu *pSubMenu = NULL; hr = pMenu->AddMenuItem((UINT)-1, pItem->GetFlags(), pItem->GetBitmap(), pItem->GetBitmapMask(), pItem->GetText(), wcslen(pItem->GetText()), &pSubMenu); if (SUCCEEDED(hr)) { _MergeMenu(pSubMenu, pItem->GetSubMenu(), plbSink, pMenuMap, nCurID); pSubMenu->Release(); } } else { hr = pMenu->AddMenuItem(ptmm->nTmpID, pItem->GetFlags(), pItem->GetBitmap(), pItem->GetBitmapMask(), pItem->GetText(), wcslen(pItem->GetText()), NULL); } if (SUCCEEDED(hr)) pItem->ClearBitmaps(); } return nCurID; } ////////////////////////////////////////////////////////////////////////////// // // CLBarItemDeviceType // ////////////////////////////////////////////////////////////////////////////// //+--------------------------------------------------------------------------- // // ctor // //---------------------------------------------------------------------------- CLBarItemDeviceType::CLBarItemDeviceType(SYSTHREAD *psfn, REFGUID rguid) : CLBarItemSystemButtonBase(psfn) { Dbg_MemSetThisNameID(TEXT("CLBarItemDeviceType")); DWORD dwNuiStyle = TF_LBI_STYLE_BTN_MENU | TF_LBI_STYLE_HIDDENSTATUSCONTROL; _guid = rguid; _nType = -1; _fHideOrder = FALSE; if (IsEqualGUID(_guid, GUID_TFCAT_TIP_KEYBOARD)) { _nType = ID_TYPE_KEYBOARD; dwNuiStyle |= TF_LBI_STYLE_SHOWNINTRAY; _dwIconMode = TF_DTLBI_USEPROFILEICON; } else if (IsEqualGUID(_guid, GUID_TFCAT_TIP_HANDWRITING)) { _nType = ID_TYPE_HANDWRITING; } else if (IsEqualGUID(_guid, GUID_TFCAT_TIP_SPEECH)) { _nType = ID_TYPE_SPEECH; } if (_nType != -1) { InitNuiInfo(CLSID_SYSTEMLANGBARITEM, rguid, dwNuiStyle, 0, CRStr(IDS_NUI_DEVICE_NAME_START + _nType)); } else { BSTR bstr = NULL; MyGetGUIDDescription(rguid, &bstr); InitNuiInfo(CLSID_SYSTEMLANGBARITEM, rguid, dwNuiStyle, 0, bstr ? bstr : L""); if (bstr) SysFreeString(bstr); } _pif = NULL; } //---------------------------------------------------------------------------- // // dtor // //---------------------------------------------------------------------------- CLBarItemDeviceType::~CLBarItemDeviceType() { if (_pif) delete _pif; if (_pces) { _pces->_Unadvise(); _pces->Release(); } } //+--------------------------------------------------------------------------- // // Init // //---------------------------------------------------------------------------- static const TCHAR c_szNuiDeviceTypeWndClass[] = "NuiDeviceTypeDummyWndClass"; void CLBarItemDeviceType::Init() { if (_nType != -1) { SetText(CRStr(IDS_NUI_DEVICE_NAME_START + _nType)); SetToolTip(CRStr(IDS_NUI_DEVICE_TIP_START + _nType)); } else { SetText(_lbiInfo.szDescription); SetToolTip(_lbiInfo.szDescription); } ShowOrHide(FALSE); } //+--------------------------------------------------------------------------- // // Uninit // //---------------------------------------------------------------------------- void CLBarItemDeviceType::Uninit() { if (_pces) { _pces->_Unadvise(); SafeReleaseClear(_pces); } } //+--------------------------------------------------------------------------- // // InitTipArray // //---------------------------------------------------------------------------- void CLBarItemDeviceType::InitTipArray(BOOL fInitIconIndex) { CAssembly *pAsm; int i; int nCnt; LANGID langid = 0; _rgGuidatomHkl.Clear(); pAsm = GetCurrentAssembly(); if (!pAsm) goto Exit; if (_psfn->plbim && _psfn->plbim->_GetLBarItemCtrl()) langid = GetCurrentAssemblyLangId(_psfn); nCnt = pAsm->Count(); if (_psfn->ptim && _psfn->ptim->_GetFocusDocInputMgr()) pAsm->RebuildSubstitutedHKLList(); else pAsm->ClearSubstitutedHKLList(); for (i = 0; i < nCnt; i++) { ASSEMBLYITEM *pItem = pAsm->GetItem(i); if (!pItem->fEnabled) continue; if (IsEqualGUID(pItem->catid, _guid)) { GUIDATOMHKL gahkl; BOOL fInsert = FALSE; if (!IsEqualGUID(pItem->clsid, GUID_NULL)) { if (_psfn->ptim && _psfn->ptim->_GetFocusDocInputMgr()) { TfGuidAtom guidatom; MyRegisterGUID(pItem->clsid, &guidatom); gahkl.guidatom = guidatom; gahkl.hkl = pItem->hkl; gahkl.pItem = pItem; fInsert = TRUE; } } else { Assert(pItem->hkl); BOOL bSkip = FALSE; if (pAsm->IsSubstitutedHKL(pItem->hkl) || ((!_psfn->ptim || !_psfn->ptim->_GetFocusDocInputMgr()) && CAssemblyList::IsFEDummyKL(pItem->hkl))) { bSkip = TRUE; } if (!bSkip) { gahkl.guidatom = TF_INVALID_GUIDATOM; gahkl.hkl = pItem->hkl; gahkl.pItem = pItem; fInsert = TRUE; } } if (fInsert) { GUIDATOMHKL *pgahkl; int nCurId; int nMaxId = _rgGuidatomHkl.Count(); for (nCurId = 0; nCurId < nMaxId; nCurId++) { GUIDATOMHKL *pgahklCur; int nCmp; pgahklCur = _rgGuidatomHkl.GetPtr(nCurId); if (!pgahklCur) continue; nCmp = CompareGUIDs(pgahklCur->pItem->clsid, gahkl.pItem->clsid); if (nCmp > 0) break; if (nCmp < 0) continue; if (CompareGUIDs(pgahklCur->pItem->guidProfile, gahkl.pItem->guidProfile) > 0) break; } if (_rgGuidatomHkl.Insert(nCurId, 1) && (pgahkl = _rgGuidatomHkl.GetPtr(nCurId))) { gahkl.uIconIndex = fInitIconIndex ? GetIconIndex(langid, pItem) : (ULONG)-1; *pgahkl = gahkl; } } } } Exit: return; } //+--------------------------------------------------------------------------- // // ShowOrHide // //---------------------------------------------------------------------------- void CLBarItemDeviceType::ShowOrHide(BOOL fNotify) { BOOL bShow = TRUE; int nCnt; // // if _fHideOrder is TRUE, someone asked not to show this category icon. // we do nothing. // if (_fHideOrder) { Assert(_dwStatus & TF_LBI_STATUS_HIDDEN); return; } InitTipArray(FALSE); nCnt = _rgGuidatomHkl.Count(); if (_nType != ID_TYPE_KEYBOARD) { CAssembly *pAsm = GetCurrentAssembly(); if (pAsm && pAsm->IsFEIMEActive()) { ShowInternal(FALSE, fNotify); return; } } if (!nCnt) { bShow = FALSE; } else if (nCnt == 1) { if (_nType == ID_TYPE_KEYBOARD) { GUIDATOMHKL *pgahkl; pgahkl = _rgGuidatomHkl.GetPtr(0); bShow = pgahkl->guidatom ? TRUE : FALSE; } else { bShow = FALSE; } } ShowInternal(bShow, fNotify); } //+--------------------------------------------------------------------------- // // Show // //---------------------------------------------------------------------------- STDAPI CLBarItemDeviceType::Show(BOOL fShow) { _fHideOrder = fShow ? FALSE : TRUE; return CLBarItemSystemButtonBase::Show(fShow); } //+--------------------------------------------------------------------------- // // InitMenu // //---------------------------------------------------------------------------- #if IDM_CUSTOM_MENU_START <= IDM_ASM_MENU_START #erroe IDM_CUSTOM_MENU_START is smaller than IDM_ASM_MENU_START #endif #if IDM_ASM_MENU_START <= IDM_LANG_MENU_START #erroe IDM_ASM_MENU_START is smaller than IDM_LANG_MENU_START #endif STDAPI CLBarItemDeviceType::InitMenu(ITfMenu *pMenu) { CThreadInputMgr *ptim = NULL; CDocumentInputManager *pdim = NULL; CInputContext *pic; int nCntGuidatomHkl; int i; CLSID clsid; UINT nTipCurMenuID = IDM_CUSTOM_MENU_START; LANGID langid = 0; BOOL bMenuChecked = FALSE; GUIDATOMHKL *pgahkl; BOOL fTransitory = FALSE; ptim = _psfn->ptim; InitTipArray(TRUE); nCntGuidatomHkl = _rgGuidatomHkl.Count(); if (!ptim) goto SetHKLMenu; if (!(pdim = ptim->_GetFocusDocInputMgr())) goto SetHKLMenu; pic = pdim->_GetTopIC(); if (pic) { TF_STATUS dcs; if (SUCCEEDED(pic->GetStatus(&dcs)) && (dcs.dwStaticFlags & TF_SS_TRANSITORY)) fTransitory = TRUE; } if (!_InsertCustomMenus(pMenu, &nTipCurMenuID)) goto Exit; // // Insert separator. // if (nCntGuidatomHkl && (nTipCurMenuID > IDM_CUSTOM_MENU_START)) LangBarInsertSeparator(pMenu); if (_psfn->plbim && _psfn->plbim->_GetLBarItemCtrl()) langid = GetCurrentAssemblyLangId(_psfn); // // Insert TIPs to menu // for (i = 0; i < nCntGuidatomHkl; i++) { BOOL bCheckThis; pgahkl = _rgGuidatomHkl.GetPtr(i); if (i >= IDM_CUSTOM_MENU_START - IDM_ASM_MENU_START) { Assert(0); break; } if (!pgahkl->guidatom) continue; MyGetGUID(pgahkl->guidatom, &clsid); if (!CAssemblyList::CheckLangSupport(clsid, langid)) continue; bCheckThis = (pgahkl->pItem->fActive) ? TRUE : FALSE; if (fTransitory && pgahkl->pItem->fDisabledOnTransitory) LangBarInsertGrayedMenu(pMenu, pgahkl->pItem->szProfile, TF_InatExtractIcon(pgahkl->uIconIndex)); else LangBarInsertMenu(pMenu, IDM_ASM_MENU_START + i, pgahkl->pItem->szProfile, bCheckThis, TF_InatExtractIcon(pgahkl->uIconIndex)); if (bCheckThis) { bMenuChecked = TRUE; } } SetHKLMenu: // // Insert HKLs to menu // for (i = 0; i < nCntGuidatomHkl; i++) { BOOL bCheckIt = FALSE; pgahkl = _rgGuidatomHkl.GetPtr(i); if (i >= IDM_CUSTOM_MENU_START - IDM_ASM_MENU_START) { Assert(0); break; } if (pgahkl->guidatom) continue; if (!bMenuChecked && pgahkl->hkl == GetKeyboardLayout(0)) { if (pdim) bCheckIt = (pgahkl->pItem->fActive) ? TRUE : FALSE; else bCheckIt = TRUE; } LangBarInsertMenu(pMenu, IDM_LANG_MENU_START + i, pgahkl->pItem->szProfile, bCheckIt, IsPureIMEHKL(pgahkl->hkl) ? TF_InatExtractIcon(pgahkl->uIconIndex) : NULL); if (bCheckIt) { bMenuChecked = TRUE; } } // // If the lbiCtrl is hidden (there is only one language available) and // the floating toolbar is minimized, the keyboard langbar item // has a "Show Langbar" menu item. // if ((_nType == ID_TYPE_KEYBOARD) && _psfn->plbim) { CLBarItemCtrl *plbiCtrl = _psfn->plbim->_GetLBarItemCtrl(); if (plbiCtrl) { DWORD dwFlags; DWORD dwStatus; dwStatus = plbiCtrl->GetStatusInternal(); if ((dwStatus & TF_LBI_STATUS_HIDDEN) && SUCCEEDED(CLangBarMgr::s_GetShowFloatingStatus(&dwFlags)) && (dwFlags & (TF_SFT_MINIMIZED | TF_SFT_DESKBAND))) { LangBarInsertSeparator(pMenu); LangBarInsertMenu(pMenu, IDM_SHOWLANGBAR, CRStr(IDS_SHOWLANGBAR)); } } } Exit: return S_OK; } //+--------------------------------------------------------------------------- // // OnMenuSelect // //---------------------------------------------------------------------------- STDAPI CLBarItemDeviceType::OnMenuSelect(UINT uID) { CThreadInputMgr *ptim; int i; GUIDATOMHKL *pgahkl; ptim = _psfn->ptim; if (uID == IDM_SHOWLANGBAR) { CLangBarMgr::s_ShowFloating(TF_SFT_SHOWNORMAL); } else if (uID >= IDM_CUSTOM_MENU_START) { Assert(ptim); int nMenuMapoCnt = _pMenuMap->Count(); for (i = 0; i < nMenuMapoCnt; i++) { TIPMENUITEMMAP *ptmm; ptmm = _pMenuMap->GetPtr(i); if (ptmm->nTmpID == (UINT)uID) { ptmm->plbSink->OnMenuSelect(ptmm->nOrgID); break; } } } else if (uID >= IDM_ASM_MENU_START) { Assert(ptim); pgahkl = _rgGuidatomHkl.GetPtr(uID - IDM_ASM_MENU_START); Assert(pgahkl); Assert(pgahkl->guidatom); ASSEMBLYITEM *pItem = pgahkl->pItem; if (!pgahkl->pItem->fActive) { LANGID langid = GetCurrentAssemblyLangId(_psfn); ActivateAssemblyItem(_psfn, langid, pItem, AAIF_CHANGEDEFAULT); CAssemblyList *pAsmList = EnsureAssemblyList(_psfn); if (pAsmList) { CAssembly *pAsm = pAsmList->FindAssemblyByLangId(langid); if (pAsm) { pAsmList->SetDefaultTIPInAssemblyInternal(pAsm, pItem, TRUE); } } } // #ifdef HANDWRITINGAUTOSHOW if (_nType == ID_TYPE_HANDWRITING) { MySetCompartmentDWORD(g_gaSystem, ptim, GUID_COMPARTMENT_HANDWRITING_OPENCLOSE, TRUE); } // #endif } else if (uID >= IDM_LANG_MENU_START) { pgahkl = _rgGuidatomHkl.GetPtr(uID - IDM_LANG_MENU_START); Assert(pgahkl); Assert(pgahkl->hkl); ActivateAssemblyItem(_psfn, GetCurrentAssemblyLangId(_psfn), pgahkl->pItem, AAIF_CHANGEDEFAULT); } ClearMenuMap(); return S_OK; } //---------------------------------------------------------------------------- // // CompEventSinkCallback (static) // //---------------------------------------------------------------------------- HRESULT CLBarItemDeviceType::CompEventSinkCallback(void *pv, REFGUID rguid) { CLBarItemDeviceType *_this = (CLBarItemDeviceType *)pv; if (IsEqualGUID(rguid, GUID_COMPARTMENT_SPEECH_OPENCLOSE)) { _this->SetSpeechButtonState(_this->_psfn->ptim); } return S_FALSE; } //---------------------------------------------------------------------------- // // SetSpeechButtonState // //---------------------------------------------------------------------------- HRESULT CLBarItemDeviceType::SetSpeechButtonState(CThreadInputMgr *ptim) { DWORD dw = 0; MyGetCompartmentDWORD(ptim->GetGlobalComp(), GUID_COMPARTMENT_SPEECH_OPENCLOSE, &dw); SetOrClearStatus(TF_LBI_STATUS_BTN_TOGGLED, dw); if (_plbiSink) _plbiSink->OnUpdate(TF_LBI_STATUS); return S_OK; } //---------------------------------------------------------------------------- // // SetIcon // //---------------------------------------------------------------------------- STDAPI CLBarItemDeviceType::SetIcon(HICON hIcon) { CLBarItemButtonBase::SetIcon(hIcon); return S_OK; } //---------------------------------------------------------------------------- // // GetIcon // //---------------------------------------------------------------------------- STDAPI CLBarItemDeviceType::GetIcon(HICON *phIcon) { if (CLBarItemButtonBase::GetIcon()) { return CLBarItemButtonBase::GetIcon(phIcon); } HICON hIcon = NULL; if (_nType != -1) { hIcon = LoadSmIcon(g_hInst, MAKEINTRESOURCE(ID_ICON_DEVICE_START + _nType)); } else { int cx, cy; InatGetIconSize(&cx, &cy); if (!_pif) { BSTR bstr; HRESULT hr; ICONFILE *pif; pif = new ICONFILE; if (!pif) goto Exit; if (FAILED(hr = MyGetGUIDValue(_guid, c_szIconIndexW, &bstr))) { delete pif; goto Exit; } pif->uIconIndex = WToNum(bstr); SysFreeString(bstr); if (FAILED(hr = MyGetGUIDValue(_guid, c_szIconFileW, &bstr))) { delete pif; goto Exit; } wcsncpy(pif->szFile, bstr, ARRAYSIZE(pif->szFile)); SysFreeString(bstr); _pif = pif; } hIcon = GetIconFromFile(cx, cy, _pif->szFile, _pif->uIconIndex); } Exit: *phIcon = hIcon; return S_OK; } //---------------------------------------------------------------------------- // // SetTooltipString // //---------------------------------------------------------------------------- STDAPI CLBarItemDeviceType::SetTooltipString(WCHAR *pchToolTip, ULONG cch) { if (!pchToolTip) { SetToolTip(CRStr(IDS_NUI_DEVICE_TIP_START + _nType)); } else SetToolTip(pchToolTip, cch); return S_OK; } //+--------------------------------------------------------------------------- // // UpdateLangIcon // //---------------------------------------------------------------------------- void CLBarItemDeviceType::SetBrandingIcon(HKL hKL, BOOL fNotify) { CThreadInputMgr *ptim; HICON hIcon; ULONG uIconIndex = -1; ASSEMBLYITEM *pItem = NULL; CAssembly *pAsm; WCHAR szDesc[128]; if (!hKL) hKL = GetKeyboardLayout(0); if (!(_dwIconMode & TF_DTLBI_USEPROFILEICON)) return; ptim = CThreadInputMgr::_GetThisFromSYSTHREAD(_psfn); pAsm = GetCurrentAssembly(_psfn); if (!pAsm) return; #ifdef USE_ASM_ISFEIMEACTIVE BOOL fIsPureIME = FALSE; if (_nType == ID_TYPE_KEYBOARD) { if (ptim && ptim->_GetFocusDocInputMgr()) { fIsPureIME = pAsm->IsFEIMEActive(); } else { fIsPureIME = IsPureIMEHKL(hKL); } } #endif USE_ASM_ISFEIMEACTIVE hIcon = NULL; szDesc[0] = L'\0'; #ifdef USE_ASM_ISFEIMEACTIVE if (fIsPureIMEHKL) #else if (IsPureIMEHKL(hKL)) #endif USE_ASM_ISFEIMEACTIVE { pItem = pAsm->FindKeyboardLayoutItem(hKL); uIconIndex = GetIconIndexFromhKL(hKL); if (uIconIndex != -1) hIcon = TF_InatExtractIcon(uIconIndex); } else if (ptim && ptim->_GetFocusDocInputMgr()) { pItem = pAsm->FindActiveKeyboardItem(); // // if it is Cicero item, we will show the branding Icon. // if (pItem && !IsEqualGUID(pItem->clsid, GUID_NULL)) { uIconIndex = GetIconIndex(LOWORD(HandleToLong(hKL)), pItem); if (uIconIndex != -1) hIcon = TF_InatExtractIcon(uIconIndex); } } else { MLNGINFO mlInfo; if (GetMlngInfoByhKL(hKL, &mlInfo) != -1) { wcsncpy(szDesc, mlInfo.GetDesc(), ARRAYSIZE(szDesc)); } } HICON hIconOld = GetIcon(); SetIcon(hIcon); if (hIconOld) DestroyIcon(hIconOld); if (pItem) { SetText(pItem->szProfile); SetToolTip(pItem->szProfile); } else if (szDesc[0]) { SetText(szDesc); SetToolTip(szDesc); } else if (_nType != -1) { SetText(CRStr(IDS_NUI_DEVICE_NAME_START + _nType)); SetToolTip(CRStr(IDS_NUI_DEVICE_TIP_START + _nType)); } if (fNotify && _plbiSink) _plbiSink->OnUpdate(TF_LBI_ICON | TF_LBI_TEXT | TF_LBI_TOOLTIP); } //+--------------------------------------------------------------------------- // // SetDefaultIcon // //---------------------------------------------------------------------------- void CLBarItemDeviceType::SetDefaultIcon(BOOL fNotify) { HICON hIconOld = GetIcon(); SetIcon(NULL); if (hIconOld) DestroyIcon(hIconOld); if (_nType != -1) { SetToolTip(CRStr(IDS_NUI_DEVICE_NAME_START + _nType)); SetText(_szToolTip); } if (fNotify && _plbiSink) _plbiSink->OnUpdate(TF_LBI_ICON | TF_LBI_TEXT | TF_LBI_TOOLTIP); }