https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0bce79a50b52bce96b54a…
commit 0bce79a50b52bce96b54ab334bb0bf7fe742feb8
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Feb 6 21:39:32 2024 +0900
Commit: GitHub <noreply(a)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);