Fix confusion with LOGFONT{A,W} parameters to MSW GetTheme[Sys]Font().
Change the signature of GetThemeFont() and GetThemeSysFont() methods of wxUxThemeEngine to take an artificial wxUxThemeFont::Ptr type instead of LOGFONT which allows the broken code to compile correctly and even work in Unicode builds but crashed in ANSI ones under Windows Vista/7 as these functions expect a LOGFONTW and not LOGFONTA even in non-Unicode build under these systems. This generalizes the previous fix/workaround for the same problem in wxStaticBox so remove it now and use wxUxThemeFont both there and in wxMenuItem to avoid crashes when using owner-drawn menus in ANSI build. Closes #12364. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65955 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -17,6 +17,74 @@
|
||||
#include "wx/msw/private.h" // we use GetHwndOf()
|
||||
#include "wx/msw/uxthemep.h"
|
||||
|
||||
// Amazingly, GetThemeFont() and GetThemeSysFont() functions use LOGFONTA under
|
||||
// XP but LOGFONTW (even in non-Unicode build) under later versions of Windows.
|
||||
// If we declare them as taking LOGFONT below, the code would be able to
|
||||
// silently pass LOGFONTA to them in ANSI build and would crash at run-time
|
||||
// under Windows Vista/7 because of a buffer overrun (LOGFONTA being smaller
|
||||
// than LOGFONTW expected by these functions). If we we declare them as taking
|
||||
// LOGFONTW, the code wouldn't work correctly under XP. So we use a special
|
||||
// wxUxThemeFont class to encapsulate this and intentionally change the LOGFONT
|
||||
// output parameters of the theme functions to take it instead.
|
||||
|
||||
class wxUxThemeFont
|
||||
{
|
||||
public:
|
||||
// Trivial default ctor.
|
||||
wxUxThemeFont() { }
|
||||
|
||||
// Just some unique type.
|
||||
struct Ptr { };
|
||||
|
||||
#if wxUSE_UNICODE
|
||||
// In Unicode build we always use LOGFONT anyhow so this class is
|
||||
// completely trivial.
|
||||
Ptr *GetPtr() { return reinterpret_cast<Ptr *>(&m_lfW); }
|
||||
const LOGFONTW& GetLOGFONT() { return m_lfW; }
|
||||
#else // !wxUSE_UNICODE
|
||||
// Return either LOGFONTA or LOGFONTW pointer as required by the current
|
||||
// Windows version.
|
||||
Ptr *GetPtr()
|
||||
{
|
||||
return UseLOGFONTW() ? reinterpret_cast<Ptr *>(&m_lfW)
|
||||
: reinterpret_cast<Ptr *>(&m_lfA);
|
||||
}
|
||||
|
||||
// This method returns LOGFONT (i.e. LOGFONTA in ANSI build and LOGFONTW in
|
||||
// Unicode one) which can be used with other, normal, Windows or wx
|
||||
// functions. Internally it may need to transform LOGFONTW to LOGFONTA.
|
||||
const LOGFONTA& GetLOGFONT()
|
||||
{
|
||||
if ( UseLOGFONTW() )
|
||||
{
|
||||
// Most of the fields are the same in LOGFONTA and LOGFONTW so just
|
||||
// copy everything by default.
|
||||
memcpy(&m_lfA, &m_lfW, sizeof(m_lfA));
|
||||
|
||||
// But the face name must be converted from Unicode.
|
||||
WideCharToMultiByte(CP_ACP, 0, m_lfW.lfFaceName, -1,
|
||||
m_lfA.lfFaceName, sizeof(m_lfA.lfFaceName),
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
return m_lfA;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool UseLOGFONTW()
|
||||
{
|
||||
return wxGetWinVersion() >= wxWinVersion_Vista;
|
||||
}
|
||||
|
||||
LOGFONTA m_lfA;
|
||||
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
|
||||
|
||||
private:
|
||||
LOGFONTW m_lfW;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxUxThemeFont);
|
||||
};
|
||||
|
||||
typedef HTHEME (__stdcall *PFNWXUOPENTHEMEDATA)(HWND, const wchar_t *);
|
||||
typedef HRESULT (__stdcall *PFNWXUCLOSETHEMEDATA)(HTHEME);
|
||||
typedef HRESULT (__stdcall *PFNWXUDRAWTHEMEBACKGROUND)(HTHEME, HDC, int, int, const RECT *, const RECT *);
|
||||
@@ -39,7 +107,7 @@ typedef HRESULT (__stdcall *PFNWXUGETTHEMEBOOL)(HTHEME, int, int, int, BOOL *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMEINT)(HTHEME, int, int, int, int *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMEENUMVALUE)(HTHEME, int, int, int, int *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMEPOSITION)(HTHEME, int, int, int, POINT *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMEFONT)(HTHEME, HDC, int, int, int, LOGFONT *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMEFONT)(HTHEME, HDC, int, int, int, wxUxThemeFont::Ptr *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMERECT)(HTHEME, int, int, int, RECT *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMEMARGINS)(HTHEME, HDC, int, int, int, RECT *, MARGINS *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMEINTLIST)(HTHEME, int, int, int, INTLIST*);
|
||||
@@ -50,7 +118,7 @@ typedef COLORREF(__stdcall *PFNWXUGETTHEMESYSCOLOR)(HTHEME, int);
|
||||
typedef HBRUSH (__stdcall *PFNWXUGETTHEMESYSCOLORBRUSH)(HTHEME, int);
|
||||
typedef BOOL (__stdcall *PFNWXUGETTHEMESYSBOOL)(HTHEME, int);
|
||||
typedef int (__stdcall *PFNWXUGETTHEMESYSSIZE)(HTHEME, int);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMESYSFONT)(HTHEME, int, LOGFONT *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMESYSFONT)(HTHEME, int, wxUxThemeFont::Ptr *);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMESYSSTRING)(HTHEME, int, wchar_t *, int);
|
||||
typedef HRESULT (__stdcall *PFNWXUGETTHEMESYSINT)(HTHEME, int, int *);
|
||||
typedef BOOL (__stdcall *PFNWXUISTHEMEACTIVE)();
|
||||
|
Reference in New Issue
Block a user