diff --git a/src/Shared/XamlHelper.cpp b/src/Shared/XamlHelper.cpp index b08f959..a6bf3df 100644 --- a/src/Shared/XamlHelper.cpp +++ b/src/Shared/XamlHelper.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "XamlHelper.h" +#include "Win32Helper.h" #include +#include namespace winrt { using namespace Windows::UI::Xaml; @@ -84,4 +86,47 @@ void XamlHelper::CloseComboBoxPopup(winrt::XamlRoot const& root) { } } +void XamlHelper::UpdateThemeOfXamlPopups(winrt::XamlRoot const& root, winrt::ElementTheme theme) { + for (const auto& popup : winrt::VisualTreeHelper::GetOpenPopupsForXamlRoot(root)) { + winrt::FrameworkElement child = popup.Child().as(); + child.RequestedTheme(theme); + UpdateThemeOfTooltips(child, theme); + } +} + +void XamlHelper::UpdateThemeOfTooltips(winrt::DependencyObject const& root, winrt::ElementTheme theme) { + if (Win32Helper::GetOSVersion().IsWin11()) { + // Win11 中 Tooltip 自动适应主题 + return; + } + + // 遍历 XAML 树 + std::vector elems{ root }; + do { + std::vector temp; + + for (const winrt::DependencyObject& elem : elems) { + const int count = winrt::VisualTreeHelper::GetChildrenCount(elem); + for (int i = 0; i < count; ++i) { + winrt::DependencyObject current = winrt::VisualTreeHelper::GetChild(elem, i); + + if (winrt::IInspectable tooltipContent = winrt::ToolTipService::GetToolTip(current)) { + if (winrt::ToolTip tooltip = tooltipContent.try_as()) { + tooltip.RequestedTheme(theme); + } else { + winrt::ToolTip themedTooltip; + themedTooltip.Content(tooltipContent); + themedTooltip.RequestedTheme(theme); + winrt::ToolTipService::SetToolTip(current, themedTooltip); + } + } + + temp.emplace_back(std::move(current)); + } + } + + elems = std::move(temp); + } while (!elems.empty()); +} + } diff --git a/src/Shared/XamlHelper.h b/src/Shared/XamlHelper.h index aed7e23..5366aef 100644 --- a/src/Shared/XamlHelper.h +++ b/src/Shared/XamlHelper.h @@ -5,7 +5,18 @@ namespace XamlIslandsCpp { struct XamlHelper { static void RepositionXamlPopups(winrt::Windows::UI::Xaml::XamlRoot const& root, bool closeFlyoutPresenter); + static void CloseComboBoxPopup(winrt::Windows::UI::Xaml::XamlRoot const& root); + + static void UpdateThemeOfXamlPopups( + const winrt::Windows::UI::Xaml::XamlRoot& root, + winrt::Windows::UI::Xaml::ElementTheme theme + ); + + static void UpdateThemeOfTooltips( + const winrt::Windows::UI::Xaml::DependencyObject& root, + winrt::Windows::UI::Xaml::ElementTheme theme + ); }; } diff --git a/src/XamlIslandsCpp.App/RootPage.cpp b/src/XamlIslandsCpp.App/RootPage.cpp index 8fd4b8b..6be0fb4 100644 --- a/src/XamlIslandsCpp.App/RootPage.cpp +++ b/src/XamlIslandsCpp.App/RootPage.cpp @@ -5,6 +5,7 @@ #endif #include "Win32Helper.h" #include "CommonSharedConstants.h" +#include "XamlHelper.h" using namespace XamlIslandsCpp; @@ -43,6 +44,12 @@ void RootPage::Theme(int value) { _propertyChangedEvent(*this, PropertyChangedEventArgs(L"Theme")); } +void RootPage::ComboBox_DropDownOpened(IInspectable const&, IInspectable const&) const { + // 修复下拉框不适配主题的问题 + // https://github.com/microsoft/microsoft-ui-xaml/issues/6622 + XamlHelper::UpdateThemeOfXamlPopups(XamlRoot(), ActualTheme()); +} + static Color Win32ColorToWinRTColor(COLORREF color) { return { 255, GetRValue(color), GetGValue(color), GetBValue(color) }; } diff --git a/src/XamlIslandsCpp.App/RootPage.h b/src/XamlIslandsCpp.App/RootPage.h index dcc7f77..e528a78 100644 --- a/src/XamlIslandsCpp.App/RootPage.h +++ b/src/XamlIslandsCpp.App/RootPage.h @@ -24,6 +24,8 @@ struct RootPage : RootPageT { int Theme() const noexcept; void Theme(int value); + void ComboBox_DropDownOpened(IInspectable const&, IInspectable const&) const; + private: void _SetTheme(AppTheme theme); diff --git a/src/XamlIslandsCpp.App/RootPage.xaml b/src/XamlIslandsCpp.App/RootPage.xaml index 1ea677f..1c0e7b5 100644 --- a/src/XamlIslandsCpp.App/RootPage.xaml +++ b/src/XamlIslandsCpp.App/RootPage.xaml @@ -48,6 +48,7 @@ @@ -59,6 +60,7 @@ Acrylic diff --git a/src/XamlIslandsCpp.App/TitleBarControl.cpp b/src/XamlIslandsCpp.App/TitleBarControl.cpp index 37c5d61..b30b68a 100644 --- a/src/XamlIslandsCpp.App/TitleBarControl.cpp +++ b/src/XamlIslandsCpp.App/TitleBarControl.cpp @@ -11,6 +11,7 @@ namespace winrt::XamlIslandsCpp::App::implementation { void TitleBarControl::IsWindowActive(bool value) { VisualStateManager::GoToState(*this, value ? L"Active" : L"NotActive", false); + CaptionButtons().IsWindowActive(value); } } diff --git a/src/XamlIslandsCpp/MainWindow.cpp b/src/XamlIslandsCpp/MainWindow.cpp index 67feb3b..9466d4e 100644 --- a/src/XamlIslandsCpp/MainWindow.cpp +++ b/src/XamlIslandsCpp/MainWindow.cpp @@ -186,10 +186,7 @@ LRESULT MainWindow::_MessageHandler(UINT msg, WPARAM wParam, LPARAM lParam) noex } case WM_ACTIVATE: { - if (_isCustomTitleBarEnabled) { - _content.TitleBar().IsWindowActive(LOWORD(wParam) != WA_INACTIVE); - } - + _content.TitleBar().IsWindowActive(LOWORD(wParam) != WA_INACTIVE); break; } case WM_DESTROY: