Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 17 additions & 46 deletions Explorer++/Explorer++/MainFontSetter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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<WindowSubclass>(m_hwnd, std::bind_front(&MainFontSetter::WndProc, this)));
Expand All @@ -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<int>(std::size(className)));

if (res == 0)
{
DCHECK(false);
return;
}

if (lstrcmp(className, TOOLTIPS_CLASS) == 0)
{
m_windowSubclasses.push_back(std::make_unique<WindowSubclass>(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<WPARAM>(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
Expand Down
4 changes: 1 addition & 3 deletions Explorer++/Explorer++/MainFontSetter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@ class MainFontSetter
SignalWrapper<MainFontSetter, void()> 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;
Expand Down
54 changes: 54 additions & 0 deletions Explorer++/TestExplorer++/BookmarksToolbarTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <boost/range/combine.hpp>
#include <gtest/gtest.h>
#include <uxtheme.h>

class BookmarksToolbarTest : public BrowserTestBase
{
Expand Down Expand Up @@ -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<BookmarkItem>(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<HFONT>(
SendMessage(m_bookmarksToolbarView->GetHWND(), WM_GETFONT, 0, 0));
ASSERT_NE(toolbarFont, nullptr);

LOGFONT toolbarLogFont;
ASSERT_EQ(GetObject(toolbarFont, sizeof(toolbarLogFont), &toolbarLogFont),
static_cast<int>(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<int>(sizeof(expectedLogFont)));

EXPECT_EQ(toolbarLogFont, expectedLogFont);
}