microsoft-ui-xaml icon indicating copy to clipboard operation
microsoft-ui-xaml copied to clipboard

Handle Multi Lang Strings in XAML base C++ WinRT Unpackaged application

Open mdnchauhan opened this issue 10 months ago • 6 comments

Describe the bug

My application is - WinUI3 XAML based C++WinRT, Unpackaged App for handling MultiLanguages strings, I am implementing .resw files. [Microsoft.Windows.CppWinRT version 2.0.240405.15]

There are two resw files

Englishtext Strings/en-US/Resources.resw

Polish text Strings\pl-PL\Resources.resw

Problem :- I get the text of the Lang which is set as Preferred Lang in settings. If it is a Polish machine and user has changed the "Preferred Languages" to English instead of Polish. (Settings -> Time&Language -> Lang & Region -> Preferred Languages ), then it picks English string NOT the Polish one.

Is there any way to set the Language as per our need in c++ WinRT app in such a way that my app will pick Polish text only... irrespective of what is set as Default Preferred lang.

I tried to set DefaultLang by using winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride but it throws exception message "The process has no package identity".

Thanks, MChauhan

Steps to reproduce the bug

Expected behavior

No response

Screenshots

No response

NuGet package version

None

Windows version

No response

Additional context

No response

mdnchauhan avatar Feb 28 '25 08:02 mdnchauhan

  1. for Changing Language in Packaged/UnPackaged, you should use Microsoft::Globalization::ApplicationLanguages (or mybe Microsoft.Windows.**) and not Windows::Globalization::ApplicationLanguages
  2. You can receive a text in the desired language without changing the language. The codes are C#, but converting them to C++ is definitely easy.
var resourceManager = new ResourceManager();
var resourceContext = resourceManager.CreateResourceContext();
resourceContext.QualifierValues["Language"] = "fa-IR";

var candidate = resourceManager.MainResourceMap.TryGetValue($"Resources/{key}", resourceContext);
var value = candidate != null ? candidate.ValueAsString : key;

when you are working with WinUI, always make sure you are using Microsoft.* namespaces and not Windows.*

ghost1372 avatar Feb 28 '25 13:02 ghost1372

There are two things to remember here, there isn't a "Polish" version or an "English" version of Windows. There are versions of Windows with an English language pack and a Polish language pack installed. Even single language versions of Windows Home can have the language pack changed if you know what you are doing. Secondly, the language that Windows is set to display is the user's preferred setting. Having an application just outright ignore that isn't a nice thing. You really should have an in app setting if you want to do this, but be sure that you default to the user's preference.

I normally have two language packs installed on my system. I completely expect any application to show my preferred display language by default, always.

DarranRowe avatar Feb 28 '25 15:02 DarranRowe

  1. for Changing Language in Packaged/UnPackaged, you should use Microsoft::Globalization::ApplicationLanguages (or mybe Microsoft.Windows.**) and not Windows::Globalization::ApplicationLanguages
  2. You can receive a text in the desired language without changing the language. The codes are C#, but converting them to C++ is definitely easy.

var resourceManager = new ResourceManager(); var resourceContext = resourceManager.CreateResourceContext(); resourceContext.QualifierValues["Language"] = "fa-IR";

var candidate = resourceManager.MainResourceMap.TryGetValue($"Resources/{key}", resourceContext); var value = candidate != null ? candidate.ValueAsString : key; when you are working with WinUI, always make sure you are using Microsoft.* namespaces and not Windows.*

Hi, Thanks for the explanation.

My application is C++ WinRT based WinUI3 app. I don't see "Globalization" under Microsoft::Windows::Globalization. But can access winrt::Windows::Globalization. The reason might be that Microsoft prefix indicates that this namespace is rooted in MS WinRT APIs used in UWP app. Whereas winrt prefix indicates that this namespace is specifically tailored for use with modern C++ (C++17 and later).

I can change the default Lang setting in same way you did in your shared c# code. But that does not solve my concern. By doing so I need to Set the text for each control in c++ code.

I want to do something like shared in This Video(C#).

Thanks.

mdnchauhan avatar Mar 05 '25 09:03 mdnchauhan

I don't see "Globalization" under Microsoft::Windows::Globalization. But can access winrt::Windows::Globalization.

Did you include the appropriate header? Are you using the Windows App SDK 1.6, because Microsoft.Windows.Globalization.ApplicationLanguages is documented.

As a convention, we normally refer to these by the WinRT namespace name, but when you see Microsoft.Windows.Globalization, you should automatically convert this to Microsoft::Windows::Globalization for C++. C++/WinRT then also adds on winrt as the projection namespace normally, but this can actually be configured.

DarranRowe avatar Mar 05 '25 16:03 DarranRowe

Yes I am using WindowsAppSDK 1.6.250108002.

Like I said the problem seems to be with ApplicationLanguages::PrimaryLanguageOverride property that does not work for Unpackaged WinUI3 XAML based C++WinRT.

I found the same issue mentioned in other few threads also. #18419 and #4523 These threads mentioned that there was issue with this property in Unpackaged app. It seems that this is resolved for C# but not for C++WinRT.

Thanks

mdnchauhan avatar Mar 10 '25 11:03 mdnchauhan

C++/WinRT then also adds on winrt as the projection namespace normally, but this can actually be configured.

This can't be configured. cppwinrt always adds winrt to the namespace.

You should be looking for winrt::Microsoft::Windows::Globalization::ApplicationLanguages

Make sure to add #include <winrt/Microsoft.Windows.Globalization.h> somewhere. Probably in your PCH.

sylveon avatar Mar 12 '25 07:03 sylveon