Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Systray Watcher
some time ago i worked on a multi monitor taskbar solution,
i even had it running as exe.
but what me really bothered was how to display what is in systray.

how do i get the process name from the tooltip?

Function SystrayWatcher
Select All      Help
int hwnd=id(1504 win("" "Shell_TrayWnd" "explorer"))
out hwnd
// 1 left 2 right 3 middle
type TRAYICON str'tooltip !hidden
EnumTrayIcons 0 a
int i
for i 0 a.len
,,out a[i].tooltip
once i know the programs it is possible to load icons.

powerpro has such tool for capture tray icons.
there you can map mouse click.
training mode.
Thanks to ... llTrayInfo

Tested on Windows 2000, XP, Vista 32-bit and Windows 7 64-bit.

This method of getting tray icon info is not documented and therefore may stop working in future Windows versions.

Function EnumTrayIcons
Select All      Help
function hwnd ARRAY(TRAYICONINFO)&a mask ;;mask: 1 get tooltip, 2 get hwnd, hicon, callbackMsg, callbackId

;Gets tray icon data for all icons.

;hwnd - tray toolbar control handle. If 0, the function tries to find the control.
;a - receives each icon info:
;;;.tooltip - tooltip text.
;;;.hidden - 0 if the icon is visible, 1 if hidden.
;;;.idCommand - toolbar control button id.
;;;.hwnd - handle of window that added the icon.
;;;.hicon - icon handle.
;;;.callbackMsg, .callbackId - on mouse and other events the window receives this message with this id.
;mask - must be 3 to get all info. If some info not needed, use 0, 1 or 2. It will make faster.

;#compile "__TRAYICONINFO"
;EnumTrayIcons 0 a 3
;int i
;for i 0 a.len
,;if(r.hidden) continue
,;RecGetWindowName r.hwnd &_s
,;out "tt='%s'  idcmd=%i  window=%s  hicon=%i  callbackId=%i  callbackMsg=%i" r.tooltip r.idCommand _s r.hicon r.callbackId r.callbackMsg

type __SHTRAYICON hwnd callbackId callbackMsg unknown[2] hIcon
type __SHTRAYICON64 %hwnd callbackId callbackMsg unknown[2] %hIcon
type TBBUTTON64 iBitmap idCommand !fsState !fsStyle !bReserved[6] %dwData %iString

if(!hwnd) hwnd=child("" "ToolbarWindow32" "+Shell_TrayWnd" 0x1); if(!hwnd) end ES_WINDOW
int i n=SendMessage(hwnd TB_BUTTONCOUNT 0 0)
if(!n) ret

lock _share
TBBUTTON* bq=share
TBBUTTON* be=share(hwnd)
word* tq=bq+sizeof(TBBUTTON64)
word* te=be+sizeof(TBBUTTON64)
,GetWindowThreadProcessId(hwnd &_i)

for i 0 n
,if(!SendMessage(hwnd TB_GETBUTTON i be)) continue
,,_i=SendMessage(hwnd TB_GETBUTTONTEXTW bq.idCommand 0)
,,if(_i<0 or _i>450 or SendMessage(hwnd TB_GETBUTTONTEXTW bq.idCommand te)<0) tq[0]=0
,,,if(ReadProcessMemory(hp +bq.dwData &sti sizeof(sti) 0))
,,,__SHTRAYICON64 sti64
,,,if(ReadProcessMemory(hp +bq.iString &sti64 sizeof(sti64) 0)) ;;64-bit dwData offset == 32-bit iString offset

Select All      Help
type TRAYICONINFO str'tooltip !hidden idCommand hwnd hicon callbackMsg callbackId
;#compile "__TRAYICONINFO"

Error in "SystrayWatcher /124"oSystrayWatcher: item not found.
Forgot it.
Now also works on 64-bit Windows.
Gintaras Wrote:Now also works on 64-bit Windows.
i am on 7 and it works Smile
thanks for the update.

when using the systray hide icons option only visible icons are enumerated.
how to get all active trayicons?

i once asked if it possible to use tray in a qm toolbar.

i think it is possible to simulate systray by hiding windows systray and having a timer function to capture current loaded systray items.

now iconpath will be extracted from item and added to qm systray bar 1.
toolbar function now checks which button has been clicked by mouse.
mouse click will be forwarded to hidden win systray icon to involve default action.

can this work?
On XP and Vista, hidden tray icons exist as hidden buttons in toolbar control. On Seven they don't exist. You can see it in 'Find accessible object' dialog.
doh. :lol:
if(r.hidden) continue

Forum Jump:

Users browsing this thread: 1 Guest(s)