天天看點

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

//以下代碼網上收集的,變量 初始化 指針句柄 及函數是否成功都沒判定

//需要的自己加下判定,有時間再改了

[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. hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);  
  21. hWnd = FindWindowEx(hWnd, 0, _T("TrayNotifyWnd"), NULL);  
  22. hWndPaper = FindWindowEx(hWnd, 0, _T("SysPager"), NULL);  
  23. if(!hWndPaper)  
  24. hWnd = FindWindowEx(hWnd, 0, _T("ToolbarWindow32"), NULL);  
  25. else  
  26. hWnd = FindWindowEx(hWndPaper, 0, _T("ToolbarWindow32"), NULL);  
  27. ret = GetWindowThreadProcessId(hWnd, &lngPID);  
  28. hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,0,lngPID);  
  29. lngAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE);  
  30. lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);                        
  31. RECT rc; POINT point;  
  32. LPVOID lngRect = VirtualAllocEx(hProcess,0,sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);  
  33. CRect rect;  
  34. for(int i=0 ;i< lngButtons;i++)  
  35. {  
  36. int j = i;  
  37. ret = SendMessage(hWnd,TB_GETBUTTON,j,long(lngAddress));  
  38. ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 16),&lngTextAdr,4,0);  
  39. if(lngTextAdr != -1)  
  40. {  
  41. ret = ReadProcessMemory(hProcess, LPVOID(lngTextAdr),strBuff,1024,0);  
  42. //ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 12),&lngHwndAdr,4,0); //擷取句柄  
  43. //ret = ReadProcessMemory(hProcess, LPVOID(lngHwndAdr),&lngHwnd, 4,0);  
  44. //ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 4),&lngButtonID,4,0);//擷取buttonID  
  45. CString str(strBuff);  
  46. if (str.Compare(m_NotifyIconData.szTip) == 0)  
  47. {  
  48. ::SendMessage(hWnd,TB_GETITEMRECT,(WPARAM)j,(LPARAM)lngRect);  
  49. ReadProcessMemory(hProcess,lngRect,&rc, sizeof(rc),0);  //擷取托盤圖示區域  
  50. CWnd::FromHandle(hWnd)->ClientToScreen(&rc);  
  51. }  
  52. //以下是隐藏托盤圖示  
  53. //    {  
  54. //    if(show)  
  55. //    {  
  56. //    SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,0);  
  57. //    }  
  58. //    else  
  59. //    {   
  60. //    SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,1);  
  61. //    }  
  62. //    }  
  63. }  
  64. }  
  65. VirtualFreeEx( hProcess, lngAddress, 0x4096, MEM_DECOMMIT);  
  66. VirtualFreeEx( hProcess, lngAddress, 0, MEM_RELEASE);  
  67. VirtualFreeEx( hProcess, lngRect, sizeof(RECT), MEM_DECOMMIT);  
  68. VirtualFreeEx( hProcess, lngRect, 0, MEM_RELEASE);  
  69. CloseHandle(hProcess);  
  70. }  

//另一例子

[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.      HWND hTray = FindWindow("Shell_TrayWnd", NULL);  
  10.      hTray = FindWindowEx(hTray, 0, "TrayNotifyWnd", NULL);  
  11.      hTray = FindWindowEx(hTray, 0, "SysPager", NULL);  
  12.      hTray = FindWindowEx(hTray, 0, "ToolbarWindow32", NULL);  
  13.         //擷取explore程序ID  
  14.          DWORD TrayPid;  
  15.          GetWindowThreadProcessId(hTray, &TrayPid);  
  16.         //打開程序 并且開辟程序空間  
  17.          RECT rect;  
  18.          TBBUTTON tb;  
  19.          TBBUTTON pTb;  
  20.          LPVOID lpAddr;  
  21.          DWORD dwThreadIdOfICO;  
  22.          DWORD dwTempId = FindStorm("Stormtray.exe"); //你要點選的程序的PID  
  23.          TRAYDATA traydata;  
  24.         HANDLE hOpen = OpenProcess(PROCESS_ALL_ACCESS, FALSE, TrayPid);  
  25.          lpAddr = VirtualAllocEx(hOpen, NULL, sizeof(tb) + sizeof(rect), MEM_COMMIT, PAGE_READWRITE);  
  26.         int nCount = SendMessage(hTray, TB_BUTTONCOUNT, 0, 0);  
  27.          int i;  
  28.          DWORD dwOutWrite;  
  29.          for ( i = 0; i < nCount; i ++)  
  30.          {  
  31.                  ZeroMemory(&tb, sizeof(tb));  
  32.                  ZeroMemory(&rect, sizeof(rect));  
  33.                  //把參數寫進目标程序  
  34.                  WriteProcessMemory(hOpen, lpAddr, &tb, sizeof(tb), &dwOutWrite);  
  35.                  //WriteProcessMemory(hOpen, (LPVOID)((DWORD)lpAddr + sizeof(pTb)), &rect, sizeof(rect), &dwOutWrite);  
  36.                  //擷取BUTTON  
  37.                  SendMessage(hTray, TB_GETBUTTON, i, LPARAM(lpAddr));  
  38.                  //讀取TBBUTTON結構  
  39.                  ReadProcessMemory(hOpen, lpAddr, &pTb, sizeof(TBBUTTON), &dwOutWrite);  
  40.                  //讀取TRAYDATA結構  
  41.                  ReadProcessMemory(hOpen, (LPVOID)pTb.dwData, &traydata, sizeof(TRAYDATA), &dwOutWrite);  
  42.                  GetWindowThreadProcessId(traydata.hwnd, &dwThreadIdOfICO);  
  43.                  if ( dwThreadIdOfICO == dwTempId )  
  44.                  {  
  45.                          //擷取ICO的RECT  
  46.                          LPVOID lp = (LPVOID)((DWORD)lpAddr + sizeof(pTb));  
  47.                          SendMessage(hTray, TB_GETITEMRECT, i, (LPARAM)lp);  
  48.                          LPVOID lpdata = (LPVOID)((DWORD)lpAddr + sizeof(TBBUTTON));  
  49.                          ReadProcessMemory(hOpen, lpdata, &rect, sizeof(rect), &dwOutWrite);  
  50.                          int iGap = rect.right/2; //得到圖示的中間坐标的間隔  
  51.                          //點選  
  52.                          SendMessage(hTray, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.right - iGap, rect.bottom - iGap));  
  53.                          SendMessage(hTray, WM_LBUTTONUP, 0, MAKELPARAM(rect.right - iGap, rect.bottom - iGap));  
  54.                          //  
  55.                          CloseHandle(hOpen);  
  56.                          break;;  
  57.                  }  
  58.          }  
  59. }  

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

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

對于使用托盤圖示的程式,當我們通過強制結束程序,或者程式異常退出時,托盤圖示區域總會有托盤圖示的殘留,需要我們用滑鼠移到殘留區域時,托盤圖示才會自動消失。有時我們需要去做相關的處理,比如在軟體更新時,會強制結束程序,這時需要自動的去清除殘留的托盤圖示。通過研究和查閱網絡,整理如下的方法。

        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. hWnd = ::FindWindow( "Shell_TrayWnd", NULL );  
  11. hWnd = ::FindWindowEx( hWnd, 0, "TrayNotifyWnd", NULL );  
  12. hWndPaper = ::FindWindowEx( hWnd, 0, "SysPager", NULL );  
  13.    if( !hWndPaper )  
  14.     hWnd = ::FindWindowEx( hWnd, 0, "ToolbarWindow32", NULL );  
  15.    else  
  16.     hWnd = ::FindWindowEx( hWndPaper, 0, "ToolbarWindow32", NULL );  
  17. ret = GetWindowThreadProcessId( hWnd, &lngPID );  
  18. hProcess = OpenProcess( PROCESS_ALL_ACCESS  
  19.     |PROCESS_VM_OPERATION  
  20.     |PROCESS_VM_READ  
  21.     |PROCESS_VM_WRITE,  
  22.     0,  
  23.     lngPID );  
  24. lngAddress = VirtualAllocEx( hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE );  
  25. lngButtons = ::SendMessage( hWnd, TB_BUTTONCOUNT, 0, 0 );  
  26.    for( int i=0; i< lngButtons - 1; i++ )  
  27. {  
  28.     ret = ::SendMessage( hWnd, TB_GETBUTTON, i, long(lngAddress) );  
  29.     ret = ReadProcessMemory( hProcess, LPVOID(long(lngAddress) + 16), &lngTextAdr, 4, 0 );  
  30.        if( lngTextAdr != -1 )  
  31.     {  
  32.         ret = ReadProcessMemory( hProcess, LPVOID(lngTextAdr), strBuff, 1024, 0 );  
  33.         ret = ReadProcessMemory( hProcess, LPVOID(long(lngAddress) + 12), &lngHwndAdr, 4, 0 );  
  34.         ret = ReadProcessMemory( hProcess, LPVOID(lngHwndAdr),&lngHwnd, 4, 0 );  
  35.         ret = ReadProcessMemory( hProcess, LPVOID(long(lngAddress) + 4), &lngButtonID, 4, 0 );  
  36.         USES_CONVERSION;  
  37.         str = OLE2T( (LPOLESTR)( strBuff ) );  
  38.         pp=strstr( str,"阿裡旺旺" ); // 通過視窗名稱來比對  
  39.            if(pp != NULL)  
  40.         {  
  41.             ::SendMessage( hWnd, TB_HIDEBUTTON, lngButtonID, 1 );  
  42.         }  
  43.     }  
  44. }  
  45. VirtualFreeEx( hProcess, lngAddress, 0X4096, MEM_RELEASE );  
  46. 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;  

}  

但是,有時誤清除,會把其他的沒有結束的程序的圖示也關掉。還有待解決。。。

繼續閱讀