分享

用VC制作迅雷批量下载列表生成器(上)

 沿阶草_2 2013-10-30

一、引言

迅雷是目前的下载工具中用户最多的一款下载软件,其中有一项功能是批量下载。所谓批量下载就是指只要指定一个初始网络路径、通配符及取值范围,就可以在这个路径基础上自动生成批量下载列表,方便用户在批量下载具有规律网络路径的文件。如图1就是迅雷的新建批量任务的界面。同时迅雷也支持导入外部下载列表文件(*.lst文件)来进行批量下载。


1 迅雷批量下载界面

从图1可以看出,迅雷的批量下载列表生成功能比较弱,因为其只支持一个通配符的下载列表,当用户批量下载文件的网络路径同时有两个或两个以上的可变值时,迅雷就无能为力了。所以,为了解决这个问题,本文利用VC++6.0开发了迅雷批量下载列表生成器。

 

二、设计思路

迅雷批量下载列表生成器基于MFC的对话框开发,其开发思路是:首先通过MFC AppWizard新建一个基于对话框的工程;然后添加相应的控件设计出界面,为控件添加消息响应;在控件消息响应函数中添加相应代码,主要有通配符的识别、列表生成、出列表文件等。

迅雷批量下载列表生成器的界面设计如图2所示。界面主要的控件信息如表1所示。

 


2 迅雷批量下载列表生成器的界面设计

 

1 迅雷批量下载列表生成器界面的主要控件元素设计

控件ID

类型

功能说明

IDC_EDIT_URL

Edit

初始网络路径输入框

IDC_EDIT_STARTNUM1

Edit

第一个通配符的起始数字

IDC_EDIT_ENDNUM1

Edit

第一个通配符的终止数字

IDC_EDIT_STARTCHAR1

Edit

第一个通配符的起始字母

IDC_EDIT_ENDCHAR1

Edit

第一个通配符的终止字母

IDC_EDIT_WIDTH1

Edit

第一个通配符的长度

IDC_LIST1

ListBox

列表显示框

IDC_BTN_CREATE

PushButton

生成列表按钮

IDC_BTN_EXPORTLIST

PushButton

导出列表文件按钮

IDC_BTN_EXIT

PushButton

退出按钮

 

迅雷批量下载列表生成器关键算法是自动识别通配符的个数,并根据通配符的先后位置及字符范围来生成下载列表,设计流程如图3所示,

 


 

  

3 设计流程图

三、制作过程

新建一个基于MFC的对话框工程,工程名称叫DownList。添加如图2所示的控件,控件ID按照表1命名,并对控件添加消息响应,如表2所示。

2 控件的消息映射

控件ID

消息类型

函数名称

说明

IDC_BTN_CREATE

BN_CLICKED

OnBtnCreate

生成下载列表

IDC_BTN_EXPORTLIST

BN_CLICKED

OnBtnExportlist

导出下载列表文件

IDC_EDIT_URL

EN_CHANGE

OnChangeEditUrl

检测通配符的出现个数

IDC_RADIO_COMMON10

BN_CLICKED

OnRadioCommon10

选择单选按钮时的响应

IDC_EDIT_WIDTH1

EN_CHANGE

OnChangeEditWidth1

输入数字宽度的响应

 

1.对话框初始化,定位到OnInitDialog()

return TRUE所在行的上一行添加如下代码:

DisableCommonCtrls();//使设置范围控件初始时不可用

DisableCommonCtrls函数的作用就是设置通配符的设置控件不可用,下面为CDownListDlg类添加成员函数DisableCommonCtrls()

 

 

void CDownListDlg::DisableCommonCtrls()

{

    for (int i=0; i<36; i++)

    {

        HWND hWnd = ::GetDlgItem(this->m_hWnd, IDC_RADIO_COMMON10+i);

        ::EnableWindow(hWnd, FALSE);//使控件呈灰色不可用状态

    }

}

2.检测输入通配符的个数,为初始网络地址输入框的CHANGE消息响应函数添加代码。

void CDownListDlg::OnChangeEditUrl()

{

    UpdateData();//接收控件数据

    int nCount = 0;//通配符计数器,初始为0

    for (int i=0; i<m_strURL.GetLength(); i++)

    {

        if(m_strURL.Mid(i,1) == "*")

        {

            nCount ++;//通配符*的计数

        }

    }

    if (nCount > 4) //目前只支持1-4个通配符,所以异常处理大于4个通配符的情况

    {

        MessageBox("通配符个数1-4");

    }

    m_nCommonNum = nCount;

    UpdateData(false);

    EnableWnd(nCount); // 根据通配符的个数确定控件的可用程度

    // TODO: Add your control notification handler code here

}

其中EnableWnd函数的功能就是根据通配符的个数确定控件的可用程度,实参nCount传入的就是输入的通配符个数,EnableWnd函数定义如下:

void CDownListDlg::EnableWnd(int nNum)

{

    switch(nNum) {

    case 0:

    {

        DisableCommonCtrls();//当没有通配符时,全部不可用

        break;

    }

    case 1:

    {

DisableCommonCtrls();

EnableCommonCtrl1();//当一个通配符时,使第一组设置控件可用

        break;

    }

    case 2:

    {

        DisableCommonCtrls();

        EnableCommonCtrl1();

        EnableCommonCtrl2();//当一个通配符时,使第一、二组设置控件可用

        break;

    }

    case 3:

    {

        DisableCommonCtrls();

        EnableCommonCtrl1();

        EnableCommonCtrl2();

        EnableCommonCtrl3();//当一个通配符时,使第一、二、三组设置控件可用

        break;

    }

    case 4:

    {

        DisableCommonCtrls();

        EnableCommonCtrl1();

        EnableCommonCtrl2();

        EnableCommonCtrl3();

        EnableCommonCtrl4();//当一个通配符时,使四组设置控件全部可用

        break;

    }

    default:;

    }

}

3.生成下载列表,这也是本程序的核心部分。为生成列表按钮单击响应函数添加代码如下:

void CDownListDlg::OnBtnCreate()

{

    UpdateData();//接收控件数据

    m_listBox.ResetContent();//清空

    // TODO: Add your control notification handler code here

    CString str[5];//四个通配符 将字符串分为5段,用数组str[5]存储

    int n1,n2,n3,n4;// 通配符位置

    n1 = m_strURL.Find("*");//寻找第一通配符

if (n1 == -1)//如果没找到通配符

    {

m_listBox.AddString(m_strURL);

return;

    }

    //如果找到第一个通配符执行以下代码

    str[0] = m_strURL.Left(n1);//第一段字符串

    n2 = m_strURL.Find("*",n1+1);//搜索第二个通配符

    if (n2 == -1)//未搜索到第二个*

    {

        str[1] = m_strURL.Mid(n1+1);//第二段字符串

        str[2] = "";//3段字符串

        str[3] = "";//4段字符串

        str[4] = "";//5段字符串

    }

    else

    {

        str[1] = m_strURL.Mid(n1+1,n2-n1-1);//第二段字符串

        n3 = m_strURL.Find("*",n2+1);

        if (n3 == -1)

        {

            str[2] = m_strURL.Mid(n2+1);//3段字符串

            str[3] = "";//4段字符串

            str[4] = "";//5段字符串

        }

        else

        {

            str[2] = m_strURL.Mid(n2+1,n3-n2-1);//3段字符串

            n4 = m_strURL.Find("*",n3+1);

            if (n4 == -1)

            {

                str[3] = m_strURL.Mid(n3+1);//4段字符串

                str[4] = "";//5段字符串

            }

            else

            {

                str[3] = m_strURL.Mid(n3+1,n4-n3-1);//4段字符串

                str[4] = m_strURL.Right(m_strURL.GetLength()-n4-1);//5段字符串

            }

        }

    }

//记录起点 终点的变量

    int nStart1,nStart2,nStart3,nStart4;

    int nEnd1,nEnd2,nEnd3,nEnd4;

    if (m_nCommon1Type == 0)//如果为数字通配符

    {

        nStart1 = m_nStartNum1;

nEnd1 = m_nEndNum1;

    }

    else//如果为字母通配符

    {

        nStart1 = m_strStartChar1.GetAt(0); //获取ASII码值

        nEnd1 = m_strEndChar1.GetAt(0); //获取ASII码值

    }

    if (m_nCommon2Type == 0)

    {

        nStart2 = m_nStartNum2;

        nEnd2 = m_nEndNum2;

    }

    else

    {

        nStart2 = m_strStartChar2.GetAt(0);

        nEnd2 = m_strEndChar2.GetAt(0);

    }

 

    if (m_nCommon3Type == 0)

    {

        nStart3 = m_nStartNum3;

        nEnd3 = m_nEndNum3;

    }

    else

    {

        nStart3 = m_strStartChar3.GetAt(0); //获取ASII码值

        nEnd3 = m_strEndChar3.GetAt(0); //获取ASII码值

    }

    if (m_nCommon4Type == 0)

    {

        nStart4 = m_nStartNum4;

        nEnd4 = m_nEndNum4;

    }

    else

    {

        nStart4 = m_strStartChar4.GetAt(0); //获取ASII码值

        nEnd4 = m_strEndChar4.GetAt(0); //获取ASII码值

    }  

//不同个数的通配符,循环的层数不同

    switch(m_nCommonNum) {

    case 1://一个通配符时,一层循环

    {

        for (int i=nStart1; i<=nEnd1; i++)

        {

            CString strTmp;

            strTmp.Format("%s%d%s",str[0],i,str[1]);

            m_listBox.AddString(strTmp);//为显示列表框添加生成的列表

        }

        break;

    }

    case 2: //两个通配符时,两层循环

    {

        for (int i=nStart1; i<=nEnd1; i++)

        {

            for (int j=nStart2;j<=nEnd2; j++)

            {              

                CString strTmp;

                strTmp.Format("%s%d%s%d%s",str[0],i,str[1],j,str[2]);

                m_listBox.AddString(strTmp); //为显示列表框添加生成的列表

            }

        }

        break;

    }

    case 3: //三个通配符时,三层循环

    {

        for (int i=nStart1; i<=nEnd1; i++)

        {

            for (int j=nStart2;j<=nEnd2; j++)

            {

                for (int k=nStart3; k<=nEnd3; k++)

                {

                    CString strTmp;

                strTmp.Format("%s%d%s%d%s%d%s",str[0],i,str[1],j,str[2],k,str[3]);

                    m_listBox.AddString(strTmp);

 

                }

            }

        }

        break;

    }

    case 4: //四个通配符时,四层循环

    {

        for (int i=nStart1; i<=nEnd1; i++)

        {

            for (int j=nStart2;j<=nEnd2; j++)

            {

                for (int k=nStart3; k<=nEnd3; k++)

{

                    for (int l=nStart4; l<=nEnd4; l++)

                    {

                        CString strTmp;

                strTmp.Format("%s%d%s%d%s%d%s",str[0],i,str[1],j,str[2],k,str[3]);

                        m_listBox.AddString(strTmp);

                    }

                }

            }

        }

        break;

    }

    default:;

    }

}

4.导出下载列表,为导出列表文件按钮单击消息响应函数添加代码。

void CDownListDlg::OnBtnExportlist()

{

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多