Introduction
MessageBox()
may be one of the most popular API in Windows. Whenever you want to notify user something, just call it and a messagebox pops up. But MessageBox
has some shortcomings. One of which is that when it shows up, the user has to click "OK" to dismiss it. What's worse, if it's in an unattended process, a messagebox interrupts everything.
Maybe that's why Microsoft invented the Notification Balloon. In some circumstances, a notification balloon may be the best choice because the user has been informed. No interaction needed. Processing continues. And, pretty cool, eh?
To use the notification balloon, there is no handy function like messagebox to call; you have to fill the dirty NOTIFYICONDATA struct
with care, call the ugly Shell_NotifyIcon()
to show it, and then call it again to dismiss it. That's not what our lazy programmer wants. We need something like a MessageBalloon()
- just pass in the message and the caption, done. Here it comes!
Using the code
I introduced a class MessageBalloon
to do the whole thing. you can use it like this:
{
MessageBalloon mb("A long time operation..", "MsgBalloon Demo");
Sleep(3000); }
Because balloons would be destroyed in a destructor, the surrounding braces are necessary to trigger the destruction of the MessageBalloon
object after the long time operation finishes.
Pretty easy to use. right?
Points of Interest
The implementation is easy too. Here is everything underneath:
struct MessageBalloon : public NOTIFYICONDATA
{
MessageBalloon(LPCTSTR _szInfo = _T("Prompt"), LPCTSTR _szInfoTitle = 0,
LPCTSTR _szTip = 0, HICON _hIcon = 0)
{
static struct wnd_holder{
HWND hwnd_;
wnd_holder(){hwnd_ = CreateWindowW(L"STATIC", 0, 0, 0, 0, 0, 0, 0,
0, 0, 0);}
~wnd_holder(){DestroyWindow(hwnd_);}
} wh;
memset(this, 0, sizeof(*this));
cbSize = sizeof(*this);
hWnd = wh.hwnd_;
hIcon = _hIcon ? _hIcon :
::LoadIcon(::GetModuleHandle(NULL),
MAKEINTRESOURCE(128));
if (! hIcon) hIcon = ::LoadIcon(NULL, IDI_INFORMATION);
uFlags = NIF_INFO | NIF_TIP | NIF_ICON;
dwInfoFlags = NIIF_INFO;
_tcscpy(szInfo, _szInfo);
if (! _szInfoTitle) LoadString(::GetModuleHandle(NULL),
57344, szInfoTitle, sizeof(szInfoTitle));
else _tcscpy(szInfoTitle, _szInfoTitle);
_tcscpy(szTip, _szTip ? _szTip : szInfoTitle);
Shell_NotifyIcon(NIM_ADD, this);
}
~MessageBalloon(){Shell_NotifyIcon(NIM_DELETE, this);}
};
Nothing obscure. To obtain the window handle, a window has been created which is held by a static variable. This enables us to use MessageBalloon
several times while only creating/destroying the window once. If the class is being used in MFC, the IDR_MAINFRAME
icon would be loaded as a notification icon, or else system default information icon would be used. The default balloon title is AFX_IDS_APP_TITLE
in MFC.
The notification balloon has been only supported in Windows 2000 or above, so the MessageBalloon can only be used in those platforms. To compile the source code, Windows 2000 SDK or above should be installed.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.