diff --git a/Explorer++/Explorer++/MainFontSetter.cpp b/Explorer++/Explorer++/MainFontSetter.cpp index 96ee08f780..31ed4872fc 100644 --- a/Explorer++/Explorer++/MainFontSetter.cpp +++ b/Explorer++/Explorer++/MainFontSetter.cpp @@ -15,8 +15,7 @@ MainFontSetter::MainFontSetter(HWND hwnd, const Config *config, m_config(config), m_defaultFontAt96Dpi(defaultFontAt96Dpi) { - SubclassWindowForDpiChanges(); - MaybeSubclassSpecificWindowClasses(); + InstallWindowSubclass(); UpdateFont(); m_connections.push_back( @@ -25,7 +24,7 @@ MainFontSetter::MainFontSetter(HWND hwnd, const Config *config, MainFontSetter::~MainFontSetter() = default; -void MainFontSetter::SubclassWindowForDpiChanges() +void MainFontSetter::InstallWindowSubclass() { m_windowSubclasses.push_back( std::make_unique(m_hwnd, std::bind_front(&MainFontSetter::WndProc, this))); @@ -38,66 +37,38 @@ LRESULT MainFontSetter::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara case WM_DPICHANGED_AFTERPARENT: OnDpiChanged(); break; - } - - return DefSubclassProc(hwnd, msg, wParam, lParam); -} -void MainFontSetter::OnDpiChanged() -{ - if (!m_config->mainFont.get() && !m_defaultFontAt96Dpi) - { - // In this situation, the control is using its default font, so there's no need to perform - // any manual updates. - return; - } - - UpdateFont(); -} - -void MainFontSetter::MaybeSubclassSpecificWindowClasses() -{ - WCHAR className[256]; - auto res = GetClassName(m_hwnd, className, static_cast(std::size(className))); - - if (res == 0) - { - DCHECK(false); - return; - } - - if (lstrcmp(className, TOOLTIPS_CLASS) == 0) - { - m_windowSubclasses.push_back(std::make_unique(m_hwnd, - std::bind_front(&MainFontSetter::TooltipWndProc, this))); - } -} - -LRESULT MainFontSetter::TooltipWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { case WM_THEMECHANGED: { auto res = DefSubclassProc(hwnd, msg, wParam, lParam); - // The tooltip control will internally reset its font when it receives a WM_THEMECHANGED - // message. Therefore, if a custom font is currently active within the application, that - // font will need to be restored. If a custom font isn't active, the control can use the - // default font it sets. + // Some controls, including toolbars and tooltips, reset their font when the theme is + // changed. Restore the active custom font after the control has processed the message. if (m_font) { SendMessage(m_hwnd, WM_SETFONT, reinterpret_cast(m_font.get()), true); + fontUpdatedSignal.m_signal(); } return res; } - break; } return DefSubclassProc(hwnd, msg, wParam, lParam); } +void MainFontSetter::OnDpiChanged() +{ + if (!m_config->mainFont.get() && !m_defaultFontAt96Dpi) + { + // In this situation, the control is using its default font, so there's no need to perform + // any manual updates. + return; + } + + UpdateFont(); +} + void MainFontSetter::UpdateFont() { // If a custom font isn't active, the default value (nullptr) will be passed into diff --git a/Explorer++/Explorer++/MainFontSetter.h b/Explorer++/Explorer++/MainFontSetter.h index ec94d1c844..d307809997 100644 --- a/Explorer++/Explorer++/MainFontSetter.h +++ b/Explorer++/Explorer++/MainFontSetter.h @@ -25,11 +25,9 @@ class MainFontSetter SignalWrapper fontUpdatedSignal; private: - void SubclassWindowForDpiChanges(); + void InstallWindowSubclass(); LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void OnDpiChanged(); - void MaybeSubclassSpecificWindowClasses(); - LRESULT TooltipWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void UpdateFont(); HWND m_hwnd; diff --git a/Explorer++/TestExplorer++/BookmarksToolbarTest.cpp b/Explorer++/TestExplorer++/BookmarksToolbarTest.cpp index 458cab02ab..3230213d92 100644 --- a/Explorer++/TestExplorer++/BookmarksToolbarTest.cpp +++ b/Explorer++/TestExplorer++/BookmarksToolbarTest.cpp @@ -7,12 +7,15 @@ #include "Bookmarks/UI/Views/BookmarksToolbarView.h" #include "BrowserTestBase.h" #include "BrowserWindowFake.h" +#include "CustomFont.h" +#include "FontHelper.h" #include "IconFetcherFake.h" #include "PidlTestHelper.h" #include "ShellBrowser/ShellBrowser.h" #include "ShellBrowser/ShellNavigationController.h" #include #include +#include class BookmarksToolbarTest : public BrowserTestBase { @@ -138,3 +141,54 @@ TEST_F(BookmarksToolbarTest, OpenBookmarkOnClick) EXPECT_EQ(currentEntry->GetPidl(), CreateSimplePidlForTest(bookmark->GetLocation())); } } + +class BookmarksToolbarFontTest : public BrowserTestBase +{ +protected: + BookmarksToolbarFontTest() : + m_browser(AddBrowser()), + m_bookmarksToolbarView(CreateBookmarksToolbarView(m_browser->GetHWND(), &m_config)) + { + m_bookmarkTree.AddBookmarkItem(m_bookmarkTree.GetBookmarksToolbarFolder(), + std::make_unique(std::nullopt, L"Bookmark", L"c:\\path")); + + m_bookmarksToolbar = + BookmarksToolbar::Create(m_bookmarksToolbarView, m_browser, &m_acceleratorManager, + &m_resourceLoader, &m_iconFetcher, &m_bookmarkTree, &m_platformContext); + } + + static BookmarksToolbarView *CreateBookmarksToolbarView(HWND parent, Config *config) + { + config->mainFont = CustomFont(L"Segoe UI", 15); + return BookmarksToolbarView::Create(parent, config); + } + + IconFetcherFake m_iconFetcher; + BrowserWindowFake *const m_browser; + BookmarksToolbarView *const m_bookmarksToolbarView; + BookmarksToolbar *m_bookmarksToolbar = nullptr; +}; + +TEST_F(BookmarksToolbarFontTest, UsesConfiguredFontOnStartup) +{ + // The theme is applied after the main window and all its child controls have been created. + ASSERT_TRUE(SUCCEEDED(SetWindowTheme(m_bookmarksToolbarView->GetHWND(), L"", nullptr))); + + auto toolbarFont = reinterpret_cast( + SendMessage(m_bookmarksToolbarView->GetHWND(), WM_GETFONT, 0, 0)); + ASSERT_NE(toolbarFont, nullptr); + + LOGFONT toolbarLogFont; + ASSERT_EQ(GetObject(toolbarFont, sizeof(toolbarLogFont), &toolbarLogFont), + static_cast(sizeof(toolbarLogFont))); + + auto expectedFont = CreateFontFromNameAndSize(L"Segoe UI", 15, + m_bookmarksToolbarView->GetHWND()); + ASSERT_NE(expectedFont, nullptr); + + LOGFONT expectedLogFont; + ASSERT_EQ(GetObject(expectedFont.get(), sizeof(expectedLogFont), &expectedLogFont), + static_cast(sizeof(expectedLogFont))); + + EXPECT_EQ(toolbarLogFont, expectedLogFont); +}