openshot-audio  0.1.2
juce_win32_HiddenMessageWindow.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2015 - ROLI Ltd.
6 
7  Permission is granted to use this software under the terms of either:
8  a) the GPL v2 (or any later version)
9  b) the Affero GPL v3
10 
11  Details of these licenses can be found at: www.gnu.org/licenses
12 
13  JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17  ------------------------------------------------------------------------------
18 
19  To release a closed-source product which uses JUCE, commercial licenses are
20  available: visit www.juce.com for more information.
21 
22  ==============================================================================
23 */
24 
25 #ifndef JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED
26 #define JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED
27 
28 //==============================================================================
30 {
31 public:
32  HiddenMessageWindow (const TCHAR* const messageWindowName, WNDPROC wndProc)
33  {
34  String className ("JUCE_");
36 
37  HMODULE moduleHandle = (HMODULE) Process::getCurrentModuleInstanceHandle();
38 
39  WNDCLASSEX wc = { 0 };
40  wc.cbSize = sizeof (wc);
41  wc.lpfnWndProc = wndProc;
42  wc.cbWndExtra = 4;
43  wc.hInstance = moduleHandle;
44  wc.lpszClassName = className.toWideCharPointer();
45 
46  atom = RegisterClassEx (&wc);
47  jassert (atom != 0);
48 
49  hwnd = CreateWindow (getClassNameFromAtom(), messageWindowName,
50  0, 0, 0, 0, 0, 0, 0, moduleHandle, 0);
51  jassert (hwnd != 0);
52  }
53 
55  {
56  DestroyWindow (hwnd);
57  UnregisterClass (getClassNameFromAtom(), 0);
58  }
59 
60  inline HWND getHWND() const noexcept { return hwnd; }
61 
62 private:
63  ATOM atom;
64  HWND hwnd;
65 
66  LPCTSTR getClassNameFromAtom() noexcept { return (LPCTSTR) MAKELONG (atom, 0); }
67 };
68 
69 //==============================================================================
71 {
72 public:
73  static bool isJUCEWindow (HWND hwnd) noexcept
74  {
75  return GetWindowLongPtr (hwnd, GWLP_USERDATA) == getImprobableWindowNumber();
76  }
77 
78  static void setAsJUCEWindow (HWND hwnd, bool isJuceWindow) noexcept
79  {
80  SetWindowLongPtr (hwnd, GWLP_USERDATA, isJuceWindow ? getImprobableWindowNumber() : 0);
81  }
82 
83 private:
84  static LONG_PTR getImprobableWindowNumber() noexcept
85  {
86  static LONG_PTR number = (LONG_PTR) Random::getSystemRandom().nextInt64();
87  return number;
88  }
89 };
90 
91 //==============================================================================
92 class DeviceChangeDetector : private Timer
93 {
94 public:
95  DeviceChangeDetector (const wchar_t* const name)
96  : messageWindow (name, (WNDPROC) deviceChangeEventCallback)
97  {
98  SetWindowLongPtr (messageWindow.getHWND(), GWLP_USERDATA, (LONG_PTR) this);
99  }
100 
102 
103  virtual void systemDeviceChanged() = 0;
104 
106  {
107  // We'll pause before sending a message, because on device removal, the OS hasn't always updated
108  // its device lists correctly at this point. This also helps avoid repeated callbacks.
109  startTimer (500);
110  }
111 
112 private:
114 
115  static LRESULT CALLBACK deviceChangeEventCallback (HWND h, const UINT message,
116  const WPARAM wParam, const LPARAM lParam)
117  {
118  if (message == WM_DEVICECHANGE
119  && (wParam == 0x8000 /*DBT_DEVICEARRIVAL*/
120  || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/
121  || wParam == 0x0007 /*DBT_DEVNODES_CHANGED*/))
122  {
123  ((DeviceChangeDetector*) GetWindowLongPtr (h, GWLP_USERDATA))
124  ->triggerAsyncDeviceChangeCallback();
125  }
126 
127  return DefWindowProc (h, message, wParam, lParam);
128  }
129 
130  void timerCallback() override
131  {
132  stopTimer();
133  systemDeviceChanged();
134  }
135 };
136 
137 #endif // JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED
HWND getHWND() const noexcept
Definition: juce_win32_HiddenMessageWindow.h:60
static String toHexString(int number)
Definition: juce_String.cpp:1925
Definition: juce_win32_HiddenMessageWindow.h:92
const wchar_t * toWideCharPointer() const
Definition: juce_String.cpp:2066
#define noexcept
Definition: juce_CompilerSupport.h:141
Definition: juce_String.h:43
static int64 getHighResolutionTicks() noexcept
Definition: juce_android_SystemStats.cpp:293
ScopedPointer< HiddenMessageWindow > messageWindow
Definition: juce_win32_Messaging.cpp:37
#define const
void triggerAsyncDeviceChangeCallback()
Definition: juce_win32_HiddenMessageWindow.h:105
~HiddenMessageWindow()
Definition: juce_win32_HiddenMessageWindow.h:54
static void setAsJUCEWindow(HWND hwnd, bool isJuceWindow) noexcept
Definition: juce_win32_HiddenMessageWindow.h:78
DeviceChangeDetector(const wchar_t *const name)
Definition: juce_win32_HiddenMessageWindow.h:95
static bool isJUCEWindow(HWND hwnd) noexcept
Definition: juce_win32_HiddenMessageWindow.h:73
const TCHAR messageWindowName[]
Definition: juce_win32_Messaging.cpp:36
static Random & getSystemRandom() noexcept
Definition: juce_Random.cpp:64
HiddenMessageWindow(const TCHAR *const messageWindowName, WNDPROC wndProc)
Definition: juce_win32_HiddenMessageWindow.h:32
Definition: juce_win32_HiddenMessageWindow.h:70
#define jassert(a)
Definition: juce_PlatformDefs.h:146
typedef UINT
Definition: juce_win32_Windowing.cpp:123
virtual ~DeviceChangeDetector()
Definition: juce_win32_HiddenMessageWindow.h:101
Definition: juce_Timer.h:52
Definition: juce_win32_HiddenMessageWindow.h:29
int64 nextInt64() noexcept
Definition: juce_Random.cpp:89