スクリーンセーバーを作ろう!
(4)画像を表示する機能
前章では、画像のファイル名得る方法の説明をしました。
で、画像のダウンロードは、その名前を元に(2)の方法ダウンロードします。
その部分の説明は省略させて頂きます。m(_ _)m
あとでソースをみて、ああ、ここでダウンロードしているのか?
ってのを、確認してみてください。
で、今回はダウンロードしてきた画像ファイルの表示です。
ダウンロードはもうしてあるので、あとは表示部分ですね。
ファイルをオープンして表示する方法です。

まずはファイルを読み込むルーチンです。
mouget.cppの一部

int
ReadImg()
{
    int        i = 0 ;
    char    buff[1024] ;
    char    filebuff[1024] ;
    char szTemp[32];
    char szText[256];

    IStream        *iStream ;
    BOOL        ret;
    DWORD        nReadByte;
    DWORD        nFileSize;
    HANDLE        hFile;

    GetTempPath( sizeof( buff ), buff ) ;
    GetPrivateProfileString(szAppName, MOU_KEY_DIR, buff, szText, sizeof(szText), szIniFile);

    while( 1 ) {
        sprintf( filebuff, MOU_FRM_GIF, szText, i ) ;

        // ファイルのオープン
        hFile = CreateFile(filebuff, GENERIC_READ, 0, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

        if(hFile == INVALID_HANDLE_VALUE) {
            // 読み込み失敗
            break ;
        }

        // ファイルサイズの取得
        nFileSize = GetFileSize(hFile, NULL);
        // 読み込み用のバッファの確保
        hGlobal[i] = GlobalAlloc(GPTR, nFileSize);

        // ファイルの読み込み
        ret = ReadFile(hFile, hGlobal[i], nFileSize, &nReadByte, NULL);
        if ( ret == 0 ) {
            // 読み込み失敗
            return( 0 ) ;
        }
        CloseHandle(hFile);

        // iStream作成
        CreateStreamOnHGlobal(hGlobal[i], TRUE, &iStream);
        // iPictureに割り付け
        OleLoadPicture(iStream, nFileSize, TRUE, IID_IPicture, (LPVOID*)&iPicture[i]);
        iStream->Release() ; 
        i ++ ;
        if ( i == 10 ) break ;
    }
    if ( ImgCnt != i ) {
        ImgCnt = i ;
        wsprintf(szTemp, "%d", ImgCnt);
        WritePrivateProfileString(szAppName, MOU_KEY_IMGCNT, szTemp, szIniFile);
    }
    if ( ImgCnt == 0 ) {
        return( 0 ) ;
    }
    return( 1 ) ;
}
む〜ん。スンマセン・・・説明できるほど、グラフィック系詳しくないです。m(_ _)m

CreateFile() で画像ファイルをオープンします。
GetFileSize()で画像サイズを得てファイルを読み込む領域をGlobalAlloc()で確保します。
ReadFile() で画像データを読み込みCreateStreamOnHGlobal() で iStream に割り付けます
OleLoadPicture() で、iPicture に変換します。
んんん?なんのこっちゃ???
おいらも最後の方はちょっとわかんないっす・・・(^^;;;
まぁお決まりの手順だと思ってやってみるとあら不思議?表示出来ちゃうんですねぇ〜

んで、表示は簡単

iPicture->Render(hDC, x, y, dx, dy, 0, cy, cx, -cy, NULL);

とやるだけ・・・
スンマセン。これも理解していません・・・m(_ _)m

表示するルーチンは以下の感じです。
mouget.cppの一部

void
ImagePut( HWND hWnd, int x, int y ) 
{
    HDC            hDC;
    OLE_XSIZE_HIMETRIC cx;
    OLE_YSIZE_HIMETRIC cy;
    int cxPerInch ;
    int cyPerInch ;
    long        dx, dy ;

    if ( iPicture[ImgNum] != NULL ) {
        hDC = GetDC(hWnd);
        iPicture[ImgNum]->get_Width(&cx);
        iPicture[ImgNum]->get_Height(&cy);

        cxPerInch = GetDeviceCaps(hDC,LOGPIXELSX);
        cyPerInch = GetDeviceCaps(hDC,LOGPIXELSY);

        dx = MulDiv(cx,cxPerInch,HIMETRIC_INCH) ;
        dy = MulDiv(cy,cyPerInch,HIMETRIC_INCH) ;

        // 画像の表示
        iPicture[ImgNum]->Render(hDC, x, y, dx, dy,  0, cy, cx, -cy, NULL);
        ReleaseDC(hWnd, hDC);
    }
}
xy表示する座標を指定します。
呼び元で乱数xy を求めてこのルーチン呼び出します。
GetDeviceCaps() とか MulDiv() ってのは画像の縦横サイズ
ピクセル変換しています。

まぁ理解してなくても、手順通りやっておけば表示できるってことです・・・
フォローになってない・・・
このルーチンだと、やったことないけど、jpg とかも表示できるらしい。
というか gif の表示自体がイレギュラーらしいんですが・・・
著作権の問題があるとか・・・
まぁまぁ特に特殊なロジックを書いたわけでないので
著作権的には大丈夫でしょう・・・多分・・・




って感じで、
これらの処理組み合わせるスクリーンセーバー出来上がりとなります。
お粗末なプログラムでスンマセンでした。
あ、説明もお粗末でしたね。スンマセン。m(_ _)m
全ソースはこちらです。

←前へ ↑TOPへ