4#include <QtCore/qt_windows.h>
12#include <QtGui/qguiapplication.h>
13#include <QtGui/qpixmap.h>
14#include <QtCore/qdebug.h>
15#include <QtCore/qlist.h>
16#include <QtCore/qrect.h>
17#include <QtCore/qsettings.h>
18#include <qpa/qwindowsysteminterface.h>
30#define MYWM_NOTIFYICON (WM_APP+101)
46 memset(&tnd, 0,
sizeof(NOTIFYICONDATA));
47 tnd.cbSize =
sizeof(NOTIFYICONDATA);
48 tnd.uVersion = NOTIFYICON_VERSION_4;
53 tnd.uFlags |= NIF_MESSAGE | NIF_ICON | NIF_TIP;
61 tnd.uFlags |= NIF_STATE;
62 tnd.dwStateMask = NIS_HIDDEN;
63 tnd.dwState =
v ? 0 : NIS_HIDDEN;
81 if (entries->
at(
i).hwnd == hwnd)
88 WPARAM wParam, LPARAM lParam)
100 msg.pt.x = GET_X_LPARAM(lParam);
101 msg.pt.y = GET_Y_LPARAM(lParam);
103 if (hwndTrayIconEntries()->
at(
index).trayIcon->winEvent(msg, &
result))
107 return DefWindowProc(hwnd,
message, wParam, lParam);
121 const wchar_t windowName[] = L
"QTrayIconMessageWindow";
122 return CreateWindowEx(0,
reinterpret_cast<const wchar_t *
>(
className.utf16()),
123 windowName, WS_OVERLAPPED,
124 CW_USEDEFAULT, CW_USEDEFAULT,
125 CW_USEDEFAULT, CW_USEDEFAULT,
127 static_cast<HINSTANCE
>(GetModuleHandle(
nullptr)),
nullptr);
143 qCDebug(lcQpaTrayIcon) << __FUNCTION__ <<
this;
149 qCDebug(lcQpaTrayIcon) << __FUNCTION__ <<
this;
151 if (!setIconVisible(m_visible))
157 qCDebug(lcQpaTrayIcon) << __FUNCTION__ <<
this;
164 qCDebug(lcQpaTrayIcon) << __FUNCTION__ <<
'(' <<
icon <<
')' <<
this;
168 const HICON hIconToDestroy = createIcon(
icon);
169 if (ensureInstalled())
170 sendTrayMessage(NIM_MODIFY);
172 DestroyIcon(hIconToDestroy);
177 qCDebug(lcQpaTrayIcon) << __FUNCTION__ <<
'(' << tooltip <<
')' <<
this;
178 if (m_toolTip == tooltip)
182 sendTrayMessage(NIM_MODIFY);
187 NOTIFYICONIDENTIFIER nid;
188 memset(&nid, 0,
sizeof(nid));
189 nid.cbSize =
sizeof(nid);
196 qCDebug(lcQpaTrayIcon) << __FUNCTION__ <<
this <<
"returns" <<
result;
206 << iconType << msecsIn <<
')' <<
this;
220 tnd.dwInfoFlags = NIIF_USER;
222 QSize size(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
223 const QSize largeIcon(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
226 tnd.dwInfoFlags |= NIIF_LARGE_ICON;
231 tnd.dwInfoFlags = NIIF_INFO;
234 qWarning(
"QSystemTrayIcon::showMessage: Wrong icon size (%dx%d), please add standard one: %dx%d",
241 tnd.uTimeout = msecsIn <= 0 ? UINT(10000) : UINT(msecsIn);
242 tnd.uFlags = NIF_INFO | NIF_SHOWTIP;
244 Shell_NotifyIcon(NIM_MODIFY, &tnd);
257 qCDebug(lcQpaTrayIcon) << __FUNCTION__ <<
this <<
"returns" << m_menu.
data();
258 return m_menu.
data();
262bool QWindowsSystemTrayIcon::ensureInstalled()
266 if (m_hIcon ==
nullptr)
279 hwndTrayIconEntries()->append(
entry);
280 sendTrayMessage(NIM_ADD);
284void QWindowsSystemTrayIcon::ensureCleanup()
289 hwndTrayIconEntries()->removeAt(
index);
290 sendTrayMessage(NIM_DELETE);
291 DestroyWindow(m_hwnd);
294 if (m_hIcon !=
nullptr)
295 DestroyIcon(m_hIcon);
301bool QWindowsSystemTrayIcon::setIconVisible(
bool visible)
310 return Shell_NotifyIcon(NIM_MODIFY, &tnd) == TRUE;
313bool QWindowsSystemTrayIcon::sendTrayMessage(DWORD msg)
319 tnd.uFlags = NIF_SHOWTIP;
320 if (msg != NIM_DELETE && !m_visible)
322 if (msg == NIM_ADD || msg == NIM_MODIFY)
324 if (!Shell_NotifyIcon(msg, &tnd))
326 return msg != NIM_ADD || Shell_NotifyIcon(NIM_SETVERSION, &tnd);
330HICON QWindowsSystemTrayIcon::createIcon(
const QIcon &
icon)
332 const HICON oldIcon = m_hIcon;
336 const QSize requestedSize =
QSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
350 const int trayMessage = LOWORD(
message.lParam);
351 switch (trayMessage) {
354 if (m_ignoreNextMouseRelease)
355 m_ignoreNextMouseRelease =
false;
359 case WM_LBUTTONDBLCLK:
360 m_ignoreNextMouseRelease =
true;
363 case WM_CONTEXTMENU: {
371 screen = screenManager.screens().value(0);
378 SetForegroundWindow(m_hwnd);
384 case NIN_BALLOONUSERCLICK:
396 case WM_INITMENUPOPUP:
400 QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>();
409 const QIcon oldIcon = m_icon;
413 sendTrayMessage(NIM_ADD);
420#ifndef QT_NO_DEBUG_STREAM
424 d << static_cast<const void *>(
this) <<
", \"" << m_toolTip
425 <<
"\", hwnd=" << m_hwnd <<
", m_hIcon=" << m_hIcon <<
", menu="
434 d <<
"QWindowsSystemTrayIcon(";
The QIcon class provides scalable icons in different modes and states.
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
qint64 cacheKey() const
Returns a number that identifies the contents of this QIcon object.
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
QPixmap scaled(int w, int h, Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode mode=Qt::FastTransformation) const
QSize size() const
Returns the size of the pixmap.
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
\inmodule QtCore\reentrant
constexpr int x() const noexcept
Returns the x coordinate of this point.
constexpr int y() const noexcept
Returns the y coordinate of this point.
bool isNull() const
Returns true if the referenced object has been destroyed or if there is no referenced object; otherwi...
\inmodule QtCore\reentrant
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
\macro QT_RESTRICTED_CAST_FROM_ASCII
void clear()
Clears the contents of the string and makes it null.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QString & append(QChar c)
Singleton container for all relevant information.
QWindowsScreenManager & screenManager()
static QString classNamePrefix()
static DWORD readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue)
static QWindowsContext * instance()
Windows native system tray icon.
void cleanup() override
This method is called to cleanup the platform dependent implementation.
bool supportsMessages() const override
Returns true if the system tray supports messages on the platform.
bool winEvent(const MSG &message, long *result)
void formatDebug(QDebug &d) const
QPlatformMenu * createMenu() const override
This method allows platforms to use a different QPlatformMenu for system tray menus than what would n...
void updateToolTip(const QString &tooltip) override
This method is called when the tooltip text did change.
void init() override
This method is called to initialize the platform dependent implementation.
void updateIcon(const QIcon &icon) override
This method is called when the icon did change.
void showMessage(const QString &title, const QString &msg, const QIcon &icon, MessageIcon iconType, int msecs) override
Shows a balloon message for the entry with the given title, message msg and icon for the time specifi...
QRect geometry() const override
This method returns the geometry of the platform dependent system tray icon on the screen.
~QWindowsSystemTrayIcon() override
static bool useNativeMenus()
Combined button and popup list for selecting options.
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLuint GLsizei const GLchar * message
HICON qt_pixmapToWinHICON(const QPixmap &p)
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE const UINT q_uNOTIFYICONID
static void setIconVisibility(NOTIFYICONDATA &tnd, bool v)
Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &)
static HWND createTrayIconMessageWindow()
static uint MYWM_TASKBARCREATED
QDebug operator<<(QDebug d, const QWindowsSystemTrayIcon *t)
static void initNotifyIconData(NOTIFYICONDATA &tnd)
static void setIconContents(NOTIFYICONDATA &tnd, const QString &tip, HICON hIcon)
LRESULT QT_WIN_CALLBACK qWindowsTrayIconWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static void qStringToLimitedWCharArray(QString in, wchar_t *target, int maxLength)
static int indexOfHwnd(HWND hwnd)
const char className[16]
[1]
QWindowsSystemTrayIcon * trayIcon