https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0bce79a50b52bce96b54ab334bb0bf7fe742feb8
commit 0bce79a50b52bce96b54ab334bb0bf7fe742feb8 Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Tue Feb 6 21:39:32 2024 +0900 Commit: GitHub <nore...@github.com> CommitDate: Tue Feb 6 21:39:32 2024 +0900 [MSCTF][MSUTB][SDK] Add CLBarInatItem (#6447) Supporting Language Bar... JIRA issue: CORE-19363 - Modify msctf.spec. - Add some helper functions. - Half-implement CLBarInatItem class. - Add some TF_... function prototypes to "msctf.idl". --- dll/win32/msctf/msctf.spec | 8 +- dll/win32/msutb/lang/en-US.rc | 3 + dll/win32/msutb/msutb.cpp | 208 ++++++++++++++++++++++++++++++++++++ dll/win32/msutb/resource.h | 3 + sdk/include/psdk/msctf.idl | 5 + sdk/include/reactos/cicero/cicutb.h | 1 + 6 files changed, 224 insertions(+), 4 deletions(-) diff --git a/dll/win32/msctf/msctf.spec b/dll/win32/msctf/msctf.spec index 52288129e1c..975acdb2118 100644 --- a/dll/win32/msctf/msctf.spec +++ b/dll/win32/msctf/msctf.spec @@ -19,11 +19,11 @@ @ stdcall -stub TF_GetGlobalCompartment(ptr) @ stub TF_GetInputScope @ stdcall -stub TF_GetLangIcon(long ptr long) -@ stub TF_GetMlngHKL -@ stub TF_GetMlngIconIndex +@ stdcall -stub TF_GetMlngHKL(long ptr ptr long) +@ stdcall -stub TF_GetMlngIconIndex(long) @ stub TF_GetThreadFlags @ stdcall TF_GetThreadMgr(ptr) -@ stub TF_InatExtractIcon +@ stdcall -stub TF_InatExtractIcon(long) @ stdcall TF_InitMlngInfo() @ stdcall -stub TF_InitSystem() @ stdcall -stub TF_UninitSystem() @@ -31,7 +31,7 @@ @ stdcall TF_InvalidAssemblyListCacheIfExist() @ stdcall TF_IsCtfmonRunning() @ stub TF_IsInMarshaling -@ stub TF_MlngInfoCount +@ stdcall -stub TF_MlngInfoCount() @ stdcall TF_RunInputCPL() @ stdcall -stub TF_PostAllThreadMsg(long long) @ stdcall TF_RegisterLangBarAddIn(ptr wstr long) diff --git a/dll/win32/msutb/lang/en-US.rc b/dll/win32/msutb/lang/en-US.rc index 3c3a7a579dd..8b09fb014c3 100644 --- a/dll/win32/msutb/lang/en-US.rc +++ b/dll/win32/msutb/lang/en-US.rc @@ -18,6 +18,9 @@ BEGIN IDS_NO "&No" IDS_RESTORELANGBAR "Restore Language Bar" + IDS_LANGUAGE "Language" + IDS_RESTORELANGBAR2 "&Restore Language Bar" + IDS_LANGUAGEBUTTON "Language Button" IDS_MENUWND "Menu Window" IDS_LEFTCLICK "Left Click" END diff --git a/dll/win32/msutb/msutb.cpp b/dll/win32/msutb/msutb.cpp index 21a68f70b54..37b5176bb1e 100644 --- a/dll/win32/msutb/msutb.cpp +++ b/dll/win32/msutb/msutb.cpp @@ -111,6 +111,22 @@ BOOL IsBiDiLocalizedSystem(void) return (Sig.lsUsb[3] & 0x8000000) != 0; } +BOOL GetFontSig(HWND hWnd, HKL hKL) +{ + LOCALESIGNATURE Sig; + INT size = sizeof(Sig) / sizeof(WCHAR); + if (!::GetLocaleInfoW(LOWORD(hKL), LOCALE_FONTSIGNATURE, (LPWSTR)&Sig, size)) + return FALSE; + + HDC hDC = ::GetDC(hWnd); + DWORD CharSet = ::GetTextCharsetInfo(hDC, NULL, 0); + CHARSETINFO CharSetInfo; + ::TranslateCharsetInfo((DWORD*)(DWORD_PTR)CharSet, &CharSetInfo, TCI_SRCCHARSET); + ::ReleaseDC(hWnd, hDC); + + return !!(CharSetInfo.fs.fsCsb[0] & Sig.lsCsbSupported[0]); +} + void InitSkipRedrawHKLArray(void) { g_prghklSkipRedrawing = new(cicNoThrow) CicArray<HKL>(); @@ -228,6 +244,69 @@ void DoCloseLangbar(void) ::RegDeleteValue(regKey, TEXT("ctfmon.exe")); } +INT GetIconIndexFromhKL(_In_ HKL hKL) +{ + HKL hGotKL; + + INT iKL, cKLs = TF_MlngInfoCount(); + for (iKL = 0; iKL < cKLs; ++iKL) + { + if (TF_GetMlngHKL(iKL, &hGotKL, NULL, 0) && hKL == hGotKL) + return TF_GetMlngIconIndex(iKL); + } + + if (!TF_GetMlngHKL(0, &hGotKL, NULL, 0)) + return -1; + + return TF_GetMlngIconIndex(0); +} + +BOOL GethKLDesc(_In_ HKL hKL, _Out_ LPWSTR pszDesc, _In_ UINT cchDesc) +{ + HKL hGotKL; + + INT iKL, cKLs = TF_MlngInfoCount(); + for (iKL = 0; iKL < cKLs; ++iKL) + { + if (TF_GetMlngHKL(iKL, &hGotKL, pszDesc, cchDesc) && hKL == hGotKL) + return TRUE; + } + + return TF_GetMlngHKL(0, &hGotKL, pszDesc, cchDesc); +} + +HRESULT +LangBarInsertMenu( + _In_ ITfMenu *pMenu, + _In_ UINT uId, + _In_ LPCWSTR pszText, + _In_ BOOL bChecked, + _Inout_opt_ HICON hIcon) +{ + HBITMAP hbmp = NULL, hbmpMask = NULL; + if (hIcon) + { + HICON hIconNew = (HICON)::CopyImage(hIcon, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE); + SIZE iconSize = { 16, 16 }; + if (!hIconNew) + hIconNew = hIcon; + if (!cicGetIconBitmaps(hIconNew, &hbmp, &hbmpMask, &iconSize)) + return E_FAIL; + if (hIconNew) + ::DestroyIcon(hIconNew); + ::DestroyIcon(hIcon); + } + + INT cchText = lstrlenW(pszText); + DWORD dwFlags = (bChecked ? TF_LBMENUF_CHECKED : 0); + return pMenu->AddMenuItem(uId, dwFlags, hbmp, hbmpMask, pszText, cchText, NULL); +} + +HRESULT LangBarInsertSeparator(_In_ ITfMenu *pMenu) +{ + return pMenu->AddMenuItem(-1, TF_LBMENUF_SEPARATOR, NULL, NULL, NULL, 0, NULL); +} + BOOL InitFromReg(void) { DWORD dwValue; @@ -934,6 +1013,24 @@ public: STDMETHOD(UnadviseSink)(DWORD dwCookie) override; }; +/***********************************************************************/ + +/// Language Bar international item +class CLBarInatItem : public CLBarItemButtonBase +{ +protected: + HKL m_hKL; + DWORD m_dwThreadId; + +public: + CLBarInatItem(DWORD dwThreadId); + + STDMETHOD(InitMenu)(ITfMenu *pMenu) override; + STDMETHOD(OnMenuSelect)(INT nCommandId); + STDMETHOD(GetIcon)(HICON *phIcon) override; + STDMETHOD(GetText)(BSTR *pbstr) override; +}; + /*********************************************************************** * CUTBLangBarDlg */ @@ -2779,6 +2876,117 @@ STDMETHODIMP CLBarItemButtonBase::UnadviseSink(DWORD dwCookie) return CLBarItemBase::UnadviseSink(dwCookie); } +/*********************************************************************** + * CLBarInatItem + */ + +CLBarInatItem::CLBarInatItem(DWORD dwThreadId) +{ + WCHAR szText[256]; + ::LoadStringW(g_hInst, IDS_LANGUAGE, szText, _countof(szText)); + InitNuiInfo(CLSID_SYSTEMLANGBARITEM, GUID_LBI_INATITEM, 0x20001, 0, szText); + + ::LoadStringW(g_hInst, IDS_LANGUAGEBUTTON, szText, _countof(szText)); + StringCchCopyW(m_szToolTipText, _countof(m_szToolTipText), szText); + m_dwThreadId = dwThreadId; + m_hKL = ::GetKeyboardLayout(m_dwThreadId); + + TF_InitMlngInfo(); + ShowInternal(TF_MlngInfoCount() > 1, 0); +} + +STDMETHODIMP CLBarInatItem::GetIcon(HICON *phIcon) +{ + HICON hIcon = NULL; + INT iIndex = GetIconIndexFromhKL(m_hKL); + if (iIndex != -1) + hIcon = TF_InatExtractIcon(iIndex); + *phIcon = hIcon; + return S_OK; +} + +STDMETHODIMP CLBarInatItem::GetText(BSTR *pbstr) +{ + if (!pbstr) + return E_INVALIDARG; + + WCHAR szText[256]; + if (!GethKLDesc(m_hKL, szText, _countof(szText))) + return GetText(pbstr); + + *pbstr = ::SysAllocString(szText); + return S_OK; +} + +STDMETHODIMP CLBarInatItem::InitMenu(ITfMenu *pMenu) +{ + TF_InitMlngInfo(); + + INT iKL, cKLs = TF_MlngInfoCount(); + for (iKL = 0; iKL < cKLs; ++iKL) + { + HKL hKL; + WCHAR szDesc[128]; + if (TF_GetMlngHKL(iKL, &hKL, szDesc, _countof(szDesc))) + { + HICON hIcon = NULL; + INT iIndex = GetIconIndexFromhKL(hKL); + if (iIndex != -1) + hIcon = TF_InatExtractIcon(iIndex); + + LangBarInsertMenu(pMenu, iKL, szDesc, (hKL == m_hKL), hIcon); + } + } + +#if 0 // FIXME: g_pTipbarWnd + DWORD dwStatus; + if (g_pTipbarWnd && + g_pTipbarWnd->m_pLangBarMgr && + SUCCEEDED(g_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus)) && + (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED))) + { + LangBarInsertSeparator(pMenu); + + WCHAR szText[256]; + ::LoadStringW(g_hInst, IDS_RESTORELANGBAR2, szText, _countof(szText)); + LangBarInsertMenu(pMenu, 2000, szText, FALSE, NULL); + } +#endif + + return S_OK; +} + +STDMETHODIMP CLBarInatItem::OnMenuSelect(INT nCommandId) +{ + HKL hKL; + + if (nCommandId == 2000) + { + if (g_pTipbarWnd) + { +#if 0 // FIXME: g_pTipbarWnd + ITfLangBarMgr *pLangBarMgr = g_pTipbarWnd->m_pLangBarMgr; + if (pLangBarMgr) + pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL); +#endif + } + } + else if (TF_GetMlngHKL(nCommandId, &hKL, NULL, 0)) + { +#if 0 // FIXME: g_pTipbarWnd + g_pTipbarWnd->RestoreLastFocus(0, (g_pTipbarWnd->m_dwTipbarWndFlags & 2) != 0); +#endif + HWND hwndFore = GetForegroundWindow(); + if (m_dwThreadId == ::GetWindowThreadProcessId(hwndFore, NULL)) + { + BOOL FontSig = GetFontSig(hwndFore, hKL); + ::PostMessage(hwndFore, WM_INPUTLANGCHANGEREQUEST, FontSig, (LPARAM)hKL); + } + } + + return S_OK; +} + /*********************************************************************** * GetLibTls (MSUTB.@) * diff --git a/dll/win32/msutb/resource.h b/dll/win32/msutb/resource.h index c3abc6b696c..ee02ba159b2 100644 --- a/dll/win32/msutb/resource.h +++ b/dll/win32/msutb/resource.h @@ -11,6 +11,9 @@ #define IDI_MAINICON 100 #define IDS_RESTORELANGBAR 308 +#define IDS_LANGUAGE 309 +#define IDS_LANGUAGEBUTTON 310 +#define IDS_RESTORELANGBAR2 321 #define IDS_MENUWND 322 #define IDS_LEFTCLICK 323 diff --git a/sdk/include/psdk/msctf.idl b/sdk/include/psdk/msctf.idl index 748787fb795..f9f6e6fe17d 100644 --- a/sdk/include/psdk/msctf.idl +++ b/sdk/include/psdk/msctf.idl @@ -62,6 +62,11 @@ cpp_quote("EXTERN_C HRESULT WINAPI TF_DllDetachInOther(VOID);") cpp_quote("EXTERN_C HRESULT WINAPI TF_CreateCategoryMgr(ITfCategoryMgr **ppcat);") cpp_quote("EXTERN_C HRESULT WINAPI TF_CreateDisplayAttributeMgr(ITfDisplayAttributeMgr **ppdam);") cpp_quote("EXTERN_C HICON WINAPI TF_GetLangIcon(LANGID LangID, LPWSTR pszText, INT cchText);") +cpp_quote("EXTERN_C HRESULT WINAPI TF_InitMlngInfo(VOID);") +cpp_quote("EXTERN_C INT WINAPI TF_MlngInfoCount(VOID);") +cpp_quote("EXTERN_C BOOL WINAPI TF_GetMlngHKL(INT iKL, HKL *phKL, LPWSTR pszText, INT cchText);") +cpp_quote("EXTERN_C INT WINAPI TF_GetMlngIconIndex(INT iKL);") +cpp_quote("EXTERN_C HICON WINAPI TF_InatExtractIcon(INT iKL);") cpp_quote("EXTERN_C const GUID GUID_PROP_TEXTOWNER;") cpp_quote("EXTERN_C const GUID GUID_PROP_ATTRIBUTE;") diff --git a/sdk/include/reactos/cicero/cicutb.h b/sdk/include/reactos/cicero/cicutb.h index 916b0c4befb..6df17b7c0f2 100644 --- a/sdk/include/reactos/cicero/cicutb.h +++ b/sdk/include/reactos/cicero/cicutb.h @@ -12,6 +12,7 @@ DEFINE_GUID(GUID_LBI_TRAYMAIN, 0xE0B724E9, 0x6F76, 0x45F7, 0xB4, DEFINE_GUID(GUID_LBI_INATITEM, 0xCDBC683A, 0x55CE, 0x4717, 0xBA, 0xC0, 0x50, 0xBF, 0x44, 0xA3, 0x27, 0x0C); DEFINE_GUID(GUID_LBI_CTRL, 0x58C99D96, 0x2F9B, 0x42CE, 0x91, 0xBE, 0x37, 0xEF, 0x18, 0x60, 0xF8, 0x82); DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63, 0xB2F0, 0x4784, 0x8B, 0x67, 0x5E, 0x12, 0xC8, 0x70, 0x1A, 0x31); +DEFINE_GUID(CLSID_SYSTEMLANGBARITEM, 0xBEBACC94, 0x5CD3, 0x4662, 0xA1, 0xE0, 0xF3, 0x31, 0x99, 0x49, 0x36, 0x69); EXTERN_C LPVOID WINAPI GetLibTls(VOID); EXTERN_C BOOL WINAPI GetPopupTipbar(HWND hWnd, BOOL fWinLogon);