Merge branch 'per-monitor-dpi-aware-framework' of https://github.com/MaartenBent/wxWidgets
Add preliminary support for per-monitor DPI awareness to wxMSW. Individual controls still need to be fixed, so this support is still experimental/unfinished for now. See https://github.com/wxWidgets/wxWidgets/pull/1499
This commit is contained in:
@@ -2830,6 +2830,7 @@ WX_MSW_DECLARE_HANDLE(HBITMAP);
|
|||||||
WX_MSW_DECLARE_HANDLE(HIMAGELIST);
|
WX_MSW_DECLARE_HANDLE(HIMAGELIST);
|
||||||
WX_MSW_DECLARE_HANDLE(HGLOBAL);
|
WX_MSW_DECLARE_HANDLE(HGLOBAL);
|
||||||
WX_MSW_DECLARE_HANDLE(HDC);
|
WX_MSW_DECLARE_HANDLE(HDC);
|
||||||
|
WX_MSW_DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
||||||
typedef WXHINSTANCE WXHMODULE;
|
typedef WXHINSTANCE WXHMODULE;
|
||||||
|
|
||||||
#undef WX_MSW_DECLARE_HANDLE
|
#undef WX_MSW_DECLARE_HANDLE
|
||||||
|
@@ -641,6 +641,7 @@ class WXDLLIMPEXP_FWD_CORE wxMenuEvent;
|
|||||||
class WXDLLIMPEXP_FWD_CORE wxContextMenuEvent;
|
class WXDLLIMPEXP_FWD_CORE wxContextMenuEvent;
|
||||||
class WXDLLIMPEXP_FWD_CORE wxSysColourChangedEvent;
|
class WXDLLIMPEXP_FWD_CORE wxSysColourChangedEvent;
|
||||||
class WXDLLIMPEXP_FWD_CORE wxDisplayChangedEvent;
|
class WXDLLIMPEXP_FWD_CORE wxDisplayChangedEvent;
|
||||||
|
class WXDLLIMPEXP_FWD_CORE wxDPIChangedEvent;
|
||||||
class WXDLLIMPEXP_FWD_CORE wxQueryNewPaletteEvent;
|
class WXDLLIMPEXP_FWD_CORE wxQueryNewPaletteEvent;
|
||||||
class WXDLLIMPEXP_FWD_CORE wxPaletteChangedEvent;
|
class WXDLLIMPEXP_FWD_CORE wxPaletteChangedEvent;
|
||||||
class WXDLLIMPEXP_FWD_CORE wxJoystickEvent;
|
class WXDLLIMPEXP_FWD_CORE wxJoystickEvent;
|
||||||
@@ -793,6 +794,7 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_MENU_HIGHLIGHT, wxMenuEvent);
|
|||||||
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_CONTEXT_MENU, wxContextMenuEvent);
|
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_CONTEXT_MENU, wxContextMenuEvent);
|
||||||
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEvent);
|
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEvent);
|
||||||
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_DISPLAY_CHANGED, wxDisplayChangedEvent);
|
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_DISPLAY_CHANGED, wxDisplayChangedEvent);
|
||||||
|
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_DPI_CHANGED, wxDPIChangedEvent);
|
||||||
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_QUERY_NEW_PALETTE, wxQueryNewPaletteEvent);
|
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_QUERY_NEW_PALETTE, wxQueryNewPaletteEvent);
|
||||||
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_PALETTE_CHANGED, wxPaletteChangedEvent);
|
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_PALETTE_CHANGED, wxPaletteChangedEvent);
|
||||||
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_JOY_BUTTON_DOWN, wxJoystickEvent);
|
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_JOY_BUTTON_DOWN, wxJoystickEvent);
|
||||||
@@ -3031,6 +3033,32 @@ public:
|
|||||||
virtual wxEvent *Clone() const wxOVERRIDE { return new wxDisplayChangedEvent(*this); }
|
virtual wxEvent *Clone() const wxOVERRIDE { return new wxDisplayChangedEvent(*this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
wxEVT_DPI_CHANGED
|
||||||
|
*/
|
||||||
|
class WXDLLIMPEXP_CORE wxDPIChangedEvent : public wxEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit
|
||||||
|
wxDPIChangedEvent(const wxSize& oldDPI = wxDefaultSize,
|
||||||
|
const wxSize& newDPI = wxDefaultSize)
|
||||||
|
: wxEvent(0, wxEVT_DPI_CHANGED),
|
||||||
|
m_oldDPI(oldDPI),
|
||||||
|
m_newDPI(newDPI)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
wxSize GetOldDPI() const { return m_oldDPI; }
|
||||||
|
wxSize GetNewDPI() const { return m_newDPI; }
|
||||||
|
|
||||||
|
virtual wxEvent *Clone() const wxOVERRIDE { return new wxDPIChangedEvent(*this); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxSize m_oldDPI;
|
||||||
|
wxSize m_newDPI;
|
||||||
|
|
||||||
|
wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxDPIChangedEvent);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
wxEVT_PALETTE_CHANGED
|
wxEVT_PALETTE_CHANGED
|
||||||
*/
|
*/
|
||||||
@@ -4108,6 +4136,7 @@ typedef void (wxEvtHandler::*wxDropFilesEventFunction)(wxDropFilesEvent&);
|
|||||||
typedef void (wxEvtHandler::*wxInitDialogEventFunction)(wxInitDialogEvent&);
|
typedef void (wxEvtHandler::*wxInitDialogEventFunction)(wxInitDialogEvent&);
|
||||||
typedef void (wxEvtHandler::*wxSysColourChangedEventFunction)(wxSysColourChangedEvent&);
|
typedef void (wxEvtHandler::*wxSysColourChangedEventFunction)(wxSysColourChangedEvent&);
|
||||||
typedef void (wxEvtHandler::*wxDisplayChangedEventFunction)(wxDisplayChangedEvent&);
|
typedef void (wxEvtHandler::*wxDisplayChangedEventFunction)(wxDisplayChangedEvent&);
|
||||||
|
typedef void (wxEvtHandler::*wxDPIChangedEventFunction)(wxDPIChangedEvent&);
|
||||||
typedef void (wxEvtHandler::*wxUpdateUIEventFunction)(wxUpdateUIEvent&);
|
typedef void (wxEvtHandler::*wxUpdateUIEventFunction)(wxUpdateUIEvent&);
|
||||||
typedef void (wxEvtHandler::*wxCloseEventFunction)(wxCloseEvent&);
|
typedef void (wxEvtHandler::*wxCloseEventFunction)(wxCloseEvent&);
|
||||||
typedef void (wxEvtHandler::*wxShowEventFunction)(wxShowEvent&);
|
typedef void (wxEvtHandler::*wxShowEventFunction)(wxShowEvent&);
|
||||||
@@ -4171,6 +4200,8 @@ typedef void (wxEvtHandler::*wxPressAndTapEventFunction)(wxPressAndTapEvent&);
|
|||||||
wxEVENT_HANDLER_CAST(wxSysColourChangedEventFunction, func)
|
wxEVENT_HANDLER_CAST(wxSysColourChangedEventFunction, func)
|
||||||
#define wxDisplayChangedEventHandler(func) \
|
#define wxDisplayChangedEventHandler(func) \
|
||||||
wxEVENT_HANDLER_CAST(wxDisplayChangedEventFunction, func)
|
wxEVENT_HANDLER_CAST(wxDisplayChangedEventFunction, func)
|
||||||
|
#define wxDPIChangedEventHandler(func) \
|
||||||
|
wxEVENT_HANDLER_CAST(wxDPIChangedEventFunction, func)
|
||||||
#define wxUpdateUIEventHandler(func) \
|
#define wxUpdateUIEventHandler(func) \
|
||||||
wxEVENT_HANDLER_CAST(wxUpdateUIEventFunction, func)
|
wxEVENT_HANDLER_CAST(wxUpdateUIEventFunction, func)
|
||||||
#define wxCloseEventHandler(func) \
|
#define wxCloseEventHandler(func) \
|
||||||
@@ -4430,6 +4461,7 @@ typedef void (wxEvtHandler::*wxPressAndTapEventFunction)(wxPressAndTapEvent&);
|
|||||||
#define EVT_INIT_DIALOG(func) wx__DECLARE_EVT0(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(func))
|
#define EVT_INIT_DIALOG(func) wx__DECLARE_EVT0(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(func))
|
||||||
#define EVT_SYS_COLOUR_CHANGED(func) wx__DECLARE_EVT0(wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEventHandler(func))
|
#define EVT_SYS_COLOUR_CHANGED(func) wx__DECLARE_EVT0(wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEventHandler(func))
|
||||||
#define EVT_DISPLAY_CHANGED(func) wx__DECLARE_EVT0(wxEVT_DISPLAY_CHANGED, wxDisplayChangedEventHandler(func))
|
#define EVT_DISPLAY_CHANGED(func) wx__DECLARE_EVT0(wxEVT_DISPLAY_CHANGED, wxDisplayChangedEventHandler(func))
|
||||||
|
#define EVT_DPI_CHANGED(func) wx__DECLARE_EVT0(wxEVT_DPI_CHANGED, wxDPIChangedEventHandler(func))
|
||||||
#define EVT_SHOW(func) wx__DECLARE_EVT0(wxEVT_SHOW, wxShowEventHandler(func))
|
#define EVT_SHOW(func) wx__DECLARE_EVT0(wxEVT_SHOW, wxShowEventHandler(func))
|
||||||
#define EVT_MAXIMIZE(func) wx__DECLARE_EVT0(wxEVT_MAXIMIZE, wxMaximizeEventHandler(func))
|
#define EVT_MAXIMIZE(func) wx__DECLARE_EVT0(wxEVT_MAXIMIZE, wxMaximizeEventHandler(func))
|
||||||
#define EVT_ICONIZE(func) wx__DECLARE_EVT0(wxEVT_ICONIZE, wxIconizeEventHandler(func))
|
#define EVT_ICONIZE(func) wx__DECLARE_EVT0(wxEVT_ICONIZE, wxIconizeEventHandler(func))
|
||||||
|
@@ -501,6 +501,13 @@ public:
|
|||||||
// account as well.
|
// account as well.
|
||||||
static int GetNumericWeightOf(wxFontWeight weight);
|
static int GetNumericWeightOf(wxFontWeight weight);
|
||||||
|
|
||||||
|
// Some ports need to modify the font object when the DPI of the window it
|
||||||
|
// is used with changes, this function can be used to do it.
|
||||||
|
//
|
||||||
|
// Currently it is only used in wxMSW and is not considered to be part of
|
||||||
|
// wxWidgets public API.
|
||||||
|
virtual void WXAdjustToPPI(const wxSize& WXUNUSED(ppi)) { }
|
||||||
|
|
||||||
// this doesn't do anything and is kept for compatibility only
|
// this doesn't do anything and is kept for compatibility only
|
||||||
#if WXWIN_COMPATIBILITY_2_8
|
#if WXWIN_COMPATIBILITY_2_8
|
||||||
wxDEPRECATED_INLINE(void SetNoAntiAliasing(bool no = true), wxUnusedVar(no);)
|
wxDEPRECATED_INLINE(void SetNoAntiAliasing(bool no = true), wxUnusedVar(no);)
|
||||||
|
@@ -120,25 +120,17 @@ public:
|
|||||||
#elif defined(__WXMSW__)
|
#elif defined(__WXMSW__)
|
||||||
wxNativeFontInfo(const LOGFONT& lf_)
|
wxNativeFontInfo(const LOGFONT& lf_)
|
||||||
: lf(lf_),
|
: lf(lf_),
|
||||||
pointSize(GetPointSizeFromLogFontHeight(lf.lfHeight))
|
pointSize(GetPointSizeAtPPI(lf.lfHeight))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// MSW-specific: get point size from LOGFONT height using the default DPI.
|
// MSW-specific: get point size from LOGFONT height using specified DPI,
|
||||||
static float GetPointSizeFromLogFontHeight(int height);
|
// or screen DPI when 0.
|
||||||
|
static float GetPointSizeAtPPI(int lfHeight, int ppi = 0);
|
||||||
|
|
||||||
// MSW-specific: get the height value in pixels using LOGFONT convention
|
// MSW-specific: get the height value in pixels using LOGFONT convention
|
||||||
// (i.e. negative) corresponding to the given size in points and DPI.
|
// (i.e. negative) corresponding to the given size in points and DPI.
|
||||||
static int GetLogFontHeightAtPPI(float size, int ppi)
|
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;
|
LOGFONT lf;
|
||||||
|
|
||||||
|
@@ -120,6 +120,8 @@ public:
|
|||||||
|
|
||||||
virtual bool IsFixedWidth() const wxOVERRIDE;
|
virtual bool IsFixedWidth() const wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual void WXAdjustToPPI(const wxSize& ppi) wxOVERRIDE;
|
||||||
|
|
||||||
wxDEPRECATED_MSG("use wxFONT{FAMILY,STYLE,WEIGHT}_XXX constants ie: wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD")
|
wxDEPRECATED_MSG("use wxFONT{FAMILY,STYLE,WEIGHT}_XXX constants ie: wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD")
|
||||||
wxFont(int size,
|
wxFont(int size,
|
||||||
int family,
|
int family,
|
||||||
|
@@ -23,7 +23,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WM_PRINTCLIENT
|
#ifndef WM_PRINTCLIENT
|
||||||
#define WM_PRINTCLIENT 0x318
|
#define WM_PRINTCLIENT 0x0318
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WM_DPICHANGED
|
||||||
|
#define WM_DPICHANGED 0x02E0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DT_HIDEPREFIX
|
#ifndef DT_HIDEPREFIX
|
||||||
|
@@ -165,6 +165,9 @@ protected:
|
|||||||
int& x, int& y,
|
int& x, int& y,
|
||||||
int& w, int& h) const wxOVERRIDE;
|
int& w, int& h) const wxOVERRIDE;
|
||||||
|
|
||||||
|
// WM_DPICHANGED handler.
|
||||||
|
bool HandleDPIChange(const wxSize& newDPI, const wxRect& newRect);
|
||||||
|
|
||||||
// This field contains the show command to use when showing the window the
|
// This field contains the show command to use when showing the window the
|
||||||
// next time and also indicates whether the window should be considered
|
// next time and also indicates whether the window should be considered
|
||||||
// being iconized or maximized (which may be different from whether it's
|
// being iconized or maximized (which may be different from whether it's
|
||||||
@@ -191,6 +194,14 @@ protected:
|
|||||||
wxWindowRef m_winLastFocused;
|
wxWindowRef m_winLastFocused;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Keep track of the DPI used in this window. So when per-monitor dpi
|
||||||
|
// awareness is enabled, both old and new DPI are known for
|
||||||
|
// wxDPIChangedEvent and wxWindow::MSWUpdateOnDPIChange.
|
||||||
|
wxSize m_activeDPI;
|
||||||
|
|
||||||
|
// This window supports handling per-monitor DPI awareness when the
|
||||||
|
// application manifest contains <dpiAwareness>PerMonitorV2</dpiAwareness>.
|
||||||
|
bool m_perMonitorDPIaware;
|
||||||
|
|
||||||
// The system menu: initially NULL but can be set (once) by
|
// The system menu: initially NULL but can be set (once) by
|
||||||
// MSWGetSystemMenu(). Owned by this window.
|
// MSWGetSystemMenu(). Owned by this window.
|
||||||
|
@@ -586,7 +586,17 @@ public:
|
|||||||
// Should be overridden by all classes storing the "last focused" window.
|
// Should be overridden by all classes storing the "last focused" window.
|
||||||
virtual void WXDoUpdatePendingFocus(wxWindow* WXUNUSED(win)) {}
|
virtual void WXDoUpdatePendingFocus(wxWindow* WXUNUSED(win)) {}
|
||||||
|
|
||||||
|
// Called from WM_DPICHANGED handler for all windows to let them update
|
||||||
|
// any sizes and fonts used internally when the DPI changes and generate
|
||||||
|
// wxDPIChangedEvent to let the user code do the same thing as well.
|
||||||
|
void MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Called from MSWUpdateOnDPIChange() specifically to update the control
|
||||||
|
// font, as this may need to be done differently for some specific native
|
||||||
|
// controls. The default version updates m_font of this window.
|
||||||
|
virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI);
|
||||||
|
|
||||||
// this allows you to implement standard control borders without
|
// this allows you to implement standard control borders without
|
||||||
// repeating the code in different classes that are not derived from
|
// repeating the code in different classes that are not derived from
|
||||||
// wxControl
|
// wxControl
|
||||||
|
@@ -3318,6 +3318,62 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class wxDPIChangedEvent
|
||||||
|
|
||||||
|
Event sent when the resolution (measured in dots-per-inch, or DPI) of the
|
||||||
|
monitor a window is on changes.
|
||||||
|
|
||||||
|
The event is sent to each wxTopLevelWindow affected by the change, and all
|
||||||
|
its children recursively. For example, this event is sent to the window
|
||||||
|
when it is moved, by the user, from a display using some DPI value to
|
||||||
|
another display using a different DPI value. It also sent to all program
|
||||||
|
windows on the given display if its DPI changes due to a change in the
|
||||||
|
system settings.
|
||||||
|
|
||||||
|
Currently this event is generated by wxMSW port if only and only if the
|
||||||
|
MSW application runs under Windows 10 Creators Update (v1703) or later and
|
||||||
|
is marked as being "per-monitor DPI aware", i.e. contains a @c dpiAwareness
|
||||||
|
tag with the value "PerMonitorV2" in its manifest (see Microsoft
|
||||||
|
<a href="https://docs.microsoft.com/en-us/windows/desktop/sbscs/application-manifests">"Application Manifests" documentation</a>
|
||||||
|
for more details).
|
||||||
|
|
||||||
|
@note Per-monitor DPI support is an experimental feature that is still in
|
||||||
|
development. It might not work correctly for some controls.
|
||||||
|
|
||||||
|
@beginEventTable{wxDPIChangedEvent}
|
||||||
|
@event{EVT_DPI_CHANGED(func)}
|
||||||
|
Process a @c wxEVT_DPI_CHANGED event.
|
||||||
|
@endEventTable
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
|
||||||
|
@library{wxcore}
|
||||||
|
@category{events}
|
||||||
|
|
||||||
|
@see @ref overview_events
|
||||||
|
*/
|
||||||
|
class wxDPIChangedEvent : public wxEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Returns the old DPI.
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
wxSize GetOldDPI() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the new DPI.
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
wxSize GetNewDPI() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class wxPaletteChangedEvent : public wxEvent
|
class wxPaletteChangedEvent : public wxEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -2044,7 +2044,7 @@ public:
|
|||||||
|
|
||||||
If the DPI is not available, returns @c wxSize(0,0) object.
|
If the DPI is not available, returns @c wxSize(0,0) object.
|
||||||
|
|
||||||
@see wxDisplay::GetPPI()
|
@see wxDisplay::GetPPI(), wxDPIChangedEvent
|
||||||
|
|
||||||
@since 3.1.3
|
@since 3.1.3
|
||||||
*/
|
*/
|
||||||
|
@@ -92,6 +92,7 @@
|
|||||||
wxIMPLEMENT_DYNAMIC_CLASS(wxSetCursorEvent, wxEvent);
|
wxIMPLEMENT_DYNAMIC_CLASS(wxSetCursorEvent, wxEvent);
|
||||||
wxIMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent, wxEvent);
|
wxIMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent, wxEvent);
|
||||||
wxIMPLEMENT_DYNAMIC_CLASS(wxDisplayChangedEvent, wxEvent);
|
wxIMPLEMENT_DYNAMIC_CLASS(wxDisplayChangedEvent, wxEvent);
|
||||||
|
wxIMPLEMENT_DYNAMIC_CLASS(wxDPIChangedEvent, wxEvent);
|
||||||
wxIMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent, wxCommandEvent);
|
wxIMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent, wxCommandEvent);
|
||||||
wxIMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent, wxEvent);
|
wxIMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent, wxEvent);
|
||||||
wxIMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent, wxEvent);
|
wxIMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent, wxEvent);
|
||||||
@@ -302,6 +303,7 @@ wxDEFINE_EVENT( wxEVT_MENU_HIGHLIGHT, wxMenuEvent );
|
|||||||
wxDEFINE_EVENT( wxEVT_CONTEXT_MENU, wxContextMenuEvent );
|
wxDEFINE_EVENT( wxEVT_CONTEXT_MENU, wxContextMenuEvent );
|
||||||
wxDEFINE_EVENT( wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEvent );
|
wxDEFINE_EVENT( wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEvent );
|
||||||
wxDEFINE_EVENT( wxEVT_DISPLAY_CHANGED, wxDisplayChangedEvent );
|
wxDEFINE_EVENT( wxEVT_DISPLAY_CHANGED, wxDisplayChangedEvent );
|
||||||
|
wxDEFINE_EVENT( wxEVT_DPI_CHANGED, wxDPIChangedEvent );
|
||||||
wxDEFINE_EVENT( wxEVT_QUERY_NEW_PALETTE, wxQueryNewPaletteEvent );
|
wxDEFINE_EVENT( wxEVT_QUERY_NEW_PALETTE, wxQueryNewPaletteEvent );
|
||||||
wxDEFINE_EVENT( wxEVT_PALETTE_CHANGED, wxPaletteChangedEvent );
|
wxDEFINE_EVENT( wxEVT_PALETTE_CHANGED, wxPaletteChangedEvent );
|
||||||
wxDEFINE_EVENT( wxEVT_JOY_BUTTON_DOWN, wxJoystickEvent );
|
wxDEFINE_EVENT( wxEVT_JOY_BUTTON_DOWN, wxJoystickEvent );
|
||||||
|
@@ -1726,6 +1726,8 @@ wxFont wxWindowBase::GetFont() const
|
|||||||
if ( !font.IsOk() )
|
if ( !font.IsOk() )
|
||||||
font = GetClassDefaultAttributes().font;
|
font = GetClassDefaultAttributes().font;
|
||||||
|
|
||||||
|
font.WXAdjustToPPI(GetDPI());
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1744,6 +1746,9 @@ bool wxWindowBase::SetFont(const wxFont& font)
|
|||||||
m_hasFont = font.IsOk();
|
m_hasFont = font.IsOk();
|
||||||
m_inheritFont = m_hasFont;
|
m_inheritFont = m_hasFont;
|
||||||
|
|
||||||
|
if ( m_hasFont )
|
||||||
|
m_font.WXAdjustToPPI(GetDPI());
|
||||||
|
|
||||||
InvalidateBestSize();
|
InvalidateBestSize();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -159,7 +159,8 @@ public:
|
|||||||
|
|
||||||
int GetLogFontHeightAtPPI(int ppi) const
|
int GetLogFontHeightAtPPI(int ppi) const
|
||||||
{
|
{
|
||||||
return m_nativeFontInfo.GetLogFontHeightAtPPI(ppi);
|
return m_nativeFontInfo.GetLogFontHeightAtPPI(
|
||||||
|
m_nativeFontInfo.pointSize, ppi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and setters: notice that all of them invalidate the currently
|
// ... and setters: notice that all of them invalidate the currently
|
||||||
@@ -403,12 +404,18 @@ void wxFontRefData::Free()
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
float wxNativeFontInfo::GetPointSizeFromLogFontHeight(int height)
|
float wxNativeFontInfo::GetPointSizeAtPPI(int lfHeight, int ppi)
|
||||||
{
|
{
|
||||||
// Determine the size in points using the primary screen DPI as we don't
|
if ( ppi == 0 )
|
||||||
// have anything else here.
|
ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
||||||
const float ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
|
||||||
return 72.0f * abs(height) / ppi;
|
return abs(lfHeight) * 72.0f / ppi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
int wxNativeFontInfo::GetLogFontHeightAtPPI(float size, int ppi)
|
||||||
|
{
|
||||||
|
return -wxRound(size * ppi / 72.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxNativeFontInfo::Init()
|
void wxNativeFontInfo::Init()
|
||||||
@@ -512,7 +519,8 @@ wxFontEncoding wxNativeFontInfo::GetEncoding() const
|
|||||||
void wxNativeFontInfo::SetFractionalPointSize(float pointSizeNew)
|
void wxNativeFontInfo::SetFractionalPointSize(float pointSizeNew)
|
||||||
{
|
{
|
||||||
// We don't have the correct DPI to use here, so use that of the
|
// We don't have the correct DPI to use here, so use that of the
|
||||||
// primary screen.
|
// primary screen and rely on WXAdjustToPPI() changing it later if
|
||||||
|
// necessary.
|
||||||
const int ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
const int ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
||||||
lf.lfHeight = GetLogFontHeightAtPPI(pointSizeNew, ppi);
|
lf.lfHeight = GetLogFontHeightAtPPI(pointSizeNew, ppi);
|
||||||
|
|
||||||
@@ -535,7 +543,7 @@ void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
|
|||||||
|
|
||||||
// We don't have the right DPI to use here neither, but we need to update
|
// 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.
|
// the point size too, so fall back to the default.
|
||||||
pointSize = GetPointSizeFromLogFontHeight(lf.lfHeight);
|
pointSize = GetPointSizeAtPPI(lf.lfHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxNativeFontInfo::SetStyle(wxFontStyle style)
|
void wxNativeFontInfo::SetStyle(wxFontStyle style)
|
||||||
@@ -698,7 +706,7 @@ bool wxNativeFontInfo::FromString(const wxString& s)
|
|||||||
return false;
|
return false;
|
||||||
lf.lfHeight = l;
|
lf.lfHeight = l;
|
||||||
if ( setPointSizeFromHeight )
|
if ( setPointSizeFromHeight )
|
||||||
pointSize = GetPointSizeFromLogFontHeight(l);
|
pointSize = GetPointSizeAtPPI(l);
|
||||||
|
|
||||||
token = tokenizer.GetNextToken();
|
token = tokenizer.GetNextToken();
|
||||||
if ( !token.ToLong(&l) )
|
if ( !token.ToLong(&l) )
|
||||||
@@ -899,6 +907,19 @@ void wxFont::SetPixelSize(const wxSize& pixelSize)
|
|||||||
M_FONTDATA->SetPixelSize(pixelSize);
|
M_FONTDATA->SetPixelSize(pixelSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxFont::WXAdjustToPPI(const wxSize& ppi)
|
||||||
|
{
|
||||||
|
// We only use vertical component here as we only adjust LOGFONT::lfHeight.
|
||||||
|
const int heightNew = M_FONTDATA->GetLogFontHeightAtPPI(ppi.y);
|
||||||
|
|
||||||
|
if ( heightNew != M_FONTDATA->GetLogFontHeight() )
|
||||||
|
{
|
||||||
|
AllocExclusive();
|
||||||
|
|
||||||
|
M_FONTDATA->SetLogFontHeight(heightNew);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wxFont::SetFamily(wxFontFamily family)
|
void wxFont::SetFamily(wxFontFamily family)
|
||||||
{
|
{
|
||||||
AllocExclusive();
|
AllocExclusive();
|
||||||
|
@@ -392,7 +392,15 @@ void MenuDrawData::Init()
|
|||||||
|
|
||||||
Offset = -12;
|
Offset = -12;
|
||||||
|
|
||||||
Font = wxFont(wxNativeFontInfo(metrics.lfMenuFont));
|
wxNativeFontInfo info(metrics.lfMenuFont);
|
||||||
|
// wxNativeFontInfo constructor calculates the pointSize using the
|
||||||
|
// main screen DPI. But lfHeight is based on the window DPI.
|
||||||
|
if ( window )
|
||||||
|
{
|
||||||
|
info.pointSize = wxNativeFontInfo::GetPointSizeAtPPI(
|
||||||
|
info.lf.lfHeight, window->GetDPI().y);
|
||||||
|
}
|
||||||
|
Font = wxFont(info);
|
||||||
|
|
||||||
Theme = false;
|
Theme = false;
|
||||||
}
|
}
|
||||||
|
@@ -397,8 +397,17 @@ void wxMessageDialog::AdjustButtonLabels()
|
|||||||
wxFont wxMessageDialog::GetMessageFont()
|
wxFont wxMessageDialog::GetMessageFont()
|
||||||
{
|
{
|
||||||
const wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
|
const wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
|
||||||
const NONCLIENTMETRICS& ncm = wxMSWImpl::GetNonClientMetrics(win);
|
wxNativeFontInfo info(wxMSWImpl::GetNonClientMetrics(win).lfMessageFont);
|
||||||
return wxNativeFontInfo(ncm.lfMessageFont);
|
|
||||||
|
// wxNativeFontInfo constructor calculates the pointSize using the
|
||||||
|
// main screen DPI. But lfHeight is based on the window DPI.
|
||||||
|
if ( win )
|
||||||
|
{
|
||||||
|
info.pointSize = wxNativeFontInfo::GetPointSizeAtPPI(
|
||||||
|
info.lf.lfHeight, win->GetDPI().y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxMessageDialog::ShowMessageBox()
|
int wxMessageDialog::ShowMessageBox()
|
||||||
|
@@ -183,8 +183,17 @@ wxFont wxSystemSettingsNative::GetFont(wxSystemFont index)
|
|||||||
// controls may prefer to use lfStatusFont or lfCaptionFont if it
|
// controls may prefer to use lfStatusFont or lfCaptionFont if it
|
||||||
// is more appropriate for them
|
// is more appropriate for them
|
||||||
const wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
|
const wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
|
||||||
const wxNativeFontInfo
|
wxNativeFontInfo
|
||||||
info(wxMSWImpl::GetNonClientMetrics(win).lfMessageFont);
|
info(wxMSWImpl::GetNonClientMetrics(win).lfMessageFont);
|
||||||
|
|
||||||
|
// wxNativeFontInfo constructor calculates the pointSize using the
|
||||||
|
// main screen DPI. But lfHeight is based on the window DPI.
|
||||||
|
if ( win )
|
||||||
|
{
|
||||||
|
info.pointSize = wxNativeFontInfo::GetPointSizeAtPPI(
|
||||||
|
info.lf.lfHeight, win->GetDPI().y);
|
||||||
|
}
|
||||||
|
|
||||||
gs_fontDefault = new wxFont(info);
|
gs_fontDefault = new wxFont(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -104,6 +104,9 @@ void wxTopLevelWindowMSW::Init()
|
|||||||
m_fsIsShowing = false;
|
m_fsIsShowing = false;
|
||||||
|
|
||||||
m_menuSystem = NULL;
|
m_menuSystem = NULL;
|
||||||
|
|
||||||
|
m_activeDPI = wxDefaultSize;
|
||||||
|
m_perMonitorDPIaware = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
|
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
|
||||||
@@ -246,6 +249,26 @@ WXHWND wxTopLevelWindowMSW::MSWGetParent() const
|
|||||||
return (WXHWND)hwndParent;
|
return (WXHWND)hwndParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxTopLevelWindowMSW::HandleDPIChange(const wxSize& newDPI, const wxRect& newRect)
|
||||||
|
{
|
||||||
|
if ( !m_perMonitorDPIaware )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( newDPI != m_activeDPI )
|
||||||
|
{
|
||||||
|
MSWUpdateOnDPIChange(m_activeDPI, newDPI);
|
||||||
|
m_activeDPI = newDPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSize(newRect);
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
|
WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
|
||||||
{
|
{
|
||||||
WXLRESULT rc = 0;
|
WXLRESULT rc = 0;
|
||||||
@@ -306,6 +329,17 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
|
|||||||
#endif // #ifndef __WXUNIVERSAL__
|
#endif // #ifndef __WXUNIVERSAL__
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_DPICHANGED:
|
||||||
|
{
|
||||||
|
const RECT* const prcNewWindow =
|
||||||
|
reinterpret_cast<const RECT*>(lParam);
|
||||||
|
|
||||||
|
processed = HandleDPIChange(wxSize(LOWORD(wParam),
|
||||||
|
HIWORD(wParam)),
|
||||||
|
wxRectFromRECT(*prcNewWindow));
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !processed )
|
if ( !processed )
|
||||||
@@ -314,6 +348,47 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
static bool IsPerMonitorDPIAware(HWND hwnd)
|
||||||
|
{
|
||||||
|
bool dpiAware = false;
|
||||||
|
|
||||||
|
// Determine if 'Per Monitor v2' DPI awareness is enabled in the
|
||||||
|
// applications manifest.
|
||||||
|
#if wxUSE_DYNLIB_CLASS
|
||||||
|
#define WXDPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((WXDPI_AWARENESS_CONTEXT)-4)
|
||||||
|
typedef WXDPI_AWARENESS_CONTEXT(WINAPI * GetWindowDpiAwarenessContext_t)(HWND hwnd);
|
||||||
|
typedef BOOL(WINAPI * AreDpiAwarenessContextsEqual_t)(WXDPI_AWARENESS_CONTEXT dpiContextA, WXDPI_AWARENESS_CONTEXT dpiContextB);
|
||||||
|
static GetWindowDpiAwarenessContext_t s_pfnGetWindowDpiAwarenessContext = NULL;
|
||||||
|
static AreDpiAwarenessContextsEqual_t s_pfnAreDpiAwarenessContextsEqual = NULL;
|
||||||
|
static bool s_initDone = false;
|
||||||
|
|
||||||
|
if ( !s_initDone )
|
||||||
|
{
|
||||||
|
wxLoadedDLL dllUser32("user32.dll");
|
||||||
|
wxDL_INIT_FUNC(s_pfn, GetWindowDpiAwarenessContext, dllUser32);
|
||||||
|
wxDL_INIT_FUNC(s_pfn, AreDpiAwarenessContextsEqual, dllUser32);
|
||||||
|
s_initDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( s_pfnGetWindowDpiAwarenessContext && s_pfnAreDpiAwarenessContextsEqual )
|
||||||
|
{
|
||||||
|
WXDPI_AWARENESS_CONTEXT dpiAwarenessContext = s_pfnGetWindowDpiAwarenessContext(hwnd);
|
||||||
|
|
||||||
|
if ( s_pfnAreDpiAwarenessContextsEqual(dpiAwarenessContext, WXDPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) == TRUE )
|
||||||
|
{
|
||||||
|
dpiAware = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // wxUSE_DYNLIB_CLASS
|
||||||
|
|
||||||
|
return dpiAware;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
|
bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
|
||||||
const wxString& title,
|
const wxString& title,
|
||||||
const wxPoint& pos,
|
const wxPoint& pos,
|
||||||
@@ -484,6 +559,10 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent,
|
|||||||
EnableCloseButton(false);
|
EnableCloseButton(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_activeDPI = GetDPI();
|
||||||
|
|
||||||
|
m_perMonitorDPIaware = IsPerMonitorDPIAware(GetHwnd());
|
||||||
|
|
||||||
// for standard dialogs the dialog manager generates WM_CHANGEUISTATE
|
// for standard dialogs the dialog manager generates WM_CHANGEUISTATE
|
||||||
// itself but for custom windows we have to do it ourselves in order to
|
// itself but for custom windows we have to do it ourselves in order to
|
||||||
// make the keyboard indicators (such as underlines for accelerators and
|
// make the keyboard indicators (such as underlines for accelerators and
|
||||||
|
@@ -4837,6 +4837,65 @@ wxSize wxWindowMSW::GetDPI() const
|
|||||||
return dpi;
|
return dpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWindowMSW::MSWUpdateFontOnDPIChange(const wxSize& newDPI)
|
||||||
|
{
|
||||||
|
if ( m_font.IsOk() )
|
||||||
|
{
|
||||||
|
m_font.WXAdjustToPPI(newDPI);
|
||||||
|
|
||||||
|
// WXAdjustToPPI() changes the HFONT, so reassociate it with the window.
|
||||||
|
wxSetWindowFont(GetHwnd(), m_font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to update the given coordinate by the scaling factor if it
|
||||||
|
// is set, i.e. different from wxDefaultCoord.
|
||||||
|
static void ScaleCoordIfSet(int& coord, float scaleFactor)
|
||||||
|
{
|
||||||
|
if ( coord != wxDefaultCoord )
|
||||||
|
{
|
||||||
|
const float coordScaled = coord * scaleFactor;
|
||||||
|
coord = scaleFactor > 1.0 ? ceil(coordScaled) : floor(coordScaled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
|
||||||
|
{
|
||||||
|
// update min and max size if necessary
|
||||||
|
const float scaleFactor = (float)newDPI.y / oldDPI.y;
|
||||||
|
|
||||||
|
ScaleCoordIfSet(m_minHeight, scaleFactor);
|
||||||
|
ScaleCoordIfSet(m_minWidth, scaleFactor);
|
||||||
|
ScaleCoordIfSet(m_maxHeight, scaleFactor);
|
||||||
|
ScaleCoordIfSet(m_maxWidth, scaleFactor);
|
||||||
|
|
||||||
|
InvalidateBestSize();
|
||||||
|
|
||||||
|
// update font if necessary
|
||||||
|
MSWUpdateFontOnDPIChange(newDPI);
|
||||||
|
|
||||||
|
// update children
|
||||||
|
wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
|
||||||
|
while ( current )
|
||||||
|
{
|
||||||
|
wxWindow *childWin = current->GetData();
|
||||||
|
// Update all children, except other top-level windows.
|
||||||
|
// These could be on a different monitor and will get their own
|
||||||
|
// dpi-changed event.
|
||||||
|
if ( childWin && !childWin->IsTopLevel() )
|
||||||
|
{
|
||||||
|
childWin->MSWUpdateOnDPIChange(oldDPI, newDPI);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current->GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDPIChangedEvent event(oldDPI, newDPI);
|
||||||
|
event.SetEventObject(this);
|
||||||
|
HandleWindowEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// colours and palettes
|
// colours and palettes
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user