zoukankan      html  css  js  c++  java
  • Win7以上 32/64位系统隐藏托盘图标

      前两天有朋友找我,让帮忙写个小工具,隐藏windows的托盘图标,想想最近在家也不想做太复杂的事,也好几年没写过windows上的小工具了,就答应了。想来挺简单的事,没想到还是有点小插曲的。特地来博客园上记录一下,方便自己也方便大家。

      隐藏托盘图标主要有如下5个步骤:

      1.获取ToolbarWindow32窗口对象句柄,因为图标都在这里面。(有两个,用spy++找了好久才找全)

      2.注入ToolbarWindow32进程,发送TB_BUTTONCOUNT/TB_GETBUTTON消息。

      3.读取TBBUTTON和TRAYDATA结构体数据。(64位和32位差异比较大,网上基本上都是32位的,查看了msdn才搞清楚TBBUTTON的结构体,TRAYDATA的结构体基本上就靠查资料和结合数据猜)

      4.设置NOTIFYICONDATA结构体。

      5.完工。

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

      详细过程,和示例代码如下:

      1.获取ToolbarWindow32窗口句柄,ToolbarWindow32有2个,分别存在两个不同的父窗口下,代码如下:

      a.“用户升级的通知区域”,获取代码如下:

    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);
      

      b.“溢出通知区域”,获取代码如下:

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

      2.注入ToolbarWindow32进程,发送TB_BUTTONCOUNT/TB_GETBUTTON消息。

      a.注入,因为ToolbarWindow32进程和当前进程不是同一个进程,TB_BUTTONCOUNT/TB_GETBUTTON是没法发送的,注入之后就可以发送了:

    1     GetWindowThreadProcessId(hWnd, &dwProcessId);
    2     hProcess = OpenProcess(PROCESS_ALL_ACCESS
    3         |PROCESS_VM_OPERATION
    4         |PROCESS_VM_READ
    5         |PROCESS_VM_WRITE,
    6         0,
    7         dwProcessId);                                                                // 打开目标进程
    8     lpAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE);        //申请空间,发送消息之后,用来读取获取到的结构体数据

      b.发送TB_BUTTONCOUNT/TB_GETBUTTON消息:

    1   for(int i = 0 ; i < dwButtonCount; i++)
    2     {
    3         SendMessage(hWnd, TB_GETBUTTON, i, (LPARAM)lpAddress);                      // 遍历发送TB_GETBUTTON消息,获取对应信息
    4                 ...
    5     }  

      3.读取TBBUTTON和TRAYDATA结构体数据,代码如下:

    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     }

      4.设置NOTIFYICONDATA结构体:

    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);

      5.完成。

    源码下载地址:github

  • 相关阅读:
    [转]windows下mysql配置文件my.ini的位置
    [转]Oracle 11g不能导出空表的多种解决方法
    [转]ORACLE WITH AS 用法(相当于查询开始前构造临时表,提高效率)
    [转]基于WordPress的微信小程序支付功能开发
    从数据库优化到治病(2)治好心悸过程
    算命三十多年的资深命理师的人生感悟!
    从高维度看世界
    鸾书精华
    实用QPS和TPS高的高效分析方法
    windows 安装 mysql
  • 原文地址:https://www.cnblogs.com/ddvv/p/6209636.html
Copyright © 2011-2022 走看看