In this previous post I showed some code to display balloon notifications via InfoCenter in AutoCAD 2009 (and, it seems, in AutoCAD 2008, albeit with a different look & feel).
In a comment on that post, I promised to take a look at another way to show user notification balloons in AutoCAD, by displaying balloons (or maybe it's "blowing bubbles"? :-) on the application status bar. It's really up to you to decide which style of balloon is more appropriate for your application notifications... I personally find the InfoCenter balloons less intrusive (and more modern-looking), but the choice is yours. The duration during which the balloons are displayed is also controlled differently: the status bar "tray settings" controls the status bar balloons, the duration of the InfoCenter balloons is decided more directly by the application.
From a programmatic perspective, status bar balloon notifications are also different in nature from their InfoCenter equivalents: we need to create a balloon window and have a status bar tray item display it.
In the below code we create a tray item on the fly, just for the purposes of displaying the balloon, but you may actually have your own tray icon that you provide for your users to access your application features & settings (which would be a great topic for a follow-up post, thinking about it).
Rather than me creating and providing a custom icon, this code takes the lazy option and picks up the first icon that is available in the current document's status bar (which happens to be the annotation scaling icon, on my system at least). The right way to do this is to create a custom icon file (or resource) and load it into a System.Drawing.Icon. This is left as an exercise for the reader or to be addressed in a future post (we'll see :-).
Here's the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.AcInfoCenterConn;
using Autodesk.AutoCAD.Windows;
namespace BalloonsAndBubbles
{
public class Commands
{
const string title =
"Custom Application Notification";
const string hlink =
"http://blogs.autodesk.com/through-the-interface";
const string htext =
"Link to Kean's blog";
const string msg =
"Kean has some information for you...";
const string msg2 =
"Some additional text";
[CommandMethod("icb")]
public void infoCenterBalloon()
{
InfoCenterManager icm =
AcInfoCenterConn.InfoCenterManager;
Autodesk.InfoCenter.PaletteMgr pm =
icm.PaletteManager;
pm.ShowBalloon(
title,
msg,
null, // Don't provide an icon
new System.Uri(hlink),
5, // Show the balloon for 5 seconds
1 // Make it relatively slow to fade in
);
}
[CommandMethod("sbb")]
public void statusBarBalloon()
{
const string appName =
"Kean's application";
Document doc =
Application.DocumentManager.MdiActiveDocument;
TrayItem ti = new TrayItem();
ti.ToolTipText = appName;
ti.Icon =
doc.StatusBar.TrayItems[0].Icon;
Application.StatusBar.TrayItems.Add(ti);
TrayItemBubbleWindow bw =
new TrayItemBubbleWindow();
bw.Title = title;
bw.HyperText = htext;
bw.HyperLink = hlink;
bw.Text = msg;
bw.Text2 = msg2;
bw.IconType = IconType.Information;
ti.ShowBubbleWindow(bw);
Application.StatusBar.Update();
bw.Closed +=
delegate(
object o,
TrayItemBubbleWindowClosedEventArgs args
)
{
// Use a try-catch block, as an exception
// will occur when AutoCAD is closed with
// one of our bubbles open
try
{
Application.StatusBar.TrayItems.Remove(ti);
Application.StatusBar.Update();
}
catch
{}
};
}
}
}
The ICB command is basically the same as the one shown in the previous post (with just the strings factored out into constants that are shared with the new command), and displays a notification like this from the top right of the screen (or wherever you've configured your InfoCenter to display):
The SBB command shows a balloon notification at the bottom right of the application frame:
As a temporary tray item is created for each notification, if you call the SBB command repeatedly without closing the balloons, you'll see one tray item per notification. This may or may not be what you want, of course, and it's easy enough to adjust the behaviour.
A note about the code in the SBB command: after watching the C# Whirlwind on Anonymous Methods, I implemented the "closed" event handler as an inline delegate. This code is compatible with Visual Studio 2005 and onwards, so users of Visual Studio .NET 2002 and 2003 will have to modify this. This callback removes the temporary tray item we added to the status bar.
A word of warning about a little quirk I found: if you run the SBB command twice in a row, without calling another command in-between, the notification that is displayed may lose its border:
Now this doesn't happen if you run another command in-between, so I suspect this is a non-issue for two reasons: the balloon functions just fine (it just doesn't look as pretty), and it's very unlikely you'll want to spam your users with repeated balloon notifications from consecutive commands, so it's unlikely to occur in the first place. Which is probably why this hasn't been spotted before.