Mesoscopic Programming

タコさんプログラミング専門

Programming Tips #13 画像表示のちらつき対策

ウィンドウサイズ変更時の画像表示のちらつきをなくす

画像描画時に背景をクリアしなければちらつかないのだが、アイコン表示などで背景が透明の画像はごみが残ってしまうのでどうしても背景をクリアする必要がある。
そこで背景をクリアして画像を描画したビットマップを作成して、再表示の際にこれをデバイスにベタコピーすればちらつかずに済むのだ。

INT     docWidth  = 0;
INT     docHeight = 0;
HBITMAP hBitmap   = NULL;

VOID Load( LPCTSTR path )
{
    HDC      hdc   = GetDC( hwnd );
    HDC      hdc2  = CreateCompatibleDC( hdc );
    HBRUSH   hbrBg = CreateSolidBrush( GetBkColor( hdc ) );
    WCHAR    wpath[ _MAX_PATH ];
    Image    * image;
    RECT     rc;
    Graphics * gg;

    MultiByteToWideChar( CP_ACP, 0, path, -1, wpath, sizeof wpath / sizeof ( WCHAR ) );

    image     = new Image( wpath );
    docWidth  = image->GetWidth();
    docHeight = image->GetHeight();
    hBitmap   = CreateCompatibleBitmap( hdc, docWidth, docHeight );

    SelectObject( hdc2, hBitmap );

    GetClientRect( hwnd, & rc );

    FillRect( hdc2, & rc, hbrBg );

    gg = Graphics( hdc2 );

    gg.DrawImage( image, 0, 0, docWidth, docHeight );

    delete gg;
    delete image;

    DeleteObject( hbrBg );
    DeleteDC( hdc2 );
    ReleaseDC( hwnd, hdc );
}

VOID OnWmPaint()
{
    PAINTSTRUCT ps;
    HDC         hdc  = BeginPaint( hwnd, & ps );
    HDC         hdc2 = CreateCompatibleDC( hdc );
    INT         x    = - GetScrollPos( hwnd, SB_HORZ );
    INT         y    = - GetScrollPos( hwnd, SB_VERT );

    SelectObject( hdc2, hBitmap );

    BitBlt( hdc, x, y, docWidth, docHeight, hdc2, 0, 0, SRCCOPY );

    DeleteDC( hdc2 );

    EndPaint( hwnd, & ps );
}

VOID OnWmDestroy()
{
    DeleteObject( hBitmap );
}
解説

これでちらつかないだろ。

以上。