ページ 11

デバイスコンテキストの使い方

Posted: 2007年3月03日(土) 22:54
by のぶあや
デバイスコンテキストを作成してそこに描画を行い、
それをウィンドウに描画したいのですが、上手くいきません。

コード: 全て選択


Sub MainWindow_Paint(hDC As HDC)
	BackGround(hDC)
End Sub

Sub BackGround(hDC As HDC)

	'描画領域の取得
	Dim rc As RECT
	GetClientRect(hMessageWindow, rc)

	'デバイスコンテキストの準備
	Dim hMemDC As HDC, hBmp As HBITMAP
	hMemDC=CreateCompatibleDC(hDC)
	hBmp=CreateCompatibleBitmap(hMemDC, rc.right, rc.bottom)
	SelectObject(hMemDC, hBmp)

	'ここでhMemDCに対し描画を行う

	'ウィンドウに描画
	BitBlt(hDC, 0, 0, rc_Total.right, rc_Total.bottom, hDC_buf, 0, 0, SRCCOPY)

	'オブジェクトを解放
	DeleteObject(hBmp)
	DeleteDC(hDC_buf)

End Sub
MainWindow_Paint(hDC As HDC)で送られてきたhDCや
GetDCなどで取得したウィンドウのデバイスコンテキストに
直接描画することは出来るのですが、
デバイスコンテキストを作成して描画ということができません。
おそらくビットマップオブジェクトの扱いがおかしいと思うのですが
どうすればいいのでしょうか?

また、今回のようにデバイスコンテキストとオブジェクトを作成して
解放する際の手順についても教えていただけるとありがたいです。
例えば
1.DC(デバイスコンテキスト)を作成
2.Object1を作成、DCに設定
3.Object2を作成、DCに設定
とした場合の解放手順は
・DC -> Object1 -> object2
・Object2 -> Object1 -> DC
のどちらがいいのでしょうか?

Posted: 2007年3月03日(土) 23:39
by イグトランス
CreateCompatibleBitmapにメモリデバイスコンテキストを渡すのではなく,この場合はウィンドウデバイスコンテキスト(ここでは変数hDC)を渡すようにしてみてください。作ったばかりのメモリDCに互換のビットマップを作っても,それはモノクロビットマップとなってしまうのです。
CreateCompatibleBitmap - MSDNライブラリ
またSelectObjectはそれまで選択されていたオブジェクトへのハンドルを戻り値として返しますが,それをとっておき後でSelectObjectして元に戻すというのが一般的です。また,DeleteObjectはデバイスコンテキストに選択された状態のオブジェクトを削除できないため,DeleteObjectで削除する必要のあるオブジェクトを使用している場合は特に大事です。逆にそれさえ守られていれば削除する順番はそう重要ではありません。

それを踏まえると,たとえばこういう風になります。

コード: 全て選択

Dim hMemDC As HDC, hBmp As HBITMAP, hbmpOld As HBITMAP
hMemDC = CreateCompatibleDC(hDC) 
hBmp = CreateCompatibleBitmap(hDC, rc.right, rc.bottom) 
hbmpOld = SelectObject(hMemDC, hBmp) As HBITMAP

' ...

SelectObject(hMemDC, hbmpOld)
DeleteObject(hBmp)
DeleteDC(hMemDC)
これでどうでしょうか。

Posted: 2007年3月04日(日) 01:00
by のぶあや
CreateCompatibleBitmapにhDCを渡したら上手く描画できました。
イグトランス (egtra) さんが書きました:またSelectObjectはそれまで選択されていたオブジェクトへのハンドルを戻り値として返しますが,それをとっておき後でSelectObjectして元に戻すというのが一般的です。
GetDCなどで取得したデバイスコンテキストのオブジェクトを変える際は戻してましたが、
今回のように作成したばかりのデバイスコンテキストは何もオブジェクトが選択されてない「まっさらな状態」な物だと思い込んでいました(汗

また、作成したオブジェクトは以前のオブジェクトに戻してからなら解放する手順は関係ないんですね。

御回答ありがとうございました。