[TSF-Application]How to obtain the localized name of the text service (TIP)

Windmill_City 206 Reputation points
2021-08-12T09:17:33.197+00:00

122667-image.png

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,653 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,760 questions
{count} votes

Accepted answer
  1. Windmill_City 206 Reputation points
    2021-08-14T03:38:29.543+00:00

    To obtain the localized name of the text service use ITfInputProcessorProfiles::GetLanguageProfileDescription
    https://learn.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.

    2 people found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Windmill_City 206 Reputation points
    2021-08-14T06:56:36.733+00:00
    /**
     * @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;
    }
    
    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.