Click here to Skip to main content
5,788,212 members and growing! (15,147 online)
Email Password   helpLost your password?
Desktop Development » Miscellaneous » Custom Controls     Intermediate License: The Code Project Open License (CPOL)

CBalloonMsg - An Easy-to-use Non-modal Balloon Alternative to AfxMessageBox

By Paul Roberts

Makes it easy to use a balloon tooltip to convey hints/messages non-modally
C++ (VC7.1, VC8.0, C++), Windows (Windows, WinXP, Vista), MFC, Dev

Posted: 6 Mar 2008
Updated: 1 Apr 2008
Views: 20,642
Bookmarked: 64 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
26 votes for this Article.
Popularity: 6.58 Rating: 4.65 out of 5
0 votes, 0.0%
1
1 vote, 3.8%
2
1 vote, 3.8%
3
7 votes, 26.9%
4
17 votes, 65.4%
5

Introduction

While working on a new app, I decided it would be nice to use balloon-style tooltips to convey simple messages to the user rather than relying on ye olde ::AfxMessageBox. It would be a less disruptive way of warning the user of minor things like editing mistakes, failing to fill in a field and so on.

I found an existing CodeProject article that seemed to be exactly what I was looking for: Balloon Help as a Non-modal Replacement for MessageBox(). On closer inspection, I decided against using this because it doesn't use Windows' own balloon tooltip. Instead, it draws its own, and at the time of writing I think it needs a small update for Vista. Surely there had to be a simpler solution that uses the real tooltip control? Well I didn't find one, so I wrote my own and it's called CBalloonMsg.

Prerequisites

Before going any further, please be aware that I coded this for use in theme-aware apps (i.e. those with a manifest requesting common controls v6) running on Vista or XP (preferably SP2). I haven't tried using it on Windows 2000, but I'm pretty sure it wouldn't look right. And don't even think about NT4 and Win9x!

Using the Code

This couldn't be much simpler:

  • Add BalloonMsg.h and BalloonMsg.cpp to your project.
  • Make sure your stdafx.h has WINVER and _WIN32_WINNT set to 0x0501 or better and make sure you've got a manifest in your *.rc2 (check out the demo!)
  • Finally, use one of the Show or ShowForCtrl static methods to display the balloon message, e.g.

    CBalloonMsg::ShowForCtrl( _T("Test Title"), _T("Test Text"),
        &my_ctrl, hIcon );

The Show/ShowForCtrl methods display the tooltip at the nominated position or over the nominated control. By default, the tooltip stays up for 10 seconds then closes automatically. It'll close earlier if there's a change in focus or if the mouse moves appreciably. You can change the "stay up" or autopop time easily (more on this later) and you can close or "pop" the balloon at any time using the RequestCloseAll() static method.

How it Works (Briefly)

When you call one of the Show methods, a separate user interface thread is created. This in turn creates its own small, transparent window around the current mouse position, then sets about processing that window's message queue. The window acts as the parent for a tooltip control, and calls CToolTipCtrl::RelayEvent to make sure that the tooltip has first bit at all relevant Windows messages. The tooltip is given a zero millisecond initial delay, so it appears as soon as it is activated. When the tooltip eventually closes, a call is made to PostQuitMessage which gets rid of the transparent parent window and ends the thread. The thread wrapper self-deletes for completeness.

That's about it. You'll find more detailed information on the inner workings in the code's comments.

Points of Interest

SafeShowMsg and BalloonsEnabled

By default, Windows allows the use of balloon tooltips. There is however a registry tweak available that prevents balloons from being displayed. It seems this is most often used to kill those often redundant and distracting tray balloons that Windows likes to present from time to time.

The tweak involves setting zero for the DWORD value EnableBalloonTips in HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced (thanks to DerMeister for reporting this!)

To get around this, the latest version of the class now includes two additional methods: BalloonsEnabled and SafeShowMsg.

BalloonsEnabled() returns TRUE if the user hasn't suppressed balloon tooltips. Following on from that, SafeShowMsg() uses balloons to display a message if they're enabled, and reverts to AfxMessageBox if the user has switched them off. The demo shows this function in action - take a look at CTTTestDlg::DoDataExchange.

Icons

You can supply your own icon to the Show calls, OR you can use Windows' built-in icons by using the special values described in the MSDN doc for TTM_SETTITLE: 1 for info, 2 for warning, 3 for error.

You can also change quite a few of the defaults for CMessageBalloon by setting new values for its static members:

s_nTimerStep Defaults to 30 milliseconds. Determines frequency of checks for balloon termination states (see History for Version 2 changes)
s_nAutoPop Time before balloon self-closes in milliseconds. Defaults to 10 seconds. Set to 0 to let the balloon stay up until closed through focus changes, user action etc.
s_nMaxTipWidth Maximum tip width in pixels. Makes the balloon use linebreaks.
s_nToolBorder The amount by which the mouse can move before the balloon pops

GetGUIThreadInfo

Finally, note the use of the handy function GetGUIThreadInfo which allows us to check the focus window in another thread.

Special Version Adapted for VC6 by Damir Valiulin

The third download at the top of the article is for a VC6 version of the demo project. It contains some minor differences from the original code, as follows:

  • Minor changes to be able to compile under VC6
  • Check for Win32 (no balloon tip there) and for registry disabling hack
  • Changes to function calls for simplification (got rid of calls with string IDs)

Many thanks to Damir for this!

History

Version 1: 6th March, 2008


Version 2: 16th March, 2008

Changed to using a tracking tooltip to counter anomalies in positioning of the balloon and its pointer when the dialog was near the edge of the screen. The use of TTF_TRACK necessitated other changes:

  • Repositioning of the balloon is now achieved via the TTM_TRACKPOSITION message rather than through the use of SetWindowPos.
  • TTM_TRACKACTIVATE is now used to activate the tooltip, rather than the MFC method Activate().
  • A timer is also created and set to fire every 30 milliseconds or so (this is configurable via s_nTimerStep above). The timer gives us a chance to spot changes in the state of windows owned by the primary thread that should bring about closure of the balloon. It also lets us (re)implement the automatic closure interval (autopop) that is used when s_nAutoPop is non-zero.

Version 3: 23rd March, 2008

  • Added SafeShowMsg and BalloonsEnabled to detect when the user has suppressed balloons via a reg tweak and fall back to AfxMessageBox.
  • Added overloads to take HWND for target control as well as CWnd*.

Version 4: 30th March, 2008

  • Added a VC6 version, kindly adapted by Damir Valiulin.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Paul Roberts


Started programming on a Commodore Vic 20(!), and later entered employment programming for the Mac back in the days of System 6. Soon the pull of the Dark Side became too strong and I switched to Windows (Win 3.1) and have been coding for Windows ever since.

I'm now lead programmer for a small software house in Glasgow, Scotland. Our main products include PTFB Pro, ColorCache, and LogMeister.
Occupation: Software Developer (Senior)
Location: United Kingdom United Kingdom

Other popular Miscellaneous articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 47 (Total in Forum: 47) (Refresh)FirstPrevNext
GeneralCompatibility w "normal" tooltips?memberols600014:12 15 Sep '08  
GeneralForcing tooltips to closememberroel_1:42 12 Aug '08  
QuestionHow to see Balloon Message point to icon on the system tray?memberleminh048818:08 30 May '08  
GeneralSmall fix for UnicodememberDavid Pritchard2:18 22 May '08  
GeneralRe: Small fix for UnicodememberPaul Roberts23:32 26 May '08  
GeneralIn DLL project,can not see the tootipmemberSzmgolden17:36 14 Apr '08  
GeneralRe: In DLL project,can not see the tootipmemberPaul Roberts11:36 16 Apr '08  
GeneralBalloon disappears shortly after coming upmemberRedFraggle6:38 10 Apr '08  
GeneralRe: Balloon disappears shortly after coming upmemberPaul Roberts0:09 11 Apr '08  
GeneralRe: Balloon disappears shortly after coming upmemberRedFraggle15:22 11 Apr '08  
GeneralExcellent!memberDamir Valiulin13:36 20 Mar '08  
GeneralRe: Excellent!memberPaul Roberts10:14 21 Mar '08  
GeneralRe: Excellent!memberDamir Valiulin5:53 24 Mar '08  
GeneralRe: Excellent!memberPaul Roberts10:41 24 Mar '08  
GeneralSome ideasmemberbolivar1235:32 19 Mar '08  
GeneralRe: Some ideasmemberPaul Roberts2:31 20 Mar '08  
GeneralSome questionsmvpHans Dietrich18:34 18 Mar '08  
GeneralRe: Some questionsmemberPaul Roberts1:13 19 Mar '08  
GeneralPossible reason for tooltip not showingmemberDerMeister15:59 16 Mar '08  
GeneralRe: Possible reason for tooltip not showingmemberPaul Roberts11:32 17 Mar '08  
GeneralNew version, now uses tracking tooltipsmemberPaul Roberts12:24 16 Mar '08  
GeneralBalloon points to OK buttonmemberSteveNY9:11 12 Mar '08  
GeneralRe: Balloon points to OK buttonmemberPaul Roberts1:56 13 Mar '08  
GeneralRe: Balloon points to OK buttonmemberSteveNY9:51 13 Mar '08  
GeneralRe: Balloon points to OK buttonmemberPaul Roberts9:01 15 Mar '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 1 Apr 2008
Editor: Deeksha Shenoy
Copyright 2008 by Paul Roberts
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project