diff --git a/sakura_core/util/window.cpp b/sakura_core/util/window.cpp index ac9dec87a2..e50dcccc33 100644 --- a/sakura_core/util/window.cpp +++ b/sakura_core/util/window.cpp @@ -287,56 +287,66 @@ int CTextWidthCalc::GetTextHeight() const return tm.tmHeight; } -CFontAutoDeleter::CFontAutoDeleter() - : m_hFontOld(NULL) - , m_hFont(NULL) - , m_hwnd(NULL) -{} +CFontAutoDeleter::CFontAutoDeleter(const Me& other) +{ + operator = (other); +} -CFontAutoDeleter::~CFontAutoDeleter() +CFontAutoDeleter& CFontAutoDeleter::operator = (const Me& other) { - if( m_hFont ){ - DeleteObject( m_hFont ); - m_hFont = NULL; + Clear(); + + if (const auto hFont = other.m_hFont) { + if (LOGFONT lf = {}; + ::GetObject(hFont, sizeof(lf), &lf)) { + m_hFont = ::CreateFontIndirect(&lf); + } } + + return *this; } -void CFontAutoDeleter::SetFont( HFONT hfontOld, HFONT hfont, HWND hwnd ) +CFontAutoDeleter::CFontAutoDeleter(Me&& other) noexcept { - if( m_hFont ){ - ::DeleteObject( m_hFont ); - } - if( m_hFont != hfontOld ){ - m_hFontOld = hfontOld; - } - m_hFont = hfont; - m_hwnd = hwnd; + operator = (std::move(other)); } -/*! ウィンドウのリリース(WM_DESTROY用) -*/ -void CFontAutoDeleter::ReleaseOnDestroy() +CFontAutoDeleter& CFontAutoDeleter::operator = (Me&& other) noexcept { - if( m_hFont ){ - ::DeleteObject( m_hFont ); - m_hFont = NULL; + Clear(); + + m_hFont = other.m_hFont; + other.m_hFont = nullptr; + + return *this; +} + +CFontAutoDeleter::~CFontAutoDeleter() noexcept +{ + Clear(); +} + +void CFontAutoDeleter::Clear() noexcept +{ + if (m_hFont) { + ::DeleteObject(m_hFont); + m_hFont = nullptr; } - m_hFontOld = NULL; } -/*! ウィンドウ生存中のリリース +void CFontAutoDeleter::SetFont( [[maybe_unused]] const HFONT& hFontOld, const HFONT& hFont, [[maybe_unused]] const HWND& hWnd ) +{ + Clear(); + + m_hFont = hFont; +} + +/*! ウィンドウのリリース(WM_DESTROY用) */ -#if 0 -void CFontAutoDeleter::Release() +void CFontAutoDeleter::ReleaseOnDestroy() { - if( m_hwnd && m_hFont ){ - ::SendMessageAny( m_hwnd, WM_SETFONT, (WPARAM)m_hFontOld, FALSE ); - ::DeleteObject( m_hFont ); - m_hFont = NULL; - m_hwnd = NULL; - } + Clear(); } -#endif /*! システムフォントに準拠したフォントを取得 diff --git a/sakura_core/util/window.h b/sakura_core/util/window.h index 181af5a245..146f79cba7 100644 --- a/sakura_core/util/window.h +++ b/sakura_core/util/window.h @@ -160,17 +160,25 @@ class CTextWidthCalc class CFontAutoDeleter { +private: + HFONT m_hFont = nullptr; + + using Me = CFontAutoDeleter; + + void Clear() noexcept; + public: - CFontAutoDeleter(); - ~CFontAutoDeleter(); - void SetFont( HFONT hfontOld, HFONT hfont, HWND hwnd ); - void ReleaseOnDestroy(); - // void Release(); + CFontAutoDeleter() = default; + CFontAutoDeleter(const Me& other); + Me& operator = (const Me& other); + CFontAutoDeleter(Me&& other) noexcept; + Me& operator = (Me&& other) noexcept; + virtual ~CFontAutoDeleter() noexcept; -private: - HFONT m_hFontOld; - HFONT m_hFont; - HWND m_hwnd; + void SetFont( const HFONT& hFontOld, const HFONT& hFont, const HWND& hWnd ); + void ReleaseOnDestroy(); + + [[nodiscard]] HFONT GetFont() const { return m_hFont; } }; class CDCFont diff --git a/tests/unittests/test-window.cpp b/tests/unittests/test-window.cpp new file mode 100644 index 0000000000..5a21a232f6 --- /dev/null +++ b/tests/unittests/test-window.cpp @@ -0,0 +1,70 @@ +/*! @file */ +/* + Copyright (C) 2022, Sakura Editor Organization + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ +#include + +#ifndef NOMINMAX +#define NOMINMAX +#endif /* #ifndef NOMINMAX */ + +#include +#include +#include +#include + +#include + +#include "util/window.h" + +/*! + * @brief CFontAutoDeleterのテスト + */ +TEST( CFontAutoDeleter, test ) +{ + CFontAutoDeleter deleter; + ASSERT_EQ(nullptr, deleter.GetFont()); + + if (const auto hGdiFont = GetStockFont(DEFAULT_GUI_FONT)) { + if (LOGFONT lf = {}; + ::GetObject(hGdiFont, sizeof(lf), &lf)) { + if (const auto hFont = ::CreateFontIndirect(&lf)) { + deleter.SetFont(nullptr, hFont, nullptr); + ASSERT_EQ(hFont, deleter.GetFont()); + } + } + } + + ASSERT_NE(nullptr, deleter.GetFont()); + if (const auto hFont = deleter.GetFont()) { + CFontAutoDeleter other(deleter); + ASSERT_NE(hFont, other.GetFont()); + + other.ReleaseOnDestroy(); + ASSERT_EQ(nullptr, other.GetFont()); + + CFontAutoDeleter another(std::move(deleter)); + ASSERT_EQ(hFont, another.GetFont()); + ASSERT_EQ(nullptr, deleter.GetFont()); + } +} diff --git a/tests/unittests/tests1.vcxproj b/tests/unittests/tests1.vcxproj index 9c08a294fa..f45a2273a3 100644 --- a/tests/unittests/tests1.vcxproj +++ b/tests/unittests/tests1.vcxproj @@ -150,6 +150,7 @@ + diff --git a/tests/unittests/tests1.vcxproj.filters b/tests/unittests/tests1.vcxproj.filters index c5ec04926c..2d8cc79a47 100644 --- a/tests/unittests/tests1.vcxproj.filters +++ b/tests/unittests/tests1.vcxproj.filters @@ -157,6 +157,9 @@ Test Files + + Test Files +