Windows 系统托盘图标
2011-05-13 09:49
399 查看
在 codeproject 上找到一篇关于获取系统托盘图标的文章 Shell Tray Info - Arrange your system tray icons,感觉很好,于是把他的代码的一部分分离出来,做了一个 dll 专门获取系统的托盘信息,其它的功能都没有加进去,代码如下:
1. dll 部分
ProcessData.h
ProcessData.c
TrayInfo.h
TrayInfo.c
2. 测试代码
3. 效果显示
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. 效果显示
相关文章推荐
- 获取Windows系统托盘图标
- Windows系统托盘图标程序之Java实现
- Windows系统托盘图标程序之Java实现
- 在windows系统任务栏的托盘中显示图标 c++
- Windows系统托盘图标实践(AWT)
- 在VS里创建Windows窗体,让其最小化在系统托盘,并显示一个Icon图标
- 利用批处理文件删除系统托盘上的图标(适用于Windows各个版本)
- 隐藏Windows系统托盘图标(改进版)
- VC++6.0中实现将应用程序的图标加入到Windows的系统托盘中 zz
- 隐藏Windows系统托盘图标
- 详解隐藏windows系统托盘图标
- VC++6.0中实现将应用程序的图标加入到Windows的系统托盘中
- VC++6.0中实现将应用程序的图标加入到Windows的系统托盘中
- VC++6.0中实现将应用程序的图标加入到Windows的系统托盘中
- C#将窗口最小化到系统托盘,并显示图标和快捷菜单
- 解读系统托盘图标隐藏(删除)
- Windows托盘无效图标
- Qt之任务栏系统托盘图标
- C#实现WinForm程序的动态系统托盘图标
- Ubuntu 系统托盘输入法图标消失的解决办法