15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
51
52
53
54
55
56
57
58
59
60
61
62
65
66
68QWinEventNotifier::QWinEventNotifier(QObject *parent)
69 : QObject(*
new QWinEventNotifierPrivate, parent)
73
74
75
76
77
78
79
80
81
83QWinEventNotifier::QWinEventNotifier(HANDLE hEvent, QObject *parent)
84 : QObject(*
new QWinEventNotifierPrivate(hEvent,
false), parent)
90
91
93QWinEventNotifier::~QWinEventNotifier()
99
100
101
102
103
104
105
106
108void QWinEventNotifier::setHandle(HANDLE hEvent)
110 Q_D(QWinEventNotifier);
112 d->handleToEvent = hEvent;
116
117
118
119
121HANDLE QWinEventNotifier::handle()
const
123 Q_D(
const QWinEventNotifier);
124 return d->handleToEvent;
128
129
130
131
133bool QWinEventNotifier::isEnabled()
const
135 Q_D(
const QWinEventNotifier);
140
141
142
143
144
146void QWinEventNotifier::setEnabled(
bool enable)
148 Q_D(QWinEventNotifier);
149 if (d->enabled == enable)
153 if (Q_UNLIKELY(thread() != QThread::currentThread())) {
154 qWarning(
"QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread");
162 d->winEventActPosted.testAndSetRelaxed(QWinEventNotifierPrivate::Posted,
163 QWinEventNotifierPrivate::IgnorePosted);
166 Q_ASSERT(!d->registered);
167 SetThreadpoolWait(d->waitObject, d->handleToEvent, NULL);
168 d->registered =
true;
169 }
else if (d->registered) {
172 SetThreadpoolWait(d->waitObject, NULL, NULL);
176 WaitForThreadpoolWaitCallbacks(d->waitObject, TRUE);
177 d->registered =
false;
182
183
185bool QWinEventNotifier::event(QEvent * e)
187 Q_D(QWinEventNotifier);
190 case QEvent::ThreadChange:
192 QMetaObject::invokeMethod(
this,
"setEnabled", Qt::QueuedConnection,
197 case QEvent::WinEventAct:
201 if (d->winEventActPosted.fetchAndStoreRelaxed(QWinEventNotifierPrivate::NotPosted)
202 == QWinEventNotifierPrivate::Posted && d->enabled) {
205 d->registered =
false;
207 QPointer<QWinEventNotifier> alive(
this);
208 emit activated(d->handleToEvent, QPrivateSignal());
210 if (alive && d->enabled && !d->registered) {
211 SetThreadpoolWait(d->waitObject, d->handleToEvent, NULL);
212 d->registered =
true;
219 return QObject::event(e);
222QWinEventNotifierPrivate::QWinEventNotifierPrivate(HANDLE h,
bool e)
223 : handleToEvent(h), enabled(e), registered(
false)
225 waitObject = CreateThreadpoolWait(waitCallback,
this, NULL);
226 if (waitObject == NULL)
227 qErrnoWarning(
"QWinEventNotifier:: CreateThreadpollWait failed.");
230QWinEventNotifierPrivate::~QWinEventNotifierPrivate()
232 CloseThreadpoolWait(waitObject);
235void QWinEventNotifierPrivate::waitCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
236 PTP_WAIT wait, TP_WAIT_RESULT waitResult)
240 Q_UNUSED(waitResult);
241 QWinEventNotifierPrivate *nd =
reinterpret_cast<QWinEventNotifierPrivate *>(context);
245 if (nd->winEventActPosted.fetchAndStoreRelaxed(QWinEventNotifierPrivate::Posted)
246 == QWinEventNotifierPrivate::NotPosted) {
247 QCoreApplication::postEvent(nd->q_func(),
new QEvent(QEvent::WinEventAct));
253#include "moc_qwineventnotifier.cpp"
Combined button and popup list for selecting options.