Savoir à quel programme appartient une icone de la zone de notification ("tray") et lister les icones

Description

Ce code permet de lister les icones du "Tray" à côté de l'horloge et de savoir à quel programme une icone appartient...

C'est une interprétation des données systèmes de cette zone (une barre d'outils sous ME/2000/XP)

Ce code a été testé sur 98/2000/XP

Source / Exemple :


//pour 95/98
#include "common.h"
//ToolHelp32
#include "tlhelp32.h"

//renvoie les icones du tray sous 9x
LPSYSTRAY GetTrayIcons_9x()
{
	//demande le hwnd du tray
	HWND hTray = GethWndTray();
	//alloue de la mémoire pour les infos sur le tray
	LPSYSTRAY lpSystray=(LPSYSTRAY)VirtualAlloc(NULL,sizeof(SYSTRAY),MEM_COMMIT,PAGE_READWRITE);
	if (lpSystray)
	{
		//demande le pointeur vers les infos du tray
		LPVOID lpData = (LPVOID)GetWindowLong(hTray,0);
		if (lpData)
		{
			DWORD pid=0;
			//demande le pid de Explorer.exe
			GetWindowThreadProcessId(hTray,&pid);
			//demande un handle de Explorer.exe pour lire dans son espace mémoire
			HANDLE hP = OpenProcess(PROCESS_VM_READ | PROCESS_VM_OPERATION,FALSE,pid);
			if (hP)
			{
				//lit les infos sur le tray
				if (ReadProcessMemory(hP,lpData,(LPVOID)lpSystray,sizeof(SYSTRAY),NULL))
				{
					//copie le pointeur vers l'entête de la liste d'icones
					lpData = (LPVOID)lpSystray->lpsysListHeader;
					//alloue de la mémoire pour l'entête de la liste d'icones
					lpSystray->lpsysListHeader = (LPNOTIFYLISTHEADER)VirtualAlloc(NULL,sizeof(NOTIFYLISTHEADER),MEM_COMMIT,PAGE_READWRITE);
					if (lpSystray->lpsysListHeader)
					{
						//lit l'entête de la liste d'icones
						if (ReadProcessMemory(hP,lpData,(LPVOID)lpSystray->lpsysListHeader,sizeof(NOTIFYLISTHEADER),NULL))
						{
							//nombre d'icones dans le tray
							ULONG dwCount =lpSystray->lpsysListHeader->dwCount;
							//copie le pointeur vers la liste de pointeurs vers les infos sur les icones
							lpData = (LPVOID)lpSystray->lpsysListHeader->lpNotifyDataList;
							//alloue de la mémoire pour cette liste de pointeurs
							lpSystray->lpsysListHeader->lpNotifyDataList = (LPNOTIFYENTRY*)VirtualAlloc(NULL,dwCount * sizeof(LPVOID),MEM_COMMIT,PAGE_READWRITE);

							//lit la liste de pointeurs
							if (ReadProcessMemory(hP,lpData,(LPVOID)lpSystray->lpsysListHeader->lpNotifyDataList,dwCount * sizeof(LPVOID),NULL))
							{
								//pour chaque pointeur
								for (UINT x =0; x < dwCount;x++)
								{
									//peut-être NT4 ?
									if (IsWindowsNT())
									{
										//on copie le notifyicondata
										if (((lpSystray->lpsysListHeader->lpNotifyDataList))[x] = (LPNOTIFYENTRY)VirtualAlloc(NULL,sizeof(NOTIFYICONDATAW)+4,MEM_COMMIT,PAGE_READWRITE))
											ReadProcessMemory(hP,(LPVOID)(((LPNOTIFYENTRY*)lpData)[x]),(LPVOID)((lpSystray->lpsysListHeader->lpNotifyDataList))[x],sizeof(NOTIFYICONDATAW)+4,NULL);
									}
									else
									{
										//on copie le notifyicondata
										if (((lpSystray->lpsysListHeader->lpNotifyDataList))[x] = (LPNOTIFYENTRY)VirtualAlloc(NULL,sizeof(NOTIFYICONDATAA)+4,MEM_COMMIT,PAGE_READWRITE))
											ReadProcessMemory(hP,(LPVOID)(((LPNOTIFYENTRY*)lpData)[x]),(LPVOID)((lpSystray->lpsysListHeader->lpNotifyDataList))[x],sizeof(NOTIFYICONDATAA)+4,NULL);
									}
								}
							}
						}
					}
				}
				//ferme le handle de Explorer.exe
				CloseHandle(hP);
			}
		}
	}
	//renvoie les infos
	return lpSystray;
}

//libère la mémoire allouée par GetTrayIcons_9x
void FreeTrayIcons_9x(LPSYSTRAY lpSystray)
{
if (lpSystray)
{
	if (lpSystray->lpsysListHeader)
	{
		ULONG dwCount =lpSystray->lpsysListHeader->dwCount;
		for (UINT x =0; x < dwCount;x++)
		{
			//libère chaque NOTIFYENTRY
			VirtualFree((LPVOID)(lpSystray->lpsysListHeader->lpNotifyDataList)[x],NULL,MEM_RELEASE);
		}

		//libère la liste
		VirtualFree((LPVOID)lpSystray->lpsysListHeader->lpNotifyDataList,NULL,MEM_RELEASE);
		//libère l'entête
		VirtualFree((LPVOID)lpSystray->lpsysListHeader,NULL,MEM_RELEASE);
	}
	//libère les infos du tray
	VirtualFree((LPVOID)lpSystray,NULL,MEM_RELEASE);
}
}

//renvoie le chemin et nom de l'exe d'un processus par son pid (sous 9x)
BOOL GetProcessNameFromPID_9x(DWORD pid,char* lpName)
{
	//si pas de tampon fournit
	if (lpName==NULL)
		return FALSE;

	//on crée une liste de processus
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);
	
	//on initialise la structure pour les infos sur un processus
	PROCESSENTRY32 Process={0};
	Process.dwSize = sizeof(PROCESSENTRY32);

	//demande la premier processus
	BOOL ret = Process32First(hSnap,&Process);

	//tant qu'il y a encore des processus à énumérer et que l'on a pas trouvé le processus que l'on veut
	while ((ret) && (Process.th32ProcessID != pid))
	{
		//demande le suivant
		Process.dwSize = sizeof(PROCESSENTRY32);
		ret = Process32Next(hSnap,&Process);
	}

	//libère la liste des processus
	CloseHandle(hSnap);

	//si on a trouvé
	if (ret)
	{
		//on copie le nom de l'exe
		strcpy(lpName,Process.szExeFile);
		return TRUE;
	}
	else
		return FALSE;
};

//renvoie les icones du tray sous windows ME
LPTRAY_ME GetTrayIcons_ME(int* nIcons)
{
HANDLE hProc=NULL;		//handle de Explorer.exe
HWND hTray=NULL;		//hWnd du tray
DWORD pid=0;			//identifiant d'un processus
HGLOBAL ptrVM=NULL;		//pointeur vers la zone mémoire pour TBBUTTON
DWORD ret=0;			//valeur de retour
LPVOID ptrTip=NULL;		//pointeur vers une chaîne Unicode (Tip ou Path)
TBBUTTON tbut;			//les infos sur le bouton
CHAR Char=0;		//contient un caractère unicode
int X,Y;				//compteurs
LPTRAY_ME pTray=NULL;		//pointeur vers l'entrée active du buffer Tray

//on initialise tbut
ZeroMemory((LPVOID)&tbut,sizeof(TBBUTTON));

//on demande le hWnd du tray
if ((hTray = GethWndTray())==NULL)
	return NULL;

//on demande l//identifiant de Explorer.exe
GetWindowThreadProcessId(hTray, &pid);

//on demande un handle de Explorer.exe
if ((hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pid))==NULL)
{
	//on alloue de la mémoire pour TBBUTTON
	if (ptrVM = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,sizeof(tbut)))
	{
		//on demande le nombre de boutons dans le tray

  • nIcons = (int)SendMessage(hTray, TB_BUTTONCOUNT, (WPARAM)NULL, (LPARAM)NULL);
//on alloue la mémoire nécessaire pour les infos pTray = (LPTRAY_ME)VirtualAlloc(NULL,(*nIcons) * sizeof(TRAY),MEM_COMMIT,PAGE_READWRITE); //pour chaque icone for (X = 0;X < *nIcons;X++) { //on demande les infos sur le bouton SendMessage(hTray, TB_GETBUTTON, X, (LPARAM)ptrVM); //on lit les infos sur le bouton ReadProcessMemory(hProc, ptrVM, (LPVOID)&tbut, sizeof(TBBUTTON), &ret); //on extrait les données utiles pTray[X].dwData = (LPVOID)tbut.dwData; pTray[X].fsState = tbut.fsState; pTray[X].fsStyle = tbut.fsStyle; pTray[X].iBitmap = tbut.iBitmap; pTray[X].idCommand = tbut.idCommand; pTray[X].iString = (LPVOID)tbut.iString; //la Tip ptrTip = (LPVOID)tbut.iString; Y=0; do { Char=NULL; //on lit chaque caractère unicode ReadProcessMemory(hProc, ptrTip, (LPVOID)&Char, sizeof(CHAR), &ret); pTray[X].sTip[Y] = Char; ptrTip = (LPBYTE)ptrTip + 1; Y++; //jusqu'au NULL } while (Char); //on lit les données sur l//icone (Path...) ReadProcessMemory(hProc, (LPVOID)tbut.dwData, (LPVOID)&(pTray[X]), 36, &ret); GetWindowThreadProcessId(pTray[X].hwnd,&pid); GetProcessNameFromPID_9x(pid,pTray[X].Path); } GlobalFree(ptrVM); } CloseHandle(hProc); } return pTray; } //pour NT #include "common.h" #include "psapi.h" //pointeurs de fonctions de PSAPI.dll (uniquement pour NT/2000/XP) //si l'on link avec, l'application ne marchera pas sous 9x //pour énumérer les modules de d'un processus typedef BOOL (_stdcall *lpEnumProcessModules)(HANDLE hProcess,HMODULE* lphModule,DWORD cb,LPDWORD lpcbNeeded); //pour obtenir le nom d'un module typedef DWORD (_stdcall *lpGetModuleFileNameExW)(HANDLE hProcess,HMODULE hModule,LPWSTR lpFilename,DWORD nSize); //renvoie la liste des icones présentes dans le tray //comme les infos se trouvent dans Explorer.exe et non dans notre processus //on doit allouée de la mémoire dans Explorer.exe pour pouvoir fournir un pointeur valide vers un TBBUTTON à SendMessage //cette fonction ne fonctionne que sous NT/2000/XP (car VirtualAllocEx n//est pas présent sous 9x) LPTRAY GetTrayIcons_NT(int* nIcons) { HANDLE hProc=NULL; //handle de Explorer.exe HWND hTray=NULL; //hWnd du tray DWORD pid=0; //identifiant d'un processus LPVOID ptrVM=NULL; //pointeur vers la zone mémoire pour TBBUTTON DWORD ret=0; //valeur de retour LPVOID ptrTip=NULL; //pointeur vers une chaîne Unicode (Tip ou Path) TBBUTTON tbut; //les infos sur le bouton TCHAR TChar=0; //contient un caractère unicode int X,Y; //compteurs LPTRAY pTray=NULL; //pointeur vers l'entrée active du buffer Tray //on initialise tbut ZeroMemory((LPVOID)&tbut,sizeof(TBBUTTON)); //on demande le hWnd du tray if ((hTray = GethWndTray())==NULL) return NULL; //on demande l//identifiant de Explorer.exe GetWindowThreadProcessId(hTray, &pid); //on demande un handle de Explorer.exe if ((hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pid))==NULL) return NULL; //on alloue de la mémoire pour TBBUTTON if ((ptrVM = VirtualAllocEx(hProc, NULL, sizeof(tbut), MEM_COMMIT, PAGE_READWRITE))==NULL) { CloseHandle(hProc); return NULL; } //on demande le nombre de boutons dans le tray
  • nIcons = (int)SendMessage(hTray, TB_BUTTONCOUNT, (WPARAM)NULL, (LPARAM)NULL);
//on alloue la mémoire nécessaire pour les infos pTray = (LPTRAY)VirtualAlloc(NULL,(*nIcons) * sizeof(TRAY),MEM_COMMIT,PAGE_READWRITE); //pour chaque icone for (X = 0;X < *nIcons;X++) { //on demande les infos sur le bouton SendMessage(hTray, TB_GETBUTTON, X, (LPARAM)ptrVM); //on lit les infos sur le bouton ReadProcessMemory(hProc, ptrVM, (LPVOID)&tbut, sizeof(TBBUTTON), &ret); //on extrait les données utiles pTray[X].dwData = (LPVOID)tbut.dwData; pTray[X].fsState = tbut.fsState; pTray[X].fsStyle = tbut.fsStyle; pTray[X].iBitmap = tbut.iBitmap; pTray[X].idCommand = tbut.idCommand; pTray[X].iString = (LPVOID)tbut.iString; //la Tip ptrTip = (LPVOID)tbut.iString; Y=0; do { TChar=NULL; //on lit chaque caractère unicode ReadProcessMemory(hProc, ptrTip, (LPVOID)&TChar, sizeof(TCHAR), &ret); pTray[X].sTip[Y] = TChar; ptrTip = (LPBYTE)ptrTip + 2; Y++; //jusqu'au NULL } while (TChar); //on lit les données sur l//icone (Path...) ReadProcessMemory(hProc, (LPVOID)tbut.dwData, (LPVOID)&(pTray[X]), 36, &ret); //demande la PID du processus propriétaire de l'icone GetWindowThreadProcessId(pTray[X].hwnd,&pid); //demand el nom de ce processus GetProcessNameFromPID_NT(pid,pTray[X].uniPath,255); } //on libère la mémoire allouée VirtualFreeEx(hProc,ptrVM,NULL, MEM_RELEASE); //on ferme le handle de Explorer.exe CloseHandle(hProc); //on renvoie le tout return pTray; } //renvoie le nom du processus par son PID BOOL GetProcessNameFromPID_NT(DWORD pid,WCHAR* lpName,DWORD cbName) { //si mauvais tampon if (lpName==NULL) return FALSE; //on charge PSAPI HMODULE hPSAPI = LoadLibrary("psapi.dll"); if (hPSAPI) { //on "active" les pointeurs vers EnumProcessModules et GetModuleFileNameEx lpEnumProcessModules EnumProcessModules = (lpEnumProcessModules)GetProcAddress(hPSAPI,"EnumProcessModules"); lpGetModuleFileNameExW GetModuleFileNameExW = (lpGetModuleFileNameExW)GetProcAddress(hPSAPI,"GetModuleFileNameExW"); if (EnumProcessModules && GetModuleFileNameExW) { //demande un handle du processus HANDLE hP = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,pid); if (hP) { HMODULE hMod=NULL; //HMODULE de l'exe (toujours le premier module du processus) DWORD ret=0; //demande le HMODULE de l'exe (*EnumProcessModules)(hP,&hMod,sizeof(HMODULE),&ret); if (hMod) //demande le nom de l'exe (*GetModuleFileNameExW)(hP,hMod,(WCHAR*)lpName,cbName); //ferme le handle CloseHandle(hP); //libère PSAPI FreeLibrary(hPSAPI); return TRUE; } return FALSE; } } } //renvoie une chaine descriptive de l'état d'un bouton char* GetState_NT(BYTE fsState,char* Buff) { if (!Buff) return NULL; if ((fsState & TBSTATE_CHECKED) == TBSTATE_CHECKED) strcat(Buff,"Checked - "); if ((fsState & TBSTATE_ELLIPSES) == TBSTATE_ELLIPSES) strcat(Buff,"Ellipses - "); if ((fsState & TBSTATE_ENABLED) == TBSTATE_ENABLED) strcat(Buff,"Enabled - "); if ((fsState & TBSTATE_HIDDEN) == TBSTATE_HIDDEN) strcat(Buff,"Hidden - "); if ((fsState & TBSTATE_INDETERMINATE) == TBSTATE_INDETERMINATE) strcat(Buff,"Grayed - "); if ((fsState & TBSTATE_MARKED) == TBSTATE_MARKED) strcat(Buff,"Marked - "); if ((fsState & TBSTATE_PRESSED) == TBSTATE_PRESSED) strcat(Buff,"Pressed - "); if ((fsState & TBSTATE_WRAP) == TBSTATE_WRAP) strcat(Buff,"Wrap - "); return Buff; }

Conclusion :


Ce code fonctionne même lorsque l'option "Masquer les icones inactives" est activée (XP)...

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.