views:

550

answers:

6

Is there a way to guarantee that your system tray icon is removed?

To add the system tray icon you do:

Shell_NotifyIcon(NIM_ADD, &m_tnd);

To remove the system tray icon you do:

Shell_NotifyIcon(NIM_DELETE, &m_tnd);

What I want to know: what if you application crashes? The icon stays in your system tray until you mouse over. Is there a way to guarantee that the icon will be removed, even when the application crashes? I would prefer not to use structured exception handling for various reasons.

Another case that I want to handle is when the process is killed, but doesn't necessarily crash.

+3  A: 

You could have a separate, simpler (and thus presumably more robust) program which monitors your application. This program could actually launch your program and then monitor the process. Yeah, this is a very ugly solution.

Brian
Also this external program can manage the tray icon, and the main program communicate its status using notifications, if they don't reach withing a timeout the icon is hidden, sort of keep alive message.
Ismael
+1  A: 

Hmm, you can always have an external monitor process call SendMessage with the WM_PAINT message to the system tray window (which you would have to do based on the class of the window). That should remove the icon which is no longer valid.

casperOne
A: 

You have to handle the applications exit when crashing some way or another or the icon will not disapear.

Check this out if it can be any help: http://www.codeproject.com/KB/shell/ashsystray.aspx

Stefan
+2  A: 

Personally I would use a Vectored Exception Handler. Yes, it's based on SEH, but you don't have to deal with all the different stack that you might need to unwind.

TerminateProcess() is must more destructive. You really can't guard yourself against that; when it happens your process is dead. No ore instructions are processed, so it does not matter what code there is in your application.

An external application wouldn't really help, would it? It too could crash, or be killed.

MSalters
A: 

You can use SetUnhandledExceptionFilter to catch the crash. I normally use it to create a crash dump file so that the crash can be debugged, but there's no reason you can't so some simple cleanup like removing tray icons.

Ferruccio
+1  A: 

Another thing most programmers forget to check for is if the explorer restarts/crashes. Its nice if the application handle this and recreate its own icon.

Just check for Message WM_TASKBARCREATED and recreate the icon.

Stefan