本文只是个人笔记,也就是说跟别人学的,参考:
http://www.codeproject.com/KB/applications/ShellTrayInfo.aspx
http://www.vbgood.com/viewthread.php?tid=79409
----------------------------------头文件util.h--------------------------------------
#include <Psapi.h>
#pragma comment(lib,"Psapi.lib")
struct TRAYDATA
{
HWND hwnd;
UINT uID;
UINT uCallbackMessage;
DWORD Reserved[2];
HICON hIcon;
};
TCHAR GetDriveLetter(LPCTSTR lpDevicePath)
{
TCHAR d = _T('A');
while(d <= _T('Z'))
{
TCHAR szDeviceName[3] = {d,_T(':'),_T('/0')};
TCHAR szTarget[512] = {0};
if(QueryDosDevice(szDeviceName, szTarget, 511) != 0)
if(_tcscmp(lpDevicePath, szTarget) == 0)
return d;
d++;
}
return NULL;
}
HWND FindTrayToolbarWindow()
{
HWND hWnd = ::FindWindow(_T("Shell_TrayWnd"), NULL);
if(hWnd)
{
hWnd = ::FindWindowEx(hWnd,NULL,_T("TrayNotifyWnd"), NULL);
if(hWnd)
{
hWnd = ::FindWindowEx(hWnd,NULL,_T("SysPager"), NULL);
if(hWnd)
{
hWnd = ::FindWindowEx(hWnd, NULL,_T("ToolbarWindow32"), NULL);
}
}
}
return hWnd;
}
CString GetFilenameFromPid(DWORD pid)
{
CString strRet = _T("[Unknown Process]");
TCHAR ImageFileName[1024] = {0};
HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pid);
if(ph)
{
GetProcessImageFileName(ph,ImageFileName, 1023);
CloseHandle(ph);
CString sTmp = ImageFileName;
CString strSearch = _T("//Device//HarddiskVolume");
int ind = sTmp.Find(strSearch);
if(ind != -1)
{
ind = sTmp.Find('//', ind + strSearch.GetLength());
if(ind != -1)
{
CString sReplace =_T("#:");
sReplace.SetAt(0,GetDriveLetter(sTmp.Left(ind)));
strRet = sReplace + sTmp.Mid(ind);
}
}
}
return strRet;
}
-------------------------------------------cpp--------------------------------------
// TODO: 在此添加控件通知处理程序代码
TRAYDATA trayData = {0};
TBBUTTON btnData={0};
HWND hTrayWnd=0;//托盘窗口句柄
DWORD DwTrayPid=0;//托盘进程id
HANDLE hProcess=0;//托盘进程句柄
hTrayWnd=FindTrayToolbarWindow();//找到托盘窗口句柄
GetWindowThreadProcessId(hTrayWnd, &DwTrayPid);//取得托盘窗口对应的进程id
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DwTrayPid);//打开进程,取得进程句柄
LPVOID address= VirtualAllocEx(hProcess,//在目标进程中申请一块内存,放TBBUTTON信息
NULL,
sizeof(TBBUTTON),
MEM_COMMIT,
PAGE_READWRITE);
int count = (int)::SendMessage(hTrayWnd, TB_BUTTONCOUNT, 0, 0);//给托盘窗口发消息,得到托盘里图标个数
for(int i=0; i<count; i++)
{
::SendMessage(hTrayWnd, TB_GETBUTTON, i, (LPARAM)address);//取得TBBUTTON结构到本地
ReadProcessMemory(hProcess,
(LPCVOID)address,
&btnData,
sizeof(TBBUTTON),
NULL);
ReadProcessMemory(hProcess,//从目标进程address处存放的是TBBUTTON
(LPCVOID)btnData.dwData,//取dwData字段指向的TRAYDATA结构
&trayData,
sizeof(TRAYDATA),
NULL);
DWORD dwProcessId = 0;
GetWindowThreadProcessId(trayData.hwnd,//通过TRAYDATA里的hwnd字段取得本图标的进程id
&dwProcessId);
CString path=GetFilenameFromPid(dwProcessId);//将图标拥有者进程id转为进程路径
}