如题!我看到一些例子都是使用了wininet.dll里的函数来进行下载的.但wininet.dll里并不提供返回下载进度.所以很是苦恼.自己用socket封装ftp协议嘛,一来时间不够,二来我对结构设计很烂.写出来的代码保证是乱七八糟的.大家有什么好的现成的ftp类的话,还请给小弟一份.要能有进度的.或者告诉我inet怎么可视进度

解决方案 »

  1.   

    这是一个开源项目的FTP客户端代码,倒是有进度条,不过代码太多了,没仔细看-_-bhttp://www.vckbase.com/code/network/internet/FileZilla_2_2_4b_src.rar
      

  2.   

    进度当然是需要自己计算了,其实ftp的接口已经提供了这个类似的功能,它有一个回调函数,该回调函数会返回本次传输的数量,这样就可以计算当前一共下载了多少了
      

  3.   

    呵呵,你要有进度的话就必须得知道接收到的字节数,所以必须用socket来recv
    我倒是有一个socket写的ftp类,没有进度,不过只要你在下载文件函数里保存下接收字节数就可以自己做进度条了,要的留邮箱!
      

  4.   

    to:flyelf(空谷回音)能否给出简短的示例代码?
    to:Caps77(二两指针)[email protected]
    thanks!
      

  5.   

    class CFtpClientCtrl  
    {
    public:
    CFtpClientCtrl();
    virtual ~CFtpClientCtrl();
    enum
    {
    ftp_begin, // ¶ÔÓÚ¸Ãʼþ£¬wparam = ftp_begin£¬lparam±íʾҪ´«ÊäµÄÎļþ´óС
    ftp_transfer, // ¶ÔÓÚ¸Ãʼþ£¬wparam = ftp_transfer£¬lParam±íʾÒѾ­´«ÊäµÄ´óС
    ftp_end // ¶ÔÓÚ¸Ãʼþ£¬wparam = ftp_end£¬lparam±íʾ½á¹û£¬0--ʧ°Ü£¬1--³É¹¦
    }; // ÉèÖÃftp·þÎñÆ÷µÄÁ¬½Ó²ÎÊý
    BOOL SetServerParam( LPCTSTR lpszIpAddr, // IPµØÖ·
    LPCTSTR lpszUser, // µÇ¼Ãû³Æ
    LPCTSTR lpszPwd, // µÇ¼¿ÚÁî
    WORD wPort = INTERNET_DEFAULT_FTP_PORT, // FTP·þÎñÆ÷¶Ë¿Ú
    LPCTSTR lpszProxyName = NULL, // ´úÀíÃû³Æ
    LPCTSTR lpszProxyPwd = NULL); // ´úÀí¿ÚÁî // ¿ªÊ¼ÏÂÔØÎļþ
    BOOL BeginDownload( HWND hWnd, // ½ÓÊÕÏûÏ¢µÄ´°¿Ú
    LPCTSTR lpszRemote, // Ô¶³ÌÎļþÃû³Æ
    LPCTSTR lpszLocal, // ±£´æ±¾µØµÄÎļþ
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // Îļþ´«Êä
    BOOL BeginDownload( DWORD dwThread, // ½ÓÊÕÏûÏ¢µÄÏß³Ì
    LPCTSTR lpszRemote, // Ô¶³ÌÎļþÃû³Æ
    LPCTSTR lpszLocal, // ±£´æ±¾µØµÄÎļþ
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // Îļþ´«Êä

    // ¿ªÊ¼ÉÏ´«Îļþ
    BOOL BeginUpload( HWND hWnd, // ½ÓÊÕÏûÏ¢µÄ´°¿Ú
    LPCTSTR lpszRemote, // Ô¶³ÌÎļþÃû³Æ
    LPCTSTR lpszLocal, // ±¾µØÎļþÃû³Æ
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // Îļþ´«Êä
    BOOL BeginUpload( DWORD dwThread, // ½ÓÊÕÏûÏ¢µÄÏß³Ì
    LPCTSTR lpszRemote, // Ô¶³ÌÎļþÃû³Æ
    LPCTSTR lpszLocal, // ±¾µØÎļþÃû³Æ
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // Îļþ´«Êä
    // ½áÊø´«ÊäÎļþ
    BOOL EndFtpFile();
      

  6.   


    // µÃµ½µ±Ç°ftpµÄ»á»°¾ä±ú
    HINTERNET GetCurrentSession() const{return m_hSession;}
    // µÃµ½µ±Ç°µÄÁ¬½Ó¾ä±ú
    HINTERNET GetCurrentConnect() const{return m_hConnect;}
    // »ñÈ¡Ô¶³ÌÎļþÃû³Æ
    LPCTSTR GetCurrentRemoteFile() const{return m_szRemote;}
    // »ñÈ¡±¾µØÎļþÃû³Æ
    LPCTSTR GetCurrentLocalFile() const{return m_szLocal;}
    // »ñÈ¡µ±Ç°´«ÊäµÄÎļþÀàÐÍ
    DWORD GetCurrentFileType() const{return m_dwFileType;}
    // »ñÈ¡µ±Ç°´«Êä½ÓÊÕÏûÏ¢´°¿Ú
    HWND GetCurrentFtpWnd() const{return m_hWnd;}
    // »ñÈ¡µ±Ç°´«Êä½ÓÊÕÏûÏ¢Ïß³Ì
    DWORD GetCurrentFtpThread() const{return m_dwThread;}
    // »ñÈ¡µ±Ç°ÒѾ­´«ÊäµÄ´óС
    DWORD GetCurrentFtpSize() const{return m_dwCurrentFtpSize;}
    // µÝÔöÒѾ­´«ÊäµÄ´óС
    DWORD IncreaseFtpSize(DWORD dwStep);
    // ×¢²áÒ»¸öÏûÏ¢
    void RegisterMsgHandle(UINT uMsgHandle){m_uMsgHandle = uMsgHandle;}
    // »ñÈ¡ÒѾ­×¢²áµÄÏûÏ¢
    UINT GetRegisterMsgHandle() const{return m_uMsgHandle;}
    // »ñÈ¡Îļþ×ܳ¤¶È
    DWORD GetTotalFileSize() const{return m_dwTotalFileSize;}
    // Çå³ýFTP
    void ClearFtpSession();
    // ÉèÖÃFTP´«Êä·½Ïò
    void SetFtpDirect(BOOL bDownload = TRUE){m_bFtpDirect = bDownload;}
    // »ñÈ¡FTP´«Êä·½Ïò
    BOOL GetFtpDirect() const{return m_bFtpDirect;}
    // ÅжÏÎļþÀàÐÍÊÇ·ñÊÇASCII
    static BOOL IsFileAscii(LPCTSTR lpszFile);
    protected:
    // »ñÈ¡Ô¶³ÌÎļþµÄ´óС
    DWORD GetRemoteFileSize();
    // »ñÈ¡±¾µØÎļþµÄ´óС
    DWORD GetLocalFileSize();
    // ÏÂÔØÎļþ
    BOOL DownloadFile( LPCTSTR lpszRemote, // Ô¶³ÌÎļþÃû³Æ
    LPCTSTR lpszLocal, // ±£´æ±¾µØµÄÎļþ
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // Îļþ´«Êä
    // ÉÏ´«Îļþ
    BOOL UploadFile( LPCTSTR lpszRemote, // Ô¶³ÌÎļþÃû³Æ
    LPCTSTR lpszLocal, // ±£´æ±¾µØµÄÎļþ
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // Îļþ´«Êä

    protected:
    HINTERNET m_hSession; // Ó¦ÓÃÓÚInternetOpen
    HINTERNET m_hConnect; // Ó¦ÓÃÓÚInternetConnect TCHAR m_szFtpSrvIp[24]; // FTP·þÎñÆ÷µÄipµØÖ·
    TCHAR m_szFtpSrvUser[32]; // FTP·þÎñÆ÷µÄµÇ¼Óû§
    TCHAR m_szFtpSrvPwd[32]; // FTP·þÎñÆ÷µÄµÇ¼¿ÚÁî
    TCHAR m_szProxyName[64]; // ´úÀíµÄÃû³Æ
    TCHAR m_szProxyPwd[32]; // ´úÀíµÄ¿ÚÁî
    WORD m_wFtpSrvPort; // FTP·þÎñÆ÷µÄ¼àÌý¶Ë¿Ú HANDLE m_hFtpThread; // FTP´«ÊäµÄÏ߳̾ä±ú
    DWORD m_dwFtpThread; // FTP´«ÊäµÄÏ̱߳àºÅ TCHAR m_szRemote[MAX_PATH]; // Ô¶³ÌÎļþ
    TCHAR m_szLocal[MAX_PATH]; // ±¾µØÎļþ
    DWORD m_dwFileType; // ´«ÊäµÄÎļþÀàÐÍ HWND m_hWnd; // ½ÓÊÕ´«Êä½ø¶ÈÏûÏ¢µÄ´°¿Ú
    DWORD m_dwThread; // ½ÓÊÕ´«Êä½ø¶ÈÏûÏ¢µÄÏß³Ì DWORD m_dwCurrentFtpSize; // µ±Ç°´«ÊäµÄ´óС
    DWORD m_dwTotalFileSize; // Îļþ×Ü´óС UINT m_uMsgHandle; // ÏûÏ¢¾ä±ú£¬ÓÉÍâ½ç¶¨Òå BOOL m_bFtpDirect; // ´«Êä·½Ïò£¬TRUEΪÏÂÔØ£¬FALSEΪÉÏ´«£¬Ä¬ÈÏΪTRUEpublic:
    DWORD m_dwFtpHead; // FTP´«ÊäÍ·--×Ô´ÓInternetConnectÖ®ºó·¢Ë͵ĴÎÊý
    private:
    BOOL m_bTransfering; // ÊÇ·ñÕýÔÚ´«Êä
    };
      

  7.   

    class CFtpClientCtrl  
    {
    public:
    CFtpClientCtrl();
    virtual ~CFtpClientCtrl();
    enum
    {
    ftp_begin, // 对于该事件,wparam = ftp_begin,lparam表示要传输的文件大小
    ftp_transfer, // 对于该事件,wparam = ftp_transfer,lParam表示已经传输的大小
    ftp_end // 对于该事件,wparam = ftp_end,lparam表示结果,0--失败,1--成功
    }; // 设置ftp服务器的连接参数
    BOOL SetServerParam( LPCTSTR lpszIpAddr, // IP地址
    LPCTSTR lpszUser, // 登录名称
    LPCTSTR lpszPwd, // 登录口令
    WORD wPort = INTERNET_DEFAULT_FTP_PORT, // FTP服务器端口
    LPCTSTR lpszProxyName = NULL, // 代理名称
    LPCTSTR lpszProxyPwd = NULL); // 代理口令 // 开始下载文件
    BOOL BeginDownload( HWND hWnd, // 接收消息的窗口
    LPCTSTR lpszRemote, // 远程文件名称
    LPCTSTR lpszLocal, // 保存本地的文件
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
    BOOL BeginDownload( DWORD dwThread, // 接收消息的线程
    LPCTSTR lpszRemote, // 远程文件名称
    LPCTSTR lpszLocal, // 保存本地的文件
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输

    // 开始上传文件
    BOOL BeginUpload( HWND hWnd, // 接收消息的窗口
    LPCTSTR lpszRemote, // 远程文件名称
    LPCTSTR lpszLocal, // 本地文件名称
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
    BOOL BeginUpload( DWORD dwThread, // 接收消息的线程
    LPCTSTR lpszRemote, // 远程文件名称
    LPCTSTR lpszLocal, // 本地文件名称
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
    // 结束传输文件
    BOOL EndFtpFile();
      

  8.   

    // 得到当前ftp的会话句柄
    HINTERNET GetCurrentSession() const{return m_hSession;}
    // 得到当前的连接句柄
    HINTERNET GetCurrentConnect() const{return m_hConnect;}
    // 获取远程文件名称
    LPCTSTR GetCurrentRemoteFile() const{return m_szRemote;}
    // 获取本地文件名称
    LPCTSTR GetCurrentLocalFile() const{return m_szLocal;}
    // 获取当前传输的文件类型
    DWORD GetCurrentFileType() const{return m_dwFileType;}
    // 获取当前传输接收消息窗口
    HWND GetCurrentFtpWnd() const{return m_hWnd;}
    // 获取当前传输接收消息线程
    DWORD GetCurrentFtpThread() const{return m_dwThread;}
    // 获取当前已经传输的大小
    DWORD GetCurrentFtpSize() const{return m_dwCurrentFtpSize;}
    // 递增已经传输的大小
    DWORD IncreaseFtpSize(DWORD dwStep);
    // 注册一个消息
    void RegisterMsgHandle(UINT uMsgHandle){m_uMsgHandle = uMsgHandle;}
    // 获取已经注册的消息
    UINT GetRegisterMsgHandle() const{return m_uMsgHandle;}
    // 获取文件总长度
    DWORD GetTotalFileSize() const{return m_dwTotalFileSize;}
    // 清除FTP
    void ClearFtpSession();
    // 设置FTP传输方向
    void SetFtpDirect(BOOL bDownload = TRUE){m_bFtpDirect = bDownload;}
    // 获取FTP传输方向
    BOOL GetFtpDirect() const{return m_bFtpDirect;}
    // 判断文件类型是否是ASCII
    static BOOL IsFileAscii(LPCTSTR lpszFile);
    protected:
    // 获取远程文件的大小
    DWORD GetRemoteFileSize();
    // 获取本地文件的大小
    DWORD GetLocalFileSize();
    // 下载文件
    BOOL DownloadFile( LPCTSTR lpszRemote, // 远程文件名称
    LPCTSTR lpszLocal, // 保存本地的文件
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输
    // 上传文件
    BOOL UploadFile( LPCTSTR lpszRemote, // 远程文件名称
    LPCTSTR lpszLocal, // 保存本地的文件
    DWORD dwFileType = FTP_TRANSFER_TYPE_UNKNOWN); // 文件传输

    protected:
    HINTERNET m_hSession; // 应用于InternetOpen
    HINTERNET m_hConnect; // 应用于InternetConnect TCHAR m_szFtpSrvIp[24]; // FTP服务器的ip地址
    TCHAR m_szFtpSrvUser[32]; // FTP服务器的登录用户
    TCHAR m_szFtpSrvPwd[32]; // FTP服务器的登录口令
    TCHAR m_szProxyName[64]; // 代理的名称
    TCHAR m_szProxyPwd[32]; // 代理的口令
    WORD m_wFtpSrvPort; // FTP服务器的监听端口 HANDLE m_hFtpThread; // FTP传输的线程句柄
    DWORD m_dwFtpThread; // FTP传输的线程编号 TCHAR m_szRemote[MAX_PATH]; // 远程文件
    TCHAR m_szLocal[MAX_PATH]; // 本地文件
    DWORD m_dwFileType; // 传输的文件类型 HWND m_hWnd; // 接收传输进度消息的窗口
    DWORD m_dwThread; // 接收传输进度消息的线程 DWORD m_dwCurrentFtpSize; // 当前传输的大小
    DWORD m_dwTotalFileSize; // 文件总大小 UINT m_uMsgHandle; // 消息句柄,由外界定义 BOOL m_bFtpDirect; // 传输方向,TRUE为下载,FALSE为上传,默认为TRUEpublic:
    DWORD m_dwFtpHead; // FTP传输头--自从InternetConnect之后发送的次数
    private:
    BOOL m_bTransfering; // 是否正在传输
    };
      

  9.   

    //////////////////////////////////////////////////////////////////////////
    // 名称:FtpCtrl_CallbackStatus
    // 描述:文件传输过程中的状态回调函数,用于报告当前文件传输的进度等消息
    // 原型:void CALLBACK FtpCtrl_CallbackStatus( HINTERNET hInternet,// 句柄
    // DWORD dwContext, // 上下文
    // DWORD dwInternetStatus, // 状态
    // LPVOID lpvStatusInformation,// 信息
    // DWORD dwStatusInformationLength)
    // 参数:
    // [in] hInternet:Internet连接的句柄,从InternetOpen中得到
    // [in] dwContext:自定义的上下文数据
    // [in] dwInternetStatus:当前回调的状态
    // [in] lpvStatusInformation:当前回调的信息,根据dwInternetStatus的不同
    // 状态代表不同的意思
    // [in] dwStatusInformationLength:回调信息lpvStatusInformation的长度
    // 备注:
    //
    // 修改记录
    // 日期 版本 修改人 修改内容
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  2003/09/08      V2.00                 wjr                创建 
    //________________________________________________________________________
    void CALLBACK FtpCtrl_CallbackStatus( HINTERNET hInternet,
    DWORD dwContext,
    DWORD dwInternetStatus,
    LPVOID lpvStatusInformation,
    DWORD dwStatusInformationLength)
    {
    // 获取上下文信息
    CFtpClientCtrl *pcFtpMsg = reinterpret_cast<CFtpClientCtrl*>(dwContext);
    if(pcFtpMsg == NULL)
    {
    return;
    }
    LPDWORD pdwInformation(NULL);
    TRACE("FtpCtrl_CallbackStatus's Internet Status is %d\n", dwInternetStatus);
    // 查询当前文件传输状态
    switch(dwInternetStatus)
    {
    case INTERNET_STATUS_RESOLVING_NAME: // 10
    TRACE("Looking up the IP address for %s\n", (LPCTSTR)lpvStatusInformation);
    break;
    case INTERNET_STATUS_NAME_RESOLVED: // 11
    TRACE("Name resolved %s\n", (LPCTSTR)lpvStatusInformation);
    break;
    case INTERNET_STATUS_CONNECTING_TO_SERVER: // 20
    // lpvStatusInformation是一个SOCKADDR的指针
    TRACE("Connecting to server--%s...\n", (LPCTSTR)lpvStatusInformation);
    break;
    case INTERNET_STATUS_CONNECTED_TO_SERVER: // 21
    // lpvStatusInformation是一个SOCKADDR的指针
    TRACE("Connected to server--%s\n", (LPCTSTR)lpvStatusInformation);
    break;
    case INTERNET_STATUS_SENDING_REQUEST: // 30
    TRACE("Sending request\n");
    break;
    case INTERNET_STATUS_REQUEST_SENT: // 31
    {
    // 发送数据到服务器
    if(!pcFtpMsg->GetFtpDirect())
    {
    // 只有当处于上传状态的时候,才处理
    if(pcFtpMsg->m_dwFtpHead > 0 && pcFtpMsg->m_dwFtpHead < 5)
    {
    // 5这个值是一个经验值,具体为什么,由于没有深入研究rfc的协议
    // 所以还不知道,将来如果知道原因,可以补充上
    pcFtpMsg->m_dwFtpHead ++;
    }
    pdwInformation = (LPDWORD)lpvStatusInformation;
    if(pcFtpMsg->m_dwFtpHead == 5)
    {
    DWORD dwCurrentSize = pcFtpMsg->IncreaseFtpSize(*pdwInformation);
    TRACE("本次发送的数据大小为: %d,总共数据为:%d\n", *pdwInformation,
    dwCurrentSize);
    if(pcFtpMsg->GetCurrentFtpWnd() != NULL)
    {
    // 首先的第一选择是给窗口发送消息
    ::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),
    pcFtpMsg->GetRegisterMsgHandle(),
    CFtpClientCtrl::ftp_transfer,
    dwCurrentSize);
    }
    else if(pcFtpMsg->GetCurrentFtpThread() != 0)
    {
    ::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),
    pcFtpMsg->GetRegisterMsgHandle(),
    CFtpClientCtrl::ftp_transfer,
    dwCurrentSize);
    }
    }// End if 5,经验值
    }// end if 文件上传
    }
    break;
    case INTERNET_STATUS_RESPONSE_RECEIVED: // 41
    {
    // 从服务器接收到的响应
    if(pcFtpMsg->GetFtpDirect())
    {
    // 只有当处于下载状态的时候,才处理
    pdwInformation = (LPDWORD)lpvStatusInformation;
    if(pcFtpMsg->m_dwFtpHead > 0 && pcFtpMsg->m_dwFtpHead < 6)
    {
    // 6这个值是一个经验值,具体为什么,由于没有深入研究rfc的协议
    // 所以还不知道,将来如果知道原因,可以补充上
    pcFtpMsg->m_dwFtpHead ++;
    // TRACE("在连接之后第%d次接收数据!\n", pcFtpMsg->m_dwFtpHead);
    }
    if(pcFtpMsg->m_dwFtpHead == 6)
    {
    DWORD dwCurrentSize = pcFtpMsg->IncreaseFtpSize(*pdwInformation);
    TRACE("Response received: %d, TotalReceived is %d\n",
    *pdwInformation, dwCurrentSize);
    if(pcFtpMsg->GetCurrentFtpWnd() != NULL)
    {
    ::PostMessage( pcFtpMsg->GetCurrentFtpWnd(),
    pcFtpMsg->GetRegisterMsgHandle(),
    CFtpClientCtrl::ftp_transfer,
    dwCurrentSize);
    }
    else if(pcFtpMsg->GetCurrentFtpThread() != 0)
    {
    ::PostThreadMessage(pcFtpMsg->GetCurrentFtpThread(),
    pcFtpMsg->GetRegisterMsgHandle(),
    CFtpClientCtrl::ftp_transfer,
    dwCurrentSize);
    }
    }// End if 6,经验值
    }// End if 文件下载
    }
    break;
    case INTERNET_STATUS_RECEIVING_RESPONSE: // 40
    // 等待服务器的响应,lpvStatusInformation = NULL
    TRACE("等待服务器的响应!\n");
    break;
    case INTERNET_STATUS_CTL_RESPONSE_RECEIVED: // 42
    case INTERNET_STATUS_PREFETCH: // 43
    case INTERNET_STATUS_CLOSING_CONNECTION: // 50
    TRACE("Closing connection\n");
    break;
    case INTERNET_STATUS_CONNECTION_CLOSED: // 51
    TRACE("Connection closed\n");
    break;
    case INTERNET_STATUS_HANDLE_CREATED: // 60
    {
    LPINTERNET_ASYNC_RESULT ptIAR =
    reinterpret_cast<LPINTERNET_ASYNC_RESULT>(lpvStatusInformation);
    if(hInternet == pcFtpMsg->GetCurrentConnect())
    {
    TRACE("Connect Handle Created!\n");
    pcFtpMsg->m_dwFtpHead = 1;
    }
    else if(hInternet == pcFtpMsg->GetCurrentSession())
    {
    TRACE("Session handle created!\n");
    }
    }
    break;
    case INTERNET_STATUS_HANDLE_CLOSING: // 70
    pcFtpMsg->m_dwFtpHead = 0;
    TRACE("Handle closed with dif %d!\n",
    pcFtpMsg->GetCurrentFtpSize() - pcFtpMsg->GetTotalFileSize());
    break;
    case INTERNET_STATUS_DETECTING_PROXY: // 80
    TRACE("Detecting proxy\n");
    break;
    case INTERNET_STATUS_REQUEST_COMPLETE: // 100
    // 一个异步操作已经完成,lpvStatusInformation是INTERNET_ASYNC_RESULT的指针
    {
    LPINTERNET_ASYNC_RESULT ptIAR =
    reinterpret_cast<LPINTERNET_ASYNC_RESULT>(lpvStatusInformation);
    TRACE("一个异步操作完成,错误为:%d,结果为:%d\n",
    ptIAR->dwError, ptIAR->dwResult);
    }
    break;
    case INTERNET_STATUS_REDIRECT: // 110
    TRACE("HTTP request redirected to \n");
    break;
    case INTERNET_STATUS_INTERMEDIATE_RESPONSE: // 120
    TRACE("Received intermediate status message from the server.\n");
    break;
    case INTERNET_STATUS_STATE_CHANGE: // 200
    TRACE("'Moved between a secure and a nonsecure site\n");
    {
    LPDWORD pdwRead = (LPDWORD)lpvStatusInformation;
    switch(*pdwRead)
    {
    case INTERNET_STATE_CONNECTED: // 0x00000001
    TRACE("Connected state moved between secure and nonsecure site\n");
    break;
    case INTERNET_STATE_DISCONNECTED: // 0x00000002
    TRACE("Disconnected from network\n");
    break;
    case INTERNET_STATE_DISCONNECTED_BY_USER: // 0x00000010
    TRACE("Disconnected by user request\n");
    break;
    case INTERNET_STATE_IDLE: // 0x00000100
    TRACE("No network requests are being made (by Wininet).\n");
    break;
    case INTERNET_STATE_BUSY: // 0x00000200
    TRACE("Network requests are being made (by Wininet).\n");
    break;
    case INTERNET_STATUS_USER_INPUT_REQUIRED: // 0x00000040
    TRACE("The request requires user input to complete\n");
    break;
    default:
    break;
    }
    }
    break;
    default:
    break;
    }
    }// End Ftp_CallbackStatus
    // Ftp_CallbackStatu结束
    //////////////////////////////////////////////////////////////////////////
      

  10.   

    给我也发个如何?本人也正在做这个,谢谢了
    [email protected]
      

  11.   

    晕.那就帮忙发到 [email protected]非常感谢!!!