「ちらつき」を抑えてスクロール

BackBuffer Serface を取得して「ちらつき」を抑えてスクロールします。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. BackBuffer Serface を取得して「ちらつき」を抑えてスクロールします。
    hBackDC と hBackBitmap は BackBuffer Serface の定義です。
    HFONT hFont; はタイトルを表示するフォントを設定する領域です。
    S_POS はスクロールメッセージを制御する領域で、タイマ割り込みで「400~0」まで変化します。
    RECT はメッセージを描画する矩形領域の定義です。
    MsgTxt[] が表示するメッセージの定義です。
        /**********************************************/
        /*★ Message Scroll のプログラム    前田 稔 ★*/
        /**********************************************/
        #define     NAME    "Msg Scroll BackBuf"
        #include    <windows.h>
        #define     ID_TIMER    (WM_APP + 0)
        #define     WIDTH       640
        #define     HEIGHT      480
    
        HINSTANCE   g_hInst;
        HWND        g_hWnd;
        HDC         hBackDC= NULL;      //Back Buffer DC
        HBITMAP     hBackBitmap= NULL;  //Back Buffer HBitMap
        HFONT       hFont,hFontOld;
        int         S_POS= 400;
        RECT        RC= { 0, 0, WIDTH-1, HEIGHT-1 };
    
        LPSTR       MsgTxt[] =
        { "宇宙暦○△□×、宇宙連合とクリンゴンは1000",
          "年間に渡り宇宙の覇権争いを続けていた。",
          "近年宇宙連合の劣勢は覆いがたく、このまま行けば",
          "クリンゴンに征服される日も近い。",
          "そこで起死回生の秘策として温存されていた宇宙船",
          "エンタープライズを出動させることにした。"
        };
        
  2. CALLBACK 関数の WM_CREATE: です。
    CreateBuf(); で BackBuffer Serface を生成します。
    SetMyFont() でメッセージを表示するフォントを生成します。
    SetTimer() でタイマを起動してスクロールを開始します。
            case WM_CREATE:
                CreateBuf(hWnd);
                hFont = SetMyFont((LPCTSTR)"MS 明朝",26,0);
                SetTimer(hWnd,ID_TIMER,50,NULL);
                break;
        
  3. WM_TIMER: では S_POS が400から始まり、ゼロになるまでカウントダウンされます。
    WM_PAINT: から描画するとチラツクので、ここから View() 関数で描画しています。
            case WM_TIMER:
                if (S_POS)
                {   S_POS--;
                    View();
                }
                break;
        
  4. WM_KEYDOWN: では、ESC キーを検出してプログラムを終了します。
            case WM_KEYDOWN:            //KEY が押された
                switch(wParam)
                {   case VK_ESCAPE:     //ESC KEY
                        DestroyWindow(hWnd);
                        return 0L;
                }
                break;
        
  5. WM_DESTROY: ではタイマを停止して、リソースを開放して下さい。
    hBackDC, hBackBitmap も開放して下さい。
            case WM_DESTROY:
                KillTimer(hWnd,ID_TIMER);
                DeleteDC(hBackDC);
                DeleteObject(hBackBitmap);
                DeleteObject(hFont);
                PostQuitMessage(0);
                return 0L;
        
  6. BackBuffer Serface を生成する CreateBuf(); 関数です。
    メインウインドウと同じ形式の Buffer を、WIDTH, HEIGHT のサイズで生成します。
        void  CreateBuf(HWND hWnd)
        {   HDC     hDC;
    
            hDC= GetDC(hWnd);
            hBackDC= CreateCompatibleDC(hDC);
            //ウインドウと同じ画面生成
            hBackBitmap= CreateCompatibleBitmap(hDC,WIDTH,HEIGHT);
            SelectObject(hBackDC,hBackBitmap);
            ReleaseDC(hWnd,hDC);
        }
        
  7. メッセージを表示する View() 関数です。
    画面全体を BLACK_BRUSH でクリアします。
    TEXT の色とフォントを設定します。
    S_POS は400からカウントダウンされるので、この値を使って表示する行を設定します。
    hBackDC から hDC に一挙に転送することによりチラツキを抑えます。
        void  View()
        {   HDC     hDC;
            int     i;
    
            //裏画面をクリア
            FillRect(hBackDC,&RC,(HBRUSH)GetStockObject(BLACK_BRUSH));
            SetTextColor(hBackDC, RGB(255,115,0));
            SetBkMode(hBackDC,TRANSPARENT);
            hFontOld= (HFONT)SelectObject(hBackDC, hFont);
            for(i=0; i<6; i++)
                TextOut(hBackDC,20,(S_POS)+i*40,MsgTxt[i],strlen(MsgTxt[i]));
            SelectObject(hBackDC, hFontOld);
    
            hDC= GetDC(g_hWnd);
            BitBlt(hDC,0,0,WIDTH,HEIGHT,hBackDC,0,0,SRCCOPY);
            ReleaseDC(g_hWnd,hDC);
        }
        
  8. フォントの設定は 文字フォントを設定して描画する を参照して下さい。
    WinMain() では WIDTH, HEIGHT のサイズでウインドウを生成して表示します。
        g_hWnd= CreateWindow(NAME,NAME,WS_OVERLAPPEDWINDOW,
                100,100,WIDTH,HEIGHT,NULL,NULL,hInst,NULL);
        

【演習】

  1. プログラムを完成させて下さい。
  2. ページ先頭画面のように背景に画像を描画して、その上でメッセージをスクロールして下さい。
  3. Enter キーでスクロールを開始するようにプログラムして下さい。

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