antenn-a
company profile

MFC航海日記 二十四日(表示ルーチンの実装)

さて、今回は前回解説した設計の実装編である。

やり方は・・・実は簡単だったりするのですが、サンプル載せて以上終わりではあまりにも酷いので一応解説をあわせます。

prev

まず、表示させたいウィンドウのWM_PAINTを捕まえます。(要はclass wizでWM_PAINTをオーバーライドします) オーバーライドしたならば、ここで必要な変数を定義します。

必要なのは、 CRect, CDC, CBitmap CBitmap* の四つである。 それぞれ、
CRect.....表示するウィンドウのサイズ
CDC.......メモリDCになる
CBitmap...メモリ上に作成するキャンパス
CBitmap*..ビットマップのバックアップ

となる。

表示するサイズを測り、メモリ領域にキャンパスを作り、作った時にバックアップを取っておく。 作ったキャンパスにあれこれ書き込んでビット転送して表示する。

このような流れ作業になる。

prev

void EMemColorWnd::OnPaint() 
{
    CPaintDC    dc(this); // 描画用のデバイス コンテキスト
    CRect       rct;
    CDC         memDC;
    CBitmap     memBmp;
    CBitmap*    backup;
    CSize size;
    
    //表示サイズを測る
    GetClientRect( rct );
    //CPaintDCとリンクするようなビットマップの作成
    memBmp.CreateBitmap( rct.Width(), rct.Height(),10, 1, NULL );

    //CPaintDCとリンクするようなDCの作成(メモリDCの作成)
    memDC.CreateCompatibleDC( &dc );
    //メモリDCとビットマップの関連付けと、バックアップの作成
    backup = memDC.SelectObject( &memBmp );

    //メモリDCに対して背景色の塗りつぶし(FillRectよりも速度は速い(らしい))
    memDC.FillSolidRect( rct, RGB( 0, 0, 0 ) );
    //テキストエリアの背景を設定
    memDC.SetBkColor( RGB( 0, 0, 0 ) );
    //テキスト色を設定
    memDC.SetTextColor( RGB( 255, 255, 255 ) );
    
    //現在選択されているフォントのサイズを計測
    size = memDC.GetTextExtent( CString( "あ" ) );
    メモリDCに対して書き込み
    memDC.TextOut( 5, 5, "この文章はテストです" );
    memDC.TextOut( 5, 5 + size.cy, "こちら側は、メモリDCで出力しています。" );

    //画面に対してビット転送
    dc.BitBlt( 0, 0, rct.Width(), rct.Height(), &memDC, 0, 0, SRCCOPY );

    //バックアップを元に戻す。
    memDC.SelectObject( backup );
    //ビットマップの消去
    memBmp.DeleteObject();
    //メモリDCの破棄
    memDC.DeleteDC();
    
    // 描画用メッセージとして CWnd::OnPaint() を呼び出してはいけません
}

prev

本来は、メモリDCをいちいち作るのではなくてメンバとして持っておく事が速度を上げる方法なのだが、サンプルとして分かりづらくなると思った為、ここでは関数内にスコープを置くようにした。

このようにしてメモリDCを使った表示は非常に早いので活用すべきだと思う。

今回のサンプルはここからダウンロードできる。このサンプルでは速さを体感できないが、ダウンロードしたファイルに手を加えてColor Makerもどきを作ってみれば体感できるだろう。


antenn-a

prev next


antenn-a