关于系统托盘图标的小问题

    昨天同事写一个进程的守护程序,实时监控另一个进程,如果异常退出则重新加载该进程。问题的描述大致如此。按道理说,通过一个进程来监控另一个进程问题不大。然而被监控进程是一个最小化托盘的程序,在其异常退出后没有自己清除系统托盘里的图标。这样,经过几次异常退出,重新加载的轮回,系统托盘里就快排满了一个足球队的Icon。看上去尉为壮观。

    很多时候我们也有这样的经验,在托盘程序异常退出的时候自身的图标往往不能自我清除,这大多是许多应用程序自身异常检测机制中没有去清除的缘故,但原因也不仅限于此。此时我们用鼠标hover过这些图标区域,哪些dead icon自然就清除掉了。因此我们自然想到了在守护进程中,每次检测到被守护进程异常退出时候,首先将鼠标set过托盘区域,模拟人手操作的过程,最后再复原到原有position。实时说明,这样做的效果是不错的。由于内部处理速度极快,用户根本觉察不到鼠标的移动过程,这样就实现了自动清除dead icon的目的。

    下面把这段儿代码共享一下:

{  刷新系统托盘图标}
procedure RefreshTrayIcon;
var
  TrayWindow : HWnd;
  WindowRect : TRect;
  SmallIconWidth : Integer;
  SmallIconHeight : Integer;
  CursorPos : TPoint;
  Row : Integer;
  Col : Integer;
begin
  { Get tray window handle and bounding rectangle }
  TrayWindow := FindWindowEx(FindWindow('Shell_TrayWnd',NIL),0,'TrayNotifyWnd',NIL);
  if not GetWindowRect(TrayWindow,WindowRect) then Exit;
  { Get small icon metrics }
  SmallIconWidth := GetSystemMetrics(SM_CXSMICON);
  SmallIconHeight := GetSystemMetrics(SM_CYSMICON);
  { Save current mouse position }
  GetCursorPos(CursorPos);
  { Sweep the mouse cursor over each icon in the tray in both dimensions }
  with WindowRect do
    for Row := 0 to (Bottom - Top) DIV SmallIconHeight do
      for Col := 0 to (Right - Left) DIV SmallIconWidth do
        begin
        SetCursorPos(Left + Col * SmallIconWidth, Top + Row * SmallIconHeight);
        Sleep(0);
        end;
  { Restore mouse position }
  SetCursorPos(CursorPos.X,CursorPos.Y);
  { Redraw tray window (to fix bug in multi-line tray area) }
  RedrawWindow(TrayWindow,NIL,0,RDW_INVALIDATE OR RDW_ERASE OR RDW_UPDATENOW);

end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值