From 525929226e86e913f547145ae97e169249eb5cc5 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Fri, 9 Feb 2024 09:38:35 +0100 Subject: [PATCH 01/12] [MRTCore] Add global PrimaryLanguageOverride switch --- .../src/ApplicationLanguages.cpp | 22 ++++++++++++++ .../src/ApplicationLanguages.h | 29 +++++++++++++++++++ ...oft.Windows.ApplicationModel.Resources.idl | 9 +++++- ...Windows.ApplicationModel.Resources.vcxproj | 6 ++-- ...ApplicationModel.Resources.vcxproj.filters | 9 ++++++ .../src/ResourceContext.cpp | 4 +++ 6 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp create mode 100644 dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp new file mode 100644 index 0000000000..57e84bcd56 --- /dev/null +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" +#include "ApplicationLanguages.h" +#include "ApplicationLanguages.g.cpp" + +namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation +{ + hstring ApplicationLanguages::m_language; + + void ApplicationLanguages::PrimaryLanguageOverride(hstring language) + { + m_language = language; + } + + hstring ApplicationLanguages::PrimaryLanguageOverride() + { + return m_language; + } + +} // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h new file mode 100644 index 0000000000..b491cec35b --- /dev/null +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#pragma once +#include "ApplicationLanguages.g.h" + +namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation +{ + +struct ApplicationLanguages +{ + ApplicationLanguages() = delete; + + static void PrimaryLanguageOverride(hstring language); + static hstring PrimaryLanguageOverride(); + +private: + static hstring m_language; +}; + +} // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation + +namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation +{ + struct ApplicationLanguages : ApplicationLanguagesT + { + }; +} +// namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl index 3c78578a64..50ca6b4f6f 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl @@ -113,4 +113,11 @@ namespace Microsoft.Windows.ApplicationModel.Resources static String TargetSize { get; }; static String Theme { get; }; } -} // namespace Microsoft.Windows.ApplicationModel.Resources + + [contract(MrtCoreContract, 1)] + runtimeclass ApplicationLanguages + { + static String PrimaryLanguageOverride; + } + +} // namespace Microsoft.Windows.ApplicationModel. Resources diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj index d03e31913f..bcc67c2622 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj @@ -109,6 +109,7 @@ + @@ -120,6 +121,7 @@ + @@ -140,7 +142,7 @@ - + $(RepoRoot);%(AdditionalIncludeDirectories) @@ -186,4 +188,4 @@ - + \ No newline at end of file diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj.filters b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj.filters index da85707150..2bec9237a6 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj.filters +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj.filters @@ -29,6 +29,9 @@ Source Files + + Source Files + @@ -58,6 +61,9 @@ Header Files + + Header Files + @@ -75,4 +81,7 @@ {54696afe-f42a-494a-bc24-3fd0d4192122} + + + \ No newline at end of file diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp index 88ca9a0b31..b9a80bbcf6 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp @@ -97,6 +97,10 @@ void ResourceContext::Apply() winrt::check_hresult(MrmSetQualifier(m_resourceContext, eachValue.Key().c_str(), eachValue.Value().c_str())); } } + if (!ApplicationLanguages::PrimaryLanguageOverride().empty()) + { + winrt::check_hresult(MrmSetQualifier(m_resourceContext, c_languageQualifierName, ApplicationLanguages::PrimaryLanguageOverride().c_str())); + } } hstring ResourceContext::GetLangugageContext() From 410c575424160aaf93f62de65a6ebf5bc5e57e34 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Thu, 6 Jun 2024 15:10:35 +0200 Subject: [PATCH 02/12] Address PR comment --- .../src/ApplicationLanguages.cpp | 9 ++++---- .../src/ApplicationLanguages.h | 21 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp index 57e84bcd56..6b78e52e5f 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -9,14 +9,13 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { hstring ApplicationLanguages::m_language; - void ApplicationLanguages::PrimaryLanguageOverride(hstring language) - { - m_language = language; - } - hstring ApplicationLanguages::PrimaryLanguageOverride() { return m_language; } + void ApplicationLanguages::PrimaryLanguageOverride(hstring const& language) + { + m_language = language; + } } // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h index b491cec35b..41afc748ee 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h @@ -6,18 +6,16 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { + struct ApplicationLanguages + { + ApplicationLanguages() = delete; -struct ApplicationLanguages -{ - ApplicationLanguages() = delete; - - static void PrimaryLanguageOverride(hstring language); - static hstring PrimaryLanguageOverride(); - -private: - static hstring m_language; -}; + static hstring PrimaryLanguageOverride(); + static void PrimaryLanguageOverride(hstring const& language); + private: + static hstring m_language; + }; } // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation @@ -25,5 +23,4 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implem struct ApplicationLanguages : ApplicationLanguagesT { }; -} -// namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation +} // winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation From 7053cb828f15e0c5fd747283f5be0f6c17ef869f Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Fri, 7 Jun 2024 09:46:58 +0200 Subject: [PATCH 03/12] Bump MrtCoreContract --- .../src/Microsoft.Windows.ApplicationModel.Resources.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl index 50ca6b4f6f..1aa78ff2a5 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl @@ -114,7 +114,7 @@ namespace Microsoft.Windows.ApplicationModel.Resources static String Theme { get; }; } - [contract(MrtCoreContract, 1)] + [contract(MrtCoreContract, 2)] runtimeclass ApplicationLanguages { static String PrimaryLanguageOverride; From 3f8a0d78ec933d471101f4d0766e769cb57fa660 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Fri, 14 Jun 2024 08:39:01 +0200 Subject: [PATCH 04/12] Add Languages and ManifestLanguages properties. Add GetLanguagesForUser method --- .../src/ApplicationLanguages.cpp | 18 ++++++++++++++++++ .../src/ApplicationLanguages.h | 3 +++ ...soft.Windows.ApplicationModel.Resources.idl | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp index 6b78e52e5f..b36e83d0d3 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -5,10 +5,22 @@ #include "ApplicationLanguages.h" #include "ApplicationLanguages.g.cpp" +#include + namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { hstring ApplicationLanguages::m_language; + winrt::Windows::Foundation::Collections::IVectorView ApplicationLanguages::Languages() + { + return winrt::Windows::Globalization::ApplicationLanguages::Languages(); + } + + winrt::Windows::Foundation::Collections::IVectorView ApplicationLanguages::ManifestLanguages() + { + return winrt::Windows::Globalization::ApplicationLanguages::ManifestLanguages(); + } + hstring ApplicationLanguages::PrimaryLanguageOverride() { return m_language; @@ -18,4 +30,10 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { m_language = language; } + + winrt::Windows::Foundation::Collections::IVectorView ApplicationLanguages::GetLanguagesForUser(winrt::Windows::System::User const& user) + { + return winrt::Windows::Globalization::ApplicationLanguages::GetLanguagesForUser(user); + } + } // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h index 41afc748ee..600f94fe7a 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h @@ -10,8 +10,11 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { ApplicationLanguages() = delete; + static winrt::Windows::Foundation::Collections::IVectorView Languages(); + static winrt::Windows::Foundation::Collections::IVectorView ManifestLanguages(); static hstring PrimaryLanguageOverride(); static void PrimaryLanguageOverride(hstring const& language); + static winrt::Windows::Foundation::Collections::IVectorView GetLanguagesForUser(winrt::Windows::System::User const& user); private: static hstring m_language; diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl index 1aa78ff2a5..8d4815c5c8 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl @@ -117,7 +117,11 @@ namespace Microsoft.Windows.ApplicationModel.Resources [contract(MrtCoreContract, 2)] runtimeclass ApplicationLanguages { + static IVectorView Languages { get; }; + static IVectorView ManifestLanguages { get; }; static String PrimaryLanguageOverride; + + static IVectorView GetLanguagesForUser(Windows.System.User user); } } // namespace Microsoft.Windows.ApplicationModel. Resources From e3b424e79598ffe2abb7b977446a76cf15b30539 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Wed, 19 Jun 2024 09:34:35 +0200 Subject: [PATCH 05/12] Remove GetLanguagesForUser Thread safe PrimaryLanguageOverride for un-packaged Use W.G.PrimaryLanguageOverride for packaged --- .../src/ApplicationLanguages.cpp | 23 +++++++++++++------ .../src/ApplicationLanguages.h | 1 - ...oft.Windows.ApplicationModel.Resources.idl | 2 -- ...Windows.ApplicationModel.Resources.vcxproj | 3 +++ .../src/packages.config | 3 ++- .../src/pch.h | 3 +++ 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp index b36e83d0d3..0cb90ebb09 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -7,6 +7,8 @@ #include +#include + namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { hstring ApplicationLanguages::m_language; @@ -23,17 +25,24 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation hstring ApplicationLanguages::PrimaryLanguageOverride() { + static wil::srwlock lock; + + auto criticalSection{ lock.lock_shared() }; return m_language; } void ApplicationLanguages::PrimaryLanguageOverride(hstring const& language) { - m_language = language; - } - - winrt::Windows::Foundation::Collections::IVectorView ApplicationLanguages::GetLanguagesForUser(winrt::Windows::System::User const& user) - { - return winrt::Windows::Globalization::ApplicationLanguages::GetLanguagesForUser(user); + if (AppModel::Identity::IsPackagedProcess()) + { + winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride(language); + } + else + { + static wil::srwlock lock; + + auto criticalSection{ lock.lock_exclusive() }; + m_language = language; + } } - } // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h index 600f94fe7a..7abaf5a698 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h @@ -14,7 +14,6 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation static winrt::Windows::Foundation::Collections::IVectorView ManifestLanguages(); static hstring PrimaryLanguageOverride(); static void PrimaryLanguageOverride(hstring const& language); - static winrt::Windows::Foundation::Collections::IVectorView GetLanguagesForUser(winrt::Windows::System::User const& user); private: static hstring m_language; diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl index 8d4815c5c8..0686dc4744 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl @@ -120,8 +120,6 @@ namespace Microsoft.Windows.ApplicationModel.Resources static IVectorView Languages { get; }; static IVectorView ManifestLanguages { get; }; static String PrimaryLanguageOverride; - - static IVectorView GetLanguagesForUser(Windows.System.User user); } } // namespace Microsoft.Windows.ApplicationModel. Resources diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj index bcc67c2622..1b6e034cbe 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj @@ -90,6 +90,7 @@ _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + $(RepoRoot)\dev\Common;%(AdditionalIncludeDirectories) Console @@ -173,6 +174,7 @@ + @@ -187,5 +189,6 @@ + \ No newline at end of file diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/packages.config b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/packages.config index 9b45da6a85..28bc519cd2 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/packages.config +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/packages.config @@ -4,4 +4,5 @@ - + + \ No newline at end of file diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/pch.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/pch.h index 5aae2ce383..d1d419ea2e 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/pch.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/pch.h @@ -7,6 +7,9 @@ #include #include "..\..\core\src\MRM.h" +#include +#include + struct StringResourceFreer { void operator()(wchar_t* resource) { MrmFreeResource(resource); } From 108def9e89796b0cde7311d653b04362f7d48331 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Wed, 26 Jun 2024 16:48:54 +0200 Subject: [PATCH 06/12] Return empty ManifestLanguages list for unpackaged apps Check if valid language tag is passed to PrimaryLanguageOverride --- .../src/ApplicationLanguages.cpp | 27 ++++++++++++------ .../src/ApplicationLanguages.h | 2 +- .../src/Helper.cpp | 28 +++++++++++++++++++ .../src/Helper.h | 1 + 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp index 0cb90ebb09..8dc98a9133 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -9,6 +9,8 @@ #include +#include "Helper.h" + namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { hstring ApplicationLanguages::m_language; @@ -20,7 +22,14 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation winrt::Windows::Foundation::Collections::IVectorView ApplicationLanguages::ManifestLanguages() { - return winrt::Windows::Globalization::ApplicationLanguages::ManifestLanguages(); + if (AppModel::Identity::IsPackagedProcess()) + { + return winrt::Windows::Globalization::ApplicationLanguages::ManifestLanguages(); + } + else + { + return {}; + } } hstring ApplicationLanguages::PrimaryLanguageOverride() @@ -33,16 +42,18 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation void ApplicationLanguages::PrimaryLanguageOverride(hstring const& language) { + bool isValidLanguageTag = IsWellFormedLanguageTag(language.c_str()); + + THROW_HR_IF_MSG(E_INVALIDARG, isValidLanguageTag, "The parameter is incorrect"); + + static wil::srwlock lock; + + auto criticalSection {lock.lock_exclusive()}; + m_language = language; + if (AppModel::Identity::IsPackagedProcess()) { winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride(language); } - else - { - static wil::srwlock lock; - - auto criticalSection{ lock.lock_exclusive() }; - m_language = language; - } } } // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h index 7abaf5a698..5ed827fb85 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h @@ -25,4 +25,4 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implem struct ApplicationLanguages : ApplicationLanguagesT { }; -} // winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation +} // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index f502592f7c..cac5423560 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -86,3 +86,31 @@ HRESULT GetDefaultPriFile(winrt::hstring& filePath) bool isPackaged = (hr != HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE)); return GetDefaultPriFileForCurentModule(isPackaged, filePath); } + +bool IsWellFormedLanguageTag(const wchar_t* languageTag) +{ + // Implementation taken from Platform.h, without accepting semi-colon, as it must be a single language tag + if (languageTag == nullptr || *languageTag == L'\0') + { + return FALSE; + } + + BOOLEAN ok = TRUE; + PCWSTR test = languageTag; + + while (ok && (*test != L'\0')) + { + // we accept letters, numbers, dash and semi-colon (as list separator) + if (((*test >= L'0') && (*test <= L'9')) || ((*test >= L'a') && (*test <= L'z')) || ((*test >= L'A') && (*test <= L'Z')) || + (*test == L'-')) + { + test++; + } + else + { + ok = FALSE; + } + } + + return ok && ((test - languageTag) >= 2); +} diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h index eb405dd8c7..c9dec2a4ab 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h @@ -4,3 +4,4 @@ #pragma once bool IsResourceNotFound(HRESULT hr); HRESULT GetDefaultPriFile(winrt::hstring& path); +bool IsWellFormedLanguageTag(const wchar_t* languageTag); From a344d8a11b91c4cb89a7f0f8ac43cd59055ae2c5 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Thu, 27 Jun 2024 12:17:51 +0200 Subject: [PATCH 07/12] Move to Microsoft.Windows.Globalization namespace --- BuildAll.ps1 | 1 + build/NuSpecs/AppxManifest.xml | 1 + ...indows.ApplicationModel.Resources.Projection.csproj | 7 ++++--- .../src/ApplicationLanguages.cpp | 8 ++++---- .../src/ApplicationLanguages.h | 10 +++++----- .../src/Helper.cpp | 2 +- .../Microsoft.Windows.ApplicationModel.Resources.idl | 8 +++++++- .../src/ResourceContext.cpp | 4 ++++ 8 files changed, 27 insertions(+), 14 deletions(-) diff --git a/BuildAll.ps1 b/BuildAll.ps1 index 5d99bb1055..23b0fbd30a 100644 --- a/BuildAll.ps1 +++ b/BuildAll.ps1 @@ -332,6 +332,7 @@ Try { Copy-Item -path "BuildOutput\$configurationForMrtAndAnyCPU\$platformToRun\Microsoft.Windows.ApplicationModel.Resources.Projection\Microsoft.Windows.ApplicationModel.Resources.Projection.dll" -destination "$BasePath\lib\net6.0-windows10.0.17763.0" -force Copy-Item -path "BuildOutput\$configurationForMrtAndAnyCPU\$platformToRun\Microsoft.Windows.ApplicationModel.Resources.Projection\Microsoft.Windows.ApplicationModel.Resources.Projection.pdb" -destination "$BasePath\lib\net6.0-windows10.0.17763.0" -force Copy-Item -path "BuildOutput\$configurationForMrtAndAnyCPU\$platformToRun\Microsoft.Windows.ApplicationModel.Resources\Microsoft.Windows.ApplicationModel.Resources.winmd" -destination "$BasePath\lib\uap10.0" -force + Copy-Item -path "BuildOutput\$configurationForMrtAndAnyCPU\$platformToRun\Microsoft.Windows.ApplicationModel.Resources\Microsoft.Windows.Globalization.winmd" -destination "$BasePath\lib\uap10.0" -force } } diff --git a/build/NuSpecs/AppxManifest.xml b/build/NuSpecs/AppxManifest.xml index e08876e201..d715353b56 100644 --- a/build/NuSpecs/AppxManifest.xml +++ b/build/NuSpecs/AppxManifest.xml @@ -22,6 +22,7 @@ + diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/projection/Microsoft.Windows.ApplicationModel.Resources.Projection.csproj b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/projection/Microsoft.Windows.ApplicationModel.Resources.Projection.csproj index 1630e110f5..65a0c7a109 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/projection/Microsoft.Windows.ApplicationModel.Resources.Projection.csproj +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/projection/Microsoft.Windows.ApplicationModel.Resources.Projection.csproj @@ -1,4 +1,4 @@ - + net6.0-windows10.0.17763.0 10.0.17763.0 @@ -21,7 +21,7 @@ - Microsoft.Windows.ApplicationModel.Resources + Microsoft.Windows.Globalization;Microsoft.Windows.ApplicationModel.Resources 10.0.17763.0 MSB3271 @@ -30,10 +30,11 @@ pdbonly true - + + diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp index 8dc98a9133..e8d5885d6f 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -3,7 +3,7 @@ #include "pch.h" #include "ApplicationLanguages.h" -#include "ApplicationLanguages.g.cpp" +#include "Microsoft.Windows.Globalization.ApplicationLanguages.g.cpp" #include @@ -11,7 +11,7 @@ #include "Helper.h" -namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation +namespace winrt::Microsoft::Windows::Globalization::implementation { hstring ApplicationLanguages::m_language; @@ -44,7 +44,7 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { bool isValidLanguageTag = IsWellFormedLanguageTag(language.c_str()); - THROW_HR_IF_MSG(E_INVALIDARG, isValidLanguageTag, "The parameter is incorrect"); + THROW_HR_IF_MSG(E_INVALIDARG, !isValidLanguageTag, "The parameter is incorrect"); static wil::srwlock lock; @@ -56,4 +56,4 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride(language); } } -} // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation +} // namespace winrt::Microsoft::Windows::Globalization::implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h index 5ed827fb85..b31a3fc751 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h @@ -2,9 +2,9 @@ // Licensed under the MIT License. #pragma once -#include "ApplicationLanguages.g.h" +#include "Microsoft.Windows.Globalization.ApplicationLanguages.g.h" -namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation +namespace winrt::Microsoft::Windows::Globalization::implementation { struct ApplicationLanguages { @@ -18,11 +18,11 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation private: static hstring m_language; }; -} // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation +} // namespace winrt::Microsoft::Windows::Globalization::implementation -namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation +namespace winrt::Microsoft::Windows::Globalization::factory_implementation { struct ApplicationLanguages : ApplicationLanguagesT { }; -} // namespace winrt::Microsoft::Windows::ApplicationModel::Resources::factory_implementation +} // namespace winrt::Microsoft::Windows::Globalization::factory_implementation diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index cac5423560..71dc9e82c2 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -100,7 +100,7 @@ bool IsWellFormedLanguageTag(const wchar_t* languageTag) while (ok && (*test != L'\0')) { - // we accept letters, numbers, dash and semi-colon (as list separator) + // we accept letters, numbers and dash if (((*test >= L'0') && (*test <= L'9')) || ((*test >= L'a') && (*test <= L'z')) || ((*test >= L'A') && (*test <= L'Z')) || (*test == L'-')) { diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl index 0686dc4744..ce3debc026 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.idl @@ -113,6 +113,12 @@ namespace Microsoft.Windows.ApplicationModel.Resources static String TargetSize { get; }; static String Theme { get; }; } +} // namespace Microsoft.Windows.ApplicationModel.Resources + +namespace Microsoft.Windows.Globalization +{ + [contractversion(1)] + apicontract MrtCoreContract{}; [contract(MrtCoreContract, 2)] runtimeclass ApplicationLanguages @@ -122,4 +128,4 @@ namespace Microsoft.Windows.ApplicationModel.Resources static String PrimaryLanguageOverride; } -} // namespace Microsoft.Windows.ApplicationModel. Resources +} // namespace Microsoft.Windows.Globalization diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp index b9a80bbcf6..73a7e2188b 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp @@ -8,6 +8,10 @@ const wchar_t c_languageQualifierName[] = L"Language"; +#include "ApplicationLanguages.h" + +using namespace winrt::Microsoft::Windows::Globalization; + namespace winrt::Microsoft::Windows::ApplicationModel::Resources::implementation { void ResourceContext::InitializeQualifierNames() From b710e14c2a48ff223f96c70227db1998df1fafcb Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Thu, 27 Jun 2024 19:43:50 +0200 Subject: [PATCH 08/12] static lock --- .../src/ApplicationLanguages.cpp | 10 ++++------ .../src/ApplicationLanguages.h | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp index e8d5885d6f..0c703c8104 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -14,6 +14,8 @@ namespace winrt::Microsoft::Windows::Globalization::implementation { hstring ApplicationLanguages::m_language; + wil::srwlock ApplicationLanguages::m_lock; + winrt::Windows::Foundation::Collections::IVectorView ApplicationLanguages::Languages() { @@ -34,9 +36,7 @@ namespace winrt::Microsoft::Windows::Globalization::implementation hstring ApplicationLanguages::PrimaryLanguageOverride() { - static wil::srwlock lock; - - auto criticalSection{ lock.lock_shared() }; + auto criticalSection{ m_lock.lock_shared() }; return m_language; } @@ -46,9 +46,7 @@ namespace winrt::Microsoft::Windows::Globalization::implementation THROW_HR_IF_MSG(E_INVALIDARG, !isValidLanguageTag, "The parameter is incorrect"); - static wil::srwlock lock; - - auto criticalSection {lock.lock_exclusive()}; + auto criticalSection {m_lock.lock_exclusive()}; m_language = language; if (AppModel::Identity::IsPackagedProcess()) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h index b31a3fc751..a7ebba9b0c 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.h @@ -17,6 +17,7 @@ namespace winrt::Microsoft::Windows::Globalization::implementation private: static hstring m_language; + static wil::srwlock m_lock; }; } // namespace winrt::Microsoft::Windows::Globalization::implementation From 544211dc305eaa2f52f1994230fd18b6371c56c4 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Thu, 27 Jun 2024 23:04:58 +0200 Subject: [PATCH 09/12] Use bcp47mrm IsWellFormedTag --- .../src/ApplicationLanguages.cpp | 2 +- .../src/Helper.cpp | 72 ++++++++++++++----- .../src/Helper.h | 2 +- 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp index 0c703c8104..62ea919a56 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -42,7 +42,7 @@ namespace winrt::Microsoft::Windows::Globalization::implementation void ApplicationLanguages::PrimaryLanguageOverride(hstring const& language) { - bool isValidLanguageTag = IsWellFormedLanguageTag(language.c_str()); + bool isValidLanguageTag = _DefIsWellFormedTag(language.c_str()); THROW_HR_IF_MSG(E_INVALIDARG, !isValidLanguageTag, "The parameter is incorrect"); diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index 71dc9e82c2..5c93af2883 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -87,30 +87,66 @@ HRESULT GetDefaultPriFile(winrt::hstring& filePath) return GetDefaultPriFileForCurentModule(isPackaged, filePath); } -bool IsWellFormedLanguageTag(const wchar_t* languageTag) +// Taken from Platform.h/.cpp +typedef bool(WINAPI* IsWellFormedTagFunc)(PCWSTR); +HMODULE g_bcp47 = (HMODULE)(-1); + +HMODULE LoadBcp47ModuleFrom(_In_ PCWSTR moduleName) { - // Implementation taken from Platform.h, without accepting semi-colon, as it must be a single language tag - if (languageTag == nullptr || *languageTag == L'\0') + HMODULE module = LoadLibraryExW(moduleName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (module != nullptr) { - return FALSE; + // All BCP47 APIs we are interested are always exported from the same dll together. So we just pick anyone for probe. + IsWellFormedTagFunc func = (IsWellFormedTagFunc)(GetProcAddress(module, "IsWellFormedTag")); + if (func != nullptr) + { + return module; + } + FreeLibrary(module); } - BOOLEAN ok = TRUE; - PCWSTR test = languageTag; + return nullptr; +} - while (ok && (*test != L'\0')) +HMODULE LoadBcp47Module() +{ + HMODULE module = LoadBcp47ModuleFrom(L"bcp47mrm.dll"); + if (module == nullptr) { - // we accept letters, numbers and dash - if (((*test >= L'0') && (*test <= L'9')) || ((*test >= L'a') && (*test <= L'z')) || ((*test >= L'A') && (*test <= L'Z')) || - (*test == L'-')) - { - test++; - } - else - { - ok = FALSE; - } + // In downlevel OS, the API is exposed by bcp47langs.dll. + module = LoadBcp47ModuleFrom(L"bcp47langs.dll"); + } + + return module; +} + +void InitializeBcp47Module() +{ + HMODULE comparand = (HMODULE)(-1); + if (InterlockedCompareExchangePointer(reinterpret_cast(&g_bcp47), comparand, comparand) == comparand) + { + HMODULE module = LoadBcp47Module(); + InterlockedExchangePointer(reinterpret_cast(&g_bcp47), module); + } +} + +BOOLEAN _DefIsWellFormedTag(_In_ PCWSTR tag) +{ + // Before new SDK is released, we need to use LoadLibrary/GetProcAddress + InitializeBcp47Module(); + + if (g_bcp47 == nullptr) + { + // Didn't find an implementation. Just return TRUE. + return TRUE; + } + + IsWellFormedTagFunc func = (IsWellFormedTagFunc)(GetProcAddress(g_bcp47, "IsWellFormedTag")); + if (func != nullptr) + { + return func(tag); } - return ok && ((test - languageTag) >= 2); + // Should not reach here. + return TRUE; } diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h index c9dec2a4ab..b0f5a69ca4 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h @@ -4,4 +4,4 @@ #pragma once bool IsResourceNotFound(HRESULT hr); HRESULT GetDefaultPriFile(winrt::hstring& path); -bool IsWellFormedLanguageTag(const wchar_t* languageTag); +BOOLEAN _DefIsWellFormedTag(_In_ PCWSTR tag); From acbcd27fe1994488b00d29878112409ef7c6d645 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Fri, 28 Jun 2024 10:26:33 +0200 Subject: [PATCH 10/12] Use bcp47mrm header --- .../src/ApplicationLanguages.cpp | 5 +- .../src/Helper.cpp | 64 ------------------- .../src/Helper.h | 1 - ...Windows.ApplicationModel.Resources.vcxproj | 4 +- 4 files changed, 4 insertions(+), 70 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp index 62ea919a56..892a3ab55a 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ApplicationLanguages.cpp @@ -5,12 +5,11 @@ #include "ApplicationLanguages.h" #include "Microsoft.Windows.Globalization.ApplicationLanguages.g.cpp" +#include #include #include -#include "Helper.h" - namespace winrt::Microsoft::Windows::Globalization::implementation { hstring ApplicationLanguages::m_language; @@ -42,7 +41,7 @@ namespace winrt::Microsoft::Windows::Globalization::implementation void ApplicationLanguages::PrimaryLanguageOverride(hstring const& language) { - bool isValidLanguageTag = _DefIsWellFormedTag(language.c_str()); + bool isValidLanguageTag = IsWellFormedTag(language.c_str()); THROW_HR_IF_MSG(E_INVALIDARG, !isValidLanguageTag, "The parameter is incorrect"); diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp index 5c93af2883..f502592f7c 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp @@ -86,67 +86,3 @@ HRESULT GetDefaultPriFile(winrt::hstring& filePath) bool isPackaged = (hr != HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE)); return GetDefaultPriFileForCurentModule(isPackaged, filePath); } - -// Taken from Platform.h/.cpp -typedef bool(WINAPI* IsWellFormedTagFunc)(PCWSTR); -HMODULE g_bcp47 = (HMODULE)(-1); - -HMODULE LoadBcp47ModuleFrom(_In_ PCWSTR moduleName) -{ - HMODULE module = LoadLibraryExW(moduleName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); - if (module != nullptr) - { - // All BCP47 APIs we are interested are always exported from the same dll together. So we just pick anyone for probe. - IsWellFormedTagFunc func = (IsWellFormedTagFunc)(GetProcAddress(module, "IsWellFormedTag")); - if (func != nullptr) - { - return module; - } - FreeLibrary(module); - } - - return nullptr; -} - -HMODULE LoadBcp47Module() -{ - HMODULE module = LoadBcp47ModuleFrom(L"bcp47mrm.dll"); - if (module == nullptr) - { - // In downlevel OS, the API is exposed by bcp47langs.dll. - module = LoadBcp47ModuleFrom(L"bcp47langs.dll"); - } - - return module; -} - -void InitializeBcp47Module() -{ - HMODULE comparand = (HMODULE)(-1); - if (InterlockedCompareExchangePointer(reinterpret_cast(&g_bcp47), comparand, comparand) == comparand) - { - HMODULE module = LoadBcp47Module(); - InterlockedExchangePointer(reinterpret_cast(&g_bcp47), module); - } -} - -BOOLEAN _DefIsWellFormedTag(_In_ PCWSTR tag) -{ - // Before new SDK is released, we need to use LoadLibrary/GetProcAddress - InitializeBcp47Module(); - - if (g_bcp47 == nullptr) - { - // Didn't find an implementation. Just return TRUE. - return TRUE; - } - - IsWellFormedTagFunc func = (IsWellFormedTagFunc)(GetProcAddress(g_bcp47, "IsWellFormedTag")); - if (func != nullptr) - { - return func(tag); - } - - // Should not reach here. - return TRUE; -} diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h index b0f5a69ca4..eb405dd8c7 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.h @@ -4,4 +4,3 @@ #pragma once bool IsResourceNotFound(HRESULT hr); HRESULT GetDefaultPriFile(winrt::hstring& path); -BOOLEAN _DefIsWellFormedTag(_In_ PCWSTR tag); diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj index 1b6e034cbe..354014afcd 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Microsoft.Windows.ApplicationModel.Resources.vcxproj @@ -17,7 +17,7 @@ en-US 14.0 Win32Proj - 10.0.18362.0 + 10.0.20348.0 10.0.17134.0 @@ -96,7 +96,7 @@ Console false Microsoft.Windows.ApplicationModel.Resources.def - $(OutDir)..\mrm\MRM.lib;onecoreuap.lib;%(AdditionalDependencies) + $(OutDir)..\mrm\MRM.lib;onecoreuap.lib;bcp47mrm.lib;%(AdditionalDependencies) From b273263ee10950ae42c264d0e5d50b45b20fdaeb Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Fri, 28 Jun 2024 13:30:57 +0200 Subject: [PATCH 11/12] Do not override explicit Language set --- .../src/ResourceContext.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp index 73a7e2188b..3190389828 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp @@ -56,8 +56,15 @@ void ResourceContext::InitializeQualifierValueMap() // Override the default behavior if (m_qualifierNames[i] == c_languageQualifierName) { + auto primaryLanguageOverride = ApplicationLanguages::PrimaryLanguageOverride(); auto languages = GetLangugageContext(); - if (!languages.empty()) + + if (!primaryLanguageOverride.empty()) + { + m_qualifierValueMap.Insert(m_qualifierNames[i], primaryLanguageOverride); + continue; + } + else if (!languages.empty()) { m_qualifierValueMap.Insert(m_qualifierNames[i], languages); continue; @@ -101,10 +108,6 @@ void ResourceContext::Apply() winrt::check_hresult(MrmSetQualifier(m_resourceContext, eachValue.Key().c_str(), eachValue.Value().c_str())); } } - if (!ApplicationLanguages::PrimaryLanguageOverride().empty()) - { - winrt::check_hresult(MrmSetQualifier(m_resourceContext, c_languageQualifierName, ApplicationLanguages::PrimaryLanguageOverride().c_str())); - } } hstring ResourceContext::GetLangugageContext() From 2d1c89247056aeb291919e292c8f95b73abe77f3 Mon Sep 17 00:00:00 2001 From: Stefan Markovic Date: Fri, 28 Jun 2024 16:24:50 +0200 Subject: [PATCH 12/12] Revert "Do not override explicit Language set" This reverts commit b273263ee10950ae42c264d0e5d50b45b20fdaeb. --- .../src/ResourceContext.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp index 3190389828..73a7e2188b 100644 --- a/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp +++ b/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/ResourceContext.cpp @@ -56,15 +56,8 @@ void ResourceContext::InitializeQualifierValueMap() // Override the default behavior if (m_qualifierNames[i] == c_languageQualifierName) { - auto primaryLanguageOverride = ApplicationLanguages::PrimaryLanguageOverride(); auto languages = GetLangugageContext(); - - if (!primaryLanguageOverride.empty()) - { - m_qualifierValueMap.Insert(m_qualifierNames[i], primaryLanguageOverride); - continue; - } - else if (!languages.empty()) + if (!languages.empty()) { m_qualifierValueMap.Insert(m_qualifierNames[i], languages); continue; @@ -108,6 +101,10 @@ void ResourceContext::Apply() winrt::check_hresult(MrmSetQualifier(m_resourceContext, eachValue.Key().c_str(), eachValue.Value().c_str())); } } + if (!ApplicationLanguages::PrimaryLanguageOverride().empty()) + { + winrt::check_hresult(MrmSetQualifier(m_resourceContext, c_languageQualifierName, ApplicationLanguages::PrimaryLanguageOverride().c_str())); + } } hstring ResourceContext::GetLangugageContext()