viksoe.dk

Balloon Dialog

Balloon Dialog


This article was submitted .


This is a WTL Balloon Dialog control. It is a substitute for a message box rather than a tooltip.

I know that a neat WTL balloon tip class already exists on CodeProject.com, but this control was actually inspired from my old CountDown sample and a Delphi component by Jonathan Hosking (I'm a former Pascal programmer, so it was fun to look at some Delphi code).

The control was created because I required something more of my balloons. This control uses a dialog template to render the balloon, allowing you to put a multitude of texts and shiny buttons inside it.

Being a dialog means that it works best in a modal state. But you can have modeless balloons floating around too.

The dialog needs a buddy. That's a window it can position itself relative to. You can choose on which side it should prefer to attach itself, but if there is not enough real estate, the dialog will move to another side of the buddy window.

The sample contains some Office 97 buttons as well. They are not perfect, but I included them anyway so you could perhaps build your own pesky Office Assistant look-alike into your WTL app.

A few quirks

Implementing this was not without a few quirks.

The little arrow-head turned out to be most troublesome. Normally you would paint the entire balloon frame in one go, however if i.e. the arrow-head should be painted to the left, then the entire dialog content had to be shifted to the right. To avoid this maneuver, I applied the arrow-head as a separate window, which is attached on-top of the dialog at runtime.

Another problem is of course that you might want to resize your dialog depending on the size of text and other controls. You can still resize the dialog in a WM_INITDIALOG handler - probably even using the WTL Dialog Resize classes.

How to use it

Simply create a dialog class as usual.
The dialog should be a popup dialog, with all borders and captions removed.

Add the Tool Window style so it does not appear in the task list.
Then derive from CBalloonDialog...
class CMyTipDlg : 
  public CDialogImpl<CMyTipDlg>, 
  public CBalloonDialog<CMyTipDlg>
{
public:
  enum { IDD = IDD_MYTIPDLG };
  ...
In your dialog message map, add a few chains...
  BEGIN_MSG_MAP(CMyTipDlg)
    CHAIN_MSG_MAP( CBalloonDialog<CMyTipDlg> )
    ...
    MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  ALT_MSG_MAP(1)
    CHAIN_MSG_MAP_ALT( CBalloonDialog<CMyTipDlg>, 1 )
  END_MSG_MAP()
Finally, to show the dialog, simply use the DoModal() method.
But first you must attach your buddy window...
  CMyTipDlg dlg;
  dlg.SetBuddy(GetDlgItem(IDC_EDIT1));
  UINT nRes = dlg.DoModal();
If you do not assign the buddy window, the balloon dialog will appear as a MessageBox-like dialog - without the arrow and centered on the owner window.

The CBalloonDialog class needs to handle a few important messages, such as the WM_INITDIALOG. Place the CHAIN_MSG_MAP macro at the top of your message map or make sure to set bHandled to FALSE if you handle these messages locally as well.

Source Code Dependencies

Microsoft Visual C++ 6.0
Microsoft WTL 3.1 Library

Download Files

DownloadSource Code (40 Kb)

To the top