WindowSystemEvent
Qt中为WindowSystemEvent事件定义了处理函数Handler,通过宏定义和模版来声明定义
---- QT_DEFINE_QPA_EVENT_HANDLER Matches (25 in 1 files) ----
qwindowsysteminterface.cpp (gui\kernel) line 199 : #define QT_DEFINE_QPA_EVENT_HANDLER(ReturnType, HandlerName, ...) \
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleEnterEvent, QWindow *window, const QPointF &local, const QPointF &global)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleLeaveEvent, QWindow *window)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleFocusWindowChanged, QWindow *window, Qt::FocusReason r)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowStates newState, int oldState)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowScreenChanged, QWindow *window, QScreen *screen)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowDevicePixelRatioChanged, QWindow *window)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleSafeAreaMarginsChanged, QWindow *window)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::ApplicationState newState, bool forcePropagate)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleApplicationTermination)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleExposeEvent, QWindow *window, const QRegion ®ion)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handlePaintEvent, QWindow *window, const QRegion ®ion)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleCloseEvent, QWindow *window)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window,
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, const QPointingDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong timestamp,
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong timestamp, const QPointingDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleKeyEvent, QWindow *window, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleKeyEvent, QWindow *window, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, const QPointingDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, ulong timestamp, const QPointingDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, const QPointingDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, ulong timestamp, const QPointingDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER in qwindowsysteminterface.cpp (gui\kernel) : QT_DEFINE_QPA_EVENT_HANDLER(void, handleThemeChange, QWindow *window)
以MouseEvent为例,最重将事件append到 windowSystemEventQueue 队列里面,然后wakeUp可能休眠的EventDispatcher:
template<>
template<typename EventType, typename ...Args>
bool QWindowSystemHelper<QWindowSystemInterface::AsynchronousDelivery>::handleEvent(Args ...args)
{
QWindowSystemInterfacePrivate::windowSystemEventQueue.append(new EventType(args...));
if (QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher())
dispatcher->wakeUp();
return true;
}
template <typename EventType, typename Delivery = QWindowSystemInterface::DefaultDelivery, typename ...Args>
static bool handleWindowSystemEvent(Args ...args)
{
return QWindowSystemHelper<Delivery>::template handleEvent<EventType>(args...);
}
#define QT_DEFINE_QPA_EVENT_HANDLER(ReturnType, HandlerName, ...) \
template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::DefaultDelivery>(__VA_ARGS__); \
template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::SynchronousDelivery>(__VA_ARGS__); \
template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::AsynchronousDelivery>(__VA_ARGS__); \
template<typename Delivery> ReturnType QWindowSystemInterface::HandlerName(__VA_ARGS__)
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
return handleMouseEvent<Delivery>(window, time, local, global, state, button, type, mods, source);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, const QPointingDevice *device,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
return handleMouseEvent<Delivery>(window, time, device, local, global, state, button, type, mods, source);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong timestamp,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
return handleMouseEvent<Delivery>(window, timestamp, QPointingDevice::primaryPointingDevice(),
local, global, state, button, type, mods, source);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
bool isNonClientArea = {};
switch (type) {
case QEvent::MouseButtonDblClick:
case QEvent::NonClientAreaMouseButtonDblClick:
Q_ASSERT_X(false, "QWindowSystemInterface::handleMouseEvent",
"QTBUG-71263: Native double clicks are not implemented.");
return false;
case QEvent::MouseMove:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
isNonClientArea = false;
break;
case QEvent::NonClientAreaMouseMove:
case QEvent::NonClientAreaMouseButtonPress:
case QEvent::NonClientAreaMouseButtonRelease:
isNonClientArea = true;
break;
default:
Q_UNREACHABLE();
}
auto localPos = QHighDpi::fromNativeLocalPosition(local, window);
auto globalPos = QHighDpi::fromNativeGlobalPosition(global, window);
return handleWindowSystemEvent<QWindowSystemInterfacePrivate::MouseEvent, Delivery>(window,
timestamp, localPos, globalPos, state, mods, button, type, source, isNonClientArea, device);
}
/*!
\brief Main windows procedure registered for windows.
\sa QWindowsGuiEventDispatcher
*/
bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
QtWindows::WindowsEventType et,
WPARAM wParam, LPARAM lParam,
LRESULT *result,
QWindowsWindow **platformWindowPtr)
{
......
......
case QtWindows::MouseWheelEvent:
case QtWindows::MouseEvent:
case QtWindows::LeaveEvent:
{
QWindow *window = platformWindow->window();
while (window && (window->flags() & Qt::WindowTransparentForInput))
window = window->parent();
if (!window)
return false;
if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer)
return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result);
else
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result);
}
break;
......
......
}
struct QWindowsContextPrivate {
QWindowsContextPrivate();
......
......
QWindowsMouseHandler m_mouseHandler;
QWindowsPointerHandler m_pointerHandler;
......
......
};
bool QWindowsMouseHandler::translateMouseEvent(QWindow *window,
HWND hwnd,
QtWindows::WindowsEventType et,
MSG msg,
LRESULT *result)
{
......
......
if (!discardEvent && mouseEvent.type != QEvent::None) {
QWindowSystemInterface::handleMouseEvent(window, device, clientPosition, globalPosition, buttons,
mouseEvent.button, mouseEvent.type,
keyModifiers, source);
}
......
......
}
extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result;
const QtWindows::WindowsEventType et = windowsEventType(message, wParam, lParam);
QWindowsWindow *platformWindow = nullptr;
const RECT ncCalcSizeFrame = rectFromNcCalcSize(message, wParam, lParam, 0);
const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow);
......
......
if (!handled)
result = DefWindowProc(hwnd, message, wParam, lParam);
......
......
return result;
}
// Window class registering code (from qapplication_win.cpp)
QString QWindowsContext::registerWindowClass(const QWindow *w)
{
......
......
return registerWindowClass(cname, qWindowsWndProc, style, nullptr, icon);
}
QString QWindowsContext::registerWindowClass(QString cname,
WNDPROC proc,
unsigned style,
HBRUSH brush,
bool icon)
{
// since multiple Qt versions can be used in one process
// each one has to have window class names with a unique name
// The first instance gets the unmodified name; if the class
// has already been registered by another instance of Qt then
// add a UUID. The check needs to be performed for each name
// in case new message windows are added (QTBUG-81347).
// Note: GetClassInfo() returns != 0 when a class exists.
const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));
......
......
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = style;
wc.lpfnWndProc = proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = appInstance;
wc.hCursor = nullptr;
wc.hbrBackground = brush;
......
......
wc.lpszMenuName = nullptr;
wc.lpszClassName = reinterpret_cast<LPCWSTR>(cname.utf16());
ATOM atom = RegisterClassEx(&wc);
......
......
return cname;
}
QWindowsWindowData WindowCreationData::create(const QWindow *w, const WindowData &data, QString title) const
{
WindowData result;
result.flags = flags;
const auto appinst = reinterpret_cast<HINSTANCE>(GetModuleHandle(nullptr));
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);
const QScreen *screen{};
const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,defaultWindowWidth, defaultWindowHeight,&screen);
......
......
result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,style,pos.x(), pos.y(),
context->frameWidth, context->frameHeight,
parentHandle, nullptr, appinst, nullptr);
......
......
return result;
}
============================================================================================================================================
下面看看是如何消费windowSystemEventQueue中的事件
void QWindowsGuiEventDispatcher::sendPostedEvents()
{
QEventDispatcherWin32::sendPostedEvents();
QWindowSystemInterface::sendWindowSystemEvents(m_flags);
}
bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
{
int nevents = 0;
while (QWindowSystemInterfacePrivate::windowSystemEventsQueued()) {
QWindowSystemInterfacePrivate::WindowSystemEvent *event =
flags & QEventLoop::ExcludeUserInputEvents ?
QWindowSystemInterfacePrivate::getNonUserInputWindowSystemEvent() :
QWindowSystemInterfacePrivate::getWindowSystemEvent();
if (!event)
break;
if (QWindowSystemInterfacePrivate::eventHandler) {
if (QWindowSystemInterfacePrivate::eventHandler->sendEvent(event))
nevents++;
} else {
nevents++;
QGuiApplicationPrivate::processWindowSystemEvent(event);
}
// Record the accepted state for the processed event
// (excluding flush events). This state can then be
// returned by flushWindowSystemEvents().
if (event->type != QWindowSystemInterfacePrivate::FlushEvents)
QWindowSystemInterfacePrivate::eventAccepted.storeRelaxed(event->eventAccepted);
delete event;
}
return (nevents > 0);
}
void Q_TRACE_INSTRUMENT(qtgui) QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
{
Q_TRACE_PARAM_REPLACE(QWindowSystemInterfacePrivate::WindowSystemEvent *, int);
Q_TRACE_SCOPE(QGuiApplicationPrivate_processWindowSystemEvent, e->type);
switch(e->type) {
case QWindowSystemInterfacePrivate::Mouse:
QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
break;
......
......
default:
qWarning() << "Unknown user input event type:" << e->type;
break;
}
}
void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
{
QWindow *window = e->window.data();
......
......
QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, e->buttons, e->modifiers, e->source, device);
......
QGuiApplication::sendSpontaneousEvent(window, &ev);
......
......
}
bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
{
......
......
event->m_spont = true;
return notifyInternal2(receiver, event);
}
bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
{
......
......
return self->notify(receiver, event);
}
bool QCoreApplication::notify(QObject *receiver, QEvent *event)
{
Q_ASSERT(receiver);
Q_ASSERT(event);
#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed()
== QCoreApplicationPrivate::mainThread());
#endif
// no events are delivered after ~QCoreApplication() has started
if (QCoreApplicationPrivate::is_app_closing)
return true;
return doNotify(receiver, event);
}
static bool doNotify(QObject *receiver, QEvent *event)
{
......
......
return receiver->isWidgetType() ? false : QCoreApplicationPrivate::notify_helper(receiver, event);
}
bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
{
// Note: when adjusting the tracepoints in here
// consider adjusting QApplicationPrivate::notify_helper too.
Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type());
bool consumed = false;
bool filtered = false;
Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered);
// send to all application event filters (only does anything in the main thread)
if (receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread()
&& QCoreApplication::self
&& QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
filtered = true;
return filtered;
}
// send to all receiver event filters
if (sendThroughObjectEventFilters(receiver, event)) {
filtered = true;
return filtered;
}
// deliver the event
consumed = receiver->event(event);
return consumed;
}
分类:
QT
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探