summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2014-06-06 14:26:26 +0200
committerFriedemann Kleint <Friedemann.Kleint@digia.com>2014-06-19 17:23:16 +0200
commitfeda990ae8fa3bc25ad5b5b7f7cc4733137519d6 (patch)
treee3fee4bb8c8db1722c9f06ed5dc644d6e239e159 /src/corelib/kernel
parent54a2206bba699687c4218bde2d9b295c2cf5a549 (diff)
QEventDispatcherWin32: Use a shared class name for the message window.
Introduce a global-static struct storing atom and class name for the message window to be shared between threads. This prevents RegisterWindow()/UnregisterWindow() of different threads (using exec()) from interfering and silently failing. Task-number: QTBUG-39471 Change-Id: I9bc1106a41f64749c55825a96973921bb831458f Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp54
1 files changed, 45 insertions, 9 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 64ad2ff0d3..db2d30f2f5 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -325,8 +325,6 @@ QEventDispatcherWin32Private::~QEventDispatcherWin32Private()
{
if (internalHwnd)
DestroyWindow(internalHwnd);
- QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
- UnregisterClass((wchar_t*)className.utf16(), qWinAppInst());
}
void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen)
@@ -486,10 +484,26 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
#endif
}
-static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
+// Provide class name and atom for the message window used by
+// QEventDispatcherWin32Private via Q_GLOBAL_STATIC shared between threads.
+struct QWindowsMessageWindowClassContext
+{
+ QWindowsMessageWindowClassContext();
+ ~QWindowsMessageWindowClassContext();
+
+ ATOM atom;
+ wchar_t *className;
+};
+
+QWindowsMessageWindowClassContext::QWindowsMessageWindowClassContext()
+ : atom(0), className(0)
{
// make sure that multiple Qt's can coexist in the same process
- QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
+ const QString qClassName = QStringLiteral("QEventDispatcherWin32_Internal_Widget")
+ + QString::number(quintptr(qt_internal_proc));
+ className = new wchar_t[qClassName.size() + 1];
+ qClassName.toWCharArray(className);
+ className[qClassName.size()] = 0;
WNDCLASS wc;
wc.style = 0;
@@ -501,16 +515,37 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
wc.hCursor = 0;
wc.hbrBackground = 0;
wc.lpszMenuName = NULL;
- wc.lpszClassName = reinterpret_cast<const wchar_t *> (className.utf16());
+ wc.lpszClassName = className;
+ atom = RegisterClass(&wc);
+ if (!atom) {
+ qErrnoWarning("%s: RegisterClass() failed", Q_FUNC_INFO, qPrintable(qClassName));
+ delete [] className;
+ className = 0;
+ }
+}
+
+QWindowsMessageWindowClassContext::~QWindowsMessageWindowClassContext()
+{
+ if (className) {
+ UnregisterClass(className, qWinAppInst());
+ delete [] className;
+ }
+}
+
+Q_GLOBAL_STATIC(QWindowsMessageWindowClassContext, qWindowsMessageWindowClassContext)
- RegisterClass(&wc);
+static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
+{
+ QWindowsMessageWindowClassContext *ctx = qWindowsMessageWindowClassContext();
+ if (!ctx->atom)
+ return 0;
#ifdef Q_OS_WINCE
HWND parent = 0;
#else
HWND parent = HWND_MESSAGE;
#endif
- HWND wnd = CreateWindow(wc.lpszClassName, // classname
- wc.lpszClassName, // window name
+ HWND wnd = CreateWindow(ctx->className, // classname
+ ctx->className, // window name
0, // style
0, 0, 0, 0, // geometry
parent, // parent
@@ -519,7 +554,8 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
0); // windows creation data.
if (!wnd) {
- qWarning("QEventDispatcher: Failed to create QEventDispatcherWin32 internal window: %d\n", (int)GetLastError());
+ qErrnoWarning("%s: CreateWindow() for QEventDispatcherWin32 internal window failed", Q_FUNC_INFO);
+ return 0;
}
#ifdef GWLP_USERDATA