![]() |
Desktop Development »
Shell and IE programming »
Beginners
Beginner
Basic use of Shell_NotifyIcon in Win32By Abraxas23Starting your app minimized on the sytem tray. |
VC7, VC7.1Win2K, WinXP, Win2003, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||
Recently I was browsing CodeProject, looking for a simple example of how to manage system tray icons. Ooops sorry, I shouldn't call them tray icons as MSDN documentation so carefully points out:
"The taskbar notification area is sometimes erroneously called the tray."
In spite of this, I will insist on calling a spade a shovel and refer to the "taskbar notification area" as the "tray" and "taskbar notification area icons" as "tray icons". Anyway back to the point, why another article about tray icons?
Shell_NotifyIcon with a minimum amount of code.
Adding, modifying, hiding and deleting tray icons is accomplished in two steps:
NOTIFYICONDATA structure
Shell_NotifyIcon // zero the structure - note: Some Windows funtions // require this but I can't be bothered to remember // which ones do and which ones don't. NOTIFYICONDATA niData; ZeroMemory(&niData,sizeof(NOTIFYICONDATA)); // get Shell32 version number and set the size of the // structure note: the MSDN documentation about this is // a little dubious(see bolow) and I'm not at all sure // if the code bellow is correct ULONGLONG ullVersion = GetDllVersion(_T("Shell32.dll")); if(ullVersion >= MAKEDLLVERULL(6,0,0,0)) niData.cbSize = sizeof(NOTIFYICONDATA); else if(ullVersion >= MAKEDLLVERULL(5,0,0,0)) niData.cbSize = NOTIFYICONDATA_V2_SIZE; else niData.cbSize = NOTIFYICONDATA_V1_SIZE; // the ID number can be any UINT you choose and will // be used to identify your icon in later calls to // Shell_NotifyIcon niData.uID = MY_TRAY_ICON_ID; // state which structure members are valid // here you can also choose the style of tooltip // window if any - specifying a balloon window: // NIF_INFO is a little more complicated niData.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; // load the icon note: you should destroy the icon // after the call to Shell_NotifyIcon niData.hIcon = (HICON)LoadImage( hInstance, MAKEINTRESOURCE(IDI_MY_ICON), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); // set the window you want to recieve event messages niData.hWnd = hWnd; // set the message to send // note: the message value should be in the // range of WM_APP through 0xBFFF niData.uCallbackMessage = MY_TRAY_ICON_MESSAGE;
// NIM_ADD adds a new tray icon Shell_NotifyIcon(NIM_ADD,&niData);
I've seen more than a few posts asking how to begin a dialog app minimized to the system tray, hence the name Stealth Dialog. This can be accomplished simply by first creating a modeless dialog:
HWND hWnd = CreateDialog( hInstance,
MAKEINTRESOURCE(MY_DIALOG),
NULL,
(DLGPROC)MyDlgProc );
Then use Shell_NotifyIcon as shown above to add your icon to the
tray. Do not call ShowWindow.
Messages from the tray will go to the window specified by the
hWnd member of the NOTIFYICONDATA struct
and the message ID is specified by the uCallbackMessage member (see
above). The specific message is in the LPARAM.
INT_PTR CALLBACK MyDlgProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case MY_TRAY_ICON_MESSAGE:
switch(lParam)
{
case WM_LBUTTONDBLCLK:
ShowWindow(hWnd, SW_RESTORE);
break;
case WM_RBUTTONDOWN:
case WM_CONTEXTMENU:
ShowContextMenu(hWnd);
}
break;
case...
If you implement a context menu, messages are received through
WM_COMMAND and the menu item ID is contained in the low-order word
of the WPARAM.
case WM_COMMAND: switch (LOWORD(wParam)) { case MY_MENU_MSG1: ... break; case MY_MENU_MSG2: ...
Important: If you implement a context menu, it's vital that you set
your window to the foreground before calling TrackPopupMenu to
ensure the menu closes properly.
void ShowContextMenu(HWND hWnd) { ... HMENU hMenu; // create or load a menu ... SetForegroundWindow(hWnd); TrackPopupMenu(hMenu, ...
Sometime before your app closes you should remove your tray icon by calling
Shell_NotifyIcon with the NIM_DELETE flag.
case WM_DESTROY:
Shell_NotifyIcon(NIM_DELETE,&niData);
The MSDN documentation says about the cbSize member of the
NOTIFYICONDATA structure:
"You can keep your application compatible with all Shell32.dll versions
while still using the current header files by setting the size of the
NOTIFYICONDATA structure appropriately. Before
initializing the structure, use the DllGetVersion function
to determine which Shell32.dll version is installed on the system. If it is
version 5.0 or greater, initialize the cbSize member
with:
nid.cbSize = sizeof(NOTIFYICONDATA);
Setting cbSize to this value enables all the version
5.0 and 6.0 enhancements. For earlier versions, the size of the pre-6.0
structure is given by the NOTIFYICONDATA_V2_SIZE constant
and the pre-5.0 structure is given by the
NOTIFYICONDATA_V1_SIZE constant. Initialize the
cbSize member with:
nid.cbSize = NOTIFYICONDATA_V2_SIZE;
Using this value for cbSize enables your application
to use NOTIFYICONDATA with earlier Shell32.dll
versions, although without the version 6.0 enhancements:"
Now maybe it's my neighbors Turkish tobacco or maybe I'm just not catching on here, but there seems to be an overlapping conflict between "5.0 or greater" and "pre-6.0".
Anyway, if anybody can shed any light on this or anything else they care to shed light on, please shed.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 15 Aug 2003 Editor: Smitha Vijayan |
Copyright 2003 by Abraxas23 Everything else Copyright © CodeProject, 1999-2009 Web17 | Advertise on the Code Project |