前回の記事(1)はこちら↓

https://ameblo.jp/devprogc15/entry-12674298187.html

 
class C*1 を定義。インターネットを開く関数だけを作成してある。
 
この記事では、インターネット上のテキストファイルを開いて読み込んでみる。
バイト列として取得。

 

宣言部分(コンストラクタなど一部略)

class C*2 : public C*1
{
protected:
    // 1. URL 上のテキストファイルを開く //
    static BOOL OpenURL(
                HINTERNET   hInternet       ,
                LPCTSTR     lpszURL         ,
                CByteArray& arrayBytes      ,
                int         nMaxByteToAbort
            ) ;
private:
    // 2-(1). (静的関数) (private) 全体を読み取り //
    static BOOL ReadFile(
                HINTERNET   hConnect ,

                CByteArray& arrayBytes
            ) ;
    // 2-(2). (静的関数) (private) 指定された長さだけ読み取り //
    static DWORD ReadBytes(
                HINTERNET   hConnect        ,
                DWORD       dwBufferSize    ,
                CByteArray& arrayResultRead
            ) ;
};

関数の中身は以下の感じ。 

// Macro //
#define DEFAULT_BUFFER_SIZE   1024

// 1. URL 上のテキストファイルを開く //
BOOL C*2::OpenURL(
                HINTERNET   hInternet ,
                LPCTSTR     lpszURL     ,
                CByteArray& arrayBytes    )
{

    // これは意味がわからない //

    TCHAR pszHeader[] = _T("Accept: */*\r\n\r\n") ;

    // 1. インターネット URL へのアクセス //
    /**************************************************
    HINTERNET InternetOpenUrl(
        IN HINTERNET hInternetSession,
        IN LPCSTR lpszUrl,
        IN LPCSTR lpszHeaders,
        IN DWORD dwHeadersLength,
        IN DWORD dwFlags,
        IN DWORD dwContext
    );
    Begins reading a complete FTP, Gopher, or HTTP URL.

    Use InternetCanonicalizeUrl first if the URL being used contains

    a relative URL and a base URL separated by blank spaces.
   **************************************************/
    // (1). 接続 //

    HINTERNET hConnect = ::InternetOpenUrl(
                            hInternet ,
                            lpszURL ,
                            pszHeader , // NULL でも良い //
                            -1 , // 自動で長さ判定 //
                            INTERNET_FLAG_DONT_CACHE ,
                            0
                        );
    // (2). 失敗した場合 //
    if(hConnect == NULL) return FALSE ;

    // 2. 全体を読み取り //
    BOOL bResult = ReadFile(hConnect , arrayBytes) ;

    // 3. 終了処理 //
    ::InternetCloseHandle(hConnect) ;

    return bResult ;
}

// 2-(1). (静的関数) (private) 全体を読み取り //
BOOL C*2::ReadFile(
                HINTERNET   hConnect  ,
                CByteArray& arrayBytes )
{
    CByteArray arrayResultRead ;


    // 1. 合計サイズ //
    DWORD dwTotalSize = 0 ;

    // 2. 読み取り //
    while(1)
    {
        // (1). 指定された長さだけ読み取り //
        DWORD dwResultReadSize = ReadBytes(
                         hConnect ,
                         (DWORD)DEFAULT_BUFFER_SIZE ,
                         arrayResultRead
                    ) ;

        // (2). 終了する場合 //
        if (dwResultReadSize == 0) break ;

        // (3). 合計サイズを加算 //
        dwTotalSize += dwResultReadSize ;

        // (4). バイト列を追加 //
        arrayBytes.Append(arrayResultRead) ;
    }

    return TRUE ;
}

// 2-(2). (静的関数) (private) 指定された長さだけ読み取り //
DWORD C*2::ReadBytes(
                HINTERNET   hConnect        ,
                DWORD       dwBufferSize    ,
                CByteArray& arrayResultRead   )
{
    DWORD dwResultReadSize = 0 ;

    // 1. 初期設定 //
    // (1). 配列を初期化 //

    arrayResultRead.SetSize(0) ;

    // (2). データ領域を確保 //
    BYTE* pcbBuffer = new BYTE[ dwBufferSize ] ;

    // 2. インターネット上のファイルからバイト列を読み取り //
    BOOL bRet = ::InternetReadFile(
                              hConnect ,
                              pcbBuffer ,
                              dwBufferSize ,
                              &dwResultReadSize
                          ) ;

    // 3. 成功した場合 //
    if (bRet && dwResultReadSize > 0)
    {
        // (1). 配列のサイズを確保 //
        arrayResultRead.SetSize( (int)dwResultReadSize ) ;

        // (2). 要素をコピー //
        // これ、何とかならなかったか? //

        for(int k = 0 ; k < (int)dwResultReadSize ; k++)
        {
              arrayResultRead.SetAt( k , pcbBuffer[k] ) ;
        }
    }

    // 4. メモリ解放 //
    delete pcbBuffer ;

    return dwResultReadSize ;
}

 

以上の感じ。

 

これで、どう使うか。

 

CByteArray arrayBytes ;

 

// ファイルを開いて読み取り //
// (1). インターネット開始 //
HINTERNET hInternet = C*1::InternetOpen() ;
if (hInternet == NULL) return ;

// (2). URL上のファイルデータを読み取り //
BOOL bResult = C*2::OpenURL(

                                  hInternet ,

                                  lpszURL ,

                                  arrayBytes

                               ) ;

// (3). 終了処理 //
::InternetCloseHandle(hInternet) ;

 
 
最終的に、こんな自動アップデートを目指します。
(Google Chrome や Firefox などのように)
 
 
 
 
**************************************************************