Shell Functions


Shell_NotifyIcon Function

Sends a message to the taskbar's status area.

Syntax

BOOL Shell_NotifyIcon(      
    DWORD dwMessage,     PNOTIFYICONDATA lpdata );

Parameters

dwMessage
[in] A value that specifies the action to be taken by this function. It can have one of the following values:

NIM_ADD
0x00000000. Adds an icon to the status area. The icon is given an identifier in the NOTIFYICONDATA structure pointed to by lpdata—either through its uID or guidItem member. This identifier is used in subsequent calls to Shell_NotifyIcon to perform later actions on the icon.
NIM_MODIFY
0x00000001. Modifies an icon in the status area. NOTIFYICONDATA structure pointed to by lpdata uses the ID originally assigned to the icon when it was added to the notification area (NIM_ADD) to identify the icon to be modified.
NIM_DELETE
0x00000002. Deletes an icon from the status area. NOTIFYICONDATA structure pointed to by lpdata uses the ID originally assigned to the icon when it was added to the notification area (NIM_ADD) to identify the icon to be deleted.
NIM_SETFOCUS
0x00000003. Shell32.dll version 5.0 and later only. Returns focus to the taskbar notification area. Notification area icons should use this message when they have completed their user interface (UI) operation. For example, if the icon displays a shortcut menu, but the user presses ESC to cancel it, use NIM_SETFOCUS to return focus to the notification area.
NIM_SETVERSION
0x00000004. Shell32.dll version 5.0 and later only. Instructs the notification area to behave according to the version number specified in the uVersion member of the structure pointed to by lpdata. The version number specifies which members are recognized.

NIM_SETVERSION must be called every time a notification area icon is added (NIM_ADD)>. It does not need to be called with NIM_MOFIDY. The version setting is not persisted once a user logs off.

For details, see the Remarks section.

lpdata
[in] A pointer to a NOTIFYICONDATA structure. The content of the structure depends on the value of dwMessage. It can define an icon to add to the notification area, cause that icon to display a notification, or identify an icon to modify or delete.

Return Value

Returns TRUE if successful, or FALSE otherwise. If dwMessage is set to NIM_SETVERSION, the function returns TRUE if the version was successfully changed, or FALSE if the requested version is not supported.

You can call GetLastError for more specific information about a failure case. The most common cause of failure is that the taskbar window doesn't exist or is unresponsive. GetLastError in that case returns E_FILE_NOT_FOUND.

Remarks

As of Microsoft Windows 2000 (Shell32.dll version 5.0), Shell_NotifyIcon mouse and keyboard events are handled differently than in earlier Shell versions found on Microsoft Windows NT 4.0, Windows 95, and Windows 98. The differences include the following:

  • If a user selects a notify icon's shortcut menu with the keyboard, the Shell now sends the associated application a WM_CONTEXTMENU message. Earlier versions send WM_RBUTTONDOWN and WM_RBUTTONUP messages.
  • If a user selects a notify icon with the keyboard and activates it with the SPACEBAR or ENTER key, the version 5.0 Shell sends the associated application an NIN_KEYSELECT notification. Earlier versions send WM_RBUTTONDOWN and WM_RBUTTONUP messages.
  • If a user selects a notify icon with the mouse and activates it with the ENTER key, the Shell now sends the associated application an NIN_SELECT notification. Earlier versions send WM_RBUTTONDOWN and WM_RBUTTONUP messages.

As of Windows XP (Shell32.dll version 6.0), if a user passes the mouse pointer over an icon with which a balloon notification is associated, the Shell sends the following messages:

  • NIN_BALLOONSHOW. Sent when the balloon is shown (balloons are queued).
  • NIN_BALLOONHIDE. Sent when the balloon disappears. For example, when the icon is deleted. This message is not sent if the balloon is dismissed because of a timeout or if the user clicks the mouse.

    As of Windows 7, NIN_BALLOONHIDE is also sent when a notification with the NIIF_RESPECT_QUIET_TIME flag set attempts to display during quiet time (a user's first hour on a new computer). In that case, the balloon is never displayed at all.

  • NIN_BALLOONTIMEOUT. Sent when the balloon is dismissed because of a timeout.
  • NIN_BALLOONUSERCLICK. Sent when the balloon is dismissed because the user clicked the mouse.

In addition to those messages, as of Windows Vista (Shell32.dll version 6.0.6), if a user passes the mouse pointer over an icon with which a balloon notification is associated, the Windows Vista Shell also adds the following messages:

  • NIN_POPUPOPEN. Sent when the user hovers the cursor over an icon to indicate that the richer pop-up UI should be used in place of a standard textual tooltip.
  • NIN_POPUPCLOSE. Sent when a cursor no longer hovers over an icon to indicate that the rich pop-up UI should be closed.

Regardless of the operating system version, you can select which way the Shell should behave by calling Shell_NotifyIcon with dwMessage set to NIM_SETVERSION. Set the uVersion member of the NOTIFYICONDATA structure pointed to by lpdata to indicate whether you want Windows 2000, Windows Vista, or pre-version 5.0 (Windows 95) behavior.

Note  The messages discussed above are not conventional Windows messages. They are sent as the lParam value of the application-defined message that is specified in the uCallbackMessage member of the NOTIFYICONDATA structure pointed to by lpdata, when Shell_NotifyIcon is called with the NIM_ADD flag set in dwMessage.

As of Windows XP Service Pack 2 (SP2), a custom icon can be displayed in the notification balloon. This allows the calling process to customize the notification beyond the previously available options of info, warning, and error, and distinguish it from other types of notification for the user.

Function Information

Minimum DLL Versionshell32.dll version 4.0 or later
Custom ImplementationNo
Headershellapi.h
Import libraryshell32.lib
Minimum operating systems Windows NT 4.0, Windows 95
UnicodeImplemented as ANSI and Unicode versions.

See Also

Notifications and the Notification Area
Tags :


Community Content

Thomas Lee
Handling Shell_NotifyIcon failure
Shell_NotifyIcon will often fail when called during Windows startup (for instance, if your application is listed in HKLM\Software\Microsoft\Windows\CurrentVersion\Run. This appears to be because the system is busy starting applications. The failure is more common on low-spec computers or computers with some brands of antivirus software installed, which seem to be very intensive at startup.

Unfortunately, you cannot rely on the error code returned by GetLastError. When Shell_NotifyIcon returns false, some of the common errors returned by GetLastError are:
  • ERROR_FILE_NOT_FOUND (2)
  • ERROR_TIMEOUT (1460)
  • ERROR_SUCCESS (0)
The most appropriate response to any error returned by Shell_NotifyIcon is to sleep for a period of time and retry.

An explanation of why the error code may differ has been made by Paul Baker, paraphrased from http://groups.google.com/group/microsoft.public.platformsdk.shell/msg/59235b293cbf5dfa and http://groups.google.com/group/microsoft.public.platformsdk.shell/msg/73973287f15c03fc:

Shell_NotifyIcon actually calls SetLastError(0) initially. After that, basically it uses FindWindow to find the tray notification window. If this fails, it will typically return ERROR_FILE_NOT_FOUND. Otherwise it sends a WM_COPYDATA message to the tray notification window, using SendMessageTimeout with a timeout of only 4 seconds. If that message returns zero, then Shell_NotifyIcon will fail with GetLastError returning zero.

reply to the above...
Applications that want to use the notification APIs that are running before or during explorer startup should listen for the notification message that indicates the taskbar is ready to receive API calls. This is the “TaskbarCreated “ message. This also enables your application to re-register if the explorer is re-started.
This is described in the section titled “Taskbar Creation Notification” on this page:
http://msdn.microsoft.com/en-us/library/cc144179(VS.85).aspx



Stefanov
Windows CE
lpdata->hWnd seems to be required in Windows CE. If hWnd is not set Shell_NotifyIcon returns false and GetLastError returns 87 - invalid parameter.

This code may solve that problem:

lpdata->hWnd = GetDesktopWindow();


Tags :

Thomas Lee
NIM_MODIFY
NIM_MODIFY not only needs hWnd and uID to work, you have to put NIF_ICON in uFlags too.

rogerdpack
NOTIFYICONDATA structure is useful
See NOTIFYICONDATA http://msdn.microsoft.com/en-us/library/bb773352(VS.85).aspx to understand more what will happen when you call this method.


ondra.novacisko.cz
Handling Shell_NotifyIcon failure (update: Windows Seven RC 1)

I found, that there is difference on handling the Shell_NotifyIcon failure. Unfortunately, _ANY_ failure is reported as ERROR_TIMEOUT, so if you use this error state to repeat request after a while, your program will be trapped into the infinite loop.

I don't know, why this has been changed, but I cannot find any logic in this modification. You should no longer check GetLastError for the state ERROR_TIMEOUT in the Windows Seven.


76BE73B2 lea eax,[ebp-1640h] 
76BE73B8 push eax
76BE73B9 push dword ptr [esi+4]
76BE73BC mov dword ptr [ebp-1618h],34753423h
76BE73C6 push 4Ah ;WM_COPYDATA
76BE73C8 push dword ptr [ebp-1650h]
76BE73CE mov dword ptr [ebp-161Ch],edi
76BE73D4 mov dword ptr [ebp-1640h],1
76BE73DE mov dword ptr [ebp-163Ch],5CCh
76BE73E8 call dword ptr [__imp__SendMessageTimeoutW@28 (76B81CB4h)] ; sending WM_COPYDATA
76BE73EE mov ebx,eax
76BE73F0 neg ebx
76BE73F2 sbb ebx,ebx
76BE73F4 and ebx,dword ptr [ebp-161Ch]
76BE73FA test byte ptr [esi+0Ch],10h
76BE73FE jne _Shell_NotifyIconW@8+3B4h (76BAE341h)
76BE7404 cmp ebx,edi ;edi = 0, ebx = return code
76BE7406 je _Shell_NotifyIconW@8+3F2h (76BE7457h) ;error, jump below line
........
-------------------------------------------------------------------
76BE7457 call dword ptr [__imp__GetLastError@0 (76B81128h)] ; read last error
76BE745D test eax,eax ; is zero?
76BE745F jne 76BE7408 ; no, this is OK
76BE7461 push 5B4h ; ERROR_TIMEOUT (why?)
76BE7466 call dword ptr [__imp__SetLastError@4 (76B81114h)] ; set last error
76BE746C jmp 76BE7408 ; now it is ok, go back
Tags :

Page view tracker