5

我可以在通知区域用图标枚举应用程序(句柄、pid、路径),我可以控制图标的位置,但我无法获得工具提示。

如何枚举系统托盘图标,包括工具提示?

4

3 回答 3

4

Shell 不提供检查不属于您的程序的通知图标的功能。(而且它甚至无法枚举属于您的程序的图标您应该已经知道这些。)

我曾经使用一个程序劫持了部分或全部图标,并有选择地将它们显示在自己的窗口中,而不是在时钟附近的区域中,因此它一定能够获取所有图标的列表。这是Mike Lin 的TraySaver。如果您想了解他的 hack 是如何工作的,可以使用该源。

您还可以查看上一个关于控制通知区域中图标位置的问题的答案。

于 2010-02-04T23:54:37.757 回答
2

你应该看看 madshis 组件集合的madKernal 包。它有一些使用托盘图标的接口。但请注意:

使用 madKernel,您可以管理任何应用程序的托盘图标(参见 API “Shell_NotifyIcon”)。这种功能完全没有文档记录,但从 win95 到 winXP 都可以正常工作。

ITrayIcon 接口具有提示、图标、位置等属性。

于 2010-02-05T09:09:06.240 回答
1

这是我用 windows xp 和 delphi 2010 测试的方法,如果您使用的是不支持 unicode 的 delphi 版本,请确保您将读取的字符串转换为 ansi

uses CommCtrl;

function TForm1.GetIconsCount: Integer;
begin
  Result := SendMessage(FindTrayToolbar, TB_BUTTONCOUNT, 0, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    ListTips;
end;

function TForm1.FindTrayToolbar: HWND;
begin
  Result := FindWindow('Shell_TrayWND', nil);
  Result := FindWindowEx(Result, 0, 'TrayNotifyWnd', nil);
  Result := FindWindowEx(Result, 0, 'SysPager', nil);
  Result := FindWindowEx(Result, 0, 'ToolbarWindow32', nil);
end;

procedure TForm1.ListTips;
var
  dwTray: DWORD;
  wndTray: HWND;
  hTray: THandle;
  remoteTray: Pointer;
  tdata: TTBBUTTON;
  i: Integer;
  btsread:DWORD;
  str:Pchar;
begin
  wndTray := FindTrayToolbar;
  GetWindowThreadProcessId(wndTray, @dwTray);
  hTray := OpenProcess(PROCESS_ALL_ACCESS, false, dwTray);
  if hTray <> 0 then
  begin
   remoteTray := VirtualAllocEx(hTray, nil, Sizeof(tdata), MEM_COMMIT,
      PAGE_READWRITE);
    for i := 0 to GetIconsCount - 1 do
    begin
      SendMessage(FindTrayToolbar,TB_GETBUTTON,wparam(i),lparam(remotetray));
      ReadProcessMemory(hTray,remotetray,@tdata,sizeof(tdata),btsread);
      GetMem(str,255);
      ReadProcessMemory(hTray,Ptr(tdata.iString),str,255,btsread);
      ListBox1.Items.Add(str);
      end;
       end
        else ShowMessage('Could not locate tray icons');
    end;
    end.
于 2011-05-28T09:21:22.280 回答