Derry的专栏

深呼吸,闭上你的眼睛^_^...

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

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

阅读更多
文章标签: integer div shell each
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

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

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭