C++、C#、VC、JAVA、Androidプログラミングを初歩的なことから書いていきます。
ダブルバッファリング
GUIにおいて、動的に描画を変化させた場合が多々あります。しかし、普通に描画内容を変更し、再描画をすると、チラツキが生じてしまいます。
そこで、ダブルバッファリングという技術を使用します。以下がそのソースとなります。
//ビューア
void CViewerDlg::myViewer(){
//白色ブラシ
CBrush br_white;
br_white.CreateSolidBrush(RGB(255,255,255));
//デバイスコンテキスト
CDC* pDC;
//仮想デバイスコンテキスト用ビットマップ作成
CBitmap memBmp;
//仮想デバイスコンテキスト作成
CDC memDC;
//仮想デバイスコンテキストにビットマップ設定
CBitmap* memOldBmp;
//元のブラシをoldbrに保持
CBrush* oldbr;
pDC = mPict.GetDC();
//PictureControlの大きさ取得
mPict.GetClientRect(&mRect);
//仮想デバイスコンテキスト作成
memDC.CreateCompatibleDC(pDC);
//仮想デバイスコンテキスト用ビットマップ作成
mMemBmp.CreateCompatibleBitmap(pDC,mRect.Width(),mRect.Height());
//仮想デバイスコンテキストにビットマップ設定
memOldBmp=memDC.SelectObject(&memBmp);
//元のブラシをoldbrに保持
oldbr=memDC.SelectObject(&br_white);
//ブラシを白色にする
memDC.SelectObject(&br_white);
//背景を白にする
memDC.Rectangle(&mRect);
//----------------------------------------------------------
//----------------ここに描画メソッドを書く------------------
//----------------------------------------------------------
//----------------------------------------------------------
//-----------------------ここまで---------------------------
//----------------------------------------------------------
//描画
BitBlt(pDC->GetSafeHdc(),0,0,mRect.Width(),mRect.Height(),memDC.GetSafeHdc(),0,0,SRCCOPY);
//元のブラシに戻す
memDC.SelectObject(oldbr);
//仮想デバイスコンテキストのビットマップを初期化
memDC.SelectObject(memOldBmp);
//仮想デバイスコンテキストのビットマップを廃棄
DeleteObject(memOldBmp);
DeleteObject(memBmp);
DeleteObject(oldbr);
DeleteDC(memDC);
ReleaseDC(pDC);
}
今回の例では、ピクチャーコントロール(mPict)に対してのみ再描画を行うようになっています。画面全体を再描画したい場合は、
pDC = GetDC();
//PictureControlの大きさ取得
GetClientRect(&mRect);
としてください。最後に、42〜43行目の部分に描画内容を記述し、本メソッドを、
//描画メソッド
void CViewerDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 描画のデバイス コンテキスト
SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
// クライアントの四角形領域内の中央
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// アイコンの描画
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CPaintDC dc(this); // 描画のデバイス コンテキスト
myViewer();
CDialog::OnPaint();
}
}
このように使用すればダブルバッファリングが適応されます。ただし、タイマーなどを用いてmyViewer()メソッドを呼び出すか、WM_PAINTメッセージを発生させてください。
描画内容のメソッドの例は以下のものとなります。
//四角形の描写
void CViewerDlg::viewRectangle(CDC* memDC){
CBrush br_blue(RGB(128,128,255));
//色を指定
memDC->SelectObject(&br_blue);
memDC->Rectangle(0,0,50,50);
}