ReactOS  0.4.14-dev-115-g4576127
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 
25 WINE_DEFAULT_DEBUG_CHANNEL(shell_notify);
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",
68  cbSize, NOTIFYICONDATAA_V1_SIZE);
69  cbSize = NOTIFYICONDATAA_V1_SIZE;
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));
110  MultiByteToWideChar(CP_ACP, 0, pnid->szInfoTitle, -1,
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",
161  cbSize, NOTIFYICONDATAW_V1_SIZE);
162  cbSize = NOTIFYICONDATAW_V1_SIZE;
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 = 1;
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 }
WINE_DEFAULT_DEBUG_CHANNEL(shell_notify)
#define NIF_MESSAGE
Definition: shellapi.h:102
WCHAR szInfo[256]
Definition: shellapi.h:268
#define TRUE
Definition: types.h:120
#define NOTIFYICONDATAA_V3_SIZE
Definition: shellapi.h:288
#define CP_ACP
Definition: compat.h:99
#define _countof(array)
Definition: fontsub.cpp:30
#define NOTIFYICONDATAA_V1_SIZE
Definition: shellapi.h:284
#define WARN(fmt,...)
Definition: debug.h:111
DWORD dwInfoFlags
Definition: shellapi.h:244
#define ZeroMemory
Definition: winbase.h:1642
UINT_PTR WPARAM
Definition: windef.h:207
HICON hBalloonIcon
Definition: shellapi.h:280
UINT uCallbackMessage
Definition: shellapi.h:259
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD dwStateMask
Definition: shellapi.h:237
#define NOTIFYICONDATAW_V3_SIZE
Definition: shellapi.h:289
#define NOTIFYICONDATAA_V2_SIZE
Definition: shellapi.h:286
CHAR szTip[128]
Definition: shellapi.h:235
#define NIF_TIP
Definition: shellapi.h:104
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
#define NIF_ICON
Definition: shellapi.h:103
#define WM_COPYDATA
Definition: winuser.h:1646
#define NIDV1_TIP_SIZE_W
HWND WINAPI FindWindowW(_In_opt_ LPCWSTR, _In_opt_ LPCWSTR)
WCHAR szInfoTitle[64]
Definition: shellapi.h:273
#define WINAPI
Definition: msvc.h:8
#define NIDV1_TIP_SIZE_A
#define CopyMemory
Definition: winbase.h:1640
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
DWORD dwInfoFlags
Definition: shellapi.h:274
DWORD dwStateMask
Definition: shellapi.h:267
int ret
static const WCHAR L[]
Definition: oid.c:1250
#define NOTIFYICONDATAW_V1_SIZE
Definition: shellapi.h:285
HICON hBalloonIcon
Definition: shellapi.h:250
UINT uCallbackMessage
Definition: shellapi.h:229
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid)
Definition: systray.cpp:31
#define MultiByteToWideChar
Definition: compat.h:100
CHAR szInfo[256]
Definition: shellapi.h:238
WCHAR szTip[128]
Definition: shellapi.h:265
CHAR szInfoTitle[64]
Definition: shellapi.h:243
BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW pnid)
Definition: systray.cpp:128
#define NOTIFYICONDATAW_V2_SIZE
Definition: shellapi.h:287