diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index 4762872902..70d2da0865 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -174,6 +174,8 @@ #include "native/accessibility/juce_UIAProviders_windows.h" #include "native/accessibility/juce_AccessibilityElement_windows.cpp" #include "native/accessibility/juce_Accessibility_windows.cpp" + #include "native/juce_WindowsHooks_windows.h" + #include "native/juce_WindowsHooks_windows.cpp" #include "native/juce_WindowUtils_windows.cpp" #include "native/juce_Windowing_windows.cpp" #include "native/juce_NativeMessageBox_windows.cpp" diff --git a/modules/juce_gui_basics/native/juce_WindowsHooks_windows.cpp b/modules/juce_gui_basics/native/juce_WindowsHooks_windows.cpp new file mode 100644 index 0000000000..6557f3c9b7 --- /dev/null +++ b/modules/juce_gui_basics/native/juce_WindowsHooks_windows.cpp @@ -0,0 +1,108 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2022 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 7 End-User License + Agreement and JUCE Privacy Policy. + + End User License Agreement: www.juce.com/juce-7-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#if JUCE_WINDOWS + +namespace juce::detail +{ + +// This function is in juce_win32_Windowing.cpp +bool offerKeyMessageToJUCEWindow (MSG&); + +class WindowsHooks::Hooks +{ +public: + Hooks() = default; + + ~Hooks() + { + if (mouseWheelHook != nullptr) + UnhookWindowsHookEx (mouseWheelHook); + + if (keyboardHook != nullptr) + UnhookWindowsHookEx (keyboardHook); + } + + static inline std::weak_ptr weak; + +private: + static LRESULT CALLBACK mouseWheelHookCallback (int nCode, WPARAM wParam, LPARAM lParam) + { + if (nCode >= 0 && wParam == WM_MOUSEWHEEL) + { + // using a local copy of this struct to support old mingw libraries + struct MOUSEHOOKSTRUCTEX_ : public MOUSEHOOKSTRUCT { DWORD mouseData; }; + + auto& hs = *(MOUSEHOOKSTRUCTEX_*) lParam; + + if (auto* comp = Desktop::getInstance().findComponentAt ({ hs.pt.x, hs.pt.y })) + if (comp->getWindowHandle() != nullptr) + return PostMessage ((HWND) comp->getWindowHandle(), WM_MOUSEWHEEL, + hs.mouseData & 0xffff0000, (hs.pt.x & 0xffff) | (hs.pt.y << 16)); + } + + return CallNextHookEx (getSingleton()->mouseWheelHook, nCode, wParam, lParam); + } + + static LRESULT CALLBACK keyboardHookCallback (int nCode, WPARAM wParam, LPARAM lParam) + { + MSG& msg = *(MSG*) lParam; + + if (nCode == HC_ACTION && wParam == PM_REMOVE + && offerKeyMessageToJUCEWindow (msg)) + { + zerostruct (msg); + msg.message = WM_USER; + return 0; + } + + return CallNextHookEx (getSingleton()->keyboardHook, nCode, wParam, lParam); + } + + HHOOK mouseWheelHook = SetWindowsHookEx (WH_MOUSE, + mouseWheelHookCallback, + (HINSTANCE) juce::Process::getCurrentModuleInstanceHandle(), + GetCurrentThreadId()); + HHOOK keyboardHook = SetWindowsHookEx (WH_GETMESSAGE, + keyboardHookCallback, + (HINSTANCE) juce::Process::getCurrentModuleInstanceHandle(), + GetCurrentThreadId()); +}; + +auto WindowsHooks::getSingleton() -> std::shared_ptr +{ + auto& weak = Hooks::weak; + + if (auto locked = weak.lock()) + return locked; + + auto strong = std::make_shared(); + weak = strong; + return strong; +} + +} // namespace juce::detail + +#endif diff --git a/modules/juce_gui_basics/native/juce_WindowsHooks_windows.h b/modules/juce_gui_basics/native/juce_WindowsHooks_windows.h index a37c04dad2..057289f551 100644 --- a/modules/juce_gui_basics/native/juce_WindowsHooks_windows.h +++ b/modules/juce_gui_basics/native/juce_WindowsHooks_windows.h @@ -28,85 +28,17 @@ namespace juce::detail { -// This function is in juce_win32_Windowing.cpp -bool offerKeyMessageToJUCEWindow (MSG&); - class WindowsHooks { public: WindowsHooks() = default; private: - static LRESULT CALLBACK mouseWheelHookCallback (int nCode, WPARAM wParam, LPARAM lParam) - { - if (nCode >= 0 && wParam == WM_MOUSEWHEEL) - { - // using a local copy of this struct to support old mingw libraries - struct MOUSEHOOKSTRUCTEX_ : public MOUSEHOOKSTRUCT { DWORD mouseData; }; + class Hooks; - auto& hs = *(MOUSEHOOKSTRUCTEX_*) lParam; + static std::shared_ptr getSingleton(); - if (auto* comp = Desktop::getInstance().findComponentAt ({ hs.pt.x, hs.pt.y })) - if (comp->getWindowHandle() != nullptr) - return PostMessage ((HWND) comp->getWindowHandle(), WM_MOUSEWHEEL, - hs.mouseData & 0xffff0000, (hs.pt.x & 0xffff) | (hs.pt.y << 16)); - } - - return CallNextHookEx (getSingleton()->mouseWheelHook, nCode, wParam, lParam); - } - - static LRESULT CALLBACK keyboardHookCallback (int nCode, WPARAM wParam, LPARAM lParam) - { - MSG& msg = *(MSG*) lParam; - - if (nCode == HC_ACTION && wParam == PM_REMOVE - && offerKeyMessageToJUCEWindow (msg)) - { - zerostruct (msg); - msg.message = WM_USER; - return 1; - } - - return CallNextHookEx (getSingleton()->keyboardHook, nCode, wParam, lParam); - } - - class Hooks - { - public: - Hooks() = default; - - ~Hooks() - { - if (mouseWheelHook != nullptr) - UnhookWindowsHookEx (mouseWheelHook); - - if (keyboardHook != nullptr) - UnhookWindowsHookEx (keyboardHook); - } - - HHOOK mouseWheelHook = SetWindowsHookEx (WH_MOUSE, - mouseWheelHookCallback, - (HINSTANCE) juce::Process::getCurrentModuleInstanceHandle(), - GetCurrentThreadId()); - HHOOK keyboardHook = SetWindowsHookEx (WH_GETMESSAGE, - keyboardHookCallback, - (HINSTANCE) juce::Process::getCurrentModuleInstanceHandle(), - GetCurrentThreadId()); - }; - - static std::shared_ptr getSingleton() - { - static std::weak_ptr weak; - - if (auto locked = weak.lock()) - return locked; - - auto strong = std::make_shared(); - weak = strong; - return strong; - } - - std::shared_ptr hooks = getSingleton(); + std::shared_ptr hooks = getSingleton(); }; } // namespace juce::detail