スクリーンセーバーを作ろう!
(2)インターネットからダウンロードする機能
さて、どうやってインターネットからファイルをダウンロードするのでしょう?
socket()を使ってhttpプロトコル自作して・・・
しません!(^^;;;
実はこれもAPIが用意されています。
ライブラリ wininet.lib を使います。
手順はこんな感じ。
(1)InternetOpen() でInternet APIを準備する。
(2)InternetOpenUrl() で接続するURLをOPENする。
(3)InternetReadFile() でファイルを読み込む。


う〜む。簡単ですねぇ〜(^^;;;
じゃあ、実際にプログラムを見てみましょう!
MakeWorkFile()
http://homepage1.nifty.com/mou-usshisshi/sub3.htm
ダウンロードしてくるルーチンです。
mouget.cppの一部
int
MakeWorkFile()
{
    FILE *fp;
    HINTERNET hSession;
    HINTERNET hService;

    char    buff[1024] ;
    char    urlbuff[1024] ;
    char    szText[256] ;

    // Temp ディレクトリの取得
    GetTempPath( sizeof( buff ), buff ) ;
    GetPrivateProfileString(szAppName, MOU_KEY_DIR, buff, szText, sizeof(szText), szIniFile);
    sprintf( WorkFile, MOU_FRM_FILE, szText, SUB3 ) ;
    WritePrivateProfileString(szAppName, MOU_KEY_DIR, szText, szIniFile);

    // API の準備
    hSession = InternetOpen( "Mou", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
    if( hSession == 0){
        return( 0 ) ;
    }

    // URL のOPEN
    sprintf( urlbuff, "%s%s", BASEURL, SUB3 ) ;
    hService = InternetOpenUrl( hSession, urlbuff, NULL, 0, 0, 0 );
    if( hService == 0 ){
        InternetCloseHandle(hSession);
        return( 0 ) ;
    }

    // ローカルファイルのオープン
    if( (fp=fopen(WorkFile, "wb")) == NULL ){
        InternetCloseHandle(hSession);
        return( 0 ) ;
    }
    while( 1 ) {
        char lpBuffer[1024+1];
        DWORD dwBytesRead = 1024;
        int    i ;

        // ファイルの読込み
        InternetReadFile( hService, lpBuffer, 1024, &dwBytesRead );
        if( dwBytesRead == 0 ) break;
        for ( i = 0; i < 1024 ; i++ ) {
            if ( lpBuffer[i] == NULL ) break ;
            if ( lpBuffer[i] == EOF ) break ;
            if ( lpBuffer[i] == 0x0a )  {
                fputc( 0x0d, fp ) ;
            }
            fputc( lpBuffer[i], fp ) ;
        }
        memset( lpBuffer, 0, 1024+1 ) ;
    }

    // Close 処理
    fclose(fp);
    InternetCloseHandle(hService);
    InternetCloseHandle(hSession);
    return( 1 ) ;

}

hSession = InternetOpen( "Mou", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
でAPIの準備をしますが、
INTERNET_OPEN_TYPE_PRECONFIGアクセスタイプ指定していて、
意味は
「プロキシまたはレジストリから直接コンフィギュレーションを取得する。」
です。
INTERNET_OPEN_TYPE_DIRECTなんてのもあるみたいです。
直接ダウンロードにいくのね。
でもまぁ一般的には上の方がいいんじゃない?
それかソフト設定で変えられるようにするとかね。d(^^;;;


hService = InternetOpenUrl( hSession, urlbuff, NULL, 0, 0, 0 );
ここでURL開きます
urlbuff
sprintf( urlbuff, "%s%s", BASEURL, SUB3 ) ;
で作られてますね。
ちなみ
#define BASEURL "http://homepage1.nifty.com/mou-usshisshi/"
#define SUB3 "sub3.htm"

と宣言されてますね。
なので
urlbuffの中身は"http://homepage1.nifty.com/mou-usshisshi/sub3.htm"ということになります。


InternetReadFile()
実際に"http://homepage1.nifty.com/mou-usshisshi/sub3.htm"
内容ダウンロードしてきます
fputc()で1バイトずつローカルファイルに書き込んでいます。
なぜに1バイトずつかというと・・・
if ( lpBuffer[i] == 0x0a )  {
    fputc( 0x0d, fp ) ;
}
ダウンロード後のこのif文は・・・(^^;;;
改行コードWindows用合わせています・・・
なので、1バイトずつ書き出す必要あったりします。
なぜに改行コードを変えているかというと
実はタグ解析する時に1行ずつ読み込む必要があったからです・・・

で、ダウンロードが終わったら
InternetCloseHandle()各ハンドルの後始末をしておしまいです。d(^^;;;

う〜む。簡単ですねぇ〜

←前へ →次へ