您的位置:首页 > 其它

Windows 系统托盘图标

2011-05-13 09:49 399 查看
codeproject 上找到一篇关于获取系统托盘图标的文章 Shell Tray Info - Arrange your system tray icons,感觉很好,于是把他的代码的一部分分离出来,做了一个 dll 专门获取系统的托盘信息,其它的功能都没有加进去,代码如下:



1. dll 部分

ProcessData.h

#ifndef __ProcessData_h__
#define __ProcessData_h__

#include <Windows.h>

typedef struct _process_data {
	HANDLE	_hProcess;
	LPVOID	_lpData;
} PROCESSDATA, *PPROCESSDATA;

#ifdef	__cplusplus
extern "C" {
#endif

	int		ProcessData_InitInstance	( PPROCESSDATA pProcessData, DWORD dwProcessId, SIZE_T nDataSize,
		DWORD dwDesiredAccess, DWORD dwAllocationType, DWORD dwProtect );
	void	ProcessData_UninitInstance	( PPROCESSDATA pProcessData );
	int		ProcessData_WriteData		( PPROCESSDATA pProcessData, const LPVOID pData, SIZE_T nSize );
	int		ProcessData_ReadData		( PPROCESSDATA pProcessData, LPVOID pData, SIZE_T nSize );
	int		ProcessData_GetData			( PPROCESSDATA pProcessData, const LPVOID lpcData, LPVOID pData,
		SIZE_T nSize );

#ifdef	__cplusplus
}
#endif

#endif // __ProcessData_h__




ProcessData.c

#include "ProcessData.h"

int ProcessData_InitInstance( PPROCESSDATA pProcessData, DWORD dwProcessId, SIZE_T nDataSize,
	DWORD dwDesiredAccess, DWORD dwAllocationType, DWORD dwProtect )
{
	if( NULL == pProcessData || dwProcessId <= 0 || nDataSize <= 0 )
		return 0;

	pProcessData->_hProcess = OpenProcess( dwDesiredAccess, FALSE, dwProcessId );
	if( NULL == pProcessData->_hProcess )
		return 0;

	pProcessData->_lpData = VirtualAllocEx( pProcessData->_hProcess, NULL, nDataSize,
		dwAllocationType, dwProtect );
	if( NULL == pProcessData->_lpData )
		return 0;

	return 1;
}

void ProcessData_UninitInstance( PPROCESSDATA pProcessData )
{
	if( NULL != pProcessData ) {
		if( NULL != pProcessData->_hProcess ) {
			if( NULL != pProcessData->_lpData )
				VirtualFreeEx( pProcessData->_hProcess, pProcessData->_lpData, 0, MEM_RELEASE );
			CloseHandle( pProcessData->_hProcess );
		}
	}
}

int ProcessData_WriteData( PPROCESSDATA pProcessData, const LPVOID pData, SIZE_T nSize )
{
	if( NULL == pProcessData || NULL == pProcessData->_hProcess || /
		NULL == pProcessData->_lpData || nSize <= 0 )
			return 0;

	return WriteProcessMemory( pProcessData->_hProcess, pProcessData->_lpData, pData, nSize, NULL );
}

int ProcessData_ReadData( PPROCESSDATA pProcessData, LPVOID pData, SIZE_T nSize )
{
	if( NULL == pProcessData || NULL == pProcessData->_hProcess || /
		NULL == pProcessData->_lpData || nSize <= 0 )
		return 0;

	return ReadProcessMemory( pProcessData->_hProcess, pProcessData->_lpData, pData, nSize, NULL );
}

int ProcessData_GetData( PPROCESSDATA pProcessData, const LPVOID lpcData, LPVOID pData,
	SIZE_T nSize )
{
	if( NULL == pProcessData || NULL == lpcData || NULL == pData || nSize <= 0 )
		return 0;

	return ReadProcessMemory( pProcessData->_hProcess, lpcData, pData, nSize, NULL );
}




TrayInfo.h

#ifndef __TrayInfo_h__
#define __TrayInfo_h__

#ifdef	DLL_EXPORT
#define	DLLAPI	__declspec(dllexport)
#else
#define	DLLAPI	__declspec(dllimport)
#endif

#include <Windows.h>
#include <tchar.h>

typedef struct _tray_data {
	HWND	_hWnd;
	UINT	_uId;
	UINT	_uCallbackMsg;
	DWORD	_dwReserved[2];
	HICON	_hIcon;
} TRAYDATA, *PTRAYDATA;

typedef struct _tray_item_info {
	HWND	_hWnd;
	UINT	_uId;
	UINT	_uCallbackMsg;
	TCHAR	_lpszTip[1024];
	TCHAR	_lpszProcessPath[MAX_PATH];
	BOOL	_bVisible;
} TRAYITEMINFO, *PTRAYITEMINFO;

#ifdef	__cplusplus
extern "C" {
#endif

	int	 DLLAPI GetTrayItems( PTRAYITEMINFO pTrayItemInfo, HICON *phIcon, int nMaxCount );

#ifdef	__cplusplus
}
#endif

#endif // __TrayInfo_h__




TrayInfo.c

#define DLL_EXPORT

#include "TrayInfo.h"
#include "ProcessData.h"
#include <CommCtrl.h>
#include <string.h>
#include <Psapi.h>
#pragma comment( lib, "Psapi.lib" )

//////////////////////////////////////////////////////////////////////////

HWND	FindTrayWnd			();
TCHAR	GetDriveLetter		( TCHAR *lpszDevicePath );
TCHAR*	GetFilePathFromPid	( DWORD dwPid );

//////////////////////////////////////////////////////////////////////////

int GetTrayItems( PTRAYITEMINFO pTrayItemInfo, HICON *phIcon, int nMaxCount )
{
	HWND			hWndTray		= NULL;
	DWORD			dwTrayPid		= 0;
	DWORD			dwProcessId		= 0;
	int				nCount			= 0;
	int				i				= 0;
	int				j				= 0;
	TCHAR			cTip			= 0;
	TCHAR			*pTip			= NULL;
	TCHAR			szTip[1024]		= { 0 };
	PROCESSDATA		process_data	= { 0 };
	TBBUTTON		tb_button		= { 0 };
	TRAYDATA		tray_data		= { 0 };
	TRAYITEMINFO	tray_item_info	= { 0 };

	if( NULL == pTrayItemInfo || NULL == phIcon || nMaxCount <= 0 )
		return 0;

	hWndTray = FindTrayWnd();
	if( NULL == hWndTray )
		return 0;

	GetWindowThreadProcessId( hWndTray, &dwTrayPid );
	nCount = (int)SendMessage( hWndTray, TB_BUTTONCOUNT, 0, 0 );
	nCount = nCount < nMaxCount ? nCount : nMaxCount;

	if( 0 == ProcessData_InitInstance(&process_data, dwTrayPid, sizeof(TBBUTTON), PROCESS_ALL_ACCESS,
		MEM_COMMIT, PAGE_READWRITE) )
			return 0;

	for( i = 0; i < nCount; i++ ) {
		memset( &tb_button, 0, sizeof(TBBUTTON) );
		memset( &tray_data, 0, sizeof(TRAYDATA) );
		memset( &tray_item_info, 0, sizeof(TRAYITEMINFO) );

		SendMessage( hWndTray, TB_GETBUTTON, i, (LPARAM)(process_data._lpData) );
		ProcessData_ReadData( &process_data, (LPVOID)&tb_button, sizeof(TBBUTTON) );
		ProcessData_GetData( &process_data, (LPCVOID)tb_button.dwData, &tray_data, sizeof(TRAYDATA) );

		GetWindowThreadProcessId( tray_data._hWnd, &dwProcessId );
		_tcscpy_s( tray_item_info._lpszProcessPath, MAX_PATH, GetFilePathFromPid(dwProcessId) );

		memset( szTip, 0, sizeof(TCHAR) * 1024 );
		pTip = (TCHAR*)tb_button.iString;
		if( !(tb_button.fsState & TBSTATE_HIDDEN) ) {
			tray_item_info._bVisible = TRUE;
			j = 0;
			ProcessData_GetData( &process_data, (LPVOID)pTip++, (LPVOID)&cTip, sizeof(TCHAR) );
			while( _T('/0') != cTip ) {
				if( 1023 == j )
					break;
				szTip[j++] = cTip;
				ProcessData_GetData( &process_data, (LPVOID)pTip++, (LPVOID)&cTip, sizeof(TCHAR) );
			}
		}
		else {
			tray_item_info._bVisible = FALSE;
			_tcscpy_s( szTip, 1024, _T("[Hidden Icon]") );
		}

		_tcscpy( tray_item_info._lpszTip, szTip );
		tray_item_info._hWnd			= tray_data._hWnd;
		tray_item_info._uId				= tray_data._uId;
		tray_item_info._uCallbackMsg	= tray_data._uCallbackMsg;

		pTrayItemInfo[i] = tray_item_info;
		phIcon[i] = tray_data._hIcon;
	}

	ProcessData_UninitInstance( &process_data );
	return nCount;
}

//////////////////////////////////////////////////////////////////////////

HWND FindTrayWnd()
{
	HWND	hwnd_Shell_TrayWnd		= NULL;
	HWND	hwnd_TrayNotifyWnd		= NULL;
	HWND	hwnd_SysPager			= NULL;

	hwnd_Shell_TrayWnd = FindWindow( _T("Shell_TrayWnd"), NULL );
	if( NULL == hwnd_Shell_TrayWnd )
		return NULL;

	hwnd_TrayNotifyWnd = FindWindowEx( hwnd_Shell_TrayWnd, NULL, _T("TrayNotifyWnd"), NULL );
	if( NULL == hwnd_TrayNotifyWnd )
		return NULL;

	hwnd_SysPager = FindWindowEx( hwnd_TrayNotifyWnd, NULL, _T("SysPager"), NULL );
	if( NULL == hwnd_SysPager )
		return NULL;

	return FindWindowEx( hwnd_SysPager, NULL, _T("ToolbarWindow32"), NULL );
}

TCHAR GetDriveLetter( TCHAR *lpszDevicePath )
{
	TCHAR	c				= _T('A');
	TCHAR	szDeviceName[3]	= { 0 };
	TCHAR	szTarget[512]	= { 0 };
	while( c <= _T('Z') ) {
		szDeviceName[0] = c; szDeviceName[1] = _T(':');	szDeviceName[2] = _T('/0');
		memset( szTarget, 0, sizeof(TCHAR) * 512 );
		if( 0 != QueryDosDevice(szDeviceName, szTarget, 512) ) {
			if( 0 == _tcscmp(szTarget, lpszDevicePath) )
				return c;
		}
		c++;
	}
	return _T('/0');
}

TCHAR* GetFilePathFromPid( DWORD dwPid )
{
	static TCHAR	strRet[MAX_PATH]			= { 0 };
	TCHAR			lpszImageFileName[MAX_PATH]	= { 0 };
	TCHAR			lpszSearch[]				= _T("//Device//HarddiskVolume");
	TCHAR			lpszDrive[MAX_PATH]			= { 0 };
	TCHAR			*p							= NULL;
	TCHAR			cDriveLetter				= 0;
	HANDLE			hProcess					= NULL;
	int				i							= 0;

	if( dwPid <= 0 )
		return NULL;

	hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, dwPid );
	if( NULL == hProcess )
		return NULL;

	GetProcessImageFileName( hProcess, lpszImageFileName, MAX_PATH );
	CloseHandle( hProcess );

	p = _tcsstr( lpszImageFileName, lpszSearch );
	if( NULL == p )
		return NULL;

	p = _tcschr( p + _tcslen(lpszSearch), _T('//') );
	if( NULL == p )
		return NULL;

	_tcscpy_s( lpszDrive, MAX_PATH, lpszImageFileName );
	lpszDrive[p - lpszImageFileName] = _T('/0');
	cDriveLetter = GetDriveLetter( lpszDrive );

	memset( strRet, 0, sizeof(TCHAR) * MAX_PATH );
	strRet[0] = cDriveLetter;
	strRet[1] = _T(':');
	_tcscat( strRet, p );

	return strRet;
}




2. 测试代码



_imageList.Create( 16, 16, ILC_COLOR32, 16, 16 );
_ctrlList.SetImageList( &_imageList, LVSIL_SMALL );

void CShellTrayInfoTestDlg::FillListCtrl()
{
	_ctrlList.DeleteAllItems();

	int nCount = _imageList.GetImageCount();
	for( int i = 0; i < nCount; i++ )
		_imageList.Remove( i );

	TRAYITEMINFO	tii[128]	= { 0 };
	HICON			hIcon[128]	= { 0 };
	nCount = GetTrayItems( tii, hIcon, 128 );
	if( 0 == nCount )
		return;

	for( int i = 0; i < nCount; i++ ) {
		int			iconIndex	= 0;
		ICONINFO	iconInfo	= { 0 };
		if( 0 != GetIconInfo(hIcon[i], &iconInfo) )
			iconIndex = _imageList.Add( hIcon[i] );

		LVITEM lvItem	= { 0 };
		lvItem.iItem	= i;
		lvItem.iSubItem	= 0;
		lvItem.mask		= LVIF_IMAGE;
		lvItem.iImage	= iconIndex;

		_ctrlList.InsertItem( &lvItem );

		CString strHwnd;
		strHwnd.Format( _T("0x%08x"), tii[i]._hWnd );
		_ctrlList.SetItemText( i, 1, strHwnd );
		_ctrlList.SetItemText( i, 2, tii[i]._lpszProcessPath );
		_ctrlList.SetItemText( i, 3, tii[i]._lpszTip );
	}
}




3. 效果显示



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: