diff --git a/include/wx/msw/private/dpiaware.h b/include/wx/msw/private/dpiaware.h new file mode 100644 index 0000000000..2ff769fc35 --- /dev/null +++ b/include/wx/msw/private/dpiaware.h @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/private/dpiaware.h +// Purpose: AutoSystemDpiAware class +// Author: Maarten Bent +// Created: 10/6/2016 +// 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" + +#if wxUSE_DYNLIB_CLASS + +// ---------------------------------------------------------------------------- +// Temporarily change the DPI Awareness context to System +// ---------------------------------------------------------------------------- + +class AutoSystemDpiAware +{ + #define WXDPI_AWARENESS_CONTEXT_UNAWARE ((WXDPI_AWARENESS_CONTEXT)-1) + #define WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((WXDPI_AWARENESS_CONTEXT)-2) + typedef WXDPI_AWARENESS_CONTEXT + (WINAPI *SetThreadDpiAwarenessContext_t)(WXDPI_AWARENESS_CONTEXT); + +public: + AutoSystemDpiAware() + : m_prevContext(WXDPI_AWARENESS_CONTEXT_UNAWARE), + m_pfnSetThreadDpiAwarenessContext((SetThreadDpiAwarenessContext_t)-1) + { + if ( m_pfnSetThreadDpiAwarenessContext == (SetThreadDpiAwarenessContext_t)-1) + { + wxLoadedDLL dllUser32("user32.dll"); + wxDL_INIT_FUNC(m_pfn, SetThreadDpiAwarenessContext, dllUser32); + } + + if ( m_pfnSetThreadDpiAwarenessContext ) + { + m_prevContext = m_pfnSetThreadDpiAwarenessContext( + WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + } + + } + + ~AutoSystemDpiAware() + { + if ( m_pfnSetThreadDpiAwarenessContext ) + { + m_pfnSetThreadDpiAwarenessContext(m_prevContext); + } + } + +private: + WXDPI_AWARENESS_CONTEXT m_prevContext; + + SetThreadDpiAwarenessContext_t m_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 + +#endif // _WX_MSW_DPI_AWARE_H_ diff --git a/src/msw/colordlg.cpp b/src/msw/colordlg.cpp index ab9a671525..38fac558cc 100644 --- a/src/msw/colordlg.cpp +++ b/src/msw/colordlg.cpp @@ -40,6 +40,7 @@ #include "wx/scopeguard.h" #include "wx/msw/private.h" +#include "wx/msw/private/dpiaware.h" #include #include @@ -216,6 +217,8 @@ int wxColourDialog::ShowModal() gs_activeDialog = this; wxON_BLOCK_EXIT_NULL(gs_activeDialog); + AutoSystemDpiAware dpiAwareness; + // do show the modal dialog if ( !::ChooseColor(&chooseColorStruct) ) { diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index ec0529c47d..1801adcbd3 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -47,6 +47,7 @@ #include "wx/scopeguard.h" #include "wx/tokenzr.h" #include "wx/modalhook.h" +#include "wx/msw/private/dpiaware.h" // ---------------------------------------------------------------------------- // constants @@ -375,6 +376,12 @@ void wxFileDialog::MSWOnTypeChange(WXHWND WXUNUSED(hDlg), int nFilterIndex) // err is filled with the CDERR_XXX constant static bool DoShowCommFileDialog(OPENFILENAME *of, long style, DWORD *err) { + // Extra controls do not handle per-monitor DPI, fall back to system DPI + // so entire file-dialog is resized. + wxScopedPtr dpiAwareness; + if ( of->Flags & OFN_ENABLEHOOK ) + dpiAwareness.reset(new AutoSystemDpiAware()); + if ( style & wxFD_SAVE ? GetSaveFileName(of) : GetOpenFileName(of) ) return true; diff --git a/src/msw/fontdlg.cpp b/src/msw/fontdlg.cpp index 610b2c21b1..29d62d2a19 100644 --- a/src/msw/fontdlg.cpp +++ b/src/msw/fontdlg.cpp @@ -37,6 +37,7 @@ #endif #include "wx/fontutil.h" +#include "wx/msw/private/dpiaware.h" #include #include @@ -149,6 +150,8 @@ int wxFontDialog::ShowModal() chooseFontStruct.Flags = flags; + AutoSystemDpiAware dpiAwareness; + if ( ChooseFont(&chooseFontStruct) != 0 ) { wxRGBToColour(m_fontData.m_fontColour, chooseFontStruct.rgbColors);