前兩天有朋友找我,讓幫忙寫個小工具,隱藏windows的托盤圖標,想想最近在家也不想做太復雜的事,也好幾年沒寫過windows上的小工具了,就答應了。想來挺簡單的事,沒想到還是有點小插曲的。特地來博客園上記錄一下,方便自己也方便大家。

  隱藏托盤圖標主要有如下5個步驟:

  1.獲取ToolbarWindow32窗口對象句柄,因為圖標都在這里面。(有兩個,用spy++找了好久才找全)

  2.注入ToolbarWindow32進程,發(fā)送TB_BUTTONCOUNT/TB_GETBUTTON消息。

  3.讀取TBBUTTON和TRAYDATA結構體數(shù)據(jù)。(64位和32位差異比較大,網上基本上都是32位的,查看了msdn才搞清楚TBBUTTON的結構體,TRAYDATA的結構體基本上就靠查資料和結合數(shù)據(jù)猜)

  4.設置NOTIFYICONDATA結構體。

  5.完工。

--------------------------------------------------------------------------------------------------------------------------------------

  詳細過程,和示例代碼如下:

  1.獲取ToolbarWindow32窗口句柄,ToolbarWindow32有2個,分別存在兩個不同的父窗口下,代碼如下:

  a.“用戶升級的通知區(qū)域”,獲取代碼如下:

1   hWnd1 = FindWindow(TEXT("Shell_TrayWnd"), NULL);2   hWnd1 = FindWindowEx(hWnd1, 0, TEXT("TrayNotifyWnd"), NULL);3   hWnd1 = FindWindowEx(hWnd1, 0, TEXT("SysPager"), NULL);4   hWnd1 = FindWindowEx(hWnd1, 0, TEXT("ToolbarWindow32"), NULL);
1

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

  b.“溢出通知區(qū)域”,獲取代碼如下:

1   hWnd2 = FindWindow(TEXT("NotifyIconOverflowWindow"), NULL);2   hWnd2 = FindWindowEx(hWnd2, 0, TEXT("ToolbarWindow32"), NULL);
1

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

  2.注入ToolbarWindow32進程,發(fā)送TB_BUTTONCOUNT/TB_GETBUTTON消息。

  a.注入,因為ToolbarWindow32進程和當前進程不是同一個進程,TB_BUTTONCOUNT/TB_GETBUTTON是沒法發(fā)送的,注入之后就可以發(fā)送了:

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

1     GetWindowThreadProcessId(hWnd, &dwProcessId);2     hProcess = OpenProcess(PROCESS_ALL_ACCESS3         |PROCESS_VM_OPERATION4         |PROCESS_VM_READ5         |PROCESS_VM_WRITE,6         0,7         dwProcessId);                                                                // 打開目標進程8     lpAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE);        //申請空間,發(fā)送消息之后,用來讀取獲取到的結構體數(shù)據(jù)

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

  b.發(fā)送TB_BUTTONCOUNT/TB_GETBUTTON消息:

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

1   for(int i = 0 ; i < dwButtonCount; i++)2     {3         SendMessage(hWnd, TB_GETBUTTON, i, (LPARAM)lpAddress);                      // 遍歷發(fā)送TB_GETBUTTON消息,獲取對應信息4                 ...5     }

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

  3.讀取TBBUTTON和TRAYDATA結構體數(shù)據(jù),代碼如下:

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

1   ReadProcessMemory(hProcess, lpAddress, &tb, sizeof(tb), 0);                  // 遠程讀取TBBUTTON結構體信息2 3     if(tb.iString != -1)4     {5         TRAYDATA trayData;6         WCHAR *pwsz = NULL;7         ReadProcessMemory(hProcess, (LPVOID)tb.dwData, &trayData, sizeof(TRAYDATA), 0);    // 遠程讀取TRAYDATA結構體信息8         ...9     }

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

  4.設置NOTIFYICONDATA結構體:

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

1      NOTIFYICONDATA nid;2      nid.cbSize = sizeof(NOTIFYICONDATA);3      nid.hWnd = (HWND)trayData.hWnd;4      nid.uID = trayData.uID;5      nid.uFlags = NIF_STATE;6      nid.dwState = bShow?NIS_SHAREDICON:NIS_HIDDEN;7      nid.dwStateMask = NIS_HIDDEN;8      Shell_NotifyIcon(NIM_MODIFY, &nid);

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

  5.完成。