系统托盘中的图标列表和对应程序信息
By Kingron
要获取系统托盘图标中的信息,包括图标个数,Hint信息,对应进程等,可以按以下的方式进行:
首先获取TrayIcon区域的句柄,其实TrayIcon托盘为一个ToolBar,上面的为ToolButton,我们可以按普通的Toolbar来进行处理即可,但是Windows限制了进程边界,因此我们无法直接获取Toolbar消息返回的数据,必须采取跨进程读取数据的方式才能获取数据,如果跨进程获取数据请参考《获取/隐藏系统托盘指定图标》。
给Tray Toolbar发送一下消息即可:
struct TRAYDATA
{
HWND hwnd;
UINT uID;
UINT uCallbackMessage;
DWORD Reserved[2];
HICON hIcon;
};
TRAYDATA在XP下有效!
用int count = (int)::SendMessage(m_hTrayWnd, TB_BUTTONCOUNT, 0, 0);获取托盘图标的总数.
然后用一个循环获取每一个图标的信息即可:
CProcessData<TBBUTTON> data(dwTrayPid);
TBBUTTON tb = {0};
TRAYDATA tray = {0};
TrayItemInfo tifo = {0};
for(int i=0; i<count; i++)
{
/// 使用VirtualAlloc在Explorer内开启TrayData的内存空间
SendMessage(m_hTrayWnd, TB_GETBUTTON, i, TrayData); /// TrayData必须在Explorer的进程空间内
/// ReadProcessMemroy读取TrayData
DWORD dwProcessId = 0;
GetWindowThreadProcessId(tray.hwnd,&dwProcessId);
tifo.sProcessPath = GetFilenameFromPid(dwProcessId);
wchar_t TipChar;
wchar_t sTip[1024] = {0};
wchar_t* pTip = (wchar_t*)tb.iString;
if(!(tb.fsState&TBSTATE_HIDDEN))
{
int x = 0;
do
{
if(x == 1023)
{
wcscpy(sTip,L"[ToolTip was either too long or not set]");
break;
}
data.ReadData<wchar_t>(&TipChar, (LPCVOID)pTip++);
}while(sTip[x++] = TipChar);
}
else
wcscpy(sTip,L"[Hidden Icon]");
USES_CONVERSION;
tifo.sTip = W2T(sTip);
tifo.hwnd = tray.hwnd;
tifo.uCallbackMessage = tray.uCallbackMessage;
tifo.uID = tray.uID;
tifo.bVisible = !(tb.fsState & TBSTATE_HIDDEN);
int iconindex = 0;
ICONINFO iinfo;
if(GetIconInfo(tray.hIcon,&iinfo) != 0)
{
iconindex = m_Image16List.Add(tray.hIcon);
}