From 45c42b49a0a901e42054a4ce0f1552c222f8b81e Mon Sep 17 00:00:00 2001 From: FF69B4 <78807100@qq.com> Date: Tue, 17 Feb 2026 22:19:37 +0800 Subject: [PATCH 1/4] Add TeachingTipHelper --- WinUI3Package/TeachingTipHelper.cpp | 143 ++++++++++++++++++++ WinUI3Package/TeachingTipHelper.h | 33 +++++ WinUI3Package/TeachingTipHelper.idl | 12 ++ WinUI3Package/WinUI3Package.vcxproj | 11 ++ WinUI3Package/WinUI3Package.vcxproj.filters | 4 +- 5 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 WinUI3Package/TeachingTipHelper.cpp create mode 100644 WinUI3Package/TeachingTipHelper.h create mode 100644 WinUI3Package/TeachingTipHelper.idl diff --git a/WinUI3Package/TeachingTipHelper.cpp b/WinUI3Package/TeachingTipHelper.cpp new file mode 100644 index 0000000..af08691 --- /dev/null +++ b/WinUI3Package/TeachingTipHelper.cpp @@ -0,0 +1,143 @@ +#include "pch.h" +#include "TeachingTipHelper.h" +#if __has_include("TeachingTipHelper.g.cpp") +#include "TeachingTipHelper.g.cpp" +#endif + +#include "VisualTreeHelper.hpp" +#include "AcrylicVisual.h" +#include "AcrylicVisualWithBoundedCornerRadius.h" + +namespace winrt::WinUI3Package::implementation +{ + winrt::Microsoft::UI::Xaml::DependencyProperty TeachingTipHelper::s_acrylicWorkaroundProperty = + winrt::Microsoft::UI::Xaml::DependencyProperty::RegisterAttached( + L"AcrylicWorkaround", + winrt::xaml_typename(), + winrt::xaml_typename(), + winrt::Microsoft::UI::Xaml::PropertyMetadata{ + nullptr, + &TeachingTipHelper::acrylicWorkaroundChanged + } + ); + + winrt::Microsoft::UI::Xaml::DependencyProperty TeachingTipHelper::AcrylicWorkaroundProperty() + { + return s_acrylicWorkaroundProperty; + } + + bool TeachingTipHelper::GetAcrylicWorkaround(winrt::Microsoft::UI::Xaml::Controls::TeachingTip const& teachingTip) + { + return winrt::unbox_value(teachingTip.GetValue(AcrylicWorkaroundProperty())); + } + + void TeachingTipHelper::SetAcrylicWorkaround( + winrt::Microsoft::UI::Xaml::Controls::TeachingTip const& teachingTip, + bool value + ) + { + teachingTip.SetValue(AcrylicWorkaroundProperty(), winrt::box_value(value)); + } + + + void ApplyAcrylicToGrid(winrt::Microsoft::UI::Xaml::Controls::Grid const& grid) + { + // 1. 保存原始 Background 和 CornerRadius + auto originalBackground = grid.Background(); + auto cornerRadius = grid.CornerRadius(); + + grid.Background(winrt::Microsoft::UI::Xaml::Media::SolidColorBrush( + winrt::Windows::UI::Colors::Transparent())); + + AcrylicVisualWithBoundedCornerRadius acrylicLayer{ grid }; + winrt::Microsoft::UI::Xaml::Controls::Grid::SetRow(acrylicLayer, 0); + winrt::Microsoft::UI::Xaml::Controls::Grid::SetRowSpan(acrylicLayer, 3); + + grid.Children().InsertAt(0, acrylicLayer); + } + + void PatchLightDismissSetters(winrt::Microsoft::UI::Xaml::Controls::Border const& contentRootGrid) + { + auto transparentBrush = winrt::Microsoft::UI::Xaml::Media::SolidColorBrush( + winrt::Windows::UI::Colors::Transparent()); + + auto groups = winrt::Microsoft::UI::Xaml::VisualStateManager::GetVisualStateGroups(contentRootGrid); + if (!groups) return; + + for (auto const& group : groups) + { + if (group.Name() != L"LightDismissStates") continue; + + for (auto const& state : group.States()) + { + if (state.Name() != L"LightDismiss") continue; + + for (auto const& setterBase : state.Setters()) + { + auto setter = setterBase.try_as(); + if (!setter) continue; + + auto target = setter.Target(); + if (!target) continue; + + auto PathName = target.Path().Path(); + + if (PathName == L"Background" || PathName == L"Fill") + { + setter.Value(transparentBrush); + } + } + } + } + } + + + void TeachingTipHelper::acrylicWorkaroundChanged( + winrt::Microsoft::UI::Xaml::DependencyObject const& object, + winrt::Microsoft::UI::Xaml::DependencyPropertyChangedEventArgs const& arg) + { + auto const acrylicWorkaround = winrt::unbox_value(arg.NewValue()); + + if (!acrylicWorkaround) return; + + auto teachingTip = object.as(); + + teachingTip.Background(winrt::Microsoft::UI::Xaml::Media::SolidColorBrush{ + winrt::Windows::UI::Colors::Transparent() + }); + + + auto teachingTipLoadedRevoker = std::make_shared(); + *teachingTipLoadedRevoker = teachingTip.Loaded(winrt::auto_revoke, [teachingTipLoadedRevoker](winrt::Windows::Foundation::IInspectable const& teachingTipRef, auto&&) + { + teachingTipLoadedRevoker->revoke(); + + auto teachingTip = teachingTipRef.as(); + + auto border = VisualTreeHelper::FindVisualChildByName( + teachingTip, + L"Container" + ); + + if (!border) return; + + PatchLightDismissSetters(border); + + auto borderLoadedRevoker = std::make_shared(); + *borderLoadedRevoker = border.Loaded(winrt::auto_revoke, [comboBoxRef = winrt::make_weak(teachingTip), borderLoadedRevoker](winrt::Windows::Foundation::IInspectable const& borderRef, auto&&) + { + borderLoadedRevoker->revoke(); + + auto border = borderRef.as(); + + auto contentRootGrid = border.FindName(L"ContentRootGrid").try_as(); + + if (contentRootGrid) ApplyAcrylicToGrid(contentRootGrid); + + }); + + + }); + + } +} diff --git a/WinUI3Package/TeachingTipHelper.h b/WinUI3Package/TeachingTipHelper.h new file mode 100644 index 0000000..2226c7f --- /dev/null +++ b/WinUI3Package/TeachingTipHelper.h @@ -0,0 +1,33 @@ +#pragma once + +#include "TeachingTipHelper.g.h" + +namespace winrt::WinUI3Package::implementation +{ + struct TeachingTipHelper : TeachingTipHelperT + { + TeachingTipHelper() = default; + + static winrt::Microsoft::UI::Xaml::DependencyProperty AcrylicWorkaroundProperty(); + static bool GetAcrylicWorkaround(winrt::Microsoft::UI::Xaml::Controls::TeachingTip const& teachingTip); + static void SetAcrylicWorkaround( + winrt::Microsoft::UI::Xaml::Controls::TeachingTip const& teachingTip, + bool value + ); + + private: + static winrt::Microsoft::UI::Xaml::DependencyProperty s_acrylicWorkaroundProperty; + + static void acrylicWorkaroundChanged( + winrt::Microsoft::UI::Xaml::DependencyObject const& object, + winrt::Microsoft::UI::Xaml::DependencyPropertyChangedEventArgs const& arg + ); + }; +} + +namespace winrt::WinUI3Package::factory_implementation +{ + struct TeachingTipHelper : TeachingTipHelperT + { + }; +} diff --git a/WinUI3Package/TeachingTipHelper.idl b/WinUI3Package/TeachingTipHelper.idl new file mode 100644 index 0000000..0101335 --- /dev/null +++ b/WinUI3Package/TeachingTipHelper.idl @@ -0,0 +1,12 @@ +namespace WinUI3Package +{ + [bindable] + [default_interface] + runtimeclass TeachingTipHelper + { + TeachingTipHelper(); + static Microsoft.UI.Xaml.DependencyProperty AcrylicWorkaroundProperty{get; }; + static Boolean GetAcrylicWorkaround(Microsoft.UI.Xaml.Controls.TeachingTip teachingTip); + static void SetAcrylicWorkaround(Microsoft.UI.Xaml.Controls.TeachingTip teachingTip, Boolean value); + } +} diff --git a/WinUI3Package/WinUI3Package.vcxproj b/WinUI3Package/WinUI3Package.vcxproj index 6083d07..54d635f 100644 --- a/WinUI3Package/WinUI3Package.vcxproj +++ b/WinUI3Package/WinUI3Package.vcxproj @@ -552,6 +552,10 @@ + + TeachingTipHelper.idl + Code + TenMicaBackdrop.idl Code @@ -886,6 +890,10 @@ + + TeachingTipHelper.idl + Code + TenMicaBackdrop.idl Code @@ -1140,6 +1148,9 @@ Designer + + Designer + Designer diff --git a/WinUI3Package/WinUI3Package.vcxproj.filters b/WinUI3Package/WinUI3Package.vcxproj.filters index 40018a1..6d32062 100644 --- a/WinUI3Package/WinUI3Package.vcxproj.filters +++ b/WinUI3Package/WinUI3Package.vcxproj.filters @@ -608,10 +608,10 @@ Backdrop - + Controls\Helpers - + Controls\Helpers From dbc402ddb449620f18730db4c6cbf3c403ec036b Mon Sep 17 00:00:00 2001 From: FF69B4 <78807100@qq.com> Date: Tue, 17 Feb 2026 22:20:50 +0800 Subject: [PATCH 2/4] Update TeachingTipHelper.cpp --- WinUI3Package/TeachingTipHelper.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/WinUI3Package/TeachingTipHelper.cpp b/WinUI3Package/TeachingTipHelper.cpp index af08691..2f50f6b 100644 --- a/WinUI3Package/TeachingTipHelper.cpp +++ b/WinUI3Package/TeachingTipHelper.cpp @@ -42,7 +42,6 @@ namespace winrt::WinUI3Package::implementation void ApplyAcrylicToGrid(winrt::Microsoft::UI::Xaml::Controls::Grid const& grid) { - // 1. 保存原始 Background 和 CornerRadius auto originalBackground = grid.Background(); auto cornerRadius = grid.CornerRadius(); From 4fb5e18a95ed0b474275b151f12d36b167ca395d Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 19 Feb 2026 01:41:52 +0800 Subject: [PATCH 3/4] Add a TeachingTipHelper example page --- WinUI3Example/MainWindow.xaml.cpp | 1 + WinUI3Example/MainWindow.xaml.h | 4 ++- WinUI3Example/TeachingTipHelperPage.idl | 8 ++++++ WinUI3Example/TeachingTipHelperPage.xaml | 28 ++++++++++++++++++++ WinUI3Example/TeachingTipHelperPage.xaml.cpp | 19 +++++++++++++ WinUI3Example/TeachingTipHelperPage.xaml.h | 19 +++++++++++++ WinUI3Example/WinUI3Example.vcxproj | 15 +++++++++++ WinUI3Example/WinUI3Example.vcxproj.filters | 3 +++ 8 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 WinUI3Example/TeachingTipHelperPage.idl create mode 100644 WinUI3Example/TeachingTipHelperPage.xaml create mode 100644 WinUI3Example/TeachingTipHelperPage.xaml.cpp create mode 100644 WinUI3Example/TeachingTipHelperPage.xaml.h diff --git a/WinUI3Example/MainWindow.xaml.cpp b/WinUI3Example/MainWindow.xaml.cpp index d9b0f58..9396c74 100644 --- a/WinUI3Example/MainWindow.xaml.cpp +++ b/WinUI3Example/MainWindow.xaml.cpp @@ -55,6 +55,7 @@ #include "RevealFocusPage.xaml.h" #include "TenMicaPage.xaml.h" #include "SliderHelperPage.xaml.h" +#include "TeachingTipHelperPage.xaml.h" // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. diff --git a/WinUI3Example/MainWindow.xaml.h b/WinUI3Example/MainWindow.xaml.h index bb88404..d92dc82 100644 --- a/WinUI3Example/MainWindow.xaml.h +++ b/WinUI3Example/MainWindow.xaml.h @@ -58,6 +58,7 @@ namespace winrt::WinUI3Example::implementation struct RevealFocusPage; struct TenMicaPage; struct SliderHelperPage; + struct TeachingTipHelperPage; struct MainWindow : MainWindowT { @@ -131,7 +132,8 @@ namespace winrt::WinUI3Example::implementation boost::hana::make_pair(L"NavigationViewHelper", boost::hana::type_c), boost::hana::make_pair(L"RevealFocus", boost::hana::type_c), boost::hana::make_pair(L"TenMica", boost::hana::type_c), - boost::hana::make_pair(L"SliderHelper", boost::hana::type_c) + boost::hana::make_pair(L"SliderHelper", boost::hana::type_c), + boost::hana::make_pair(L"TeachingTipHelper", boost::hana::type_c) ); static constexpr void iteratePageType(std::wstring_view key, auto&& onFound) diff --git a/WinUI3Example/TeachingTipHelperPage.idl b/WinUI3Example/TeachingTipHelperPage.idl new file mode 100644 index 0000000..13c9b95 --- /dev/null +++ b/WinUI3Example/TeachingTipHelperPage.idl @@ -0,0 +1,8 @@ +namespace WinUI3Example +{ + [default_interface] + runtimeclass TeachingTipHelperPage : Microsoft.UI.Xaml.Controls.Page + { + TeachingTipHelperPage(); + } +} diff --git a/WinUI3Example/TeachingTipHelperPage.xaml b/WinUI3Example/TeachingTipHelperPage.xaml new file mode 100644 index 0000000..d7fd8f5 --- /dev/null +++ b/WinUI3Example/TeachingTipHelperPage.xaml @@ -0,0 +1,28 @@ + + + + +