Click here to Skip to main content
Click here to Skip to main content

Basic use of Shell_NotifyIcon in Win32

By , 15 Aug 2003
 

Introduction

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?

  • I've never written a Code Project article before and this seemed pretty easy.
  • This isn't another wrapper, but simple straight forward example of Shell_NotifyIcon with a minimum amount of code.
  • I wanted an example written in pure Win32 code.
  • I wanted to address some of the common problems and questions I've seen posted in other articles on the subject.

The basics

Adding, modifying, hiding and deleting tray icons is accomplished in two steps:

  1. Initialize a NOTIFYICONDATA structure
  2. Call Shell_NotifyIcon

Initialize a NOTIFYICONDATA structure

// 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;

Call Shell_NotifyIcon

// NIM_ADD adds a new tray icon
    Shell_NotifyIcon(NIM_ADD,&niData);

Stealth dialog

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.

Menus and messages

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, ...

Cleaning up

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);

Notes:

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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Abraxas23
China China
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 4memberTELunus20 Jan '13 - 17:56 
A good clear article, but nothing spectacular.
GeneralMy vote of 5membernoobody211 Jul '10 - 20:53 
Shows how to init balloon tips under different version of OS. The first correct solution I found.
QuestionIcon Disappears [modified]memberligoten21 Oct '08 - 14:05 
I added a tray icon to the RemoteSkin application from the Windows Media Player SDK, but as soon as I mouse over the tray icon, it disappears. The rest of the program still works as I expect, but I can't use the tray icon if it disappears as soon as I mouse over it. Does anyone have a clue as to why I might be having this problem?
 
Edit: I moved the tray icon creation into CMainDlg, and everything works properly.
 
modified on Saturday, November 15, 2008 1:30 PM

GeneralThanks for the samplememberdon.leri30 Sep '08 - 8:28 
Nice sample.
 
Also thanks to JasonCipriani for his comments.
GeneralThanks for the useful articlememberjianwu9 Sep '08 - 20:59 
Thanks for the useful article
GeneralNo window at allmemberJasper9118 Jul '07 - 11:14 
Hi all,
 
is it possible to set no window at all? (So you can't open it from de TrayIcon)
 
Thx,
Jasper
GeneralRe: No window at allmemberAbraxas2319 Jul '07 - 13:39 
I think you need to set a valid window handle,
but it's up to you what happens when the user clicks de tray icon.
GeneralYou can remove the DllVersion stuff. Also, a NIF_TIP problem.memberJasonCipriani8 Feb '07 - 18:56 
A couple of comments.
 
If you simply set the size to NOTIFYICONDATA_V1_SIZE, then the system will treat it as a V1 NOTIFYICONDATA structure. While you won't have the 5.0 and 6.0 shell features available, that's not a problem as the code in this example does not use them anyway. You'd do:
 
NOTIFYICONDATA niData; 
ZeroMemory(&niData,sizeof(NOTIFYICONDATA));
niData.cbSize = NOTIFYICONDATA_V1_SIZE;
niData.uID = MY_TRAY_ICON_ID;
niData.uFlags = NIF_ICON|NIF_MESSAGE;
niData.hIcon = (HICON)LoadImage(...);
niData.hWnd = hWnd;
niData.uCallbackMessage = MY_TRAY_ICON_MESSAGE;
 
And that will do it. That will also allow your application to run correctly on earlier versions of Windows, as NOTIFYICON_V1_SIZE was the old structure size. After that, call Shell_NotifyIcon() as per usual.
 
Also this writeup makes use of NIF_TIP but does not set the tool tip string. If you do not want a tool tip, then leave NIF_TIP out of niData.uFlags. However, if you do want a tool tip, include NIF_TIP as per the example, but don't forget to set the tool tip string:
 
::strcpy(niData.szTip, "The tool tip string.");
 
The max length for the tool tip string was 64 bytes (63 ANSI chars + terminator) for the V1 version of the structure; so if you're using NOTIFYICONDATA_V1_SIZE, you'll want to not exceed that length. Note that you don't want to use sizeof(niData.szTip) to determine the max length... if you are on a system using version 5.0 or greater, niData.szTip will be larger than 64 bytes, which disagrees with your NOTIFYICONDATA_V1_SIZE.
 
One other point to make that is missing in this writeup (although you can read about it in the Shell_NotifyIcon documentation): When deleting an icon with NIM_DELETE, only the cbSize, hWnd and uID members need to be set in the NOTIFYICONDATA structure, and uFlags can be 0. The code in this example works because that is the case; but if your application is repacking data into the structure to NIM_DELETE it, you need not set any of the other members besides those three.
 
Also note that NOTIFYICONDATA_V1_SIZE is not defined on pre-5.0 machines, so while your code may run, if your goal is to compile the code on those machines, you will have issues using those constants (so be sure to check _WIN32_IE as described in the example). Applications normally use the old interface by default anyways. As a matter of fact, the docs imply that your application is responsible for setting _WIN32_IE to the version you want to use.
GeneralRe: You can remove the DllVersion stuff. Also, a NIF_TIP problem.memberAbraxas2313 Mar '07 - 20:04 
Thanks for your input. When I find the time and my internet connection is stable I will be updating this article. You are right that the code presented here makes no use of version 5.0 or 6.0 features and the structure size can be safely hard coded. However I included the GetDllVersion function because I wanted to show how the version could be determined at runtime.
The NIF_TIP flag is set because the demo project does have tooltip text and I simply copied and pasted when I wrote the article.

GeneralMany ThanksmemberARSanthosh6 Dec '06 - 13:22 
This is the only document I could find useful on this topic.
 
Santhosh
GeneralGood article, I used your code in my projectmemberDidier Stevens16 Oct '06 - 9:51 
Thanks for your article, it showed me how I could add an icon to my USBVirusScan program (it's a modification of USBDumper).
 
Here is my program: http://didierstevens.wordpress.com/2006/10/16/usbvirusscan/
 
Didier Stevens
 
https://DidierStevens.com
GeneralDefinately something to look at.memberJames R. L. X. Z.10 Oct '06 - 20:09 
The reason I say this, is not everyone has VC++. In fact, I'd say a good amount doesn't. So why make your code STRICTLY for VC++ libraries that refuse to work in other compilers? Sure, it helps the people who have the MONEY for the expensive compiler, but this takes away ALOT of your freedom. Personally, I HATE VC++'s interface. It's TOO user friendly, which C and C++ are not supposed to be. User Friendly also means a different way to do every little thing, which means you have to learn a new way to do stuff you learned when you were a C nublet. If you have to RELY on tools such as dialog creators and such, your not a programmer, your practically a scriptor with a mild programming background. More articles need to be like this, using ONLY the basic win32 libs, instead of telling everyone "You can do this using basic code, or VC++s generator... SO LET'S GO WITH THE GENERATOR!". Glad to see someone can contribute something useful to the minority. Smile | :)
GeneralRe: Definately something to look at. [modified]member2boxers15 Oct '08 - 2:27 
I realize this is an old post, but since I have used numerous linux and windows based compilers and IDEs since before 1998, I still wanted to comment.
 
The code in this contribution is not STRICTLY for VC++ as you so enthusiastically say. It is simply win32 and C++. If you do not know how to make other compilers link win32 libraries, then it is a knowledge issue, not a VC++ issue.
 
Prior to this contribution there was the free VC++ toolkit and in present day as of my reply, there is the free VC++ 2008 express, so the comment regarding MONEY was not exactly accurate.
 
Those are the facts. Now for an opinion. Using a resource editor does not mean you are not a good programmer. I can do way more with a resource editor and native Win32/C++ in a given time period than what most can do without a resource editor. It is a question of time and efficiency.
 
Your bashing the author for using a resource editor VC++ and your references to "nublet" are quite amazing to me in that given your comments they seem to apply mostly to you.
 
modified on Wednesday, October 15, 2008 10:20 AM

Generalreally good, many thanks to youmemberikohl1 Oct '06 - 4:19 
really good, many thanks to you
QuestionHow to keep my tray icon stay after explorer reboot?memberCoolboy12326 Sep '06 - 4:15 
I love your article.
It helps me a lot,but can you show me a demo how to keep my icon in the systray?
I read this
http://www.microsoft.com/msj/0299/c/c0299.aspx
 
But in my application ,it can not get the TaskbarCreated message at all!
 
Sorry for my poor English,it is not my native language....
 
Can you Help me?D'Oh! | :doh:
QuestionNot catching MY_TRAY_ICON_MESSAGEmemberparatracker18 Aug '06 - 20:29 
I am following your example targeting Pocket PC, but the window handle I put in the NOTIFYICONDATA structure is not mapping the MY_TRAY_ICON_MESSAGE to my routine. I'm tracking 'unexpected' messages in that window's DefWindowProc so I can see the tray icon messages arriving there. Besides the messages not being mapped to the routine specified in the message map, they're also generated just by having the cursor (pen) over the icon - no click (tap) necessary. Am I missing something?
 
The message map declaration looks like:
 
	//}}AFX_MSG_MAP
	ON_COMMAND( MY_TRAY_ICON_MESSAGE, OnIconNotify )
END_MESSAGE_MAP()
 
Any ideas?
 
Thanks, Mike
 
http://pnmx.com
AnswerRe: Not catching MY_TRAY_ICON_MESSAGEmemberAbraxas2320 Aug '06 - 14:07 
Is the HWND that you are passing in the NOTIFYICONDATA structure a top level window?
QuestionHow to keep tray icon active all the time?memberMadhu Kavali3 Aug '06 - 8:31 
Do you know how to programmatically change the taskbar properties? We could potentially change the property of this tray icon to show all the time.
 
Thanks
Questionstealthdialog with wamp is hanging [modified]membermrdynalink2 Aug '06 - 10:20 
I want to use stealthdialog with a wamp system (windows-apache-mysql-php on a XP machine). The idea (dream) is to start a program as background process using a webserver and have an icon in the system tray of the server as indicator.
stealdialog seemed to be the perfect solution, but I have a problem. When I start stealdialog in a php-script using the php "system" function then the script is hanging, the system call is not returning. With the Task Manager I can see the stealthdialog process running but I can not see the tray icon. If I start stealthdialog in a cmd shell, then it`s returning immediately and the tray icon is installed perfectly. The apache server is calling the stealthdialog as user "system". I have no clue and need help from a windows guru.
 
mrdynalink
 

-- modified at 16:23 Wednesday 2nd August, 2006
Answersame problem with windows task plannermembermrdynalink6 Aug '06 - 1:23 
It is possible to simulate the problem with the windows task planner.
 
If I start StealthDialog with the windows task planner under my username (e.g. after a minute) then the icon in the system tray appears but the task does not return. In the windows task planner window the task is still marked as "running". I can exit the program over the tray icon itself.

If I run the program under the user "system" (like the apache web server) then I see no tray icon but I can see the program running using the task manager and the program is marked as running in the task planner.
 
I think the problem is that the user "system" has no desktop and no assigned system tray.
 
Is it possible to "bind" the tray icon to the current desktop ?
 
mrdynalink
GeneralThank you...memberRacingTurtle27 Jan '06 - 0:16 
... for this tutorial. Straight forward and simple, but includes everthing I need. Great.
 
Turtle
Questionhow do i get the tray icon everytime after the bootmemberusha_dolly28 Dec '05 - 18:14 
hello sir,
when my system gets reboot,the trayicon is coming first before the windows taskbar.so the system is not placing the icon inthe tray ,so i'm not able to get the icon.can u plz help me how to locate the taskbar through our code.
thanking u in advance
usha
AnswerRe: how do i get the tray icon everytime after the bootmemberAbraxas237 Feb '06 - 19:41 
I've never had this problem, even when creating the icon with a service. The tray should be created before any app windows.
There are several articles here about locating the system tray, try Chris Maunder's Finding the position and dimensions of the Windows system tray.
GeneralRe: how do i get the tray icon everytime after the bootmembermgpw26 Jul '06 - 7:02 
Hi.
 
You can determine when the taskbar has been created by registering a message for _T("TaskbarCreated")
 
const UINT WM_TASKBARCREATED = ::RegisterWindowMessage(TEXT("TaskbarCreated"));
 
Then, just modify your message handler to add call your addIcon method.
 
Implementing the above should solve the "start up" problem where your app is created before the taskbar. It should also solve problems such as when Explorer falls over and the taskbar is re-created.
 

QuestionWindows 98?memberZeddie20 Dec '05 - 10:56 
Does this work with Windows 98? Confused | :confused:
 
/Zeddie
AnswerRe: Windows 98?memberAbraxas237 Feb '06 - 19:17 
I've never tested it with Win98, but yes it should work.
QuestionHow to avoid multiple tray icons of the same app?memberSstar915 Dec '05 - 19:53 
Good article.
 
But I noticed that if I click on the demo .exe file twice, there would be two Tray icons in the Notification Area.
 
Is there any standard way to avoid placing multiple tray icons of the same application into the notification area?
 
Thanks In advance for yoru
 
Create Bugs and Kill Bugs
AnswerRe: How to avoid multiple tray icons of the same app?memberAbraxas237 Feb '06 - 19:15 
The simplest way would probably be to create a mutex.
 
HANDLE hFirst = ::CreateMutex( NULL, FALSE, _T("mutex name") );
if( NULL != hFirst && ::GetLastError() != ERROR_ALREADY_EXISTS )
{
    // add tray icon
}

GeneralRe: How to avoid multiple tray icons of the same app?memberJasonCipriani8 Feb '07 - 18:41 
If you do that then while it does prevent the icon from showing twice, you still have two instances of your application running at the same time. Except one of them doesn't have an icon in the tray. And if the icon is the only way for somebody to exit your application, then you've created a very irritating situation.
 
CreateMutex is the way to go, but if you want to prevent two instances of your app from running at all, stick code similar to that snippet right at the start instead. For example, as the first bit of code in WinMain():
 
HANDLE hFirst = ::CreateMutex( NULL, FALSE, _T("mutex name") );
if( hFirst == NULL || ::GetLastError() == ERROR_ALREADY_EXISTS )
  ::ExitProcess(0); // exit program if an instance is already running

GeneralRe: How to avoid multiple tray icons of the same app?memberAbraxas2313 Mar '07 - 20:21 
If your goal is to limit the number of instances then you are right but that was not the question that was asked. Furthermore if you implement the code as you suggest you will run into the irritating situation of the user trying to start you program but nothing happens because he doesn't know there is already an instance running.
For a complete discussion of this topic see Avoiding Multiple Instances of an Application.
GeneralRe: How to avoid multiple tray icons of the same app?member"Fish" (David B. Trout)1 Oct '08 - 17:08 
But BEFORE you exit your process you should send a message to your process that's already running asking it to show its window and bring it to the foreground.
 
"Fish" (David B. Trout)
fish(at)softdevlabs.com
PGP key fingerprints:
RSA: 6B37 7110 7201 9917 9B0D 99E3 55DB 5D58 FADE 4A52
DH/DSS: 9F9B BAB0 BA7F C458 1A89 FE26 48F5 D7F4 C4EE 3E2A

GeneralHere's how to get the DLL VersionmemberElchay3 Nov '05 - 6:15 
DWORD junk;
DWORD s = GetFileVersionInfoSize(_T("Shell32.dll"), &junk);
BYTE * buf = new BYTE[s];
 
VS_FIXEDFILEINFO * pFfi;
UINT len;
 
BOOL res = GetFileVersionInfo(_T("Shell32.dll"), NULL, s, buf);
res = VerQueryValue(buf, _T("\\"), (void **)&pFfi, &len);
 
short majorVer = HIWORD(pFfi->dwFileVersionMS);
 
but according to the tests I ran on two machines here, one running a Win2K and the other a XPSP2, it worked no matter what was in the cbSize variable, even when it was zeroed...Confused | :confused:
GeneralGreat job!memberboolman19 Oct '05 - 7:38 
I just wanted to thank you for taking the time to write this tutorial / example. It helped me alot.
 
/boolman
GeneralShell_NotifyIcon sometimes fails at startupmemberLukeV18 May '05 - 9:42 
Hi!
 
My application is automatically started when Windows is lauching. Sometimes Shell_NotifyIcon will fail. I do not have an error code since I haven't been to reproduce that bug very often.
 
My guess is that the desktop is not ready or something. Do you think that it would be safe to do something like:
 
BOOL bRes;
 
do
{
bRes = Shell_NotifyIcon(...);
}while(bRes = FALSE);
 
Thanks!
GeneralRe: Shell_NotifyIcon sometimes fails at startupmemberAbraxas2319 May '05 - 4:58 
I've never experienced this problem before. The tray should be ready by the time Windows is launching startup apps. At which stage of your app startup are you calling Shell_NotifyIcon? Make sure the call is the last step of the launch process. What method are you using to launch your app? Maybe try a different method. I wouldn't recommend looping as you suggest as this will load the system and could lead to your app hanging if for some reason Shell_NotifyIcon continues to fail. In this situation I think any kind of loop would probably be a bad idea but if you find no other solution you should consider something like:
 
BOOL bRes;
 
for( int i = 0; i < 10; i++ )
{
   if( TRUE == (bRes = Shell_NotifyIcon(...))) break;
   Sleep( 1000 );
}
if( !bRes ) DoSomething();
 

GeneralRe: Shell_NotifyIcon sometimes fails at startupmemberrharting1 Aug '05 - 7:32 
I've had this problem as well. The problem I see happens when you wait too long to log into Windows. My app starts up automatically, and it starts before the log in. If I wait 5 minutes before hitting CTRL-ALT-DEL to put in my password, I will see the problem very repeatably. I assume this is because the "Tray" doesn't exist yet when the app calls Shell_NotifyIcon, but I don't know. Is there a way to tell if Shell32 is intialized and ready to go?
 
Thanks, nice article!
 
Thank You
General[ELP] hide the icon of another process than the minesussNewMAn29118564512 May '05 - 20:24 
First, excuse my poor english (it's not my native language, I'm french).
Then, how can I hide icons of other programms in the systray ? Is It possible?
 
Thanks
GeneralRe: [ELP] hide the icon of another process than the minememberAbraxas2319 May '05 - 5:19 
In order to do this you would have to obtain the window handle of the program and the id number used to add the icon. There are various ways you might obtain the window handle and this would have to be done every time Windows starts. Obtaining id would probably have to be done by brute force but once obtained shouldn't change allowing you to hard code it into your app.
General[ELP] hide the icon of another process than the minesussNewMAn291185645646512 May '05 - 20:23 
First, excuse my poor english (it's not my native language, I'm french).
Then, how can I hide icons of other programms in the systray ? Is It possible?
 
Thanks
GeneralGet existing iconssussAnonymous24 Feb '05 - 14:08 
I've looked everywhere but I can't find a function to get information about other icons in the tray. I even tried using Shell_NotifyIcon with NIM_SETFOCUS, passing it the hWnd of every open window, but it just returns true every time.
GeneralRe: Get existing iconssussAnonymous24 Feb '05 - 14:11 
[continued because the stupid thing submitted my post when I tried to add a smilie <_<]
There must be some way to get existing icon info? I've looked at the windows' styles and extended styles but there's nothing that signifies whether the window has an icon or not.
QuestionHow to keep icon active on WinXP?memberdlanders23 Dec '04 - 6:38 
Does anyone know if there is an official mechanism (or have unofficial ideas;)) to keep a tray icon active so that Windows XP does not "hide" the inactive icon? I assume that by updating the icon periodically, I can keep it "active", but that seems inefficient. Frown | :(

 
Thanks,
Dave
GeneralGetDllVersion()sussAnonymous18 Dec '04 - 7:38 
Do you realize that the GetDllVersion() function is a part of the Windows CE API?
 
It would be nice if you could write a bit about how you imported it to WinNT enviorments such as Win2K/XP like another unanswered thread was about. Its seems you avoid this subject, maybe you have realized that it renders your entire article useless.
 
Best of luck to you and please try again.
GeneralRe: GetDllVersion()memberte_mike26 Dec '04 - 15:40 
I managed with VS 2003 to compile this code and run it fine with GetDllVerion().
 
I also read in MSDN that you can use GetDllVersion() to check what features you can use.
 
This MSDN article on GetDllVersion() seems to be WinNT environment code:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q193573
 
You can actually comment out that entire section and just use:
 
niData.cbSize = sizeof(NOTIFYICONDATA);
 
I actually did that at first to make the code even simpler for a friend to learn from.
GeneralRe: GetDllVersion()memberAbraxas2319 May '05 - 5:40 
The GetDllVersion() code I am using in this sample is a direct copy and paste from MSDN and as the previous post points out not necessary in most cases. The subject of determining system versions is amply covered in other articles and not really integral to the process of adding a tray icon. I think I will just update the article and remove it altogether.
GeneralGetDllVersionmemberfolarx26 Nov '04 - 8:32 
I was wondering how did You manage to make this code work without actually importing the DllGetVersion function.
GeneralDialog box and system traymembercalpol200414 Sep '04 - 8:48 
My program has a dialog as the main window it does'nt have a "dummy" window. when the dialog is activated I can't click the icon to bring the context menu up, Unless i click the icon multiple times, I think this is because my dialog box doesn't have an owner I tried setting the handler to nidata.ucallbackmessage handler but then it does'nt appear on the taskbar. I either need a handler for window to belong to which could be a handler to the syastem tray or someway to force a program onto the taskbar.

 
cal
GeneralRe: Dialog box and system traysussoshah15 Sep '04 - 6:53 
If ms kb 135788[^] describes your problem the solution would be to use something like this code (taken right out of that kb article):
 
   SetForegroundWindow(hDlg);
 
   // Display the menu
   TrackPopupMenu(hSubMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hDlg, NULL);
 
   PostMessage(hDlg, WM_NULL, 0, 0);
 
ie. make the dialog the foreground window before making the menu (make sure the user clicked the icon first and not your dialog). Then after using the menu, send a benign message.

QuestionHow to create MFC single dialog that initialy hiden?memberWayut28 Jun '04 - 15:52 
Hi,
I need to start an MFC application that doesn't initialy show its main windows. I tried to implement virtual function PreCreateWindows and set cs.style to 0 (not putting WS_VISIBLE), and also disable the visible property of the dialog window in the outset. It doesn't work.
So far I can only call SetWindowPos function from OnDraw function to hide the main dialog window. However, the user can still see a window appear and then dissapear immediately, which is undesirable.
Please help.
 
Many thanks.
AnswerRe: How to create MFC single dialog that initialy hiden?memberAbraxas2328 Aug '04 - 23:58 
I believe an MFC dialog needs to be modeless for this to work. See the CDialog docs on how to do this. First make sure your dialog template does not have the WS_VISIBLE style and then create the dialog and don't call ShowWindow().

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 16 Aug 2003
Article Copyright 2003 by Abraxas23
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid