diff --git a/include/wx/msw/nonownedwnd.h b/include/wx/msw/nonownedwnd.h index c5d40bfa97..a3f8aa4274 100644 --- a/include/wx/msw/nonownedwnd.h +++ b/include/wx/msw/nonownedwnd.h @@ -27,11 +27,27 @@ protected: virtual bool DoSetRegionShape(const wxRegion& region) wxOVERRIDE; #if wxUSE_GRAPHICS_CONTEXT virtual bool DoSetPathShape(const wxGraphicsPath& path) wxOVERRIDE; +#endif // wxUSE_GRAPHICS_CONTEXT + + virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) wxOVERRIDE; + virtual void InheritAttributes() wxOVERRIDE; private: + bool HandleDPIChange(const wxSize& newDPI, const wxRect& newRect); + +#if wxUSE_GRAPHICS_CONTEXT wxNonOwnedWindowShapeImpl* m_shapeImpl; #endif // wxUSE_GRAPHICS_CONTEXT + // 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 PerMonitorV2. + bool m_perMonitorDPIaware; + wxDECLARE_NO_COPY_CLASS(wxNonOwnedWindow); }; diff --git a/include/wx/msw/toplevel.h b/include/wx/msw/toplevel.h index d32764bb1f..5412de421e 100644 --- a/include/wx/msw/toplevel.h +++ b/include/wx/msw/toplevel.h @@ -115,7 +115,7 @@ public: virtual WXHWND MSWGetParent() const wxOVERRIDE; // window proc for the frames - WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) wxOVERRIDE; + virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) wxOVERRIDE; // returns true if the platform should explicitly apply a theme border virtual bool CanApplyThemeBorder() const wxOVERRIDE { return false; } @@ -166,9 +166,6 @@ protected: int& x, int& y, 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 // next time and also indicates whether the window should be considered // being iconized or maximized (which may be different from whether it's @@ -195,15 +192,6 @@ protected: wxWindowRef m_winLastFocused; 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 PerMonitorV2. - bool m_perMonitorDPIaware; - // The system menu: initially NULL but can be set (once) by // MSWGetSystemMenu(). Owned by this window. wxMenu *m_menuSystem; diff --git a/src/msw/nonownedwnd.cpp b/src/msw/nonownedwnd.cpp index 3876870071..16ca7ae585 100644 --- a/src/msw/nonownedwnd.cpp +++ b/src/msw/nonownedwnd.cpp @@ -36,6 +36,7 @@ #include "wx/graphics.h" #endif // wxUSE_GRAPHICS_CONTEXT +#include "wx/dynlib.h" #include "wx/scopedptr.h" // ============================================================================ @@ -128,16 +129,6 @@ private: wxDECLARE_NO_COPY_CLASS(wxNonOwnedWindowShapeImpl); }; -wxNonOwnedWindow::wxNonOwnedWindow() -{ - m_shapeImpl = NULL; -} - -wxNonOwnedWindow::~wxNonOwnedWindow() -{ - delete m_shapeImpl; -} - bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& path) { delete m_shapeImpl; @@ -146,17 +137,115 @@ bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& path) return true; } -#else // !wxUSE_GRAPHICS_CONTEXT +#endif // wxUSE_GRAPHICS_CONTEXT -// Trivial ctor and dtor as we don't have anything to do when wxGraphicsContext -// is not used but still define them here to avoid adding even more #if checks -// to the header, it it doesn't do any harm even though it's not needed. wxNonOwnedWindow::wxNonOwnedWindow() { +#if wxUSE_GRAPHICS_CONTEXT + m_shapeImpl = NULL; +#endif // wxUSE_GRAPHICS_CONTEXT + + m_activeDPI = wxDefaultSize; + m_perMonitorDPIaware = false; } wxNonOwnedWindow::~wxNonOwnedWindow() { +#if wxUSE_GRAPHICS_CONTEXT + delete m_shapeImpl; +#endif // wxUSE_GRAPHICS_CONTEXT } -#endif // wxUSE_GRAPHICS_CONTEXT/!wxUSE_GRAPHICS_CONTEXT +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; +} + +} + +void wxNonOwnedWindow::InheritAttributes() +{ + m_activeDPI = GetDPI(); + m_perMonitorDPIaware = IsPerMonitorDPIAware(GetHwnd()); + + wxNonOwnedWindowBase::InheritAttributes(); +} + +WXLRESULT wxNonOwnedWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) +{ + WXLRESULT rc = 0; + bool processed = false; + + switch ( message ) + { + case WM_DPICHANGED: + { + const RECT* const prcNewWindow = + reinterpret_cast(lParam); + + processed = HandleDPIChange(wxSize(LOWORD(wParam), + HIWORD(wParam)), + wxRectFromRECT(*prcNewWindow)); + } + break; + } + + if (!processed) + rc = wxNonOwnedWindowBase::MSWWindowProc(message, wParam, lParam); + + return rc; +} + +bool wxNonOwnedWindow::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; +} diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 2ede920e8b..4c552f2604 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -37,7 +37,6 @@ #include "wx/module.h" #endif //WX_PRECOMP -#include "wx/dynlib.h" #include "wx/scopeguard.h" #include "wx/tooltip.h" @@ -104,9 +103,6 @@ void wxTopLevelWindowMSW::Init() m_fsIsShowing = false; m_menuSystem = NULL; - - m_activeDPI = wxDefaultSize; - m_perMonitorDPIaware = false; } WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const @@ -249,26 +245,6 @@ WXHWND wxTopLevelWindowMSW::MSWGetParent() const 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 rc = 0; @@ -329,17 +305,6 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX #endif // #ifndef __WXUNIVERSAL__ } break; - - case WM_DPICHANGED: - { - const RECT* const prcNewWindow = - reinterpret_cast(lParam); - - processed = HandleDPIChange(wxSize(LOWORD(wParam), - HIWORD(wParam)), - wxRectFromRECT(*prcNewWindow)); - } - break; } if ( !processed ) @@ -348,47 +313,6 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX 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, const wxString& title, const wxPoint& pos, @@ -559,9 +483,7 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent, EnableCloseButton(false); } - m_activeDPI = GetDPI(); - - m_perMonitorDPIaware = IsPerMonitorDPIAware(GetHwnd()); + InheritAttributes(); // for standard dialogs the dialog manager generates WM_CHANGEUISTATE // itself but for custom windows we have to do it ourselves in order to