|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionWe’re all familiar with programs that add icons to the system tray - Windows NT/2000’s Task Manager, the Microsoft offline files synchronisation manager, and many other third-party apps. Quite frequently, these icons open a dialog of some sort when double-clicked. The normal procedure is to simply hide or show the window. It would be nice if the window displayed the same animation used when minimizing or maximizing a window to and from the task bar. This article shows how simple it is to do just that. Drawing the AnimationIt is actually very simple to duplicate the effect of the
minimizing and maximizing animation - just one function call will do the trick.
BOOL WINAPI DrawAnimatedRects(HWND hwnd, // handle to clipping window <span> int idAni, // type of animation <span> CONST RECT *lprcFrom, // rectangle coordinates (minimized) <span> CONST RECT *lprcTo // rectangle coordinates (restored) ); When animating the caption, the The interesting argument is (As a brief aside, the include files that come with Visual
C++ 6 include definitions for not only Another thing to note is that the headers for the current
Platform SDK - April 2000 - only define Determining the Animation ParametersIt’s not enough to know how to display the animation; we
also need to know the start and end position. When minimizing, the “from” value
is simple, you can use the The “to” value is slightly trickier. We need to get the The most accurate way of getting the system tray dimensions
is to actually get the system tray’s window. Through judicious use of the very
handy Spy++ utility, we can see that the system tray is a window of class
“TrayNotifyWnd”, which is a child of the top-level window of class
“Shell_TrayWnd”. We can easily get these windows using The nearest thing we can get to a documented method is to use the
There is still the possibility that this will fail. This is
really only likely if explorer has been replaced by a third party shell. Many
of these shells now support a system tray ( If all else fails, we just use a default value in the bottom right of the screen. Obviously enough, when maximizing, the “to” and “from” values are the opposite to when minimizing. One Last NicetyWindows allows the animation to be disabled (using a registry setting, or a
tool such as the infamous TweakUI), so we must check for that before calling
The Sample CodeThere are two main files in the example project included with this article. MinimizeToTray.cpp contains the functions to minimize and restore the window, and MinimizeDemo.cpp contains a simple dialog app that demonstrates how to use these functions. MinimizeToTray.cpp contains two public functions: <span>VOID MinimizeWndToTray(HWND hWnd); <span>VOID RestoreWndFromTray(HWND hWnd); The One thing to note is that if MinimizeDemo.cpp shows how to use the two functions in an actual app, and even
shows a simple use of the ConclusionThis code is very easy to use. Simply drop the MinimizeToTray.cpp file into your project, and add two function calls to your app. There are plenty of comments in the source files, and the MinimizeDemo.cpp sample is very easy to follow. This code is public domain. Feel free to use and abuse it in any way you want. If you do use it though, I’d appreciate it if you dropped me a quick note. Consider it emailware. CodaThe main purpose of this article was to explain how to use
The most prevalent problem with notification icons is that once you display a menu for the icon, clicking outside of the menu doesn't dismiss it. Apparently, "this behaviour is by design" and is documented in Microsoft's Knowledge Base article Q135788. Another problem frequently encountered is that the notification icon stays
in the system tray, and disappears when the mouse moves over it. This is simply
that the program hasn't removed the icon before quitting - a call to
Finally, we have a somewhat tricky one. When double-clicking on one icon, it is sometimes possible to also activate another. This happens if the first icon is removed in response to the double-click message. As this message is sent in response to the mouse button being pressed, released and then pressed again, Windows still has a button up event left to send. And because the icons have moved in response to the first icon being removed, this message is sent somewhere it wasn't intended for. That icon may then innocently enough take action in response to this message. This is a situation where no one can take blame. However, it is one we can work around. Instead of removing the icon once we action on the double-click event, we remove it in response to the second button up, everything works perfectly. The easiest way to do this is to set a flag when we receive a double-click event, and remove the icon when the flag is set in the button up handler. The example code included shows how to do this. History1.0 28 June 2000 Initial version 1.1 19 October 2000 Added useful tips on using Shell_NotifyIcon. Thanks to Darren Schroeder for reporting this potential problem!
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||