爲了在某計算機上創建一個隱蔽的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)
參考於:http://www.codeproject.com/KB/applications/ShellTrayInfo.aspx