XP/WIN7系统中删除已结束进程托盘图标的方法

===============================下面这些很好====================================

//本例以获取程序托盘图标位置为例

//根据需要还可以获取不少信息

参考:http://www.cnblogs.com/daxingxing/archive/2012/02/06/2340384.html

[cpp]  view plain copy
  1. //获取托盘区域数据  
  2. RECT CTray::GetTrayRect()  
  3. {  
  4.     RECT rect = {0};  
  5.     HWND hWnd = NULL;  
  6.   
  7.     hWnd = FindTrayWnd();  
  8.     if (hWnd != NULL)  
  9.     {  
  10.         if (!EnumNotifyWindow(rect,hWnd))//如果没在普通托盘区  
  11.         {  
  12.             hWnd = FindNotifyIconOverflowWindow();//在溢出区(win7)  
  13.             if (hWnd != NULL)  
  14.             {  
  15.                 EnumNotifyWindow(rect,hWnd);  
  16.             }  
  17.         }  
  18.     }  
  19.   
  20.     return rect;  
  21. }  
  22. //枚举获取托盘区域位置  
  23. bool CTray::EnumNotifyWindow(RECT &rect,HWND hWnd)  
  24. {  
  25.     //RECT rect = {0};  
  26.     bool bSuc = false;  
  27.     unsigned long lngPID = 0;  
  28.     long ret = 0,lngButtons = 0;  
  29.     long lngHwndAdr = 0,lngHwnd = 0;//,lngTextAdr,lngButtonID;  
  30.     HANDLE hProcess = NULL;  
  31.     LPVOID lngAddress = NULL,lngRect = NULL;  
  32.   
  33.     if (hWnd != NULL)  
  34.     {  
  35.         ret = GetWindowThreadProcessId(hWnd, &lngPID);  
  36.         if(ret != 0 && lngPID != 0)  
  37.         {  
  38.             hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,0,lngPID);//  
  39.             if (hProcess != NULL)  
  40.             {  
  41.                 lngAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE);  
  42.                 lngRect = VirtualAllocEx(hProcess,0,sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);  
  43.                 lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0); //发送消息获取托盘button数量  
  44.                 if (lngAddress != NULL  && lngRect != NULL)  
  45.                 {  
  46.                     for(int i=0 ;i< lngButtons;i++)  
  47.                     {  
  48.                         RECT rc = {0};   
  49.                         int j = i;  
  50.                         ret = SendMessage(hWnd,TB_GETBUTTON,j,long(lngAddress));//发送消息获取托盘项数据起始地址  
  51.                         ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 12),&lngHwndAdr,4,0);  
  52.                         if(ret != 0 && lngHwndAdr != -1)  
  53.                         {  
  54.                             ret = ReadProcessMemory(hProcess, LPVOID(lngHwndAdr),&lngHwnd, 4,0);//获取句柄  
  55.                             if(ret != 0 && (HWND)lngHwnd == m_NotifyIconData.hWnd)//  
  56.                             {  
  57.                                 ret = ::SendMessage(hWnd,TB_GETITEMRECT,(WPARAM)j,(LPARAM)lngRect); //发送消息获取托盘项区域数据  
  58.                                 ret = ReadProcessMemory(hProcess,lngRect,&rc, sizeof(rc),0);  //读取托盘区域数据  
  59.                                 if(ret != 0)  
  60.                                 {  
  61.                                     CWnd::FromHandle(hWnd)->ClientToScreen(&rc);  
  62.                                     rect = rc;  
  63.                                 }  
  64.                                 bSuc = true;//在普通托盘区找到,在溢出区不再查找  
  65.                                 break;  
  66.                             }  
  67.                         }  
  68.                     }   
  69.                 }  
  70.                 if (lngAddress != NULL)  
  71.                 {  
  72.                     VirtualFreeEx( hProcess, lngAddress, 0x4096, MEM_DECOMMIT);  
  73.                     VirtualFreeEx( hProcess, lngAddress, 0, MEM_RELEASE);  
  74.                 }  
  75.                 if (lngRect != NULL)  
  76.                 {  
  77.                     VirtualFreeEx( hProcess, lngRect, sizeof(RECT), MEM_DECOMMIT);  
  78.                     VirtualFreeEx( hProcess, lngRect, 0, MEM_RELEASE);  
  79.                 }  
  80.                 CloseHandle(hProcess);  
  81.             }  
  82.         }  
  83.     }  
  84.     return bSuc;  
  85. }  
  86. //获取普通托盘区窗口句柄  
  87. HWND CTray::FindTrayWnd()  
  88. {  
  89.     HWND hWnd = NULL;  
  90.     HWND hWndPaper = NULL;  
  91.   
  92.     if ((hWnd = FindWindow(_T("Shell_TrayWnd"), NULL)) != NULL)  
  93.     {  
  94.         if ((hWnd = FindWindowEx(hWnd, 0, _T("TrayNotifyWnd"), NULL)) != NULL)  
  95.         {  
  96.             hWndPaper = FindWindowEx(hWnd, 0, _T("SysPager"), NULL);  
  97.             if(!hWndPaper)  
  98.                 hWnd = FindWindowEx(hWnd, 0, _T("ToolbarWindow32"), NULL);  
  99.             else  
  100.                 hWnd = FindWindowEx(hWndPaper, 0, _T("ToolbarWindow32"), NULL);  
  101.         }  
  102.     }  
  103.   
  104.     return hWnd;  
  105. }  
  106. //获取溢出托盘区窗口句柄  
  107. HWND CTray::FindNotifyIconOverflowWindow()  
  108. {  
  109.     HWND hWnd = NULL;  
  110.   
  111.     hWnd = FindWindow(_T("NotifyIconOverflowWindow"), NULL);  
  112.     if (hWnd != NULL)  
  113.     {  
  114.         hWnd = FindWindowEx(hWnd, NULL, _T("ToolbarWindow32"), NULL);  
  115.     }  
  116.       
  117.     return hWnd;  
  118. }  


//以下代码网上收集的,变量 初始化 指针句柄 及函数是否成功都没判定

//需要的自己加下判定,有时间再改了

[cpp]  view plain copy
  1. struct TRAYDATA  
  2. {  
  3.     HWND hwnd;                                 
  4.     UINT uID;                                 
  5.     UINT uCallbackMessage;         
  6.     DWORD Reserved[2];                 
  7.     HICON hIcon;                                 
  8. };  
  9. void CTray::GetTrayRect()  
  10. {  
  11. HWND hWnd,hWndPaper;  
  12. unsigned long lngPID;  
  13. long ret,lngButtons;  
  14. HANDLE hProcess;  
  15. LPVOID lngAddress;  
  16. long lngTextAdr,lngHwndAdr,lngHwnd,lngButtonID;  
  17. TCHAR strBuff[1024]={0};  
  18.   TRAYDATA trayData = {0};  
  19.   TBBUTTON btnData={0};  
  20.   
  21.   
  22. hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);  
  23. hWnd = FindWindowEx(hWnd, 0, _T("TrayNotifyWnd"), NULL);  
  24. hWndPaper = FindWindowEx(hWnd, 0, _T("SysPager"), NULL);  
  25. if(!hWndPaper)  
  26. hWnd = FindWindowEx(hWnd, 0, _T("ToolbarWindow32"), NULL);  
  27. else  
  28. hWnd = FindWindowEx(hWndPaper, 0, _T("ToolbarWindow32"), NULL);  
  29. ret = GetWindowThreadProcessId(hWnd, &lngPID);  
  30. hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,0,lngPID);  
  31. lngAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE);  
  32. lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);                        
  33. RECT rc; POINT point;  
  34. LPVOID lngRect = VirtualAllocEx(hProcess,0,sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);  
  35.   
  36. CRect rect;  
  37. for(int i=0 ;i< lngButtons;i++)  
  38. {  
  39. int j = i;  
  40. ret = SendMessage(hWnd,TB_GETBUTTON,j,long(lngAddress));  
  41. ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 16),&lngTextAdr,4,0);  
  42. if(lngTextAdr != -1)  
  43. {  
  44. ret = ReadProcessMemory(hProcess, LPVOID(lngTextAdr),strBuff,1024,0);  
  45. //ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 12),&lngHwndAdr,4,0); //获取句柄  
  46. //ret = ReadProcessMemory(hProcess, LPVOID(lngHwndAdr),&lngHwnd, 4,0);  
  47. //ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 4),&lngButtonID,4,0);//获取buttonID  
  48. CString str(strBuff);  
  49. if (str.Compare(m_NotifyIconData.szTip) == 0)  
  50. {  
  51. ::SendMessage(hWnd,TB_GETITEMRECT,(WPARAM)j,(LPARAM)lngRect);  
  52. ReadProcessMemory(hProcess,lngRect,&rc, sizeof(rc),0);  //获取托盘图标区域  
  53. CWnd::FromHandle(hWnd)->ClientToScreen(&rc);  
  54. }  
  55.   
  56. //以下是隐藏托盘图标  
  57. //    {  
  58. //    if(show)  
  59. //    {  
  60. //    SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,0);  
  61. //    }  
  62. //    else  
  63. //    {   
  64. //    SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,1);  
  65. //    }  
  66. //    }  
  67.   
  68.   
  69. }  
  70. }  
  71. VirtualFreeEx( hProcess, lngAddress, 0x4096, MEM_DECOMMIT);  
  72. VirtualFreeEx( hProcess, lngAddress, 0, MEM_RELEASE);  
  73. VirtualFreeEx( hProcess, lngRect, sizeof(RECT), MEM_DECOMMIT);  
  74. VirtualFreeEx( hProcess, lngRect, 0, MEM_RELEASE);  
  75. CloseHandle(hProcess);  
  76. }  


//另一例子

[cpp]  view plain copy
  1. VOID StartStorm()  
  2. {  
  3.          HWND hMain = FindWindow("animate_layered_window_class""暴风媒体中心");  
  4.          if ( hMain )  
  5.          {  
  6.                  ShowWindow(hMain, SW_HIDE);  
  7.          }  
  8.           
  9.          
  10.         //得到工具栏句柄  
  11.      HWND hTray = FindWindow("Shell_TrayWnd", NULL);  
  12.      hTray = FindWindowEx(hTray, 0, "TrayNotifyWnd", NULL);  
  13.      hTray = FindWindowEx(hTray, 0, "SysPager", NULL);  
  14.      hTray = FindWindowEx(hTray, 0, "ToolbarWindow32", NULL);  
  15.           
  16.         //获取explore进程ID  
  17.          DWORD TrayPid;  
  18.          GetWindowThreadProcessId(hTray, &TrayPid);  
  19.           
  20.         //打开进程 并且开辟进程空间  
  21.          RECT rect;  
  22.          TBBUTTON tb;  
  23.          TBBUTTON pTb;  
  24.          LPVOID lpAddr;  
  25.          DWORD dwThreadIdOfICO;  
  26.          DWORD dwTempId = FindStorm("Stormtray.exe"); //你要点击的进程的PID  
  27.           
  28.          TRAYDATA traydata;  
  29.           
  30.         HANDLE hOpen = OpenProcess(PROCESS_ALL_ACCESS, FALSE, TrayPid);  
  31.          lpAddr = VirtualAllocEx(hOpen, NULL, sizeof(tb) + sizeof(rect), MEM_COMMIT, PAGE_READWRITE);  
  32.           
  33.         int nCount = SendMessage(hTray, TB_BUTTONCOUNT, 0, 0);  
  34.          int i;  
  35.          DWORD dwOutWrite;  
  36.          for ( i = 0; i < nCount; i ++)  
  37.          {  
  38.                  ZeroMemory(&tb, sizeof(tb));  
  39.                  ZeroMemory(&rect, sizeof(rect));  
  40.                  //把参数写进目标进程  
  41.                  WriteProcessMemory(hOpen, lpAddr, &tb, sizeof(tb), &dwOutWrite);  
  42.                  //WriteProcessMemory(hOpen, (LPVOID)((DWORD)lpAddr + sizeof(pTb)), &rect, sizeof(rect), &dwOutWrite);  
  43.                  //获取BUTTON  
  44.                  SendMessage(hTray, TB_GETBUTTON, i, LPARAM(lpAddr));  
  45.                  //读取TBBUTTON结构  
  46.                  ReadProcessMemory(hOpen, lpAddr, &pTb, sizeof(TBBUTTON), &dwOutWrite);  
  47.                  //读取TRAYDATA结构  
  48.                  ReadProcessMemory(hOpen, (LPVOID)pTb.dwData, &traydata, sizeof(TRAYDATA), &dwOutWrite);  
  49.                   
  50.                  GetWindowThreadProcessId(traydata.hwnd, &dwThreadIdOfICO);  
  51.                  if ( dwThreadIdOfICO == dwTempId )  
  52.                  {  
  53.                          //获取ICO的RECT  
  54.                          LPVOID lp = (LPVOID)((DWORD)lpAddr + sizeof(pTb));  
  55.                          SendMessage(hTray, TB_GETITEMRECT, i, (LPARAM)lp);  
  56.                          LPVOID lpdata = (LPVOID)((DWORD)lpAddr + sizeof(TBBUTTON));  
  57.                          ReadProcessMemory(hOpen, lpdata, &rect, sizeof(rect), &dwOutWrite);  
  58.                          int iGap = rect.right/2; //得到图标的中间坐标的间隔  
  59.                          //点击  
  60.                          SendMessage(hTray, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.right - iGap, rect.bottom - iGap));  
  61.                          SendMessage(hTray, WM_LBUTTONUP, 0, MAKELPARAM(rect.right - iGap, rect.bottom - iGap));  
  62.                          //  
  63.                          CloseHandle(hOpen);  
  64.                          break;;  
  65.                  }  
  66.          }  
  67.           
  68. }  

//下面这个我试了,win7下可以用//

//win7有一个溢出托盘区:以下是隐藏在托盘区中的托盘信息,用以上的方法找不到,因为在NotifyIconOverflowWindow里

Fhwnd = FindWindow("NotifyIconOverflowWindow", NULL) 

参考文章:http://topic.csdn.net/u/20101003/23/859851ee-5aa1-4476-8ce1-1359826df2b0.html

[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include <afx.h>  
  3. #include <locale.h>  
  4. #include <string>  
  5. using namespace std;  
  6.   
  7.   
  8.   
  9. typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLEPBOOL);  
  10.   
  11. BOOL IsWow64()  
  12. {  
  13.     BOOL bIsWow64 = FALSE;  
  14.   
  15.     LPFN_ISWOW64PROCESS   
  16.         fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(  
  17.         GetModuleHandle(_T("kernel32")),"IsWow64Process");  
  18.   
  19.     if (NULL != fnIsWow64Process)  
  20.     {  
  21.         if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))  
  22.         {  
  23.             // handle error  
  24.         }  
  25.     }  
  26.     return bIsWow64;  
  27. }  
  28.   
  29.   
  30. HWND FindTrayWnd()  
  31. {  
  32.     HWND hWnd = NULL;  
  33.       
  34.     hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);  
  35.     hWnd = FindWindowEx(hWnd, NULL, _T("TrayNotifyWnd"), NULL);  
  36.     hWnd = FindWindowEx(hWnd, NULL, _T("SysPager"), NULL);  
  37.     hWnd = FindWindowEx(hWnd, NULL, _T("ToolbarWindow32"), NULL);  
  38.   
  39.   
  40.     return hWnd;  
  41. }  
  42.   
  43. HWND FindNotifyIconOverflowWindow()  
  44. {  
  45.     HWND hWnd = NULL;  
  46.   
  47.     hWnd = FindWindow(_T("NotifyIconOverflowWindow"), NULL);  
  48.     hWnd = FindWindowEx(hWnd, NULL, _T("ToolbarWindow32"), NULL);  
  49.   
  50.     return hWnd;  
  51. }  
  52.   
  53. void EnumNotifyWindow(HWND hWnd)  
  54. {  
  55.     DWORD dwProcessId = 0;  
  56.     GetWindowThreadProcessId(hWnd,&dwProcessId);  
  57.   
  58.     HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwProcessId);  
  59.     if ( hProcess==NULL ){  
  60.         return;  
  61.     }  
  62.     LPVOID lAddress = VirtualAllocEx(hProcess, 0, 4096, MEM_COMMIT, PAGE_READWRITE);  
  63.     if ( lAddress==NULL ){  
  64.         return;  
  65.     }  
  66.     DWORD lTextAdr = 0;  
  67.     BYTE buff[1024] = {0};  
  68.     CString strFilePath;  
  69.     CString strTile;  
  70.     HWND hMainWnd = NULL;  
  71.     int nDataOffset = sizeof(TBBUTTON) - sizeof(INT_PTR) - sizeof(DWORD_PTR);  
  72.     int nStrOffset = 18;   
  73.     if ( IsWow64() ){  
  74.         nDataOffset+=4;  
  75.         nStrOffset+=6;  
  76.     }  
  77.   
  78.     //得到圖標個數  
  79.     int lButton = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);  
  80.     for (int i = 0; i < lButton; i++) {  
  81.         SendMessage(hWnd, TB_GETBUTTON, i, (LPARAM)lAddress);  
  82.         //讀文本地址  
  83.         ReadProcessMemory(hProcess, (LPVOID)((DWORD)lAddress + nDataOffset), &lTextAdr, 4, 0);  
  84.         if ( lTextAdr!=-1 ) {  
  85.             //讀文本  
  86.             ReadProcessMemory(hProcess, (LPCVOID)lTextAdr, buff, 1024, 0);  
  87.             hMainWnd = (HWND)(*((DWORD*)buff));  
  88.             strFilePath = (WCHAR *)buff + nStrOffset;  
  89.             strTile = (WCHAR *)buff + nStrOffset + MAX_PATH;  
  90.             _tprintf(_T("%s %s\n"),strTile,strFilePath);  
  91.         }  
  92.     }  
  93.     VirtualFreeEx(hProcess, lAddress, 4096, MEM_RELEASE);  
  94.     CloseHandle(hProcess);  
  95. }  
  96.   
  97.   
  98. int _tmain(int argc, _TCHAR* argv[])  
  99. {  
  100.     setlocale(LC_ALL, "chs");  
  101.     EnumNotifyWindow(FindTrayWnd());  
  102.     _tprintf(_T("\n"));  
  103.     EnumNotifyWindow(FindNotifyIconOverflowWindow());  
  104.     system("pause");  
  105.     return 0;  
  106. }  
==================================================================

对于使用托盘图标的程序,当我们通过强制结束进程,或者程序异常退出时,托盘图标区域总会有托盘图标的残留,需要我们用鼠标移到残留区域时,托盘图标才会自动消失。有时我们需要去做相关的处理,比如在软件升级时,会强制结束进程,这时需要自动的去清除残留的托盘图标。通过研究和查阅网络,整理如下的方法。

        1、实际上托盘图标区域对应一个ToolbarWindow32工具条窗口,每个托盘图标对应一个按钮,通过遍历找到指定程序的按钮ID,向这个按钮ID发送TB_HIDEBUTTON,使托盘图标消失,代码如下:

[cpp]  view plain copy
  1. HWND hWnd,hWndPaper;  
  2. unsigned long lngPID;  
  3.    long ret,lngButtons;  
  4. HANDLE hProcess;  
  5. LPVOID lngAddress;  
  6.    long lngTextAdr,lngHwndAdr,lngHwnd,lngButtonID;  
  7.    char strBuff[1024]={0};  
  8.    char* str = NULL;  
  9.    char *pp = NULL;  
  10.   
  11. hWnd = ::FindWindow( "Shell_TrayWnd", NULL );  
  12. hWnd = ::FindWindowEx( hWnd, 0, "TrayNotifyWnd", NULL );  
  13. hWndPaper = ::FindWindowEx( hWnd, 0, "SysPager", NULL );  
  14.    if( !hWndPaper )  
  15.     hWnd = ::FindWindowEx( hWnd, 0, "ToolbarWindow32", NULL );  
  16.    else  
  17.     hWnd = ::FindWindowEx( hWndPaper, 0, "ToolbarWindow32", NULL );  
  18.   
  19. ret = GetWindowThreadProcessId( hWnd, &lngPID );  
  20. hProcess = OpenProcess( PROCESS_ALL_ACCESS  
  21.     |PROCESS_VM_OPERATION  
  22.     |PROCESS_VM_READ  
  23.     |PROCESS_VM_WRITE,  
  24.     0,  
  25.     lngPID );  
  26. lngAddress = VirtualAllocEx( hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE );  
  27. lngButtons = ::SendMessage( hWnd, TB_BUTTONCOUNT, 0, 0 );  
  28.   
  29.    forint i=0; i< lngButtons - 1; i++ )  
  30. {  
  31.     ret = ::SendMessage( hWnd, TB_GETBUTTON, i, long(lngAddress) );  
  32.     ret = ReadProcessMemory( hProcess, LPVOID(long(lngAddress) + 16), &lngTextAdr, 4, 0 );  
  33.        if( lngTextAdr != -1 )  
  34.     {  
  35.         ret = ReadProcessMemory( hProcess, LPVOID(lngTextAdr), strBuff, 1024, 0 );  
  36.         ret = ReadProcessMemory( hProcess, LPVOID(long(lngAddress) + 12), &lngHwndAdr, 4, 0 );  
  37.         ret = ReadProcessMemory( hProcess, LPVOID(lngHwndAdr),&lngHwnd, 4, 0 );  
  38.         ret = ReadProcessMemory( hProcess, LPVOID(long(lngAddress) + 4), &lngButtonID, 4, 0 );  
  39.         USES_CONVERSION;  
  40.         str = OLE2T( (LPOLESTR)( strBuff ) );  
  41.         pp=strstr( str,"阿里旺旺" ); // 通过窗口名称来比对  
  42.            if(pp != NULL)  
  43.         {  
  44.             ::SendMessage( hWnd, TB_HIDEBUTTON, lngButtonID, 1 );  
  45.         }  
  46.     }  
  47. }  
  48. VirtualFreeEx( hProcess, lngAddress, 0X4096, MEM_RELEASE );  
  49. CloseHandle( hProcess );  
        上述方法比较负责,但相对合理很多,但是这种方法只对win2000,XP系统有效,对与Win7却无能为力,没有效果。

        3、对于Win7系统,程序的托盘图标最终是放置在和XP一样的ToolbarWindow32工具条窗口,但是有两个地方,同样是ToolbarWindow32工具条窗口,父窗口是不一样的。在右下角可见区域,ToolbarWindow32工具条窗口的父窗口是SysPager窗口,遍历方法同XP一样。对于掩藏的ToolbarWindow32工具条窗口,必须通过点击桌面右下角的可见区域左边的一个按钮,才会显示出来,其父窗口则是一个叫做托盘溢出的窗口NotifyIconOverflowWindow。所以除了这两个地方都要查找,查找后面的ToolbarWindow32工具条窗口,则只要直接查找NotifyIconOverflowWindow即可,代码如下:

[cpp]  view plain copy
  1. //获取托盘溢出区域窗口句柄    
  2. hWnd = ::FindWindow(_T("NotifyIconOverflowWindow"), NULL);    
  3. hWnd = ::FindWindowEx(hWnd, NULL, _T("ToolbarWindow32"), NULL);  

        上述相关代码已通过实际测试,均能达到指定的效果。

================================================================

方法二:(已测试,在XP下可用)


//--------找出该图标所对应的进程ID,如果该ID为NULL则删除该图标--------//
bool  refreshTray()
{
HWND  hStatus=::FindWindow("Shell_TrayWnd",NULL);  //得到任务栏句柄
if  (hStatus==NULL)  
{  
qDebug()<<"Get Shell_TrayWnd error!\n";  
return false;  
}  
HWND  hNotify=FindWindowEx(hStatus,NULL,"TrayNotifyWnd",NULL); //右下角区域 
if  (hNotify==NULL)  
{  
qDebug()<<"Get TrayNotifyWnd error!\n";  
return false;  
}  
HWND  hNotify1=FindWindowEx(hNotify,NULL,"SysPager",NULL);
if  (hNotify==NULL)  
{  
qDebug()<<"Get SysPager error!\n";  
return false;  

HWND  hNotify1_0=FindWindowEx(hNotify1,NULL,"ToolBarWindow32",NULL);//右下角区域(不包括时间)
if  (hNotify1_0==NULL)   
{  
qDebug()<<"Get ToolBarWindow64 error!\n";  
return false;  
}  

//-------------------以上是得到任务栏右下脚一块地方的句柄-----------------//
DWORD  pid = 0;  
GetWindowThreadProcessId(hNotify1_0,&pid);  
if  (pid==NULL)  
{  
qDebug()<<"Get pid error!\n";  
return false;  
}   


HANDLE  hProcess=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_ALL_ACCESS,true,pid);  
if  (hProcess==NULL)  
{  
qDebug()<<"Get hd error!\n";  
return false;  
}  
::SendMessage(hNotify1_0,WM_PAINT ,NULL,NULL); 
CRect rect;
::GetWindowRect(hNotify1_0,&rect);
::InvalidateRect(hNotify1_0,&rect,false);
int  iNum=::SendMessage(hNotify1_0,TB_BUTTONCOUNT ,NULL,NULL);  //获取任务栏上图标个数


unsigned long n = 0;  
TBBUTTON  *pButton = new TBBUTTON;  
CString  strInfo = _T("");  
wchar_t  name[256] = {0};  
TBBUTTON  BButton; 
unsigned   long    whd,proid;
CString x;


for(int i=0; i<iNum; i++)  
{  
::SendMessage(hNotify1_0,TB_GETBUTTON,i,(LPARAM)(&BButton));  
ReadProcessMemory(hProcess,&BButton,pButton,sizeof(TBBUTTON),&n);   
if  (pButton->iString != 0xffffffff)  
{  
try  
{  
ReadProcessMemory(hProcess,(void *)pButton->iString,name,255,&n);
}  
catch(...)  
{  
}      
strInfo.Format("%d : %s\n",i+1,CString(name)); 
TRACE(strInfo);
qDebug()<<"strInfo = "<<strInfo<<endl;
}


try   
{   
whd=0;   
ReadProcessMemory(hProcess,(void   *)pButton->dwData,&whd,4,&n);   
}   
catch(...)   
{   
}   
proid=NULL;   
GetWindowThreadProcessId((HWND)whd,&proid);   
if(proid==NULL)
::SendMessage(hNotify1_0,TB_DELETEBUTTON,i,0);

delete pButton;


return true;

}


注:上述代码在XP中是可以用的,已经测试,但是,在win7中需要把加粗部分换成下面的代码:

//获取托盘溢出区域窗口句柄    
HWND  hStatus = ::FindWindow(_T("NotifyIconOverflowWindow"), NULL); 
if  (hStatus==NULL)  
{  
qDebug()<<"Get Shell_TrayWnd error!\n";  
return false;  
}  
HWND  hNotify1_0 = ::FindWindowEx(hStatus, NULL, _T("ToolbarWindow32"), NULL); 
if  (hNotify1_0==NULL)  
{  
qDebug()<<"Get TrayNotifyWnd error!\n";  
return false;  
}  

但是,有时误清除,会把其他的没有结束的进程的图标也关掉。还有待解决。。。



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Win XP 自带了许多系统图标,这些图标是用于表示不同类型的文件、文件夹、应用程序和系统功能等。这些图标的设计旨在让用户可以轻松识别和使用系统的各种元素。 Win XP 自带的系统图标,最常见的是文件夹图标。每个文件夹都有一个独特的图标,可以帮助用户区分不同类型的文件夹。例如,“我的文档”文件夹有一个文件夹图标,表示存储个人文档和文件的位置;而“桌面”文件夹有一个桌面图标,表示用于存放桌面上的项目和快捷方式。 此外,Win XP 还自带了各种类型的文件图标。例如,文本文件有一个纸张图标,表示存储文字内容;图片文件有一个相机图标,表示存储图像文件;音频文件有一个音符图标,表示存储声音文件等等。这些文件图标的设计都与其对应的文件类型相关联,使得用户能够快速识别它们所代表的文件类型。 除了文件和文件夹图标,Win XP 还提供了许多其他的系统图标。例如,控制面板图标用于访问系统设置和管理工具;计算机图标用于表示计算机的硬件设备和网络连接;回收站图标用于表示已删除的文件和文件夹等等。这些图标的设计和用途都旨在帮助用户轻松访问和管理系统的不同元素和功能。 总而言之,Win XP 自带了多种系统图标,用于表示文件、文件夹、应用程序和系统功能等。这些图标的设计和使用方便了用户对系统的操作和管理,使得使用 Win XP 更加便捷和高效。 ### 回答2: Win XP自带系统图标是指Windows XP操作系统默认安装的一些图标。这些图标用于表示不同类型的文件、文件夹、应用程序和系统功能等。下面是Win XP常见的一些系统图标: 1. 文件夹图标:Win XP自带了一系列文件夹图标,用于表示不同类型的文件夹,如普通文件夹、共享文件夹和系统文件夹等。 2. 文档图标:Win XP提供了多个文档图标,用于表示不同类型的文档文件,如文本文档、Word文档、Excel表格和PowerPoint演示文稿等。 3. 应用程序图标:Win XP内置了一些应用程序的图标,如Internet Explorer、Windows Media Player、Microsoft Office等常见的应用程序的图标。 4. 控制面板图标:Win XP提供了一系列控制面板图标,用于表示不同的系统设置和功能,如显示设置、声音设置和网络设置等。 5. 系统图标:Win XP自带了一些系统图标,如我的电脑、回收站、网络邻居和打印机等。这些图标用于表示与系统相关的功能和设备。 总之,Win XP自带系统图标是为了方便用户识别和访问系统的不同文件、文件夹、应用程序和系统功能等。这些图标在操作系统安装后就会自动显示,并可以根据用户的需要进行个性化设置。 ### 回答3: Win XP自带的系统图标主要包括桌面图标和开始菜单图标。桌面图标是指显示在Windows桌面上的各种快捷方式和文件夹图标,比如“我的文档”图标、Recycle Bin(回收站)图标等。开始菜单图标是指Win XP左下角的“开始”按钮旁边的图标,例如“我的文档”、“我的电脑”、“网络连接”等。 Win XP的桌面图标可以根据自己的喜好进行调整和添加。用户可以右键单击桌面上的空白处,选择“属性”,然后在“桌面”标签下,点击“自定义桌面”按钮。在自定义桌面窗口,用户可以选择显示哪些图标,并可以点击“更改图标”按钮来更改图标的外观。此外,用户还可以通过拖拽方式将文件夹或程序快捷方式添加到桌面,形成新的图标。 Win XP的开始菜单图标则是系统默认安装时自带的,不能直接进行个性化更改。但是用户可以通过在开始菜单上右键单击,选择“属性”,在“开始菜单”选项卡下,点击“自定义”按钮来自定义开始菜单的外观和布局。在自定义开始菜单窗口,用户可以选择显示或隐藏某些特定目录的图标,也可以选择将某个目录图标显示在开始菜单。 总之,Win XP的自带系统图标可以通过一些简单的操作进行调整和个性化,使得用户可以根据自己的喜好来设置桌面和开始菜单上的图标

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值