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>
This commit is contained in:
parent
54a2206bba
commit
feda990ae8
@ -325,8 +325,6 @@ QEventDispatcherWin32Private::~QEventDispatcherWin32Private()
|
|||||||
{
|
{
|
||||||
if (internalHwnd)
|
if (internalHwnd)
|
||||||
DestroyWindow(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)
|
void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen)
|
||||||
@ -486,10 +484,26 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
|
|||||||
#endif
|
#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
|
// 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;
|
WNDCLASS wc;
|
||||||
wc.style = 0;
|
wc.style = 0;
|
||||||
@ -501,16 +515,37 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
|
|||||||
wc.hCursor = 0;
|
wc.hCursor = 0;
|
||||||
wc.hbrBackground = 0;
|
wc.hbrBackground = 0;
|
||||||
wc.lpszMenuName = NULL;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RegisterClass(&wc);
|
QWindowsMessageWindowClassContext::~QWindowsMessageWindowClassContext()
|
||||||
|
{
|
||||||
|
if (className) {
|
||||||
|
UnregisterClass(className, qWinAppInst());
|
||||||
|
delete [] className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(QWindowsMessageWindowClassContext, qWindowsMessageWindowClassContext)
|
||||||
|
|
||||||
|
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
|
||||||
|
{
|
||||||
|
QWindowsMessageWindowClassContext *ctx = qWindowsMessageWindowClassContext();
|
||||||
|
if (!ctx->atom)
|
||||||
|
return 0;
|
||||||
#ifdef Q_OS_WINCE
|
#ifdef Q_OS_WINCE
|
||||||
HWND parent = 0;
|
HWND parent = 0;
|
||||||
#else
|
#else
|
||||||
HWND parent = HWND_MESSAGE;
|
HWND parent = HWND_MESSAGE;
|
||||||
#endif
|
#endif
|
||||||
HWND wnd = CreateWindow(wc.lpszClassName, // classname
|
HWND wnd = CreateWindow(ctx->className, // classname
|
||||||
wc.lpszClassName, // window name
|
ctx->className, // window name
|
||||||
0, // style
|
0, // style
|
||||||
0, 0, 0, 0, // geometry
|
0, 0, 0, 0, // geometry
|
||||||
parent, // parent
|
parent, // parent
|
||||||
@ -519,7 +554,8 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
|
|||||||
0); // windows creation data.
|
0); // windows creation data.
|
||||||
|
|
||||||
if (!wnd) {
|
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
|
#ifdef GWLP_USERDATA
|
||||||
|
Loading…
Reference in New Issue
Block a user