[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".
This commit is contained in:
Katayama Hirofumi MZ 2024-02-06 21:39:32 +09:00 committed by GitHub
parent 8bf0854c8e
commit 0bce79a50b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 224 additions and 4 deletions

View file

@ -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)

View file

@ -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

View file

@ -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.@)
*

View file

@ -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

View file

@ -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;")

View file

@ -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);