代码之家  ›  专栏  ›  技术社区  ›  Frank Osterfeld

GetUserPreferredUILanguages()从不返回两种以上的语言

  •  4
  • Frank Osterfeld  · 技术社区  · 6 年前

    我正在尝试从C++/Qt应用程序中检索用户首选语言的完整列表,如“Region&用户首选项中的“语言”页:

    Preferred languages

    为此,我尝试使用WinAPI函数 GetUserPreferredUILanguages()

    我还看了 User Interface Language Management ,但无济于事。例如,GetSystemPreferredUILanguages()只返回“en-US”。 GetUILanguageFallbackList() 返回[“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"
    

    这不是应该使用的函数,还是我误解了Windows10的语言配置?如何获得首选语言的完整列表?我懂了 UWP API

    0 回复  |  直到 6 年前
        1
  •  5
  •   emk    4 年前

    GlobalizationPreferences.Languages 可以从非托管C++中使用,因为 GlobalizationPreferences DualApiPartitionAttribute . 下面是一个使用 GlobalizationPreferences.语言 :

    #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;
        }
    }
    

    #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;
        }
    }