W32 Image Scroll

背景画像をスクロールします。(1280*480 の画像を縮小表示しています)

前田稔の超初心者のプログラム入門

プログラムの説明

  1. [Windows デスクトップ アプリケーション] はメッセージループで描画する Win32 API に準じるプラットホームです。
    メッセージループで描画すると DirectX と同様に画像のスクロールやアニメーションが可能になります。
    シューティングゲームのように背景画像をスクロールしてみましょう。
    Visual Studio で [C++ Windows デスクトップ] のプロジェクトを作成します。
    プロジェクトの作成は W32 Hello を参照して下さい。
  2. WindowsProject1.cpp の修正です。
    タイマーを使うので ID_TIMER を定義します。
    struct で IMG 構造体を定義します。
    g_Pos は背景画像をスクロールしながら描画するオフセットです。
    #define ID_TIMER    (WM_APP + 0)
    
    typedef struct
    {   int     width,height;
        HBITMAP hBmp;
        HDC     hBmpDC;
    }   IMG;
    IMG         img;
    int         g_Pos= 0;
    
  3. 続いて LoadBMP() 関数をコーディングします。
    szBitmap で指定された画像ファイルをロードして IMG 構造体に設定します。
    //★ BitMap 画像をロードする
    HRESULT  LoadBMP(HWND hWnd, LPCWSTR szBitmap)
    {   HDC         hdc;
        BITMAP      bmp;
    
        img.hBmp= (HBITMAP)LoadImage(NULL,szBitmap,IMAGE_BITMAP,0,0,
                           LR_LOADFROMFILE|LR_CREATEDIBSECTION);
        if (img.hBmp==NULL)
        {   MessageBox(NULL,szBitmap,L"LoadBMP",MB_OK);
            return S_FALSE;
        }
    
        hdc = GetDC(hWnd);
        img.hBmpDC= CreateCompatibleDC(hdc);
        SelectObject(img.hBmpDC,img.hBmp);
        GetObject(img.hBmp,sizeof(BITMAP),&bmp);
        img.width = bmp.bmWidth;
        img.height = bmp.bmHeight;
        ReleaseDC(hWnd,hdc);
        return S_OK;
    }
    
  4. 背景画像のスクロールに使用する画像は、ページ先頭の[幅:1280, 高さ:480]で 640*480 の画像を横に2枚並べた大きさです。
    画像サイズに合わせてウインドウのサイズを 640*480 に設定します。(高さはタイトルバーを考慮して 520)
       HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          //CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
          0, 0, 640, 520, nullptr, nullptr, hInstance, nullptr);
    
  5. WindowsProject1.cpp の WM_CREATE: で背景画像をロードして、描画の準備を整えます。
    ページ先頭の utyu.bmp(縮小表示されている)を c:\tmp に格納して下さい。
    SetTimer() でタイマー割込みを開始します。
        switch(msg)
        {   case WM_CREATE:
                LoadBMP(hWnd,L"c:\\tmp\\utyu.bmp");
                SetTimer(hWnd,ID_TIMER,30,NULL);
                break;
    
  6. WM_TIMER: で画像のオフセット(g_Pos)を1ドットずつアップします。
    g_Pos が中央(640)になれば0に戻します。
    このとき背景画像が連続して見えるように utyu.bmp は作成されています。
    InvalidateRect() を実行すると WM_PAINT: が呼び出されて再描画されます。
            case WM_TIMER:
                g_Pos = (g_Pos + 1) % 640;
                InvalidateRect(hWnd, NULL, FALSE);    //クリアしない
                break;
    
  7. WM_PAINT: で背景画像をスクロールしながら描画します。
    元画像のX座標に g_Pos を使って1ドットずつスクロールします。
            case WM_PAINT:
                {
                PAINTSTRUCT ps;
                HDC hdc = BeginPaint(hWnd, &ps);
                // TODO: HDC を使用する描画コードをここに追加してください...
                BitBlt(hdc, 0, 0, 640, 480, img.hBmpDC, g_Pos, 0, SRCCOPY);
                EndPaint(hWnd, &ps);
                }
                break;
    
  8. WM_DESTROY: ではプログラムを終了する前に、タイマーを止めて IMG(構造体)の領域を解放して下さい。
            case WM_DESTROY:
                KillTimer(hWnd, ID_TIMER);
                DeleteObject(img.hBmp);
                DeleteDC(img.hBmpDC);
                PostQuitMessage(0);
                return 0L;
    
  9. x64 または x86 を選んで、右三角矢印(または F5 キー)でコンパイルします。
    プログラムを起動すると背景画像がスクロールしながら描画されます。
    メニューから[ファイル][終了する]を選ぶとプログラムが終了します。
    Windows デスクトップ アプリケーションは UWP のように自動的にメニューに登録されることは無いようです。
    プログラムは Win32 API に準じるようです。詳細は[超初心者のプログラム入門(C言語 Windows)]を参照して下さい。

超初心者のプログラム入門(C/C++)

超初心者のプログラム入門(C言語 Windows)