首页
社区
课程
招聘
[原创]如何去掉迅雷下载开放引擎中的托盘图标?
发表于: 2012-5-6 14:30 8279

[原创]如何去掉迅雷下载开放引擎中的托盘图标?

2012-5-6 14:30
8279
http://xldoc.xl7.xunlei.com/0000000026/index.html
以上是迅雷开放下载引擎的内容,以dll的形式提供给了我们几个接口方便我们黑箱作业,并且也提供了相应的demo来让我们使用。
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include ".\\XLDownload.h"
#include ".\\XLError.h"

int main()
{
     // 1、初始化下载引擎
     if ( FALSE == XLInitDownloadEngine() )
     {
          printf("Initialize download engine failed.\n");
          return 1;
     }

     // 2、启动新任务
     // PS:如果链接无法通过,请把工程属性“将wchar_t设置为内置类型        (/Zc:wchar_t)”设置为Yes
     LONG   lTaskId = 0;
     DWORD  dwRet   = XLURLDownloadToFile(
                       _T("d:\\xmp.exe"), 
                       _T("http://xmp.down.sandai.net/kankan/XMPSetup_3.8.1.485-www.exe"), 
                       _T(""), lTaskId);

     if ( XL_SUCCESS != dwRet )
     {
          XLUninitDownloadEngine();
          printf("Create new task failed, error code:%d.\n", dwRet);
          return 1;
     }

     printf("Begin download file.\n");

     // 3、查询任务状态
     do 
     {
          ::Sleep(1000);

          ULONGLONG   ullFileSize = 0;
          ULONGLONG   ullRecvSize = 0;
          LONG        lStatus     = -1;

          dwRet = XLQueryTaskInfo(lTaskId, &lStatus, &ullFileSize, &ullRecvSize);
          if ( XL_SUCCESS==dwRet )
          {
               // 输出进度信息
               if ( 0 != ullFileSize )
               {
                    double  douProgress = (double)ullRecvSize/(double)ullFileSize;
                    douProgress *= 100.0;
                    printf("Download progress:%.2f%%\n", douProgress);
               }
               else
               {
                    printf("File size is zero.\n");
               }

               if ( enumTaskStatus_Success==lStatus )
               {
                    printf("Download successfully.\n");
                    break;
               }

               if ( enumTaskStatus_Fail==lStatus )
               {
                    printf("Download failed.\n");
                    break;
               }
          }
     } while( XL_SUCCESS==dwRet );

     // 4、无论是否下载成功,都必须调用XLStopTask
     XLStopTask(lTaskId);

     // 5、释放资源
     XLUninitDownloadEngine();
     return 0;
}


是一个简单的控制台程序,当然也提供了GUI的Demo(包含了下载进度条,暂停下载,继续下载,不用说,肯定是支持断点续传的),可以查找或者直接问我要都OK。
有一个被大家普通反感的问题或说诟病就是运行Demo的时候会在托盘中出现迅雷的下载图标,让人比较不爽吧。如果在我们自己的程序中出现这个。。。。。。。。。
所以如果能隐藏掉就比较理想了,也就涉及到了隐藏托盘图标,更准确一点的说是如何隐藏某个程序的托盘图标。
在CodeProject上看到一篇文章非常不错,这里分享一下:
http://www.codeproject.com/Articles/10807/Shell-Tray-Info-Arrange-your-system-tray-icons
简单来说,这个文章就是教我们如何来管理系统托盘图标的,比如调整位置啦,左右键单击双击啦等等。
网上教我们隐藏托盘图标的代码有很多,用不着我在这里啰嗦,简单说一个原理吧:

通过类名["Shell_TrayWnd" -> "TrayNotifyWnd" -> "SysPager" -> "ToolbarWindow32"]最终得到托盘窗口句柄 -> 通过发送 TB_BUTTONCOUNT消息得到托盘窗口TBBUTTON的个数 -> 通过得到总数,用For循环,向每个BUTTON发送TB_GETBUTTON消息 -> 用ReadProcessMemory读取每个TBBUTTON结构 -> 再通过TBBUTTON.dwData 得到TRAYDATA结构。顺便说一下TRAYDATA结构吧,可以在CodeProject那篇文章中看到,据说是微软没有公开的一个托盘结构。
struct TRAYDATA
{
    HWND hwnd;                
    UINT uID;                
    UINT uCallbackMessage;    
    DWORD Reserved[2];        
    HICON hIcon;                
};

只要得到这个结构,那么托盘的图标,就可以进行一系列自己想要的操作了,修改图标,隐藏图标,移动图标等。
例子:
#include<stdio.h>
#include<windows.h>
#include<tchar.h>
#include <atlbase.h>
#include <atlconv.h>
#include <CommCtrl.h>
#include "XLDownload.h"
#include "XLError.h"
#pragma comment(lib,"XLDownload.lib")

 void ShowTrayIcon(TCHAR szIcon[],BOOL show);
 void RaiseToDebugP();
int main()
{
	RaiseToDebugP();
	//1.初始化下载引擎
	if(FALSE==XLInitDownloadEngine())
	{
		printf("Initialize download engine failed.\n");
		return 1;
	}
	ShowTrayIcon(_T("迅雷下载开放引擎"),false);
	//2.启动新任务
	//PS:如果链接无法通过,请把工程属性"将wchar_t设置为内置类型 (/Zc:wchar_t)"设置为Yes
	LONG lTaskId=0;
	int dwRet=XLURLDownloadToFile(_T("d:\\xmp.exe"),_T("http://xmp.down.sandai.net/kankan/XMPSetup_3.8.1.485-www.exe"),_T(""),lTaskId);
	ShowTrayIcon(_T("迅雷下载开放引擎"),false);
	if(XL_SUCCESS!=dwRet)
	{
		XLUninitDownloadEngine();

		printf("Create new task failed,error code:%d.\n",dwRet);
		return 1;
	}
	printf("Begin download file.\n");
	//3、查询任务状态
	do
	{
		::Sleep(1000);
		ULONGLONG ullFileSize=0;
		ULONGLONG ullRecvSize=0;
		LONG lStatus=-1;
		dwRet=XLQueryTaskInfo(lTaskId,&lStatus,&ullFileSize,&ullRecvSize);
		if(XL_SUCCESS==dwRet)
		{
			//输出进度信息
			if(0!=ullFileSize)
			{
				double douProgress=(double)ullRecvSize/(double)ullFileSize;
				douProgress*=100.0;
				printf("Download progress:%.2f%%\n",douProgress);
			}
			else
			{
				printf("File Size is zero.\n");
			}
			if(enumTaskStatus_Success==lStatus)
			{
				printf("Download successfully.\n");
				break;
			}
			if(enumTaskStatus_Fail==lStatus)
			{
				printf("Download failed.\n");
				break;
			}
		}

	}while(XL_SUCCESS==dwRet);
	//4、无论是否下载成功,都必须调用XLStopTask
	XLStopTask(lTaskId);
	//5、释放资源
	XLUninitDownloadEngine();
	return 0;
}
 void ShowTrayIcon(TCHAR szIcon[],BOOL show)
    {
        HWND hWnd,hWndPaper;
        unsigned long lngPID;
        long ret,lngButtons;
        HANDLE hProcess;
        LPVOID lngAddress;
        long lngTextAdr,lngHwndAdr,lngHwnd,lngButtonID;
        TCHAR strBuff[1024]={0};
        TCHAR* str = NULL;
        TCHAR *pp = NULL;

        hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);
        hWnd = FindWindowEx(hWnd, 0, _T("TrayNotifyWnd"), NULL);
        hWndPaper = FindWindowEx(hWnd, 0, _T("SysPager"), NULL);
        if(!hWndPaper)
            hWnd = FindWindowEx(hWnd, 0, _T("ToolbarWindow32"), NULL);
        else
            hWnd = FindWindowEx(hWndPaper, 0, _T("ToolbarWindow32"), NULL);
        ret = GetWindowThreadProcessId(hWnd, &lngPID);
        hProcess = OpenProcess(PROCESS_ALL_ACCESS
                                |PROCESS_VM_OPERATION
                                |PROCESS_VM_READ
                                |PROCESS_VM_WRITE,
                                0,
                                lngPID);
        lngAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE);
        lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);

        for(int i=0 ;i< lngButtons - 1;i++)
        {
            ret = SendMessage(hWnd,TB_GETBUTTON,i,LPARAM(lngAddress));
            ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 16),&lngTextAdr,4,0);
            if(lngTextAdr != -1)
            {
                ret = ReadProcessMemory(hProcess, LPVOID(lngTextAdr),strBuff,1024,0);
                ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 12),&lngHwndAdr,4,0);
                ret = ReadProcessMemory(hProcess, LPVOID(lngHwndAdr),&lngHwnd, 4,0);
                ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 4),&lngButtonID,4,0);
                USES_CONVERSION;
                str = OLE2T((LPOLESTR)(strBuff));
                pp=_tcsstr(str,szIcon);
                if(pp != NULL)
                {
                    if(show)
                    {
                        SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,0);
                    }
                    else
                    { 
                        SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,1);
                    }
                }
            }
        }
        VirtualFreeEx( hProcess, lngAddress, 0X4096, MEM_RELEASE);
        CloseHandle(hProcess);
    }

	//提升权限函数
void RaiseToDebugP()
{
     HANDLE hToken;
     HANDLE hProcess = GetCurrentProcess();
     if ( OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
     {
         TOKEN_PRIVILEGES tkp;
         if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid) )
         {
             tkp.PrivilegeCount = 1;
             tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            
             BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0) ;
         }
         CloseHandle(hToken);
     }    
}

以上代码在VS08中测试通过,如果您是VC6.0那么不需要用到提升权限函数,不对的地方还望指出,欢迎交流。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 952
活跃值: (1831)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
...如果是自身进程的托盘图片 那调用Shell_NotifyIcon应该更简单可靠些
2012-5-6 16:44
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
此方法在WIN7上隐藏不掉。。。。。
2012-10-26 18:08
0
游客
登录 | 注册 方可回帖
返回
//