diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/widgets/util/qsystemtrayicon_win.cpp | 146 |
1 files changed, 42 insertions, 104 deletions
diff --git a/src/widgets/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp index d110cb8be4..3974e6d055 100644 --- a/src/widgets/util/qsystemtrayicon_win.cpp +++ b/src/widgets/util/qsystemtrayicon_win.cpp @@ -40,11 +40,18 @@ #include "qsystemtrayicon_p.h" #ifndef QT_NO_SYSTEMTRAYICON -#if defined(_WIN32_IE) && _WIN32_IE < 0x0600 -# undef _WIN32_IE +#if defined(WINVER) && WINVER < 0x0601 +# undef WINVER #endif -#if !defined(_WIN32_IE) -# define _WIN32_IE 0x0600 //required for NOTIFYICONDATA_V2_SIZE +#if !defined(WINVER) +# define WINVER 0x0601 // required for NOTIFYICONDATA_V2_SIZE, ChangeWindowMessageFilterEx() (MinGW 5.3) +#endif + +#if defined(NTDDI_VERSION) && NTDDI_VERSION < 0x06010000 +# undef NTDDI_VERSION +#endif +#if !defined(NTDDI_VERSION) +# define NTDDI_VERSION 0x06010000 // required for Shell_NotifyIconGetRect (MinGW 5.3) #endif #include <private/qsystemlibrary_p.h> @@ -56,6 +63,7 @@ #include <qt_windows.h> #include <commctrl.h> +#include <shellapi.h> #include <windowsx.h> QT_BEGIN_NAMESPACE @@ -65,34 +73,8 @@ static const UINT q_uNOTIFYICONID = 0; static uint MYWM_TASKBARCREATED = 0; #define MYWM_NOTIFYICON (WM_APP+101) -struct Q_NOTIFYICONIDENTIFIER { - DWORD cbSize; - HWND hWnd; - UINT uID; - GUID guidItem; -}; - -#ifndef NIN_KEYSELECT -# define NIN_KEYSELECT (WM_USER + 1) -#endif - -#ifdef Q_CC_MINGW -# define NIN_SELECT (WM_USER + 0) -# define NIN_BALLOONTIMEOUT (WM_USER + 4) -# define NIN_BALLOONUSERCLICK (WM_USER + 5) -# define NIF_SHOWTIP 0x00000080 -# define NIIF_LARGE_ICON 0x00000020 -# define NOTIFYICON_VERSION_4 4 -#endif - -#define Q_MSGFLT_ALLOW 1 - Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &); -typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation); -typedef BOOL (WINAPI *PtrChangeWindowMessageFilter)(UINT message, DWORD dwFlag); -typedef BOOL (WINAPI *PtrChangeWindowMessageFilterEx)(HWND hWnd, UINT message, DWORD action, void* pChangeFilterStruct); - // Copy QString data to a limited wchar_t array including \0. static inline void qStringToLimitedWCharArray(QString in, wchar_t *target, int maxLength) { @@ -120,8 +102,6 @@ private: HICON hIcon; QPoint globalPos; QSystemTrayIcon *q; - uint notifyIconSize; - int version; bool ignoreNextMouseRelease; }; @@ -185,41 +165,27 @@ static inline HWND createTrayIconMessageWindow() NULL, NULL, (HINSTANCE)GetModuleHandle(0), NULL); } +static inline void initNotifyIconData(NOTIFYICONDATA &tnd) +{ + memset(&tnd, 0, sizeof(NOTIFYICONDATA)); + tnd.cbSize = sizeof(NOTIFYICONDATA); + tnd.uVersion = NOTIFYICON_VERSION_4; +} + QSystemTrayIconSys::QSystemTrayIconSys(HWND hwnd, QSystemTrayIcon *object) : m_hwnd(hwnd), hIcon(0), q(object) - , notifyIconSize(sizeof(NOTIFYICONDATA)), version(NOTIFYICON_VERSION_4) , ignoreNextMouseRelease(false) { handleTrayIconHash()->insert(m_hwnd, this); - if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA) { - notifyIconSize = NOTIFYICONDATA_V2_SIZE; - version = NOTIFYICON_VERSION; - } - // For restoring the tray icon after explorer crashes if (!MYWM_TASKBARCREATED) { MYWM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated"); } - // Allow the WM_TASKBARCREATED message through the UIPI filter on Windows 7 and higher - static PtrChangeWindowMessageFilterEx pChangeWindowMessageFilterEx = - (PtrChangeWindowMessageFilterEx)QSystemLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilterEx"); - - if (pChangeWindowMessageFilterEx) { - // Call the safer ChangeWindowMessageFilterEx API if available (Windows 7 onwards) - pChangeWindowMessageFilterEx(m_hwnd, MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW, 0); - } else { - // Call the deprecated ChangeWindowMessageFilter API otherwise (Vista onwards) - // May 2016: Still resolved at runtime since the definition is not present in MinGW 4.9. - // TODO: Replace by direct invocation when upgrading MinGW. - static PtrChangeWindowMessageFilter pChangeWindowMessageFilter = - (PtrChangeWindowMessageFilter)QSystemLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilter"); - - if (pChangeWindowMessageFilter) - pChangeWindowMessageFilter(MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW); - } + // Allow the WM_TASKBARCREATED message through the UIPI filter + ChangeWindowMessageFilterEx(m_hwnd, MYWM_TASKBARCREATED, MSGFLT_ALLOW, 0); } QSystemTrayIconSys::~QSystemTrayIconSys() @@ -243,23 +209,19 @@ void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd) bool QSystemTrayIconSys::showMessage(const QString &title, const QString &message, const QIcon &icon, uint uSecs) { NOTIFYICONDATA tnd; - memset(&tnd, 0, notifyIconSize); + initNotifyIconData(tnd); qStringToLimitedWCharArray(message, tnd.szInfo, 256); qStringToLimitedWCharArray(title, tnd.szInfoTitle, 64); tnd.uID = q_uNOTIFYICONID; tnd.dwInfoFlags = NIIF_USER; - HICON *phIcon = &tnd.hIcon; QSize size(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); - if (version == NOTIFYICON_VERSION_4) { - const QSize largeIcon(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); - QSize more = icon.actualSize(largeIcon); - if (more.height() > (largeIcon.height() * 3/4) || more.width() > (largeIcon.width() * 3/4)) { - tnd.dwInfoFlags |= NIIF_LARGE_ICON; - size = largeIcon; - } - phIcon = &tnd.hBalloonIcon; + const QSize largeIcon(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); + const QSize more = icon.actualSize(largeIcon); + if (more.height() > (largeIcon.height() * 3/4) || more.width() > (largeIcon.width() * 3/4)) { + tnd.dwInfoFlags |= NIIF_LARGE_ICON; + size = largeIcon; } QPixmap pm = icon.pixmap(size); if (pm.isNull()) { @@ -270,10 +232,8 @@ bool QSystemTrayIconSys::showMessage(const QString &title, const QString &messag pm.size().width(), pm.size().height(), size.width(), size.height()); pm = pm.scaled(size, Qt::IgnoreAspectRatio); } - *phIcon = qt_pixmapToWinHICON(pm); + tnd.hBalloonIcon = qt_pixmapToWinHICON(pm); } - tnd.cbSize = notifyIconSize; - tnd.uVersion = version; tnd.hWnd = m_hwnd; tnd.uTimeout = uSecs; tnd.uFlags = NIF_INFO | NIF_SHOWTIP; @@ -284,13 +244,11 @@ bool QSystemTrayIconSys::showMessage(const QString &title, const QString &messag bool QSystemTrayIconSys::trayMessage(DWORD msg) { NOTIFYICONDATA tnd; - memset(&tnd, 0, notifyIconSize); + initNotifyIconData(tnd); tnd.uID = q_uNOTIFYICONID; - tnd.cbSize = notifyIconSize; tnd.hWnd = m_hwnd; tnd.uFlags = NIF_SHOWTIP; - tnd.uVersion = version; if (msg == NIM_ADD || msg == NIM_MODIFY) { setIconContents(tnd); @@ -311,9 +269,7 @@ HICON QSystemTrayIconSys::createIcon() const QIcon icon = q->icon(); if (icon.isNull()) return oldIcon; - const QSize requestedSize = QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA - ? QSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)) - : QSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); + const QSize requestedSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); const QSize size = icon.actualSize(requestedSize); const QPixmap pm = icon.pixmap(size); if (pm.isNull()) @@ -328,18 +284,9 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result ) switch(m->message) { case MYWM_NOTIFYICON: { - int message = 0; - QPoint gpos; - - if (version == NOTIFYICON_VERSION_4) { - Q_ASSERT(q_uNOTIFYICONID == HIWORD(m->lParam)); - message = LOWORD(m->lParam); - gpos = QPoint(GET_X_LPARAM(m->wParam), GET_Y_LPARAM(m->wParam)); - } else { - Q_ASSERT(q_uNOTIFYICONID == m->wParam); - message = m->lParam; - gpos = QCursor::pos(); - } + Q_ASSERT(q_uNOTIFYICONID == HIWORD(m->lParam)); + const int message = LOWORD(m->lParam); + const QPoint gpos = QPoint(GET_X_LPARAM(m->wParam), GET_Y_LPARAM(m->wParam)); switch (message) { case NIN_SELECT: @@ -423,24 +370,15 @@ QRect QSystemTrayIconSys::findIconGeometry(UINT iconId) UINT uID; }; - // Windows 7 onwards. - static PtrShell_NotifyIconGetRect Shell_NotifyIconGetRect = - (PtrShell_NotifyIconGetRect)QSystemLibrary::resolve(QLatin1String("shell32"), - "Shell_NotifyIconGetRect"); - - if (Shell_NotifyIconGetRect) { - Q_NOTIFYICONIDENTIFIER nid; - memset(&nid, 0, sizeof(nid)); - nid.cbSize = sizeof(nid); - nid.hWnd = m_hwnd; - nid.uID = iconId; - - RECT rect; - HRESULT hr = Shell_NotifyIconGetRect(&nid, &rect); - if (SUCCEEDED(hr)) { - return QRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); - } - } + NOTIFYICONIDENTIFIER nid; + memset(&nid, 0, sizeof(nid)); + nid.cbSize = sizeof(nid); + nid.hWnd = m_hwnd; + nid.uID = iconId; + + RECT rect; + if (SUCCEEDED(Shell_NotifyIconGetRect(&nid, &rect))) + return QRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); QRect ret; |