diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 09bde1ceb0..38e7e5c9dc 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -547,44 +547,46 @@ JUCE_API double getScaleFactorForWindow (HWND h) return 1.0; } -#if JUCE_WIN_PER_MONITOR_DPI_AWARE - JUCE_API void setThreadDPIAwarenessForWindow (HWND nativeWindow) - { - // NB. Using local functions here because we need to call this method from the plug-in wrappers - // which don't load the DPI-awareness functions on startup - static SetThreadDPIAwarenessContextFunc localSetThreadDPIAwarenessContext = nullptr; - static GetWindowDPIAwarenessContextFunc localGetWindowDPIAwarenessContext = nullptr; - static GetThreadDPIAwarenessContextFunc localGetThreadDPIAwarenessContext = nullptr; - static GetAwarenessFromDpiAwarenessContextFunc localGetAwarenessFromDPIAwarenessContext = nullptr; - - static bool hasChecked = false; - static bool loadedOK = false; - - if (! hasChecked) - { - hasChecked = true; - - localSetThreadDPIAwarenessContext = (SetThreadDPIAwarenessContextFunc) getUser32Function ("SetThreadDpiAwarenessContext"); - localGetWindowDPIAwarenessContext = (GetWindowDPIAwarenessContextFunc) getUser32Function ("GetWindowDpiAwarenessContext"); - localGetThreadDPIAwarenessContext = (GetThreadDPIAwarenessContextFunc) getUser32Function ("GetThreadDpiAwarenessContext"); - localGetAwarenessFromDPIAwarenessContext = (GetAwarenessFromDpiAwarenessContextFunc) getUser32Function ("GetAwarenessFromDpiAwarenessContext"); - - loadedOK = (localSetThreadDPIAwarenessContext != nullptr && localGetWindowDPIAwarenessContext != nullptr - && localGetThreadDPIAwarenessContext != nullptr && localGetAwarenessFromDPIAwarenessContext != nullptr); - } - - if (loadedOK) - { - auto dpiAwareWindow = localGetAwarenessFromDPIAwarenessContext (localGetWindowDPIAwarenessContext (nativeWindow)) == DPI_Awareness::DPI_Awareness_Per_Monitor_Aware; - auto dpiAwareThread = localGetAwarenessFromDPIAwarenessContext (localGetThreadDPIAwarenessContext()) == DPI_Awareness::DPI_Awareness_Per_Monitor_Aware; - - if (dpiAwareWindow && ! dpiAwareThread) - localSetThreadDPIAwarenessContext (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); - else if (! dpiAwareWindow && dpiAwareThread) - localSetThreadDPIAwarenessContext (DPI_AWARENESS_CONTEXT_UNAWARE); - } - } -#endif +JUCE_API void setThreadDPIAwarenessForWindow (HWND nativeWindow) +{ + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + // NB. Using local functions here because we need to call this method from the plug-in wrappers + // which don't load the DPI-awareness functions on startup + static SetThreadDPIAwarenessContextFunc localSetThreadDPIAwarenessContext = nullptr; + static GetWindowDPIAwarenessContextFunc localGetWindowDPIAwarenessContext = nullptr; + static GetThreadDPIAwarenessContextFunc localGetThreadDPIAwarenessContext = nullptr; + static GetAwarenessFromDpiAwarenessContextFunc localGetAwarenessFromDPIAwarenessContext = nullptr; + + static bool hasChecked = false; + static bool loadedOK = false; + + if (! hasChecked) + { + hasChecked = true; + + localSetThreadDPIAwarenessContext = (SetThreadDPIAwarenessContextFunc) getUser32Function ("SetThreadDpiAwarenessContext"); + localGetWindowDPIAwarenessContext = (GetWindowDPIAwarenessContextFunc) getUser32Function ("GetWindowDpiAwarenessContext"); + localGetThreadDPIAwarenessContext = (GetThreadDPIAwarenessContextFunc) getUser32Function ("GetThreadDpiAwarenessContext"); + localGetAwarenessFromDPIAwarenessContext = (GetAwarenessFromDpiAwarenessContextFunc) getUser32Function ("GetAwarenessFromDpiAwarenessContext"); + + loadedOK = (localSetThreadDPIAwarenessContext != nullptr && localGetWindowDPIAwarenessContext != nullptr + && localGetThreadDPIAwarenessContext != nullptr && localGetAwarenessFromDPIAwarenessContext != nullptr); + } + + if (loadedOK) + { + auto dpiAwareWindow = localGetAwarenessFromDPIAwarenessContext (localGetWindowDPIAwarenessContext (nativeWindow)) == DPI_Awareness::DPI_Awareness_Per_Monitor_Aware; + auto dpiAwareThread = localGetAwarenessFromDPIAwarenessContext (localGetThreadDPIAwarenessContext()) == DPI_Awareness::DPI_Awareness_Per_Monitor_Aware; + + if (dpiAwareWindow && ! dpiAwareThread) + localSetThreadDPIAwarenessContext (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); + else if (! dpiAwareWindow && dpiAwareThread) + localSetThreadDPIAwarenessContext (DPI_AWARENESS_CONTEXT_UNAWARE); + } + #else + ignoreUnused (nativeWindow); + #endif +} //============================================================================== static void setWindowPos (HWND hwnd, Rectangle bounds, UINT flags, bool adjustTopLeft = false) diff --git a/modules/juce_gui_extra/embedding/juce_HWNDComponent.h b/modules/juce_gui_extra/embedding/juce_HWNDComponent.h index 34761652c0..dc7c4492b7 100644 --- a/modules/juce_gui_extra/embedding/juce_HWNDComponent.h +++ b/modules/juce_gui_extra/embedding/juce_HWNDComponent.h @@ -71,6 +71,9 @@ public: /** Resizes this component to fit the HWND that it contains. */ void resizeToFit(); + /** @internal */ + void paint (Graphics&) override; + private: class Pimpl; std::unique_ptr pimpl; diff --git a/modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp b/modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp index c4d6ef77eb..1a65de43cd 100644 --- a/modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp +++ b/modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp @@ -26,6 +26,8 @@ namespace juce { +void setThreadDPIAwarenessForWindow (HWND); + class HWNDComponent::Pimpl : public ComponentMovementWatcher { public: @@ -44,27 +46,21 @@ public: DestroyWindow (hwnd); } - using ComponentMovementWatcher::componentMovedOrResized; - - void componentMovedOrResized (bool wasMoved, bool wasResized) override + void componentMovedOrResized (bool, bool) override { - auto* topComponent = owner.getTopLevelComponent(); - - if (auto* peer = owner.getPeer()) + if (auto* peer = owner.getTopLevelComponent()->getPeer()) { - auto pos = topComponent->getLocalPoint (&owner, Point()); + auto area = (peer->getAreaCoveredBy (owner).toFloat() * peer->getPlatformScaleFactor()).toNearestInt(); - auto scaled = (Rectangle (pos.x, pos.y, owner.getWidth(), owner.getHeight()).toDouble() - * peer->getPlatformScaleFactor()).getSmallestIntegerContainer(); + setThreadDPIAwarenessForWindow (hwnd); - DWORD windowFlags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER; - if (! wasMoved) windowFlags |= SWP_NOMOVE; - if (! wasResized) windowFlags |= SWP_NOSIZE; - - SetWindowPos (hwnd, nullptr, scaled.getX(), scaled.getY(), scaled.getWidth(), scaled.getHeight(), windowFlags); + SetWindowPos (hwnd, nullptr, area.getX(), area.getY(), area.getWidth(), area.getHeight(), + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER); } } + using ComponentMovementWatcher::componentMovedOrResized; + void componentPeerChanged() override { auto* peer = owner.getPeer(); @@ -85,13 +81,13 @@ public: InvalidateRect (hwnd, nullptr, 0); } - using ComponentMovementWatcher::componentVisibilityChanged; - void componentVisibilityChanged() override { componentPeerChanged(); } + using ComponentMovementWatcher::componentVisibilityChanged; + void componentBroughtToFront (Component& comp) override { ComponentMovementWatcher::componentBroughtToFront (comp); @@ -101,11 +97,13 @@ public: { if (auto* peer = owner.getPeer()) { + setThreadDPIAwarenessForWindow (hwnd); + RECT r; GetWindowRect (hwnd, &r); + Rectangle windowRectangle (r.right - r.left, r.bottom - r.top); - return (Rectangle::leftTopRightBottom (r.left, r.top, r.right, r.bottom).toDouble() - / peer->getPlatformScaleFactor()).getSmallestIntegerContainer(); + return (windowRectangle.toFloat() / peer->getPlatformScaleFactor()).toNearestInt(); } return {}; @@ -120,7 +118,8 @@ private: { auto windowFlags = GetWindowLongPtr (hwnd, -16); - windowFlags &= ~(WS_POPUP | WS_CHILD); + windowFlags &= ~WS_POPUP; + windowFlags |= WS_CHILD; SetWindowLongPtr (hwnd, -16, windowFlags); SetParent (hwnd, (HWND) currentPeer->getNativeHandle()); @@ -131,6 +130,7 @@ private: void removeFromParent() { + ShowWindow (hwnd, SW_HIDE); SetParent (hwnd, NULL); } @@ -141,12 +141,11 @@ private: }; //============================================================================== -HWNDComponent::HWNDComponent() -{ -} - +HWNDComponent::HWNDComponent() {} HWNDComponent::~HWNDComponent() {} +void HWNDComponent::paint (Graphics&) {} + void HWNDComponent::setHWND (void* hwnd) { if (hwnd != getHWND())