Friday, June 1, 2007

XPe tip #48: Get rid of System Tray icons and remap the UI

There are some 3rd party applications (and even Microsoft application like BlueTooth systray agent) that install icons in the SysTray area - the right-lower corner of the Desktop screen. Some of these application rely on the presence of that icon to provide a way to access their UI. Unfortunately, often there is no other way left.

When you are trying to get rid of Explorer shell (on some embedded devices that run a custom shell apps it will make sense) you will remove the SysTray ("Notification Area") as well since it is a part of the Explorer application. More precisely it is a part of the TaskBar feature of Explorer Desktop that runs as system shell.

So, the question is how to get rid of the SysTray (the Explorer) but yet have a way to access such application UI? No easy answer.

Here is what I'd suggest (posted my thoughts in this newsgroup thread).

1) The best approach would be to implement the missing Explorer features within your own custom shell application. It is really hard with regards to some features and requires a lot of debugging on XP/XPe to understand how those features work and how to invoke and integrate them into your own application.
Just to encourage you, I've done this for some of the Explorer features such as AutoPlay, Taskbar, Volume Manager and etc.

2) How 3rd party applications install the icons in the System Tray area?
It is basically about about one API function - Shell_NotifyIcon - that is being used by applications to add icons to SysTray area and be able to receive notifications from the shell by user clicks on those icons through the application window procedures (when you call that API you register your window procedure to receive the events). The Shell_NotifyIcon is exported by shell32.dll. Assuming you don't use shell32.dll in your image that is supposed to run a custom shell, you can create your own version of shell32.dll that will expose (export) that function only. Used as a shim it will give you the full control over what and when that application is doing in the UI.

3) Another way, much simpler, is to find out what messages are sent to the application window procedure when user clicks on the application specific icon in SysTray area or selects an item on the appropriate menu shown by the left-[right-]click on the SysTray icon. Knowing those messages and their parameters (likely WM_COMMAND messages) you can always implement them and send them out from your own shell to the 3rd party application being investigated. This way you can "remap" all the functions of the application icon in SysTray to your own UI.
The best way to watch for the messages is to start with Microsoft Spy++ tool. Next steps is to subclass the window (via global hooks in Win32) and watch for the messages through debug output.

No comments: