Windows tray icon: Fix reinstalling after restart of Explorer.

Use a normal instead of a HWND_MESSAGE-window since the latter
do not receive the "TaskbarCreated" message. Provide an invokable
slot in the native interface to register a window class for that
purpose.

Task-number: QTBUG-29160
Change-Id: Ic25222d08d21867f7d882a9e19d8aaf50f3f47cf
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
This commit is contained in:
Friedemann Kleint 2013-01-30 10:05:55 +01:00 committed by The Qt Project
parent 2be4d6ba02
commit 38f740e4de
2 changed files with 32 additions and 12 deletions

View File

@ -107,6 +107,9 @@ public:
Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
const QString &windowName,
void *eventProc) const;
Q_INVOKABLE QString registerWindowClass(const QString &classNameIn, void *eventProc) const;
bool asyncExpose() const;
void setAsyncExpose(bool value);
};
@ -186,6 +189,15 @@ void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTempl
return hwnd;
}
/*!
\brief Registers a unique window class with a callback function based on \a classNameIn.
*/
QString QWindowsNativeInterface::registerWindowClass(const QString &classNameIn, void *eventProc) const
{
return QWindowsContext::instance()->registerWindowClass(classNameIn, (WNDPROC)eventProc);
}
bool QWindowsNativeInterface::asyncExpose() const
{
return QWindowsContext::instance()->asyncExpose();

View File

@ -166,21 +166,29 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsTrayconWndProc(HWND hwnd, UINT messag
}
// Invoke a service of the native Windows interface to create
// a non-visible message window.
// a non-visible toplevel window to receive tray messages.
// Note: Message windows (HWND_MESSAGE) are not sufficient, they
// will not receive the "TaskbarCreated" message.
static inline HWND createTrayIconMessageWindow()
{
if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) {
void *hwnd = 0;
void *wndProc = reinterpret_cast<void *>(qWindowsTrayconWndProc);
if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection,
Q_RETURN_ARG(void *, hwnd),
Q_ARG(QString, QStringLiteral("QTrayIconMessageWindowClass")),
Q_ARG(QString, QStringLiteral("QTrayIconMessageWindow")),
Q_ARG(void *, wndProc)) && hwnd) {
return reinterpret_cast<HWND>(hwnd);
}
QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
if (!ni)
return 0;
// Register window class in the platform plugin.
QString className;
void *wndProc = reinterpret_cast<void *>(qWindowsTrayconWndProc);
if (!QMetaObject::invokeMethod(ni, "registerWindowClass", Qt::DirectConnection,
Q_RETURN_ARG(QString, className),
Q_ARG(QString, QStringLiteral("QTrayIconMessageWindowClass")),
Q_ARG(void *, wndProc))) {
return 0;
}
return 0;
const wchar_t windowName[] = L"QTrayIconMessageWindow";
return CreateWindowEx(0, (wchar_t*)className.utf16(),
windowName, WS_OVERLAPPED,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, (HINSTANCE)GetModuleHandle(0), NULL);
}
QSystemTrayIconSys::QSystemTrayIconSys(HWND hwnd, QSystemTrayIcon *object)