///////////////////////////////////////////////////////////////////////////// // Name: wx/msw/private/dpiaware.h // Purpose: AutoSystemDpiAware class // Author: Maarten Bent // Created: 2016-10-06 // Copyright: (c) Maarten Bent // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_MSW_DPI_AWARE_H_ #define _WX_MSW_DPI_AWARE_H_ #ifndef WX_PRECOMP #include "wx/msw/missing.h" #endif #include "wx/dynlib.h" #include "wx/display.h" #include "wx/sysopt.h" #if wxUSE_DYNLIB_CLASS namespace wxMSWImpl { // ---------------------------------------------------------------------------- // Temporarily change the DPI Awareness context to GDIScaled or System // ---------------------------------------------------------------------------- class AutoSystemDpiAware { #define WXDPI_AWARENESS_CONTEXT_UNAWARE ((WXDPI_AWARENESS_CONTEXT)-1) #define WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((WXDPI_AWARENESS_CONTEXT)-2) #define WXDPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((WXDPI_AWARENESS_CONTEXT)-5) typedef WXDPI_AWARENESS_CONTEXT (WINAPI *SetThreadDpiAwarenessContext_t)(WXDPI_AWARENESS_CONTEXT); public: AutoSystemDpiAware() : m_prevContext(WXDPI_AWARENESS_CONTEXT_UNAWARE) { if ( !Needed() ) return; if ( ms_pfnSetThreadDpiAwarenessContext == (SetThreadDpiAwarenessContext_t)-1) { wxLoadedDLL dllUser32("user32.dll"); wxDL_INIT_FUNC(ms_pfn, SetThreadDpiAwarenessContext, dllUser32); } if ( ms_pfnSetThreadDpiAwarenessContext ) { m_prevContext = ms_pfnSetThreadDpiAwarenessContext( WXDPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED); if ( !m_prevContext ) { m_prevContext = ms_pfnSetThreadDpiAwarenessContext( WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE); } } } ~AutoSystemDpiAware() { if ( ms_pfnSetThreadDpiAwarenessContext && ms_pfnSetThreadDpiAwarenessContext != (SetThreadDpiAwarenessContext_t)-1 ) { ms_pfnSetThreadDpiAwarenessContext(m_prevContext); } } static bool Needed() { // use system-dpi-aware context when: // - the user did not set an option to force per-monitor context // - there are displays with different DPI if ( wxSystemOptions::GetOptionInt("msw.native-dialogs-pmdpi") == 1 ) return false; bool diferentDPI = false; for ( unsigned i = 1; i < wxDisplay::GetCount() && !diferentDPI; ++i ) diferentDPI = wxDisplay(0u).GetPPI() != wxDisplay(i).GetPPI(); return diferentDPI; } private: WXDPI_AWARENESS_CONTEXT m_prevContext; // This static member is defined in src/msw/window.cpp. static SetThreadDpiAwarenessContext_t ms_pfnSetThreadDpiAwarenessContext; }; #else // !wxUSE_DYNLIB_CLASS // Just a stub to avoid littering the code with wxUSE_DYNLIB_CLASS checks. class AutoSystemDpiAware { }; #endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS } // namespace wxMSWImpl #endif // _WX_MSW_DPI_AWARE_H_