tags:

views:

369

answers:

4
+6  Q: 

Systray Access

Is there a way (in C#) to access the systray? I am not talking about making a notify icon. I want to iterate through the items in the tray (I would guess through the processes but I don't know how to determine what is actually in the tray and what is just a process) and also represent the items with their icons in my own ui.

+1  A: 

Mathias Rauen's madCollection (for Delphi not c#) can list Tray Icons.

And there is a commandline tool: Windows System Tray Scan Utility

I have also written (not released) my own program in Delphi (not Delphi.NET), not using madCollection, which shows tray icons, process names, tooltips and other info but it's not perfect. There are a few icons it can't display (even though it lists other info), and it can't display any icons under windows 9x. I haven't tested it at all under Vista.

Hugh Allen
+5  A: 

How do you feel about Win32 interop? I found C/Win32 code that might do the trick for you. (Actually, it looks like an interesting problem so I might try to tackle it myself, just not now).

The magic appears to be that he gets a handle to the system tray's window:

NotifyWnd = FindWindowEx(SysTray, 0, "TrayNotifyWnd", 0);

Then he sets a hook on its message pump:

hHook=SetWindowsHookEx(WH_CALLWNDPROC,HOOKPROC(MsgProc),
         hInstance,dwExplorerThreadId);

Then during the message pump hook callback, he gets a reference to some pointer data about the window:

TWDataT* twd=(TWDataT*)GetWindowLong(NotifyWnd,0);

The mystery is then his loop:

      pTWIconDataT p=COMCTL32_332(twd->iconsInfo,i);

COMCTL32_332 is defined with GetProcAddress and points to ordinal 332 of Comctl32.dll - according to my checking with Dependency Viewer, that's DPA_GetPtr, which gets data from a dynamic pointer array. I'm not familiar with what's going on behind the scenes there, but it doesn't seem entirely out of the question.

I'm going to play with this a bit myself, but hopefully it's a good place to get you started. :)

Rob
+1  A: 

In Windows 2000, the system tray icons are in a plain toolbar control (window class "ToolbarWindow32") which is a child of the "TrayNotifyWnd" window, so you can send it toolbar messages such as TB_BUTTONCOUNT and TB_GETBUTTON.

You need to be careful though: messages such as TB_GETBUTTON which require a pointer to a buffer in which to store the results need that buffer to be in the SysTray process itself. This requires that you have the right permissions, and that you use VirtualAllocEx to allocate the memory.

I haven't tried it on XP or Vista. I expect things have changed.

Anthony Williams
A: 

Rob: I am digging your answer. I am already using interop to get the current tasks so this is natural. Also I think the use of a newer function like DPA_GetPtr means I may have fewer issues integrating it with what I already have (as I am in XP.)

Would be very interested to see what you come up with if you pursue it further.

Thanks to all of you for your answers.

jvberg