How can I get the tooltips of notification-area icons?
Asked Answered
B

3

5

I can enumerate the applications (handle,pid,path) with icons in the notification area, and I can control the position of the icons, but I can't get the tooltip.

How can I enumerate systray icons including the tooltips?

Benally answered 4/2, 2010 at 23:16 Comment(0)
P
1

Here is my method tested with windows xp and delphi 2010 if you are using a version of delphi wich doesn't support unicode make shure you convert the strings read to 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.
Pavyer answered 28/5, 2011 at 9:21 Comment(0)
F
4

The shell provides no facility for inspecting notification icons that don't belong to your program. (And it provides no way of enumerating even the icons that do belong to your program; you're expected to already know about those.)

I used to use a program that hijacked some or all of the icons and optionally displayed them in its own window instead of in the area near the clock, so it must have been able to get a list of all the icons. It was TraySaver, by Mike Lin. The source is available if you wish to see how his hack worked.

You can also take a look at the answers to a previous question that asked about controlling the position of icons in the notification area.

Fleisig answered 4/2, 2010 at 23:54 Comment(3)
I can enumerate the icons in the systray I can enumerate the application (handle,pid,path) I can control the position of the icons. BUT i cant get the tooltip. Thats what i'd like to know.Benally
You could have mentioned that in the question: "I can enumerate the icons, but I can't get the tooltips. Here's the code I'm using. Please help fill in the blanks." Did you read the second link I gave you?Fleisig
Yes i read the second link. I can control the icons in the notification area. But thats another story. Using the same code more or less i can enumerate the icons in the system tray. (a translation from codeproject.com/KB/applications/ShellTrayInfo.aspx) But i cant get their tool tip.Benally
M
2

You should take a look at the madKernal package of madshis component collection. It has some interfaces for working with trayicons. Beware, though:

With madKernel you can manage tray icons (see API "Shell_NotifyIcon") of any application. This kind of functionality is totally undocumented, but works well from win95 to winXP.

The ITrayIcon-interface has properties for hint, icon, position and more.

Mallina answered 5/2, 2010 at 9:9 Comment(0)
P
1

Here is my method tested with windows xp and delphi 2010 if you are using a version of delphi wich doesn't support unicode make shure you convert the strings read to 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.
Pavyer answered 28/5, 2011 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.