The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
7.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. class WindowsUIAWrapper : public DeletedAtShutdown
  21. {
  22. public:
  23. bool isLoaded() const noexcept
  24. {
  25. return uiaReturnRawElementProvider != nullptr
  26. && uiaHostProviderFromHwnd != nullptr
  27. && uiaRaiseAutomationPropertyChangedEvent != nullptr
  28. && uiaRaiseAutomationEvent != nullptr
  29. && uiaClientsAreListening != nullptr
  30. && uiaDisconnectProvider != nullptr
  31. && uiaDisconnectAllProviders != nullptr;
  32. }
  33. //==============================================================================
  34. LRESULT returnRawElementProvider (HWND hwnd, WPARAM wParam, LPARAM lParam, IRawElementProviderSimple* provider)
  35. {
  36. return uiaReturnRawElementProvider != nullptr ? uiaReturnRawElementProvider (hwnd, wParam, lParam, provider)
  37. : (LRESULT) nullptr;
  38. }
  39. JUCE_COMRESULT hostProviderFromHwnd (HWND hwnd, IRawElementProviderSimple** provider)
  40. {
  41. return uiaHostProviderFromHwnd != nullptr ? uiaHostProviderFromHwnd (hwnd, provider)
  42. : (HRESULT) UIA_E_NOTSUPPORTED;
  43. }
  44. JUCE_COMRESULT raiseAutomationPropertyChangedEvent (IRawElementProviderSimple* provider, PROPERTYID propID, VARIANT oldValue, VARIANT newValue)
  45. {
  46. return uiaRaiseAutomationPropertyChangedEvent != nullptr ? uiaRaiseAutomationPropertyChangedEvent (provider, propID, oldValue, newValue)
  47. : (HRESULT) UIA_E_NOTSUPPORTED;
  48. }
  49. JUCE_COMRESULT raiseAutomationEvent (IRawElementProviderSimple* provider, EVENTID eventID)
  50. {
  51. return uiaRaiseAutomationEvent != nullptr ? uiaRaiseAutomationEvent (provider, eventID)
  52. : (HRESULT) UIA_E_NOTSUPPORTED;
  53. }
  54. BOOL clientsAreListening()
  55. {
  56. return uiaClientsAreListening != nullptr ? uiaClientsAreListening()
  57. : false;
  58. }
  59. JUCE_COMRESULT disconnectProvider (IRawElementProviderSimple* provider)
  60. {
  61. if (uiaDisconnectProvider != nullptr)
  62. {
  63. const ScopedValueSetter<IRawElementProviderSimple*> disconnectingProviderSetter (disconnectingProvider, provider);
  64. return uiaDisconnectProvider (provider);
  65. }
  66. return (HRESULT) UIA_E_NOTSUPPORTED;
  67. }
  68. JUCE_COMRESULT disconnectAllProviders()
  69. {
  70. if (uiaDisconnectAllProviders != nullptr)
  71. {
  72. const ScopedValueSetter<bool> disconnectingAllProvidersSetter (disconnectingAllProviders, true);
  73. return uiaDisconnectAllProviders();
  74. }
  75. return (HRESULT) UIA_E_NOTSUPPORTED;
  76. }
  77. //==============================================================================
  78. bool isProviderDisconnecting (IRawElementProviderSimple* provider)
  79. {
  80. return disconnectingProvider == provider || disconnectingAllProviders;
  81. }
  82. //==============================================================================
  83. JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (WindowsUIAWrapper)
  84. private:
  85. //==============================================================================
  86. WindowsUIAWrapper()
  87. {
  88. // force UIA COM library initialisation here to prevent an exception when calling methods from SendMessage()
  89. if (isLoaded())
  90. returnRawElementProvider (nullptr, 0, 0, nullptr);
  91. else
  92. jassertfalse; // UIAutomationCore could not be loaded!
  93. }
  94. ~WindowsUIAWrapper()
  95. {
  96. disconnectAllProviders();
  97. if (uiaHandle != nullptr)
  98. ::FreeLibrary (uiaHandle);
  99. clearSingletonInstance();
  100. }
  101. //==============================================================================
  102. template<typename FuncType>
  103. static FuncType getUiaFunction (HMODULE module, StringRef funcName)
  104. {
  105. return (FuncType) GetProcAddress (module, funcName);
  106. }
  107. //==============================================================================
  108. using UiaReturnRawElementProviderFunc = LRESULT (WINAPI*) (HWND, WPARAM, LPARAM, IRawElementProviderSimple*);
  109. using UiaHostProviderFromHwndFunc = HRESULT (WINAPI*) (HWND, IRawElementProviderSimple**);
  110. using UiaRaiseAutomationPropertyChangedEventFunc = HRESULT (WINAPI*) (IRawElementProviderSimple*, PROPERTYID, VARIANT, VARIANT);
  111. using UiaRaiseAutomationEventFunc = HRESULT (WINAPI*) (IRawElementProviderSimple*, EVENTID);
  112. using UiaClientsAreListeningFunc = BOOL (WINAPI*) ();
  113. using UiaDisconnectProviderFunc = HRESULT (WINAPI*) (IRawElementProviderSimple*);
  114. using UiaDisconnectAllProvidersFunc = HRESULT (WINAPI*) ();
  115. HMODULE uiaHandle = ::LoadLibraryA ("UIAutomationCore.dll");
  116. UiaReturnRawElementProviderFunc uiaReturnRawElementProvider = getUiaFunction<UiaReturnRawElementProviderFunc> (uiaHandle, "UiaReturnRawElementProvider");
  117. UiaHostProviderFromHwndFunc uiaHostProviderFromHwnd = getUiaFunction<UiaHostProviderFromHwndFunc> (uiaHandle, "UiaHostProviderFromHwnd");
  118. UiaRaiseAutomationPropertyChangedEventFunc uiaRaiseAutomationPropertyChangedEvent = getUiaFunction<UiaRaiseAutomationPropertyChangedEventFunc> (uiaHandle, "UiaRaiseAutomationPropertyChangedEvent");
  119. UiaRaiseAutomationEventFunc uiaRaiseAutomationEvent = getUiaFunction<UiaRaiseAutomationEventFunc> (uiaHandle, "UiaRaiseAutomationEvent");
  120. UiaClientsAreListeningFunc uiaClientsAreListening = getUiaFunction<UiaClientsAreListeningFunc> (uiaHandle, "UiaClientsAreListening");
  121. UiaDisconnectProviderFunc uiaDisconnectProvider = getUiaFunction<UiaDisconnectProviderFunc> (uiaHandle, "UiaDisconnectProvider");
  122. UiaDisconnectAllProvidersFunc uiaDisconnectAllProviders = getUiaFunction<UiaDisconnectAllProvidersFunc> (uiaHandle, "UiaDisconnectAllProviders");
  123. IRawElementProviderSimple* disconnectingProvider = nullptr;
  124. bool disconnectingAllProviders = false;
  125. //==============================================================================
  126. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsUIAWrapper)
  127. };
  128. } // namespace juce