

To obtain the localized name of the text service use ITfInputProcessorProfiles::GetLanguageProfileDescription
https://docs.microsoft.com/en-us/windows/win32/api/msctf/nf-msctf-itfinputprocessorprofiles-getlanguageprofiledescription
To obtain the localized name of the keyboard layout, see the code below.
To obtain the localized name of the LANGID, see the code below.
/**
* @brief Get the locale of the input processor
*
* @param BSTR* Pointer to a BSTR value that receives the locale string. The caller is responsible for freeing
* this memory using SysFreeString when it is no longer required.
*/
HRESULT libtf_get_input_processor_locale(libtf_InputProcessorProfile_t profile, BSTR* locale)
{
LCID lcid = MAKELCID(profile.langid, SORT_DEFAULT);
wchar_t buf[85];
GetLocaleInfoW(lcid, LOCALE_SNAME, buf, 85);
*locale = SysAllocString(buf);
return S_OK;
}
/**
* @brief Get the localized name of the locale
*
* @param BSTR locale
* @param BSTR* Pointer to a BSTR value that receives the name string. The caller is responsible for freeing
* this memory using SysFreeString when it is no longer required.
*/
HRESULT libtf_get_locale_name(BSTR locale, BSTR* name)
{
wchar_t buf[128];
GetLocaleInfoEx(locale, LOCALE_SLOCALIZEDDISPLAYNAME, buf, 128);
*name = SysAllocString(buf);
return S_OK;
}
/**
* @brief Get the localized name of the input processor
*
* @param BSTR Pointer to a BSTR value that receives the description string. The caller is responsible for freeing this
* memory using SysFreeString when it is no longer required.
*/
HRESULT libtf_get_input_processor_desc(libtf_InputProcessorProfile_t profile, BSTR* desc)
{
switch (profile.dwProfileType) {
case TF_PROFILETYPE_INPUTPROCESSOR: {
CComPtr<ITfInputProcessorProfiles> inputProcessorProfiles;
CHECK_HR(createInputProcessorProfiles(&inputProcessorProfiles));
CHECK_HR(inputProcessorProfiles->GetLanguageProfileDescription(
profile.clsid, profile.langid, profile.guidProfile, desc));
} break;
case TF_PROFILETYPE_KEYBOARDLAYOUT: {
HKEY layouts;
CHECK_ES(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"),
0,
KEY_READ,
&layouts));
HRESULT hr;
// the key of the keyboard layout is its langid
char layoutKey[9];
snprintf(layoutKey, 9, "%08x", profile.langid);
HKEY layout;
if (NOT_ES(hr = RegOpenKeyExA(layouts, layoutKey, 0, KEY_READ, &layout))) goto CloseParentKey;
DWORD size;
// Get data size first
if (NOT_ES(
hr = RegGetValueW(
layout, NULL, L"Layout Display Name", RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, NULL, NULL, &size)))
goto CloseSubKey;
{
std::unique_ptr<uint8_t[]> buf(new uint8_t[size]);
// Get resource key of the name
if (NOT_ES(hr = RegGetValueW(layout,
NULL,
L"Layout Display Name",
RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND,
NULL,
buf.get(),
&size)))
goto CloseSubKey;
// Get the layout name by resource key
std::unique_ptr<wchar_t[]> layoutName(new wchar_t[KL_NAMELENGTH]);
if (FAILED(hr = SHLoadIndirectString((wchar_t*)buf.get(), layoutName.get(), KL_NAMELENGTH, NULL)))
goto CloseSubKey;
// Return result
*desc = SysAllocString(layoutName.get());
CHECK_OOM(*desc);
}
CloseSubKey:
RegCloseKey(layout);
CloseParentKey:
RegCloseKey(layouts);
return hr;
} break;
default: return E_INVALIDARG;
}
return S_OK;
}
2 people are following this question.