Internet - Datei aus dem Internet herunterladen (mit Statusanzeige)



  • Vor der Funktion noch global deklarieren:

    int nTerminate  = 0;  //Abbruch durch User?
    int nDownloadOK = 0;  //Download erfolgreich beendet?
    int nClick      = 0;
    

    Die Threadfunktion:

    UINT DownloadFile(LPVOID pParam)
    {
       char cReadBuffer[512];  //Lese-Buffer
    
       //YourDlg = der Dialog, in dem die Funktion aufgerufen wurde bzw. in dem
       //die Informationen angezeigt werden sollen
    
       CYourDlg* pYourDlg = (CYourDlg*)pParam;
    
       CInternetSession pInetSession;  //Internet-Sitzung
       CStdioFile*      pNetFile;      //liest später die Datei vom HTTP-Server
    
       CString strFileName = "http://www.volkard.de/vcppkold/vcppk.zip";  //Internet-Dateiname
       CString strLocalFileName = "C:\\vcppk.zip";          //Dateiname auf'm PC
       CString strPercent       = "0 % (0 / 0 Bytes)";       //zeigt später in einem Static (Member-Variable m_Percent;
                                                            //Typ: CString) den Fortschritt an
    
       int nFileSize = 0;  //Dateigröße in Bytes
    
       try  //wir VERSUCHEN die Datei zu öffnen
       {
          //m_Status = Static-Feld, Member-Variable vom Typ CString
          pYourDlg->m_Status = "Vorgang initialisiert. Suche wird gestartet ...";
          pYourDlg->SetDlgItemText(IDC_STATIC_STATUS,pYourDlg->m_Status);
    
          //Datei öffnen
          pNetFile = pInetSession.OpenURL(strFileName,
                                          1,
                                          INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD);
    
          pYourDlg->m_Status = "Anfrage gesendet. Warte auf Antwort ...";
          pYourDlg->SetDlgItemText(IDC_STATIC_STATUS,pYourDlg->m_Status);
    
          nDownloadOK = 1;  //Download erfolgreich (zumindestens bis hier hin...)
    
          //Dateigröße ermitteln
          nFileSize = pNetFile->SeekToEnd(); 
          pNetFile->SeekToBegin();
    
          //CFile-Instanz zum Schreiben der Datei
          CFile pLocalFile(strLocalFileName,
                           CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
    
          //Variablen für's Lesen und für den Fortschritt
          int nBytesToWrite   = 0;
          int nPosProgressBar = 0;
          int nPercent        = 0;
    
          //Datei gefudnen, und genau das sagen wir dem User...
          pYourDlg->m_Status = "Datei gefunden. Download beginnt ...";
          pYourDlg->SetDlgItemText(IDC_STATIC_STATUS,pYourDlg->m_Status);
    
          //m_Progress = ProgressBar, Member-Variable vom Typ CProgressCtrl
          //Einstellen des Wertebereiches
          pYourDlg->m_Progress.SetRange32(0, 100);
    
          //das eigentliche Lesen und Schreiben der Dateien
          while(nBytesToWrite = pNetFile->Read(cReadBuffer, 512))
          {
             pYourDlg->m_Status = "Datei gefunden. Download läuft ...";
             pYourDlg->SetDlgItemText(IDC_STATIC_STATUS,pYourDlg->m_Status);
    
             //checken, ob User abbrechen will
             if(nTerminate == 1)
             {
                pLocalFile.Close();
                pNetFile->Close();
                delete pNetFile;
    
                pYourDlg->m_Status = "Vorgang abgebrochen!";
                pYourDlg->SetDlgItemText(IDC_STATIC_STATUS,pYourDlg->m_Status);
    
                AfxEndThread(0);
             }
    
             //die obige if-Anweisung beliebig oft einfügen, je öfter, desto öfter wird ge-
             //prüft, ob der User abbrechen will
    
             nPosProgressBar += nBytesToWrite;
    
             pLocalFile.Write(cReadBuffer, nBytesToWrite);
    
             //prozentualen Anteil der Operation berechnen
             nPercent  = nPosProgressBar * 100 / nFileSize;
             pYourDlg->m_Progress.SetPos(nPercent);
    
             //Fortschritt in Wort-Form anzeigen
             strPercent.Format("%i %% (%i / %i Bytes)",
                               nPercent, nPosProgressBar, nFileSize);
    
             pYourDlg->m_Percent = strPercent;
             pYourDlg->SetDlgItemText(IDC_STATIC_PERCENT,pYourDlg->m_Percent);
          }  //Lesen beendet !
    
          pLocalFile.Close();
       }
    
       catch(CInternetException *IE)  //mgl. Fehler abfangen
       {
          CString strError;
          TCHAR   cError[255];
    
          IE->GetErrorMessage(cError, 255);
    
          strError = cError;
    
          pYourDlg->m_Status = strError;  //Fehler anzeigen im Static
          pYourDlg->SetDlgItemText(IDC_STATIC_STATUS,pYourDlg->m_Status);   
    
          nDownloadOK = 0;
       }
    
       pYourDlg->m_Percent = "0 % (0 / 0 Bytes)";
       pYourDlg->m_Progress.SetPos(0);
       pYourDlg->SetDlgItemText(IDC_STATIC_PERCENT,pYourDlg->m_Percent);   
    
       if(nDownloadOK == 1)  //Download erfolgreich abgeschlossen!!!!
       {
          pYourDlg->m_Status = "Download abgeschlossen.";
          pYourDlg->m_Percent = strPercent;
          pYourDlg->m_Progress.SetPos(100);
          pYourDlg->SetDlgItemText(IDC_STATIC_STATUS,pYourDlg->m_Status);      
          pYourDlg->SetDlgItemText(IDC_STATIC_PERCENT,pYourDlg->m_Percent);
       }
    
       nClick = 0;   //Button wieder in Anfangszustand versetzen lassen
    
       //IDC_DOWNLOAD ist der Button, mit dem der Thread gestartet wurde.
       //Er war während des Downloads auf "Abbrechen" gestellt (siehe Code unten)
       pYourDlg->SetDlgItemText(IDC_DOWNLOAD, "Download starten");
    
       if(nDownloadOK == 1)
       {
          //Auswertung des erfolgreichen Downloads
       }
       else
       {
          //Auswertung des fehlgeschlagenen Downloads
       }
    
       return 1;  //Thread beendet
    }
    

    Diese Funktion wurde mit Hilfe eines Buttons gestartet, der IDC_DOWNLOAD heißt. Dieser startet bei Click einen Thread und verändert seine Beschriftung so, dass er "Abbrechen" anzeigt. Der Suer kann also mit dem gleichen Button, mit dem er den Download gestartet hat, ihn auch wieder abbrechen!
    Dazu schreiben wir diesen Code:

    void CYourDlg::OnDownload()   //Behandlungs-Routine OnClicked für den Button
    {
       if(nClick == 0)
       {
          nClick = 1;
    
          SetDlgItemText(IDC_DOWNLOAD, "Abbrechen");
    
          nTerminate  = 0;
          nDownloadOK = 0;
    
          CWinThread* pThread = AfxBeginThread(DownloadFile,  //Funktion
                                               this,          //Zeiger auf dieses Fenster, also der Parameter
                                                              //der Funktion
                                               THREAD_PRIORITY_NORMAL);
       }
       else
       {
          nClick = 0;
    
          nTerminate = 1;  //Zeigt dem Thread, dass er abbrechen soll
    
          SetDlgItemText(IDC_DOWNLOAD, "Download starten");
       }
    }
    

    Der Code ist eine von Happosai verbesserte Version des Codes von Codeguru.

    [ Dieser Beitrag wurde am 15.11.2002 um 18:12 Uhr von dEUs editiert. ]

    [ Dieser Beitrag wurde am 30.06.2003 um 15:06 Uhr von dEUs editiert. ]


Anmelden zum Antworten