LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) { if (wp == PM_REMOVE) { QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance()); Q_ASSERT(q != 0); if (q) { QEventDispatcherWin32Private *d = q->d_func(); int localSerialNumber = d->serialNumber; if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0) { // no more input or timer events in the message queue, we can allow posted events to be // sent now (void) d->wakeUps.fetchAndStoreRelease(0); MSG *msg = (MSG *) lp; if (localSerialNumber != d->lastSerialNumber // if this message IS the one that triggers sendPostedEvents(), no need to post it again && (msg->hwnd != d->internalHwnd || msg->message != WM_QT_SENDPOSTEDEVENTS)) { PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); } } } } #ifdef Q_OS_WINCE return 0; #else return CallNextHookEx(0, code, wp, lp); #endif }
QWinEventNotifier::QWinEventNotifier(HANDLE hEvent, QObject *parent) : QObject(parent), handleToEvent(hEvent), enabled(false) { Q_D(QObject); QEventDispatcherWin32 *eventDispatcher = qobject_cast<QEventDispatcherWin32 *>(d->threadData->eventDispatcher); Q_ASSERT_X(eventDispatcher, "QWinEventNotifier::QWinEventNotifier()", "Cannot create a win event notifier without a QEventDispatcherWin32"); eventDispatcher->registerEventNotifier(this); enabled = true; }
void QWinEventNotifier::setEnabled(bool enable) { if (enabled == enable) // no change return; enabled = enable; Q_D(QObject); QEventDispatcherWin32 *eventDispatcher = qobject_cast<QEventDispatcherWin32 *>(d->threadData->eventDispatcher); if (!eventDispatcher) // perhaps application is shutting down return; if (enabled) eventDispatcher->registerEventNotifier(this); else eventDispatcher->unregisterEventNotifier(this); }
LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) { if (wp == PM_REMOVE) { QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance()); Q_ASSERT(q != 0); if (q) { MSG *msg = (MSG *) lp; QEventDispatcherWin32Private *d = q->d_func(); const int localSerialNumber = d->serialNumber.load(); static const UINT mask = inputTimerMask(); if (HIWORD(GetQueueStatus(mask)) == 0) { // no more input or timer events in the message queue, we can allow posted events to be sent normally now if (d->sendPostedEventsWindowsTimerId != 0) { // stop the timer to send posted events, since we now allow the WM_QT_SENDPOSTEDEVENTS message KillTimer(d->internalHwnd, d->sendPostedEventsWindowsTimerId); d->sendPostedEventsWindowsTimerId = 0; } (void) d->wakeUps.fetchAndStoreRelease(0); if (localSerialNumber != d->lastSerialNumber // if this message IS the one that triggers sendPostedEvents(), no need to post it again && (msg->hwnd != d->internalHwnd || msg->message != WM_QT_SENDPOSTEDEVENTS)) { PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); } } else if (d->sendPostedEventsWindowsTimerId == 0 && localSerialNumber != d->lastSerialNumber) { // start a special timer to continue delivering posted events while // there are still input and timer messages in the message queue d->sendPostedEventsWindowsTimerId = SetTimer(d->internalHwnd, SendPostedEventsWindowsTimerId, 0, // we specify zero, but Windows uses USER_TIMER_MINIMUM NULL); // we don't check the return value of SetTimer()... if creating the timer failed, there's little // we can do. we just have to accept that posted events will be starved } } } #ifdef Q_OS_WINCE return 0; #else return CallNextHookEx(0, code, wp, lp); #endif }
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) { if (message == WM_NCCREATE) return true; MSG msg; msg.hwnd = hwnd; msg.message = message; msg.wParam = wp; msg.lParam = lp; QCoreApplication *app = QCoreApplication::instance(); long result; if (!app) { if (message == WM_TIMER) KillTimer(hwnd, wp); return 0; } else if (app->filterEvent(&msg, &result)) { return result; } #ifdef GWLP_USERDATA QEventDispatcherWin32 *q = (QEventDispatcherWin32 *) GetWindowLongPtr(hwnd, GWLP_USERDATA); #else QEventDispatcherWin32 *q = (QEventDispatcherWin32 *) GetWindowLong(hwnd, GWL_USERDATA); #endif QEventDispatcherWin32Private *d = 0; if (q != 0) d = q->d_func(); if (message == WM_QT_SOCKETNOTIFIER) { // socket notifier message int type = -1; switch (WSAGETSELECTEVENT(lp)) { case FD_READ: case FD_CLOSE: case FD_ACCEPT: type = 0; break; case FD_WRITE: case FD_CONNECT: type = 1; break; case FD_OOB: type = 2; break; } if (type >= 0) { Q_ASSERT(d != 0); QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except }; QSNDict *dict = sn_vec[type]; QSockNot *sn = dict ? dict->value(wp) : 0; if (sn) { QEvent event(QEvent::SockAct); QCoreApplication::sendEvent(sn->obj, &event); } } return 0; } else if (message == WM_QT_SENDPOSTEDEVENTS // we also use a Windows timer to send posted events when the message queue is full || (message == WM_TIMER && d->sendPostedEventsWindowsTimerId != 0 && wp == (uint)d->sendPostedEventsWindowsTimerId)) { const int localSerialNumber = d->serialNumber.load(); if (localSerialNumber != d->lastSerialNumber) { d->lastSerialNumber = localSerialNumber; QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); } return 0; } else if (message == WM_TIMER) { Q_ASSERT(d != 0); d->sendTimerEvent(wp); return 0; } return DefWindowProc(hwnd, message, wp, lp); }