zoukankan      html  css  js  c++  java
  • 解读系统托盘图标隐藏(删除)

    为了在某计算机上建立一个隐蔽的Wifi,所以面对可恶的托盘图标,令我不得不考虑写个程序将其Hide掉,以免后患。

    于是开始了大量的谷歌与 百度,看下前人是如何去做的。站在巨人的肩膀不是看得更远嘛。

    首先我们了解到托盘区似乎是个窗口性质的东西,于是乎,操起Spy++查查到底是什么情况。

    很清晰的窗口所属结构,只要我们一次通过FindWindow()和FindWindowEx()依次从窗口类为Shell_TrayWnd ->SysPager ->ToolbrWindow32,得到最终句柄,然后通过发送 TB_BUTTONCOUNT消息得到托盘窗口TBBUTTON的个数  ->  通过得到总数,遍历所有按钮,向每个BUTTON发送TB_GETBUTTON消息 获得按钮 ->  用ReadProcessMemory读取每个TBBUTTON结构  ->  再通过TBBUTTON.dwData 得到TRAYDATA结构。

    这里不得不提一下TRAYDATA,据说这是一个从未公开的结构

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

    可我们怎么找到他呢?他的信息在TBBUTON结构中的dwData

     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结构体

     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()。

    完整代码是:

     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 

  • 相关阅读:
    HDU2054_A == B ?【模拟题】【大数】【水的问题】
    hadoop结构出现后format变态
    jquery的clone办法bug修复
    Django学习笔记(三)—— 型号 model
    华夏的理财30天A和华夏财富宝货币哪个收益比较好?
    网贷平台公司 必看
    网贷平台 平安 陆金所
    网贷平台公司 各平台投资收费比较
    2012年网贷平台全国排名
    新进网贷的小散 感受
  • 原文地址:https://www.cnblogs.com/croot/p/3496576.html
Copyright © 2011-2022 走看看