From b24d7e3ae44d09b3cfed04ec68d41294d4c7962f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 29 Dec 2018 02:11:20 +0100 Subject: [PATCH 1/8] Add a simple wxSetWindowFont() helper This function is a just a very thin wrapper for WM_SETFONT, but it's still better to have it rather than write casts to WPARAM and MAKELPARAM() in several different places. Note that this removes the assert for font validity from wxWindow::SetFont() which really doesn't make much sense (and if we wanted to have it, it would be better to have it for all ports in wxWindowBase instead) and was never triggered since more than 20 years of its existence. --- include/wx/msw/private.h | 6 ++++++ include/wx/msw/subwin.h | 5 +---- src/msw/listctrl.cpp | 3 +-- src/msw/renderer.cpp | 3 ++- src/msw/spinctrl.cpp | 3 +-- src/msw/window.cpp | 6 +----- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index e04c44db50..457ecb757d 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -965,6 +965,12 @@ WXDLLIMPEXP_CORE void wxFillLogFont(LOGFONT *logFont, const wxFont *font); WXDLLIMPEXP_CORE wxFont wxCreateFontFromLogFont(const LOGFONT *logFont); WXDLLIMPEXP_CORE wxFontEncoding wxGetFontEncFromCharSet(int charset); +inline void wxSetWindowFont(HWND hwnd, const wxFont& font) +{ + ::SendMessage(hwnd, WM_SETFONT, + (WPARAM)GetHfontOf(font), MAKELPARAM(TRUE, 0)); +} + WXDLLIMPEXP_CORE void wxSliderEvent(WXHWND control, WXWORD wParam, WXWORD pos); WXDLLIMPEXP_CORE void wxScrollBarEvent(WXHWND hbar, WXWORD wParam, WXWORD pos); diff --git a/include/wx/msw/subwin.h b/include/wx/msw/subwin.h index a0178147e7..038bf303f0 100644 --- a/include/wx/msw/subwin.h +++ b/include/wx/msw/subwin.h @@ -113,14 +113,11 @@ public: // set font for all windows void SetFont(const wxFont& font) { - HFONT hfont = GetHfontOf(font); - wxCHECK_RET( hfont, wxT("invalid font") ); - for ( size_t n = 0; n < m_count; n++ ) { if ( m_hwnds[n] ) { - ::SendMessage(m_hwnds[n], WM_SETFONT, (WPARAM)hfont, 0); + wxSetWindowFont(m_hwnds[n], font); // otherwise the window might not be redrawn correctly ::InvalidateRect(m_hwnds[n], NULL, FALSE /* don't erase bg */); diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index fc27322efc..af08c83b2d 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -620,8 +620,7 @@ bool wxListCtrl::SetHeaderAttr(const wxItemAttr& attr) // We need to tell the header about its new font to let it compute // its new height. - ::SendMessage(hwndHdr, WM_SETFONT, - (WPARAM)GetHfontOf(font), MAKELPARAM(TRUE, 0)); + wxSetWindowFont(hwndHdr, font); } // Refreshing the listview makes it notice the change in height of its diff --git a/src/msw/renderer.cpp b/src/msw/renderer.cpp index b7bd070f5e..b353eec254 100644 --- a/src/msw/renderer.cpp +++ b/src/msw/renderer.cpp @@ -552,7 +552,8 @@ int wxRendererMSW::GetHeaderButtonHeight(wxWindow * win) font = win->GetFont(); if ( !font.IsOk() ) wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); - ::SendMessage(hwndHeader, WM_SETFONT, (WPARAM)GetHfontOf(font), 0); + + wxSetWindowFont(hwndHeader, font); // initialize the struct filled with the values by Header_Layout() RECT parentRect = { 0, 0, 100, 100 }; diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index 222c787bc9..6c794fb47a 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -564,8 +564,7 @@ bool wxSpinCtrl::SetFont(const wxFont& font) return false; } - WXHANDLE hFont = GetFont().GetResourceHandle(); - (void)::SendMessage(GetBuddyHwnd(), WM_SETFONT, (WPARAM)hFont, TRUE); + wxSetWindowFont(GetBuddyHwnd(), GetFont()); return true; } diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 0a380c0e8b..5f8ef7791d 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -827,11 +827,7 @@ bool wxWindowMSW::SetFont(const wxFont& font) // just been reset and in this case we need to change the font used by // the native window to the default for this class, i.e. exactly what // GetFont() returns - WXHANDLE hFont = GetFont().GetResourceHandle(); - - wxASSERT_MSG( hFont, wxT("should have valid font") ); - - ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); + wxSetWindowFont(hWnd, GetFont()); } return true; From b62563b907f2d7a3dfd2267825e39a53556cf002 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 30 Dec 2018 00:57:35 +0100 Subject: [PATCH 2/8] Remove redundant Free() from wxFont::SetFractionalPointSize() Free() is already called from wxFontRefData::SetFractionalPointSize(), so there is no need to call it from wxFont too and doing this makes this method gratuitously inconsistent with all the other setters. No real changes. --- src/msw/font.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/msw/font.cpp b/src/msw/font.cpp index 2a74f6d1b2..cc4d52bdfb 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -855,7 +855,6 @@ void wxFont::SetFractionalPointSize(float pointSize) { AllocExclusive(); - M_FONTDATA->Free(); M_FONTDATA->SetFractionalPointSize(pointSize); } From 90186f77404da63ab6a90fc38da219f4769a77ff Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 30 Dec 2018 01:06:19 +0100 Subject: [PATCH 3/8] Refactor handling point size in wxNativeFontInfo No real changes yet, this commit just prepares for adding support for per-monitor DPI by reorganizing some code. --- include/wx/fontutil.h | 6 +++- src/msw/font.cpp | 70 +++++++++++++++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/include/wx/fontutil.h b/include/wx/fontutil.h index 35bd9508a6..f7ba39237e 100644 --- a/include/wx/fontutil.h +++ b/include/wx/fontutil.h @@ -118,7 +118,11 @@ public: // set the XFLD void SetXFontName(const wxString& xFontName); #elif defined(__WXMSW__) - wxNativeFontInfo(const LOGFONT& lf_) : lf(lf_), pointSize(0.0f) { } + wxNativeFontInfo(const LOGFONT& lf_); + + // MSW-specific: get the height value in pixels using LOGFONT convention + // (i.e. negative) corresponding to the given size in points and DPI. + int GetLogFontHeightAtPPI(int ppi) const; LOGFONT lf; diff --git a/src/msw/font.cpp b/src/msw/font.cpp index cc4d52bdfb..aa18cc8bd4 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -152,6 +152,16 @@ public: return m_hFont != 0; } + int GetLogFontHeight() const + { + return m_nativeFontInfo.lf.lfHeight; + } + + int GetLogFontHeightAtPPI(int ppi) const + { + return m_nativeFontInfo.GetLogFontHeightAtPPI(ppi); + } + // ... and setters: notice that all of them invalidate the currently // allocated HFONT, if any, so that the next call to GetHFONT() recreates a // new one @@ -223,6 +233,13 @@ public: m_nativeFontInfo.SetEncoding(encoding); } + void SetLogFontHeight(int height) + { + Free(); + + m_nativeFontInfo.lf.lfHeight = height; + } + const wxNativeFontInfo& GetNativeFontInfo() const { // we need to create the font now to get the corresponding LOGFONT if @@ -385,6 +402,15 @@ void wxFontRefData::Free() // wxNativeFontInfo // ---------------------------------------------------------------------------- +wxNativeFontInfo::wxNativeFontInfo(const LOGFONT& lf_) + : lf(lf_) +{ + // Determine the size in points using the primary screen DPI as we don't + // have anything else here. + const float ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); + pointSize = 72.0f * abs(lf.lfHeight) / ppi; +} + void wxNativeFontInfo::Init() { wxZeroMemory(lf); @@ -402,14 +428,7 @@ void wxNativeFontInfo::Init() float wxNativeFontInfo::GetFractionalPointSize() const { - if ( pointSize != 0.0f ) - return pointSize; - - // FIXME: using the screen here results in incorrect font size calculation - // for printing! - const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); - - return (72.0*abs(lf.lfHeight)) / (double) ppInch; + return pointSize; } wxSize wxNativeFontInfo::GetPixelSize() const @@ -490,17 +509,31 @@ wxFontEncoding wxNativeFontInfo::GetEncoding() const return wxGetFontEncFromCharSet(lf.lfCharSet); } -void wxNativeFontInfo::SetFractionalPointSize(float pointsize) +int wxNativeFontInfo::GetLogFontHeightAtPPI(int ppi) const { - // Store it to be able to return it from GetFractionalPointSize() later - // exactly. - pointSize = pointsize; + return -wxRound(pointSize * ppi / 72.0); +} - // FIXME: using the screen here results in incorrect font size calculation - // for printing! - const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); +void wxNativeFontInfo::SetFractionalPointSize(float pointSizeNew) +{ + if ( pointSize == 0.0f ) + { + // Do this before calling GetLogFontHeightAtPPI() below. + pointSize = pointSizeNew; - lf.lfHeight = -wxRound(pointsize*((double)ppInch)/72.0); + // We don't have the correct DPI to use here, so use that of the + // primary screen. + const int ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); + lf.lfHeight = GetLogFontHeightAtPPI(ppi); + } + else // Changing the size of a valid font. + { + // Scale the font using the ratio of sizes, to ensure that we use the + // same DPI as before. + lf.lfHeight = -wxRound(abs(lf.lfHeight) * pointSizeNew / pointSize); + + pointSize = pointSizeNew; + } } void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize) @@ -516,6 +549,11 @@ void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize) // versions by passing a negative value explicitly itself. lf.lfHeight = -abs(pixelSize.GetHeight()); lf.lfWidth = pixelSize.GetWidth(); + + // We don't have the right DPI to use here neither, but we need to update + // the point size too, so fall back to the default. + const float ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); + pointSize = 72.0f * pixelSize.GetHeight() / ppi; } void wxNativeFontInfo::SetStyle(wxFontStyle style) From 72a225924dbd590a674f30ca93d4efd54447cdb6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 30 Dec 2018 16:25:41 +0100 Subject: [PATCH 4/8] Remove wxCreateFontFromLogFont() and wxFillLogFont() These functions are not really useful as converting between wxFont and LOGFONT can be done trivially by passing via wxNativeFontInfo and, in fact, wxCreateFontFromLogFont() managed to do the conversion wrongly by forgetting to update wxNativeFontInfo::pointSize member when changing wxNativeFontInfo::lf. This fixes one unit test failure after the latest changes, although not yet the other one, see the upcoming commit for this. --- include/wx/msw/private.h | 2 -- src/msw/fontdlg.cpp | 6 ++++-- src/msw/fontutil.cpp | 32 -------------------------------- src/msw/settings.cpp | 2 +- src/msw/textctrl.cpp | 10 +++++----- 5 files changed, 10 insertions(+), 42 deletions(-) diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 457ecb757d..1a426fd9ba 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -961,8 +961,6 @@ extern const wxCursor *wxGetGlobalCursor(); // from msw/cursor.cpp WXDLLIMPEXP_CORE void wxGetCursorPosMSW(POINT* pt); WXDLLIMPEXP_CORE void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font); -WXDLLIMPEXP_CORE void wxFillLogFont(LOGFONT *logFont, const wxFont *font); -WXDLLIMPEXP_CORE wxFont wxCreateFontFromLogFont(const LOGFONT *logFont); WXDLLIMPEXP_CORE wxFontEncoding wxGetFontEncFromCharSet(int charset); inline void wxSetWindowFont(HWND hwnd, const wxFont& font) diff --git a/src/msw/fontdlg.cpp b/src/msw/fontdlg.cpp index 2f7e6bb8d5..8edd4a9f91 100644 --- a/src/msw/fontdlg.cpp +++ b/src/msw/fontdlg.cpp @@ -36,6 +36,8 @@ #include "wx/math.h" #endif +#include "wx/fontutil.h" + #include #include @@ -118,7 +120,7 @@ int wxFontDialog::ShowModal() if ( m_fontData.m_initialFont.IsOk() ) { flags |= CF_INITTOLOGFONTSTRUCT; - wxFillLogFont(&logFont, &m_fontData.m_initialFont); + logFont = m_fontData.m_initialFont.GetNativeFontInfo()->lf; } if ( m_fontData.m_fontColour.IsOk() ) @@ -150,7 +152,7 @@ int wxFontDialog::ShowModal() if ( ChooseFont(&chooseFontStruct) != 0 ) { wxRGBToColour(m_fontData.m_fontColour, chooseFontStruct.rgbColors); - m_fontData.m_chosenFont = wxCreateFontFromLogFont(&logFont); + m_fontData.m_chosenFont = wxFont(wxNativeFontInfo(logFont)); m_fontData.EncodingInfo().facename = logFont.lfFaceName; m_fontData.EncodingInfo().charset = logFont.lfCharSet; diff --git a/src/msw/fontutil.cpp b/src/msw/fontutil.cpp index 3a6489b392..975ba52a02 100644 --- a/src/msw/fontutil.cpp +++ b/src/msw/fontutil.cpp @@ -264,35 +264,3 @@ wxFontEncoding wxGetFontEncFromCharSet(int cs) return fontEncoding; } - -// ---------------------------------------------------------------------------- -// wxFont <-> LOGFONT conversion -// ---------------------------------------------------------------------------- - -void wxFillLogFont(LOGFONT *logFont, const wxFont *font) -{ - wxNativeFontInfo fi; - - // maybe we already have LOGFONT for this font? - const wxNativeFontInfo *pFI = font->GetNativeFontInfo(); - if ( !pFI ) - { - // use wxNativeFontInfo methods to build a LOGFONT for this font - fi.InitFromFont(*font); - - pFI = &fi; - } - - // transfer all the data to LOGFONT - *logFont = pFI->lf; -} - -wxFont wxCreateFontFromLogFont(const LOGFONT *logFont) -{ - wxNativeFontInfo info; - - info.lf = *logFont; - - return wxFont(info); -} - diff --git a/src/msw/settings.cpp b/src/msw/settings.cpp index 3377b5b080..0581dc1a08 100644 --- a/src/msw/settings.cpp +++ b/src/msw/settings.cpp @@ -345,7 +345,7 @@ extern wxFont wxGetCCDefaultFont() 0 ) ) { - return wxFont(wxCreateFontFromLogFont(&lf)); + return wxFont(lf); } else { diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index fed5741b58..2fb9da0c49 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -40,6 +40,7 @@ #include "wx/wxcrtvararg.h" #endif +#include "wx/fontutil.h" #include "wx/scopedptr.h" #include "wx/stack.h" #include "wx/sysopt.h" @@ -2826,14 +2827,13 @@ bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end) CFM_ITALIC | CFM_BOLD | CFM_UNDERLINE | CFM_STRIKEOUT; // fill in data from LOGFONT but recalculate lfHeight because we need - // the real height in twips and not the negative number which - // wxFillLogFont() returns (this is correct in general and works with + // the real height in twips and not the negative number used inside + // LOGFONT returns (this is correct in general and works with // the Windows font mapper, but not here) wxFont font(style.GetFont()); - LOGFONT lf; - wxFillLogFont(&lf, &font); + LOGFONT lf = font.GetNativeFontInfo()->lf; cf.yHeight = 20*font.GetPointSize(); // 1 pt = 20 twips cf.bCharSet = lf.lfCharSet; cf.bPitchAndFamily = lf.lfPitchAndFamily; @@ -3157,7 +3157,7 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) else lf.lfWeight = FW_NORMAL; - wxFont font = wxCreateFontFromLogFont(& lf); + wxFont font(lf); if (font.IsOk()) { style.SetFont(font); From de6d7472a2f5a8d19c5a6135379a731277b5ffce Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 30 Dec 2018 23:53:25 +0100 Subject: [PATCH 5/8] Add static GetLogFontHeightAtPPI() overload taking point size This will be useful elsewhere too and makes SetFractionalPointSize() implementation less fragile as we don't have to be careful about changing pointSize member before setting lf.lfHeight any more. --- include/wx/fontutil.h | 11 ++++++++++- src/msw/font.cpp | 27 +++++---------------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/include/wx/fontutil.h b/include/wx/fontutil.h index f7ba39237e..38f473654e 100644 --- a/include/wx/fontutil.h +++ b/include/wx/fontutil.h @@ -122,7 +122,16 @@ public: // MSW-specific: get the height value in pixels using LOGFONT convention // (i.e. negative) corresponding to the given size in points and DPI. - int GetLogFontHeightAtPPI(int ppi) const; + static int GetLogFontHeightAtPPI(float size, int ppi) + { + return -wxRound(size * ppi / 72.0); + } + + // And the same thing for the size of this font. + int GetLogFontHeightAtPPI(int ppi) const + { + return GetLogFontHeightAtPPI(pointSize, ppi); + } LOGFONT lf; diff --git a/src/msw/font.cpp b/src/msw/font.cpp index aa18cc8bd4..255aafcdae 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -509,31 +509,14 @@ wxFontEncoding wxNativeFontInfo::GetEncoding() const return wxGetFontEncFromCharSet(lf.lfCharSet); } -int wxNativeFontInfo::GetLogFontHeightAtPPI(int ppi) const -{ - return -wxRound(pointSize * ppi / 72.0); -} - void wxNativeFontInfo::SetFractionalPointSize(float pointSizeNew) { - if ( pointSize == 0.0f ) - { - // Do this before calling GetLogFontHeightAtPPI() below. - pointSize = pointSizeNew; + // We don't have the correct DPI to use here, so use that of the + // primary screen. + const int ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); + lf.lfHeight = GetLogFontHeightAtPPI(pointSizeNew, ppi); - // We don't have the correct DPI to use here, so use that of the - // primary screen. - const int ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); - lf.lfHeight = GetLogFontHeightAtPPI(ppi); - } - else // Changing the size of a valid font. - { - // Scale the font using the ratio of sizes, to ensure that we use the - // same DPI as before. - lf.lfHeight = -wxRound(abs(lf.lfHeight) * pointSizeNew / pointSize); - - pointSize = pointSizeNew; - } + pointSize = pointSizeNew; } void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize) From 69586bb03bcd8542b866558ea6db0fd6f275e645 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 30 Dec 2018 23:54:32 +0100 Subject: [PATCH 6/8] Reuse wxNativeFontInfo::GetLogFontHeightAtPPI() Instead of calling ::MulDiv() directly, reuse GetLogFontHeightAtPPI() as it is more readable. --- src/msw/textctrl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 2fb9da0c49..8e20586ee0 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -3124,7 +3124,7 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) // Convert the height from the units of 1/20th of the point in which // CHARFORMAT stores it to pixel-based units used by LOGFONT. const wxCoord ppi = wxClientDC(this).GetPPI().y; - lf.lfHeight = -MulDiv(cf.yHeight/20, ppi, 72); + lf.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI(cf.yHeight/20.0f, ppi); lf.lfWidth = 0; lf.lfCharSet = ANSI_CHARSET; // FIXME: how to get correct charset? lf.lfClipPrecision = 0; From 63c118f186f3e89fc639cdb29f447682a49f7d59 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 31 Dec 2018 00:31:02 +0100 Subject: [PATCH 7/8] Fix DPI used in wxTextCtrl::GetStyle() Using the window DPI resulted in returning a twice bigger size in points than the size really used for the windows on high-DPI monitors as, apparently, RichEdit always uses DPI of 96 internally (tested with both wxTE_RICH and wxTE_RICH2 in 192 DPI under Windows 10.0.16299.785). --- src/msw/textctrl.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 8e20586ee0..4eccc2d9c6 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -3123,8 +3123,9 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) LOGFONT lf; // Convert the height from the units of 1/20th of the point in which // CHARFORMAT stores it to pixel-based units used by LOGFONT. - const wxCoord ppi = wxClientDC(this).GetPPI().y; - lf.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI(cf.yHeight/20.0f, ppi); + // Note that RichEdit seems to always use standard DPI of 96, even when the + // window is a monitor using a higher DPI. + lf.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI(cf.yHeight/20.0f, 96); lf.lfWidth = 0; lf.lfCharSet = ANSI_CHARSET; // FIXME: how to get correct charset? lf.lfClipPrecision = 0; From c7efab6d8a2a18ecea8d7b016915b94697a03165 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 17 Feb 2019 19:49:34 +0100 Subject: [PATCH 8/8] Fix using invalid HFONT in wxGetTextMetrics() If the window has no valid font, GetFont() returns a temporary font. Extend this font lifetime, so the HFONT remains valid till the end of the function. --- src/msw/window.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 5f8ef7791d..58d88811d2 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -7421,7 +7421,12 @@ static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win) #if !wxDIALOG_UNIT_COMPATIBILITY // and select the current font into it - HFONT hfont = GetHfontOf(win->GetFont()); + + // Note that it's important to extend the lifetime of the possibly + // temporary wxFont returned by GetFont() to ensure that its HFONT remains + // valid. + const wxFont& f(win->GetFont()); + HFONT hfont = GetHfontOf(f); if ( hfont ) { hfont = (HFONT)::SelectObject(hdc, hfont);