解讀系統托盤圖標隱藏(刪除)

爲了在某計算機上創建一個隱蔽的Wifi,因此面對可惡的托盤圖標,令我不得不考慮寫個程序將其Hide掉,以避免後患。app

因而開始了大量的谷歌與 百度,看下前人是如何去作的。站在巨人的肩膀不是看得更遠嘛。ide

首先咱們瞭解到托盤區彷佛是個窗口性質的東西,因而乎,操起Spy++查查究竟是什麼狀況。函數

 

很清晰的窗口所屬結構,只要咱們一次經過FindWindow()和FindWindowEx()依次從窗口類爲Shell_TrayWnd ->SysPager ->ToolbrWindow32,獲得最終句柄,而後經過發送 TB_BUTTONCOUNT消息獲得托盤窗口TBBUTTON的個數  ->  經過獲得總數,遍歷全部按鈕,向每一個BUTTON發送TB_GETBUTTON消息 得到按鈕 ->  用ReadProcessMemory讀取每一個TBBUTTON結構  ->  再經過TBBUTTON.dwData 獲得TRAYDATA結構。spa

這裏不得不提一下TRAYDATA,聽說這是一個從未公開的結構指針

1 struct TRAYDATA { 
2 HWND hwnd;
3 UINT uID;
4 UINT uCallbackMessage;
5 DWORD Reserved[2];
6 HICON hIcon;
7 };

可咱們怎麼找到他呢?他的信息在TBBUTON結構中的dwDatacode

 1 typedef struct {
 2   int       iBitmap;
 3   int       idCommand;
 4   BYTE      fsState;
 5   BYTE      fsStyle;
 6 #ifdef _WIN64
 7   BYTE      bReserved[6];
 8 #else 
 9 #if defined(_WIN32)
10   BYTE      bReserved[2];
11 #endif 
12 #endif 
13   DWORD_PTR dwData;
14   INT_PTR   iString;
15 } TBBUTTON, *PTBBUTTON, *LPTBBUTTON;

而後咱們能夠根據他得到信息填充下NOTIFYICONDATA結構體blog

 1 //系統定義結構體
 2 typedef struct _NOTIFYICONDATA    
 3 {    
 4  DWORD cbSize; //以字節爲單位的這個結構的大小 
 5  HWND hWnd; //接收托盤圖標通知消息的窗口句柄 
 6  UINT uID; //應用程序定義的該圖標的ID號 
 7  UINT uFlags; //設置該圖標的屬性 
 8  UINT uCallbackMessage; //應用程序定義的消息ID號,此消息傳遞給hWnd 
 9  HICON hIcon; //圖標的句柄 
10  char szTip[64]; //鼠標停留在圖標上顯示的提示信息 
11 } NOTIFYICONDATA, *PNOTIFYICONDATA;
12 
13 /*
14 該結構中,成員uFlags可使下列之一或組合:
15 
16    NIF_ICON 設置成員hIcon有效
17    NIF_MESSAGE 設置成員uCallbackMessage有效
18    NIF_TIP 設置成員szTip有效
19 */

以便咱們使用Shell_NotifyIcon()函數時調用,他是在托盤上增長,刪掉等做用的函數。進程

1 WINSHELLAPI BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid);
2 /*
3 ---Pnid是NOTIFYICONDATA結構的指針; dwMessage是被傳遞的消息,能夠是如下消息之一: 
4 
5    NIM_ADD 增長圖標
6    NIM_DELETE 刪除圖標
7    NIM_MODIFY 修改圖標
8 */

可是有的時候咱們可能不但願刪除全部的托盤圖標,因此咱們要判斷下他的文本,在TRAYDATA結構體中的szTip來確認是哪一個按鈕,若是是他就刪掉他,這個判斷加在執行Shell_NotifyIcon()前面,若是符合,則執行Shell_NotifyIcon()。ip

完整代碼是:內存

 

 1 struct TRAYDATA
 2 {
 3     HWND hWnd;
 4     UINT uID;
 5     UINT uCallbackMessage;
 6     DWORD Reserved1[2];
 7     HICON hIcon;
 8     DWORD Reserved2[3];
 9     TCHAR szExePath[MAX_PATH];
10     TCHAR szTip[128]; 
11 };
12 
13 //獲取托盤可見區域句柄
14 HWND hWnd = NULL;
15 hWnd = ::FindWindow(_T("Shell_TrayWnd"), NULL);
16 hWnd = ::FindWindowEx(hWnd, NULL, _T("TrayNotifyWnd"), NULL);
17 hWnd = ::FindWindowEx(hWnd, NULL, _T("SysPager"), NULL);
18 hWnd = ::FindWindowEx(hWnd, NULL, _T("ToolbarWindow32"), NULL);
19 
20 //獲取進程 ID
21 DWORD dwPID = 0;
22 ::GetWindowThreadProcessId(hWnd, &dwPID);
23 DWORD dwCount = ::SendMessage(hWnd, TB_BUTTONCOUNT, NULL, NULL);
24 
25 
26 
27 //打開進程
28 HANDLE hProc = ::OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwPID);
29 
30 //申請內存
31 LPVOID pTB = ::VirtualAllocEx(hProc, NULL, sizeof(TBBUTTON), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
32 
33 TBBUTTON tb;
34 TRAYDATA td;
35 NOTIFYICONDATA nid;
36 for (DWORD i = 0; i < dwCount; i++)
37 {
38     
39     ::ReadProcessMemory(hProc, pTB, &tb, sizeof(TBBUTTON), NULL);
40     
41     //獲取 TRAYDATA 信息
42     ::ReadProcessMemory(hProc, (LPVOID)tb.dwData, &td, sizeof(TRAYDATA), NULL);
43     //填充 NOTIFYICONDATA 結構體,調用 Shell_NotifyIcon 函數
44     //在這裏能夠利用判斷TRAYDATA結構體中的szTip來確認是哪一個按鈕,而後刪掉他
45     nid.cbSize = sizeof(NOTIFYICONDATA);
46     nid.hWnd = td.hWnd;
47     nid.uID = td.uID;
48     nid.uCallbackMessage = td.uCallbackMessage;
49     nid.hIcon = td.hIcon;
50     memcpy(nid.szTip, td.szTip, sizeof(nid.szTip));
51     nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
52     ::Shell_NotifyIcon(NIM_DELETE, &nid); //刪除圖標(注意這裏是刪除而不是隱藏)
53     //::Shell_NotifyIcon(NIM_ADD, &nid); //顯示圖標
54 }
55 
56 //釋放內存
57 ::VirtualFreeEx(hProc, pTB, sizeof(TBBUTTON), MEM_FREE);
58 VirtualFreeEx(hPro,pText,len,MEM_COMMIT);
59 
60 //關閉進程句柄
61 ::CloseHandle(hProc)
View Code

 

 參考於:http://www.codeproject.com/KB/applications/ShellTrayInfo.aspx 

相關文章
相關標籤/搜索