ReactOS 0.4.15-dev-7674-gc0b4db1
systray.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2004 Martin Fuchs
3 * Copyright 2018 Hermes Belusca-Maito
4 *
5 * Pass on icon notification messages to the systray implementation
6 * in the currently running shell.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "precomp.h"
24
26
27/*************************************************************************
28 * Shell_NotifyIcon [SHELL32.296]
29 * Shell_NotifyIconA [SHELL32.297]
30 */
32{
33 NOTIFYICONDATAW nidW;
34 DWORD cbSize, dwValidFlags;
35
36 /* Initialize and capture the basic data fields */
37 ZeroMemory(&nidW, sizeof(nidW));
38 nidW.cbSize = sizeof(nidW); // Use a default size for the moment
39 nidW.hWnd = pnid->hWnd;
40 nidW.uID = pnid->uID;
41 nidW.uFlags = pnid->uFlags;
43 nidW.hIcon = pnid->hIcon;
44
45 /* Validate the structure size and the flags */
46 cbSize = pnid->cbSize;
47 dwValidFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
48 if (cbSize == sizeof(NOTIFYICONDATAA))
49 {
50 nidW.cbSize = sizeof(nidW);
51 dwValidFlags |= NIF_STATE | NIF_INFO | NIF_GUID /* | NIF_REALTIME | NIF_SHOWTIP */;
52 }
53 else if (cbSize == NOTIFYICONDATAA_V3_SIZE)
54 {
56 dwValidFlags |= NIF_STATE | NIF_INFO | NIF_GUID;
57 }
58 else if (cbSize == NOTIFYICONDATAA_V2_SIZE)
59 {
61 dwValidFlags |= NIF_STATE | NIF_INFO;
62 }
63 else // if cbSize == NOTIFYICONDATAA_V1_SIZE or something else
64 {
65 if (cbSize != NOTIFYICONDATAA_V1_SIZE)
66 {
67 WARN("Invalid cbSize (%d) - using only Win95 fields (size=%d)\n",
70 }
72 }
73 nidW.uFlags &= dwValidFlags;
74
75 /* Capture the other data fields */
76
77 if (nidW.uFlags & NIF_TIP)
78 {
79 /*
80 * Depending on the size of the NOTIFYICONDATA structure
81 * we should convert part of, or all the szTip string.
82 */
83 if (cbSize <= NOTIFYICONDATAA_V1_SIZE)
84 {
85#define NIDV1_TIP_SIZE_A (NOTIFYICONDATAA_V1_SIZE - FIELD_OFFSET(NOTIFYICONDATAA, szTip))/sizeof(CHAR)
87 nidW.szTip, _countof(nidW.szTip));
88 /* Truncate the string */
89 nidW.szTip[NIDV1_TIP_SIZE_A - 1] = 0;
90#undef NIDV1_TIP_SIZE_A
91 }
92 else
93 {
94 MultiByteToWideChar(CP_ACP, 0, pnid->szTip, -1,
95 nidW.szTip, _countof(nidW.szTip));
96 }
97 }
98
99 if (cbSize >= NOTIFYICONDATAA_V2_SIZE)
100 {
101 nidW.dwState = pnid->dwState;
102 nidW.dwStateMask = pnid->dwStateMask;
103 nidW.uTimeout = pnid->uTimeout;
104 nidW.dwInfoFlags = pnid->dwInfoFlags;
105
106 if (nidW.uFlags & NIF_INFO)
107 {
108 MultiByteToWideChar(CP_ACP, 0, pnid->szInfo, -1,
109 nidW.szInfo, _countof(nidW.szInfo));
111 nidW.szInfoTitle, _countof(nidW.szInfoTitle));
112 }
113 }
114
115 if ((cbSize >= NOTIFYICONDATAA_V3_SIZE) && (nidW.uFlags & NIF_GUID))
116 nidW.guidItem = pnid->guidItem;
117
118 if (cbSize >= sizeof(NOTIFYICONDATAA))
119 nidW.hBalloonIcon = pnid->hBalloonIcon;
120
121 /* Call the unicode function */
122 return Shell_NotifyIconW(dwMessage, &nidW);
123}
124
125/*************************************************************************
126 * Shell_NotifyIconW [SHELL32.298]
127 */
129{
130 BOOL ret = FALSE;
131 HWND hShellTrayWnd;
132 DWORD cbSize, dwValidFlags;
133 TRAYNOTIFYDATAW tnid;
135
136 /* Find a handle to the shell tray window */
137 hShellTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
138 if (!hShellTrayWnd)
139 return FALSE; // None found, bail out
140
141 /* Validate the structure size and the flags */
142 cbSize = pnid->cbSize;
143 dwValidFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
144 if (cbSize == sizeof(NOTIFYICONDATAW))
145 {
146 dwValidFlags |= NIF_STATE | NIF_INFO | NIF_GUID /* | NIF_REALTIME | NIF_SHOWTIP */;
147 }
148 else if (cbSize == NOTIFYICONDATAW_V3_SIZE)
149 {
150 dwValidFlags |= NIF_STATE | NIF_INFO | NIF_GUID;
151 }
152 else if (cbSize == NOTIFYICONDATAW_V2_SIZE)
153 {
154 dwValidFlags |= NIF_STATE | NIF_INFO;
155 }
156 else // if cbSize == NOTIFYICONDATAW_V1_SIZE or something else
157 {
158 if (cbSize != NOTIFYICONDATAW_V1_SIZE)
159 {
160 WARN("Invalid cbSize (%d) - using only Win95 fields (size=%d)\n",
163 }
164 }
165
166 /* Build the data structure */
167 ZeroMemory(&tnid, sizeof(tnid));
168 tnid.dwSignature = NI_NOTIFY_SIG;
169 tnid.dwMessage = dwMessage;
170
171 /* Copy only the needed data, everything else is zeroed out */
172 CopyMemory(&tnid.nid, pnid, cbSize);
173 /* Adjust the size (the NOTIFYICONDATA structure is the full-fledged one) and the flags */
174 tnid.nid.cbSize = sizeof(tnid.nid);
175 tnid.nid.uFlags &= dwValidFlags;
176
177 /* Be sure the szTip member (that could be cut-off) is correctly NULL-terminated */
178 if (tnid.nid.uFlags & NIF_TIP)
179 {
180 if (cbSize <= NOTIFYICONDATAW_V1_SIZE)
181 {
182#define NIDV1_TIP_SIZE_W (NOTIFYICONDATAW_V1_SIZE - FIELD_OFFSET(NOTIFYICONDATAW, szTip))/sizeof(WCHAR)
183 tnid.nid.szTip[NIDV1_TIP_SIZE_W - 1] = 0;
184#undef NIDV1_TIP_SIZE_W
185 }
186 else
187 {
188 tnid.nid.szTip[_countof(tnid.nid.szTip) - 1] = 0;
189 }
190 }
191
192 /* Be sure the info strings are correctly NULL-terminated */
193 if (tnid.nid.uFlags & NIF_INFO)
194 {
195 tnid.nid.szInfo[_countof(tnid.nid.szInfo) - 1] = 0;
196 tnid.nid.szInfoTitle[_countof(tnid.nid.szInfoTitle) - 1] = 0;
197 }
198
199 /* Send the data */
200 data.dwData = TABDMC_NOTIFY;
201 data.cbData = sizeof(tnid);
202 data.lpData = &tnid;
203 if (SendMessageW(hShellTrayWnd, WM_COPYDATA, (WPARAM)pnid->hWnd, (LPARAM)&data))
204 ret = TRUE;
205
206 return ret;
207}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: debug.h:112
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define L(x)
Definition: ntvdm.h:50
#define NOTIFYICONDATAW_V1_SIZE
Definition: shellapi.h:284
#define NOTIFYICONDATAW_V3_SIZE
Definition: shellapi.h:288
#define NOTIFYICONDATAA_V1_SIZE
Definition: shellapi.h:283
#define NOTIFYICONDATAA_V2_SIZE
Definition: shellapi.h:285
#define NIF_ICON
Definition: shellapi.h:103
#define NIF_MESSAGE
Definition: shellapi.h:102
#define NOTIFYICONDATAW_V2_SIZE
Definition: shellapi.h:286
#define NIF_TIP
Definition: shellapi.h:104
#define NOTIFYICONDATAA_V3_SIZE
Definition: shellapi.h:287
#define _countof(array)
Definition: sndvol32.h:68
CHAR szInfoTitle[64]
Definition: shellapi.h:242
CHAR szInfo[256]
Definition: shellapi.h:237
UINT uCallbackMessage
Definition: shellapi.h:228
DWORD dwStateMask
Definition: shellapi.h:236
DWORD dwInfoFlags
Definition: shellapi.h:243
CHAR szTip[128]
Definition: shellapi.h:234
HICON hBalloonIcon
Definition: shellapi.h:249
WCHAR szTip[128]
Definition: shellapi.h:264
DWORD dwInfoFlags
Definition: shellapi.h:273
WCHAR szInfoTitle[64]
Definition: shellapi.h:272
HICON hBalloonIcon
Definition: shellapi.h:279
DWORD dwStateMask
Definition: shellapi.h:266
UINT uCallbackMessage
Definition: shellapi.h:258
WCHAR szInfo[256]
Definition: shellapi.h:267
BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid)
Definition: systray.cpp:31
#define NIDV1_TIP_SIZE_A
#define NIDV1_TIP_SIZE_W
BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW pnid)
Definition: systray.cpp:128
#define TABDMC_NOTIFY
Definition: undocshell.h:795
int ret
#define ZeroMemory
Definition: winbase.h:1712
#define CopyMemory
Definition: winbase.h:1710
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define WM_COPYDATA
Definition: winuser.h:1663
HWND WINAPI FindWindowW(_In_opt_ LPCWSTR, _In_opt_ LPCWSTR)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)