Merge branch 'customize-dark-mode'
Allow customizing appearance in dark mode in wxMSW. See #23275.
This commit is contained in:
commit
0fe6f04bfc
13 changed files with 371 additions and 65 deletions
|
|
@ -3211,6 +3211,7 @@ COND_TOOLKIT_MSW_GUI_HDR = \
|
|||
wx/msw/datectrl.h \
|
||||
wx/msw/calctrl.h \
|
||||
wx/generic/activityindicator.h \
|
||||
wx/msw/darkmode.h \
|
||||
wx/msw/checklst.h \
|
||||
wx/msw/fdrepdlg.h \
|
||||
wx/msw/fontdlg.h \
|
||||
|
|
|
|||
|
|
@ -1954,6 +1954,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
|
|||
wx/msw/datectrl.h
|
||||
wx/msw/calctrl.h
|
||||
wx/generic/activityindicator.h
|
||||
wx/msw/darkmode.h
|
||||
</set>
|
||||
<set var="MSW_RSC" hints="files">
|
||||
<!-- Resources must be installed together with headers: -->
|
||||
|
|
|
|||
|
|
@ -1844,6 +1844,7 @@ set(MSW_HDR
|
|||
wx/msw/datetimectrl.h
|
||||
wx/msw/timectrl.h
|
||||
wx/generic/activityindicator.h
|
||||
wx/msw/darkmode.h
|
||||
)
|
||||
|
||||
set(MSW_RSC
|
||||
|
|
|
|||
|
|
@ -1761,6 +1761,7 @@ MSW_HDR =
|
|||
wx/msw/ctrlsub.h
|
||||
wx/msw/cursor.h
|
||||
wx/msw/custombgwin.h
|
||||
wx/msw/darkmode.h
|
||||
wx/msw/datectrl.h
|
||||
wx/msw/datetimectrl.h
|
||||
wx/msw/dc.h
|
||||
|
|
|
|||
|
|
@ -1518,6 +1518,7 @@
|
|||
<ClInclude Include="..\..\include\wx\generic\creddlgg.h" />
|
||||
<ClInclude Include="..\..\include\wx\filedlgcustomize.h" />
|
||||
<ClInclude Include="..\..\include\wx\compositebookctrl.h" />
|
||||
<ClInclude Include="..\..\include\wx\msw\darkmode.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
|||
|
|
@ -1741,6 +1741,9 @@
|
|||
<ClInclude Include="..\..\include\wx\msw\custombgwin.h">
|
||||
<Filter>MSW Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\wx\msw\darkmode.h">
|
||||
<Filter>MSW Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\wx\msw\datectrl.h">
|
||||
<Filter>MSW Headers</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
class WXDLLIMPEXP_FWD_CORE wxFrame;
|
||||
class WXDLLIMPEXP_FWD_CORE wxWindow;
|
||||
class WXDLLIMPEXP_FWD_CORE wxApp;
|
||||
class WXDLLIMPEXP_FWD_CORE wxDarkModeSettings;
|
||||
class WXDLLIMPEXP_FWD_CORE wxKeyEvent;
|
||||
class WXDLLIMPEXP_FWD_BASE wxLog;
|
||||
|
||||
|
|
@ -38,12 +39,16 @@ public:
|
|||
virtual int GetPrintMode() const { return m_printMode; }
|
||||
|
||||
// MSW-specific function to enable experimental dark mode support.
|
||||
//
|
||||
// If settings are specified, the function takes ownership of the pointer,
|
||||
// otherwise the defaults are used.
|
||||
enum
|
||||
{
|
||||
DarkMode_Auto = 0, // Use dark mode if the system is using it.
|
||||
DarkMode_Always = 1 // Force using dark mode.
|
||||
};
|
||||
bool MSWEnableDarkMode(int flags = 0);
|
||||
bool
|
||||
MSWEnableDarkMode(int flags = 0, wxDarkModeSettings* settings = nullptr);
|
||||
|
||||
// implementation only
|
||||
void OnIdle(wxIdleEvent& event);
|
||||
|
|
|
|||
52
include/wx/msw/darkmode.h
Normal file
52
include/wx/msw/darkmode.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/msw/darkmode.h
|
||||
// Purpose: MSW-specific header with dark mode related declarations.
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2023-02-19
|
||||
// Copyright: (c) 2023 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_MSW_DARKMODE_H_
|
||||
#define _WX_MSW_DARKMODE_H_
|
||||
|
||||
#include "wx/settings.h"
|
||||
|
||||
// Constants used with wxDarkModeSettings::GetMenuColour().
|
||||
enum class wxMenuColour
|
||||
{
|
||||
StandardFg,
|
||||
StandardBg,
|
||||
DisabledFg,
|
||||
HotBg
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDarkModeSettings: allows to customize some of dark mode settings
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_CORE wxDarkModeSettings
|
||||
{
|
||||
public:
|
||||
wxDarkModeSettings() = default;
|
||||
virtual ~wxDarkModeSettings();
|
||||
|
||||
// Get the colour to use for the given system colour when dark mode is on.
|
||||
virtual wxColour GetColour(wxSystemColour index);
|
||||
|
||||
// Menu items don't use any of the standard colours, but are defined by
|
||||
// this function.
|
||||
virtual wxColour GetMenuColour(wxMenuColour which);
|
||||
|
||||
// Get the pen to use for drawing wxStaticBox border in dark mode.
|
||||
//
|
||||
// Returning an invalid pen indicates that the default border drawn by the
|
||||
// system should be used, which doesn't look very well in dark mode but
|
||||
// shouldn't result in any problems worse than cosmetic ones.
|
||||
virtual wxPen GetBorderPen();
|
||||
|
||||
private:
|
||||
wxDECLARE_NO_COPY_CLASS(wxDarkModeSettings);
|
||||
};
|
||||
|
||||
#endif // _WX_MSW_DARKMODE_H_
|
||||
|
|
@ -36,6 +36,9 @@ void AllowForWindow(HWND hwnd,
|
|||
// colour if it isn't.
|
||||
wxColour GetColour(wxSystemColour index);
|
||||
|
||||
// Get the pen to use for drawing the border, see wxDarkModeSettings.
|
||||
wxPen GetBorderPen();
|
||||
|
||||
// Return the background brush to be used by default in dark mode.
|
||||
HBRUSH GetBackgroundBrush();
|
||||
|
||||
|
|
|
|||
|
|
@ -1212,6 +1212,8 @@ public:
|
|||
dark mode for the application, even if the system doesn't use the
|
||||
dark mode by default. Otherwise dark mode is only used if it is the
|
||||
default mode for the applications on the current system.
|
||||
@param settings If specified, allows to customize dark mode appearance.
|
||||
Please see wxDarkModeSettings documentation for more information.
|
||||
|
||||
@return @true if dark mode support was enabled, @false if it couldn't
|
||||
be done, most likely because the system doesn't support dark mode.
|
||||
|
|
@ -1220,7 +1222,8 @@ public:
|
|||
|
||||
@since 3.3.0
|
||||
*/
|
||||
bool MSWEnableDarkMode(int flags = 0);
|
||||
bool
|
||||
MSWEnableDarkMode(int flags = 0, wxDarkModeSettings* settings = nullptr);
|
||||
|
||||
//@}
|
||||
};
|
||||
|
|
|
|||
112
interface/wx/msw/darkmode.h
Normal file
112
interface/wx/msw/darkmode.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/msw/darkmode.h
|
||||
// Purpose: Documentation for MSW-specific dark mode functionality.
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2023-02-19
|
||||
// Copyright: (c) 2023 Vadim Zeitlin
|
||||
// Licence: wxWindows Licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
Constants used with wxDarkModeSettings::GetMenuColour().
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
enum class wxMenuColour
|
||||
{
|
||||
/// Text colour used for the normal items in dark mode.
|
||||
StandardFg,
|
||||
|
||||
/// Standard menu background colour.
|
||||
StandardBg,
|
||||
|
||||
/// Foreground colour for the disabled items.
|
||||
DisabledFg,
|
||||
|
||||
/// Background colour used for the item over which mouse is hovering.
|
||||
HotBg
|
||||
};
|
||||
|
||||
/**
|
||||
Allows to customize some of the settings used in MSW dark mode.
|
||||
|
||||
An object of this class may be passed to wxApp::MSWEnableDarkMode() to
|
||||
customize some aspects of the dark mode when it is used under MSW systems.
|
||||
|
||||
For example, to customize the background colour to use a reddish black
|
||||
instead of normal black used by default, you could do the following:
|
||||
@code
|
||||
class MySettings : public wxDarkModeSettings
|
||||
{
|
||||
public:
|
||||
wxColour GetColour(wxSystemColour index) override
|
||||
{
|
||||
switch ( index )
|
||||
{
|
||||
case wxSYS_COLOUR_ACTIVECAPTION:
|
||||
case wxSYS_COLOUR_APPWORKSPACE:
|
||||
case wxSYS_COLOUR_INFOBK:
|
||||
case wxSYS_COLOUR_LISTBOX:
|
||||
case wxSYS_COLOUR_WINDOW:
|
||||
case wxSYS_COLOUR_BTNFACE:
|
||||
// Default colour used here is 0x202020.
|
||||
return wxColour(0x402020);
|
||||
|
||||
default:
|
||||
return wxDarkModeSettings::GetColour(index);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
wxTheApp->MSWEnableDarkMode(wxApp::DarkMode_Always, new MySettings());
|
||||
@endcode
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
class wxDarkModeSettings
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Default constructor does nothing.
|
||||
*/
|
||||
wxDarkModeSettings() = default;
|
||||
|
||||
/**
|
||||
Get the colour to use for the given system colour when dark mode is on.
|
||||
|
||||
The base class version of this function returns the colours commonly
|
||||
used in dark mode. As the rest of dark mode support, their exact values
|
||||
are not documented and are subject to change in the future Windows or
|
||||
wxWidgets versions.
|
||||
|
||||
@see GetMenuColour()
|
||||
*/
|
||||
virtual wxColour GetColour(wxSystemColour index);
|
||||
|
||||
/**
|
||||
Get the colour to use for the menu bar in the given state.
|
||||
|
||||
Currently the colours used by the menus in the menu bar in dark mode
|
||||
don't correspond to any of wxSystemColour values and this separate
|
||||
function is used for customizing them instead of GetColour().
|
||||
|
||||
Note that the colours returned by this function only affect the top
|
||||
level menus, the colours of the menu items inside them can be
|
||||
customized in the usual way using wxOwnerDrawn::SetTextColour().
|
||||
|
||||
The returned colour must be valid.
|
||||
*/
|
||||
virtual wxColour GetMenuColour(wxMenuColour which);
|
||||
|
||||
/**
|
||||
Get the pen to use for drawing wxStaticBox border in dark mode.
|
||||
|
||||
Returning an invalid pen indicates that the default border drawn by the
|
||||
system should be used, which doesn't look very well in dark mode but
|
||||
shouldn't result in any problems worse than cosmetic ones.
|
||||
|
||||
The base class version returns a grey pen, which looks better than the
|
||||
default white one.
|
||||
*/
|
||||
virtual wxPen GetBorderPen();
|
||||
};
|
||||
|
|
@ -44,11 +44,14 @@
|
|||
#include "wx/dynlib.h"
|
||||
#include "wx/module.h"
|
||||
|
||||
#include "wx/msw/darkmode.h"
|
||||
#include "wx/msw/dc.h"
|
||||
#include "wx/msw/uxtheme.h"
|
||||
|
||||
#include "wx/msw/private/darkmode.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
static const char* TRACE_DARKMODE = "msw-darkmode";
|
||||
|
||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||
|
|
@ -168,10 +171,25 @@ public:
|
|||
virtual bool OnInit() override { return true; }
|
||||
virtual void OnExit() override
|
||||
{
|
||||
ms_settings.reset();
|
||||
|
||||
ms_pfnDwmSetWindowAttribute = (DwmSetWindowAttribute_t)-1;
|
||||
ms_dllDWM.Unload();
|
||||
}
|
||||
|
||||
// Takes ownership of the provided pointer.
|
||||
static void SetSettings(wxDarkModeSettings* settings)
|
||||
{
|
||||
ms_settings.reset(settings);
|
||||
}
|
||||
|
||||
// Returns the currently used settings: may only be called when the dark
|
||||
// mode is on.
|
||||
static wxDarkModeSettings& GetSettings()
|
||||
{
|
||||
return *ms_settings;
|
||||
}
|
||||
|
||||
static DwmSetWindowAttribute_t GetDwmSetWindowAttribute()
|
||||
{
|
||||
if ( ms_pfnDwmSetWindowAttribute == (DwmSetWindowAttribute_t)-1 )
|
||||
|
|
@ -187,12 +205,15 @@ private:
|
|||
static wxDynamicLibrary ms_dllDWM;
|
||||
static DwmSetWindowAttribute_t ms_pfnDwmSetWindowAttribute;
|
||||
|
||||
static std::unique_ptr<wxDarkModeSettings> ms_settings;
|
||||
|
||||
wxDECLARE_DYNAMIC_CLASS(wxDarkModeModule);
|
||||
};
|
||||
|
||||
wxIMPLEMENT_DYNAMIC_CLASS(wxDarkModeModule, wxModule);
|
||||
|
||||
wxDynamicLibrary wxDarkModeModule::ms_dllDWM;
|
||||
std::unique_ptr<wxDarkModeSettings> wxDarkModeModule::ms_settings;
|
||||
|
||||
DwmSetWindowAttribute_t
|
||||
wxDarkModeModule::ms_pfnDwmSetWindowAttribute = (DwmSetWindowAttribute_t)-1;
|
||||
|
|
@ -201,7 +222,7 @@ wxDarkModeModule::ms_pfnDwmSetWindowAttribute = (DwmSetWindowAttribute_t)-1;
|
|||
// Public API
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxApp::MSWEnableDarkMode(int flags)
|
||||
bool wxApp::MSWEnableDarkMode(int flags, wxDarkModeSettings* settings)
|
||||
{
|
||||
if ( !wxMSWImpl::InitDarkMode() )
|
||||
return false;
|
||||
|
|
@ -220,61 +241,23 @@ bool wxApp::MSWEnableDarkMode(int flags)
|
|||
|
||||
gs_appMode = mode;
|
||||
|
||||
// Set up the settings to use, allocating a default one if none specified.
|
||||
if ( !settings )
|
||||
settings = new wxDarkModeSettings();
|
||||
|
||||
wxDarkModeModule::SetSettings(settings);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Supporting functions for the rest of wxMSW code
|
||||
// Default wxDarkModeSettings implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace wxMSWDarkMode
|
||||
{
|
||||
// Implemented here to ensure that it's generated inside the DLL.
|
||||
wxDarkModeSettings::~wxDarkModeSettings() = default;
|
||||
|
||||
bool IsActive()
|
||||
{
|
||||
return wxMSWImpl::ShouldUseDarkMode();
|
||||
}
|
||||
|
||||
void EnableForTLW(HWND hwnd)
|
||||
{
|
||||
// Nothing to do, dark mode support not enabled or dark mode is not used.
|
||||
if ( !wxMSWImpl::ShouldUseDarkMode() )
|
||||
return;
|
||||
|
||||
BOOL useDarkMode = TRUE;
|
||||
HRESULT hr = wxDarkModeModule::GetDwmSetWindowAttribute()
|
||||
(
|
||||
hwnd,
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||
&useDarkMode,
|
||||
sizeof(useDarkMode)
|
||||
);
|
||||
if ( FAILED(hr) )
|
||||
wxLogApiError("DwmSetWindowAttribute(USE_IMMERSIVE_DARK_MODE)", hr);
|
||||
|
||||
wxMSWImpl::AllowDarkModeForWindow(hwnd, true);
|
||||
}
|
||||
|
||||
void AllowForWindow(HWND hwnd, const wchar_t* themeName, const wchar_t* themeId)
|
||||
{
|
||||
if ( !wxMSWImpl::ShouldUseDarkMode() )
|
||||
return;
|
||||
|
||||
if ( wxMSWImpl::AllowDarkModeForWindow(hwnd, true) )
|
||||
wxLogTrace(TRACE_DARKMODE, "Allow dark mode for %p failed", hwnd);
|
||||
|
||||
if ( themeName || themeId )
|
||||
{
|
||||
HRESULT hr = ::SetWindowTheme(hwnd, themeName, themeId);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError(wxString::Format("SetWindowTheme(%p, %s, %s)",
|
||||
hwnd, themeName, themeId), hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxColour GetColour(wxSystemColour index)
|
||||
wxColour wxDarkModeSettings::GetColour(wxSystemColour index)
|
||||
{
|
||||
// This is not great at all, but better than using light mode colours that
|
||||
// are not appropriate for the dark mode.
|
||||
|
|
@ -347,6 +330,97 @@ wxColour GetColour(wxSystemColour index)
|
|||
return wxColour();
|
||||
}
|
||||
|
||||
wxColour wxDarkModeSettings::GetMenuColour(wxMenuColour which)
|
||||
{
|
||||
switch ( which )
|
||||
{
|
||||
case wxMenuColour::StandardFg:
|
||||
return wxColour(0xffffff);
|
||||
|
||||
case wxMenuColour::StandardBg:
|
||||
return wxColour(0x6d6d6d);
|
||||
|
||||
case wxMenuColour::DisabledFg:
|
||||
return wxColour(0x414141);
|
||||
|
||||
case wxMenuColour::HotBg:
|
||||
return wxColour(0x2b2b2b);
|
||||
}
|
||||
|
||||
wxFAIL_MSG( "unreachable" );
|
||||
return wxColour();
|
||||
}
|
||||
|
||||
wxPen wxDarkModeSettings::GetBorderPen()
|
||||
{
|
||||
// Use a darker pen than the default white one by default. There doesn't
|
||||
// seem to be any standard colour to use for it, Windows itself uses both
|
||||
// 0x666666 and 0x797979 for the borders in the "Colours" control panel
|
||||
// window, so it doesn't seem like anybody cares about consistency here.
|
||||
return *wxGREY_PEN;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Supporting functions for the rest of wxMSW code
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace wxMSWDarkMode
|
||||
{
|
||||
|
||||
bool IsActive()
|
||||
{
|
||||
return wxMSWImpl::ShouldUseDarkMode();
|
||||
}
|
||||
|
||||
void EnableForTLW(HWND hwnd)
|
||||
{
|
||||
// Nothing to do, dark mode support not enabled or dark mode is not used.
|
||||
if ( !wxMSWImpl::ShouldUseDarkMode() )
|
||||
return;
|
||||
|
||||
BOOL useDarkMode = TRUE;
|
||||
HRESULT hr = wxDarkModeModule::GetDwmSetWindowAttribute()
|
||||
(
|
||||
hwnd,
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||
&useDarkMode,
|
||||
sizeof(useDarkMode)
|
||||
);
|
||||
if ( FAILED(hr) )
|
||||
wxLogApiError("DwmSetWindowAttribute(USE_IMMERSIVE_DARK_MODE)", hr);
|
||||
|
||||
wxMSWImpl::AllowDarkModeForWindow(hwnd, true);
|
||||
}
|
||||
|
||||
void AllowForWindow(HWND hwnd, const wchar_t* themeName, const wchar_t* themeId)
|
||||
{
|
||||
if ( !wxMSWImpl::ShouldUseDarkMode() )
|
||||
return;
|
||||
|
||||
if ( wxMSWImpl::AllowDarkModeForWindow(hwnd, true) )
|
||||
wxLogTrace(TRACE_DARKMODE, "Allow dark mode for %p failed", hwnd);
|
||||
|
||||
if ( themeName || themeId )
|
||||
{
|
||||
HRESULT hr = ::SetWindowTheme(hwnd, themeName, themeId);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError(wxString::Format("SetWindowTheme(%p, %s, %s)",
|
||||
hwnd, themeName, themeId), hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxColour GetColour(wxSystemColour index)
|
||||
{
|
||||
return wxDarkModeModule::GetSettings().GetColour(index);
|
||||
}
|
||||
|
||||
wxPen GetBorderPen()
|
||||
{
|
||||
return wxDarkModeModule::GetSettings().GetBorderPen();
|
||||
}
|
||||
|
||||
HBRUSH GetBackgroundBrush()
|
||||
{
|
||||
wxBrush* const brush =
|
||||
|
|
@ -457,14 +531,15 @@ struct MenuBarDrawMenuItem
|
|||
MenuBarMenuItem mbmi;
|
||||
};
|
||||
|
||||
constexpr COLORREF COL_STANDARD = 0xffffff;
|
||||
constexpr COLORREF COL_DISABLED = 0x6d6d6d;
|
||||
constexpr COLORREF COL_MENU_HOT = 0x414141;
|
||||
wxColour GetMenuColour(wxMenuColour which)
|
||||
{
|
||||
return wxDarkModeModule::GetSettings().GetMenuColour(which);
|
||||
}
|
||||
|
||||
HBRUSH GetMenuBrush()
|
||||
HBRUSH GetMenuBrush(wxMenuColour which = wxMenuColour::StandardBg)
|
||||
{
|
||||
wxBrush* const brush =
|
||||
wxTheBrushList->FindOrCreateBrush(GetColour(wxSYS_COLOUR_MENU));
|
||||
wxTheBrushList->FindOrCreateBrush(GetMenuColour(which));
|
||||
|
||||
return brush ? GetHbrushOf(*brush) : 0;
|
||||
}
|
||||
|
|
@ -568,9 +643,11 @@ HandleMenuMessage(WXLRESULT* result,
|
|||
|
||||
HBRUSH hbr = 0;
|
||||
int partState = 0;
|
||||
wxMenuColour colText = wxMenuColour::StandardFg;
|
||||
if ( itemState & ODS_INACTIVE )
|
||||
{
|
||||
partState = MBI_DISABLED;
|
||||
colText = wxMenuColour::DisabledFg;
|
||||
}
|
||||
else if ( (itemState & ODS_GRAYED) && (itemState & ODS_HOTLIGHT) )
|
||||
{
|
||||
|
|
@ -579,15 +656,13 @@ HandleMenuMessage(WXLRESULT* result,
|
|||
else if ( itemState & ODS_GRAYED )
|
||||
{
|
||||
partState = MBI_DISABLED;
|
||||
colText = wxMenuColour::DisabledFg;
|
||||
}
|
||||
else if ( itemState & (ODS_HOTLIGHT | ODS_SELECTED) )
|
||||
{
|
||||
partState = MBI_HOT;
|
||||
|
||||
auto* const
|
||||
brush = wxTheBrushList->FindOrCreateBrush(COL_MENU_HOT);
|
||||
if ( brush )
|
||||
hbr = GetHbrushOf(*brush);
|
||||
hbr = GetMenuBrush(wxMenuColour::HotBg);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -607,9 +682,7 @@ HandleMenuMessage(WXLRESULT* result,
|
|||
DTTOPTS textOpts;
|
||||
textOpts.dwSize = sizeof(textOpts);
|
||||
textOpts.dwFlags = DTT_TEXTCOLOR;
|
||||
textOpts.crText = itemState & (ODS_INACTIVE | ODS_GRAYED)
|
||||
? COL_DISABLED
|
||||
: COL_STANDARD;
|
||||
textOpts.crText = wxColourToRGB(GetMenuColour(colText));
|
||||
|
||||
DWORD drawTextFlags = DT_CENTER | DT_SINGLELINE | DT_VCENTER;
|
||||
if ( itemState & ODS_NOACCEL)
|
||||
|
|
@ -630,7 +703,9 @@ HandleMenuMessage(WXLRESULT* result,
|
|||
|
||||
#else // !wxUSE_DARK_MODE
|
||||
|
||||
bool wxApp::MSWEnableDarkMode(int WXUNUSED(flags))
|
||||
bool
|
||||
wxApp::MSWEnableDarkMode(int WXUNUSED(flags),
|
||||
wxDarkModeSettings* WXUNUSED(settings))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -656,6 +731,11 @@ wxColour GetColour(wxSystemColour WXUNUSED(index))
|
|||
return wxColour();
|
||||
}
|
||||
|
||||
wxPen GetBorderPen()
|
||||
{
|
||||
return wxPen{};
|
||||
}
|
||||
|
||||
HBRUSH GetBackgroundBrush()
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/missing.h"
|
||||
#include "wx/msw/dc.h"
|
||||
#include "wx/msw/private/darkmode.h"
|
||||
#include "wx/msw/private/winstyle.h"
|
||||
|
||||
namespace
|
||||
|
|
@ -548,7 +549,49 @@ void wxStaticBox::PaintBackground(wxDC& dc, const RECT& rc)
|
|||
void wxStaticBox::PaintForeground(wxDC& dc, const RECT&)
|
||||
{
|
||||
wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
|
||||
MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(*impl), 0);
|
||||
|
||||
// Optionally use this pen to draw a border which has less contrast in dark
|
||||
// mode than the default white box which is "too shiny"
|
||||
wxPen penBorder;
|
||||
if ( wxMSWDarkMode::IsActive() )
|
||||
{
|
||||
penBorder = wxMSWDarkMode::GetBorderPen();
|
||||
}
|
||||
|
||||
if ( penBorder.IsOk() )
|
||||
{
|
||||
const wxRect clientRect = GetClientRect();
|
||||
wxRect rect = clientRect;
|
||||
wxDCBrushChanger brushChanger(dc, *wxTRANSPARENT_BRUSH);
|
||||
wxDCPenChanger penChanger(dc, penBorder);
|
||||
if ( !m_labelWin && !GetLabel().empty() )
|
||||
{
|
||||
// if the control has a font, use it
|
||||
wxDCFontChanger fontChanger(dc);
|
||||
if ( GetFont().IsOk() )
|
||||
{
|
||||
dc.SetFont(GetFont());
|
||||
}
|
||||
|
||||
// Make sure that the label is vertically aligned with the border
|
||||
wxCoord width, height;
|
||||
|
||||
// Use "Tp" as our sampling text to get the
|
||||
// maximum height from the current font
|
||||
dc.GetTextExtent(L"Tp", &width, &height);
|
||||
|
||||
// adjust the border height & Y coordinate
|
||||
int offsetFromTop = (height / 2) + LABEL_VERT_BORDER;
|
||||
rect.SetTop(offsetFromTop);
|
||||
rect.SetHeight(rect.GetHeight() - offsetFromTop);
|
||||
}
|
||||
|
||||
dc.DrawRectangle(rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(*impl), 0);
|
||||
}
|
||||
|
||||
#if wxUSE_UXTHEME
|
||||
// when using XP themes, neither setting the text colour nor transparent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue