Skip to content
December 16, 2009 / lawrencebarsanti

Display error messages with TBalloonHint

This post will explain how to display messages using the TBalloonHint component that was added in Delphi 2009.  This approach is much less intrusive than traditional modal dialog boxes that steal focus and require user interaction.  Balloon hints simply display a message then disappear after a short period of time.  ScreenShot

TBalloonHint is easy to use but there are a few subtleties that I will go over.  Controls, like TButton, have a Hint and a ShowHint property which can be used to popup text near the cursor when it is over a control;  TBalloonHint is a just a prettier and more flexible hint.  Hints are automatically displayed when the cursor is over a control so it is hard to find documentation that explains how to display a balloon hint programmatically.  That is what I will do here.

Create and Configure

TBalloonHint is found in the ‘Additional’ section of the tool panel so it can be added to a form at design time.  Since the balloon hint is not being linked to any controls, I create and configure it in the OnCreate method instead.  The HideAfter property allows you to specify, in ms, how long the balloon will be shown before it is automatically hidden.  The Delay property allows you to specify, in ms, how long the hint should wait before appearing; the default this value is 500.

procedure TForm1.FormCreate(Sender: TObject);
begin
  FBalloonHint := TBalloonHint.Create(Self);
  FBalloonHint.HideAfter := 5000;
  FBalloonHint.Delay := 0;
end;

Show and Position

Before showing a balloon hint, the Title and Description properties can be used to specify its contents.  Once the contents are set, the ShowHint method can be used to display the hint.  Since the hint is not attached to a specific control, we need to pass some position information, using screen coordinates, to ShowHint.

The orientation of the balloon depends on its screen location.  If the balloon is displayed in the bottom-half of the screen it looks like the image at the beginning and if it is displayed in the top-half of the screen it will look like the image below.   Thus telling a balloon to pop-up at the TopLeft or BottomRight corner of a control does not work well because one of the balloon orientations will cause it to cover the  control .ScreenShotBelowThis problem can be solved by passing a rectangle to ShowHint instead of a point.  When a rectangle is passed to ShowHint it will make sure that the region inside the rectangle remains visible when the hint is shown.

procedure TForm1.Button1Click(Sender: TObject);
var
  R: TRect;
begin
  FBalloonHint.Description := 'You pressed ' + Button1.Caption;
  R := Button1.BoundsRect;
  R.TopLeft := ClientToScreen(R.TopLeft);
  R.BottomRight := ClientToScreen(R.BottomRight);
  FBalloonHint.ShowHint(R);
end;

When to Hide

Balloon hints are created in their own window so it is important to hide them when your application is moved, minimized, resized or covered by another application.  The image below shows what happens when you move the form without hiding the hint.ScreenShotMovedYou only have to process two Windows messages (WM_ACTIVATEAPP and WM_WINDOWPOSCHANGED) to cover all of these situations.  To process these messages, define the following message handling functions in the protected section of the form.

protected
  procedure WMWindowPosChanged(var AMessage:TMessage); message WM_WINDOWPOSCHANGED;
  procedure WMActivateApp(var AMessage: TMessage); message WM_ACTIVATEAPP;

When you implement the functions make sure to call inherited to run the form’s message handlers.  It is possible for these message to come before the TBalloonHint object has been created so do not forget to check if it has been assigned.

procedure TForm1.WMActivateApp(var AMessage: TMessage);
begin
  if Assigned(FBalloonHint) then FBalloonHint.HideHint;
  inherited;
end;
procedure TForm1.WMWindowPosChanged(var AMessage: TMessage);
begin
  if Assigned(FBalloonHint) then FBalloonHint.HideHint;
  inherited;
end;

6 Comments

Leave a Comment
  1. Austin Naillon / Feb 7 2010 2:26 am

    Pretty good post, really helpful information. Never thought I would obtain the information I need right here. I’ve been hunting throughout the net for a while now and was starting to get irritated. Luckily, I stumbled across your blog and acquired exactly what I had been hunting for.

  2. lawrencebarsanti / Feb 7 2010 11:09 am

    Austin, thanks for the kind words. I posted this information because I had the exact same problem as you when I started using the balloon hint.

  3. Frankie Espinoza / Oct 22 2010 1:41 pm

    Hello, I just wanted to take a minute to tell you that you have a great
    site! Keep up the good work.
    Thank you
    http://frankieespinoza.livejournal.com/878.html

  4. Konstantin / Aug 21 2012 7:17 am

    Very useful article, many thanks!

  5. Konstantin / Aug 22 2012 7:36 am

    … But I would rather use WM_ACTIVATE instead of WM_ACTIVATEAPP as this will also allow to close the hint if another window of the same application is shown (something like Form2.ShowModal).

  6. Peter Bo / Oct 4 2013 3:27 am

    Thank you much! This is what should have been in Delphi help files…

Leave a comment