delphitimerdelphi-2009trayiconballoon

Close TrayIcon Balloon Programmatically


Is it possible to close the TTrayIcon Balloon hint programmatically?

The problem:

I have a timer which checks for messages every minute. When it discovers a message (eg. ABC Service is stopped), it shows the balloon with the message:

procedure TFrmTest.tmrTimer(Sender: TObject);
begin
  tmr.Enabled := False;
  try
    if IsAnyServiceStopped then
      ShowBallon(bfError, 'The ABC Service is stopped. Do something!!!');
  finally
    tmr.Enabled := True;
  end;
end;

procedure TfrmTest.ShowBallon(pFlag: TBalloonFlags; pMessage: string);
begin
  try
    // HERE I'D LIKE TO CLOSE THE BALLOON IF IT'S OPENNED
    TrayIcon.BalloonFlags := pFlag;
    TrayIcon.BalloonHint := pMessage;
    TrayIcon.ShowBalloonHint;
  except
  end;
end;

The TrayIcon BalloonTimeOut is set to 3000 (3 secs). Since the timer triggers the message every minute (when there is any message), if the user does not close it, the system makes a queue of messages. If the user comes back to PC after 30 minutes (for example), they'll close the first message, then immediately the tray icon shows the second message, and the same for the next 28 messages (poor user).

I know the balloon auto closes itself, but it closes only if the user do some input (mouse movement, key press, and the application doesn't need to be focused or even visible). So if the user is away from computer, the balloon stays there forever until the input.

Other solution I tried was to disable the Timer when showing any balloon, and enable it again only when the user closes the current balloon (or it gets auto-closed). But I couldn't find any way to discover when the balloon is closed (the OnBalloonClick event doesn't triggers if the user click on X or it gets auto-closed).


Solution

  • The reference for the NOTIFYICONDATA structure describes how to hide a balloon hint in the szInfo member description:

    To remove the balloon notification from the UI, either delete the icon (with NIM_DELETE) or set the NIF_INFO flag in uFlags and set szInfo to an empty string.

    For TTrayIcon component (at least in your Delphi version) is easy to meet the latter option because when the TTrayIcon is showing the balloon notification, the NIF_INFO flag is set, so what remains is setting the szInfo member to an empty string. In TTrayIcon component, the szInfo member can be modified by the BalloonHint property, so to hide a displayed balloon hint you can simply write:

    TrayIcon.BalloonHint := '';