本文介绍了GetUserPreferredUILanguages()永远不会返回两种以上的语言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从C ++/Qt应用程序中检索用户喜欢的语言的完整列表,如用户首选项的区域和语言"页面中所配置的那样:

I'm trying to retrieve the complete list of the user's preferred languages from a C++/Qt application, as configured in the "Region & language" page in the user's preferences:

为此,我正在尝试使用WinAPI函数在最新的Windows 10 Pro系统上,GetUserPreferredUILanguages().

For that, I am trying with the WinAPI function GetUserPreferredUILanguages(), on an up-to-date Windows 10 Pro system.

但是,该函数始终只返回第一个条目(Windows主要显示语言)和"en-US".如果将英语配置为主语言,则仅返回"en-US".例如,如果我配置了(德语,法语,英语),则返回["de-de","en-US"],则省略了法语.如果我将更多语言添加到列表中,它们也将被省略.我还查看了用户界面语言管理,但无济于事.例如,GetSystemPreferredUILanguages()仅返回"en-US". GetUILanguageFallbackList()返回["de -de," de," en-US," en].

However, the function always only returns the first entry (the main Windows display language), and "en-US". If English is configured as the main language, then only "en-US" is returned. E.g., if I have (German, French, English) configured, ["de-de", "en-US"] is returned, French is omitted. If I add more languages to the list, they are omitted as well.I also looked at User Interface Language Management, but to no avail. GetSystemPreferredUILanguages() for example only returns "en-US". GetUILanguageFallbackList() returns ["de-de", "de", "en-US", "en"].

我使用的代码:

// calling GetUserPreferredUILanguages() twice, once to get number of 
// languages and required buffer size, then to get the actual data

ULONG numberOfLanguages = 0;
DWORD bufferLength = 0;
const auto result1 = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME,
                                                 &numberOfLanguages,
                                                 nullptr,
                                                 &bufferLength);
// result1 is true, numberOfLanguages=2

QVector<wchar_t> languagesBuffer(static_cast<int>(bufferLength));
const auto result2 = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME,
                                                 &numberOfLanguages,
                                                 languagesBuffer.data(),
                                                 &bufferLength);

// result2 is true, languageBuffer contains "de-de", "en-US"

这不是正确使用的功能,还是我对Windows 10中的语言配置有误解?如何获得首选语言的完整列表?我看到 UWP API 这项工作,但如果可能的话,我想使用C API,因为它可以更轻松地与手头的C ++代码库集成. (即非托管C ++)

Is this not the right function to use, or am I misunderstanding something about the language configuration in Windows 10? How can I get the complete list of preferred languages? I see UWP API that might do the job, but if possible, I'd like to use C API, as it integrated more easily with the C++ codebase at hand. (unmanaged C++, that is)

推荐答案

GlobalizationPreferences.Languages可用于非托管C ++,因为GlobalizationPreferences具有 DualApiPartitionAttribute .这是使用GlobalizationPreferences.Languages的C ++/WinRT示例:

GlobalizationPreferences.Languages is usable from unmanaged C++ because GlobalizationPreferences has DualApiPartitionAttribute.Here is a C++/WinRT example of using GlobalizationPreferences.Languages:

#pragma once
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.System.UserProfile.h>
#include <iostream>
#pragma comment(lib, "windowsapp")

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::System::UserProfile;

int main()
{
    winrt::init_apartment();

    for (const auto& lang : GlobalizationPreferences::Languages()) {
        std::wcout << lang.c_str() << std::endl;
    }
}

还有一个无法迁移到C ++ 17的WRL示例:

And a WRL example for those who cannot migrate to C++ 17:

#include <roapi.h>
#include <wrl.h>
#include <Windows.System.UserProfile.h>
#include <iostream>
#include <stdint.h>
#pragma comment(lib, "runtimeobject.lib")

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::System::UserProfile;

int main()
{
    RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
    if (FAILED(initialize)) {
        std::cerr << "RoInitialize failed" << std::endl;
        return 1;
    }

    ComPtr<IGlobalizationPreferencesStatics> gps;
    HRESULT hr = RoGetActivationFactory(
        HStringReference(
            RuntimeClass_Windows_System_UserProfile_GlobalizationPreferences)
            .Get(),
        IID_PPV_ARGS(&gps));
    if (FAILED(hr)) {
        std::cerr << "RoGetActivationFactory failed" << std::endl;
        return 1;
    }

    ComPtr<IVectorView<HSTRING>> langs;
    hr = gps->get_Languages(&langs);
    if (FAILED(hr)) {
        std::cerr << "Could not get Languages" << std::endl;
        return 1;
    }

    uint32_t size;
    hr = langs->get_Size(&size);
    if (FAILED(hr)) {
        std::cerr << "Could not get Size" << std::endl;
        return 1;
    }
    for (uint32_t i = 0; i < size; ++i) {
        HString lang;
        hr = langs->GetAt(i, lang.GetAddressOf());
        if (FAILED(hr)) {
            std::cerr << "Could not get Languages[" << i << "]" << std::endl;
            continue;
        }
        std::wcout << lang.GetRawBuffer(nullptr) << std::endl;
    }
}

这篇关于GetUserPreferredUILanguages()永远不会返回两种以上的语言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 04:40