关闭托盘图标气泡提示的程序化方法

4

请问是否可以通过编程的方式关闭TTrayIcon气泡提示?

问题:

我有一个计时器每分钟检查消息。当它发现一条消息(例如:ABC服务停止),就会显示带有消息的气球:

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;

托盘图标的气泡超时时间设置为3000(3秒)。由于定时器每分钟触发一次消息(当有任何消息时),如果用户不关闭它,系统会将消息排队。例如,如果用户在30分钟后回到电脑,则他们将关闭第一条消息,然后托盘图标立即显示第二条消息,接下来是下一个28条消息(可怜的用户)。
我知道气球会自动关闭,但只有在用户进行某些输入(鼠标移动、键盘按键,而且应用程序不需要聚焦甚至不需要可见)时才会关闭。因此,如果用户离开电脑,气球将一直停留在那里,直到有输入为止。
我尝试过的另一种解决方案是,在显示任何气球时禁用定时器,并在用户关闭当前气球(或它被自动关闭)时再次启用它。但我找不到任何方法来发现气球何时关闭(如果用户单击X或自动关闭,则OnBalloonClick事件不会触发)。

7
TrayIcon.BalloonHint := ''; 的意思是清空系统托盘图标的气球提示。 - TLama
1
我建议忽略 TTrayIcon 并直接调用 Win32 的 Shell_NotifyIcon() 函数。这样做可以让你接收到 NIN_BALLOONSHOWNIN_BALLOONHIDENIN_BALLOONTIMEOUT 消息。TTrayIcon 并没有为这些消息暴露任何事件(尽管它会在内部处理 NIN_BALLOONHIDENIN_BALLOONTIMEOUT)。否则,你需要从 TTrayIcon 派生并重写其虚拟的 WindowProc() 方法来在代码中接收这些消息。 - Remy Lebeau
2
@TLama它像魔法一样奏效。请发布为答案,以便我可以选择它。Remy,我有意按照您所说的方式去做,但目前我没有时间和知识去这样做。我的想法是创建一个类来管理这些通知。感谢分享您的想法。 - Alisson Reinaldo Silva
1个回答

3
参考文献 NOTIFYICONDATA 结构介绍了隐藏气泡提示的方法,在 szInfo 成员描述中:

要从UI中删除气球通知,可以使用NIM_DELETE删除图标或在uFlags中设置NIF_INFO标志并将szInfo设置为空字符串。

对于TTrayIcon组件(至少在您的Delphi版本中),很容易满足后一种选择,因为当TTrayIcon显示气球通知时,会设置NIF_INFO标志,因此剩下的是将 szInfo 成员设置为空字符串。 在TTrayIcon组件中, szInfo 成员可以由BalloonHint属性修改,因此要隐藏显示的气球提示,只需简单写入:

TrayIcon.BalloonHint := '';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接