> この関数、結構便利だと思います。
> Function C_DC_C_BMP(ByRef hDC As Long,ByRef hBmp As Long,x As Long,y As Long,hWnd As Long)As Long
惜しい..せっかくここまでやったのなら、もうちょっと頑張ってみましょう!
例えば、ウィンドウ情報(ウィンドウハンドル)を初めに取得しておき、
そこからグローバルでコンパチなデバイスコンテキストを作ります。
ビットマップとかを描画する目的なので、
初めからグローバルなビットマップも作り、対応付けておきましょう。
コード: 全て選択
Dim hGlobalDC As HDC
Dim hGlobalBmp As HBITMAP
Dim hGlobalOldBmp As HBITMAP
Sub GetGlobalDC( ByVal hWnd As HWND)
Dim hdc As HDC
Dim sx As Long
Dim sy As Long
sx = GetSystemMetrics(SM_CXSCREEN)
sy = GetSystemMetrics(SM_CYSCREEN)
hdc = GetDC(hWnd)
hGlobalDC = CreateCompatibleDC(hdc)
hGlobalBmp = CreateCompatibleBitmap( hdc, sx, sy)
hGlobalOldBmp = SelectObject( hGlobalDC, hGlobalBmp)
ReleaseDC( hWnd, hdc)
End Sub
受け取りに必要な情報は、
・絵が結び付けられたデバイスコンテキスト
・絵のオブジェクトを指すビットマップハンドル
・絵のサイズ
の3つですよね?
これらを構造体、もしくはクラスのメンバ変数にしてしまいましょう。
コード: 全て選択
Type GDIBMP
hBmp As HBITMAP
hoBmp As HBITMAP
hDC As HDC
cx As Long
cy As Long
End Type
いよいよ要のビットマップロードですが、
とりあえずファイルからの例を示します。
この関数は上記のGetGlobalDC関数で指定したウィンドウに対してのみ
描画を行う前提で作ってしまいます。
返すのはもちろん、先ほど作ったGDIBMP構造体です。
..が、戻り値では返せませんので、引数に書く事にします。
なお、サイズはloadBmp関数内で自動取得しています。
コード: 全て選択
Sub loadBmp( ByRef gb As GDIBMP, ByVal cFileName As BytePtr) As Long
Dim lpBmp As BITMAP
gb.hDC = CreateCompatibleDC(hGlobalDC)
gb.hBmp = LoadImage(NULL,cFileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
gb.hoBmp = SelectObject( gb.hDC, gb.hBmp)
GetObject( gb.hBmp, SizeOf(BITMAP), lpBmp)
gb.cx = lpBmp.bmWidth
gb.cy = lpBmp.bmHeight
End Sub
GDIBMP構造体で受けたのなら、このまま渡して描画できると便利ですね。
コード: 全て選択
Sub betaDraw( ByRef gb As GDIBMP, ByVal x As Long, ByVal y As Long)
BitBlt( hGlobalDC, x, y, gb.cx, gb.cy, gb.hDC, 0, 0, SRCCOPY)
End Sub
これだけだとグローバルでコンパチなデバイスコンテキストに描画しているだけなので、
今度はグローバルでコンパチなデバイスコンテキストからウィンドウに描画を行います。
一見面倒ですが、実はこうする事でチラツキを最小限に抑えられます。
何故なら、グローバルでコンパチなデバイスコンテキスト(長い..--;)に散々ビットマップを描画しまくってから、
ウィンドウには最終形だけを貼り付けることになるためです。
以下のコードをPaintイベント内に記述してください。
コード: 全て選択
Dim sx As Long
Dim sy As Long
sx = GetSystemMetrics(SM_CXSCREEN)
sy = GetSystemMetrics(SM_CYSCREEN)
BitBlt( hDC, x, y, sx, sy, hGlobalDC, 0, 0, SRCCOPY)
※sx,syの値も最初に保存しておくとベターでしょう
これで、betaDraw関数を散々実行した後にInvalidateRect関数(API)を実行すれば、
チラツキも最小限の美しい描画が行えます。
最後に、これらの関数はメモリ領域を贅沢に使っていますので、
これら全てを開放していく必要があります。
コード: 全て選択
'■ビットマップの開放
Sub freeBmp( ByRef gb As GDIBMP)
SelectObject( gb.hDC, gb.hoBmp)
DeleteObject(gb.hBmp)
DeleteDC(gb.hDC)
End Sub
'■グローバルなやつらを解放
Sub GlobalDCFree()
SelectObject( hGlobalDC, hGlobalOldBmp)
DeleteObject(hGlobalBmp)
DeleteDC(hGlobalDC)
End Sub
※この辺はDestroyイベント辺りに置いておけば良いでしょう
..いかがでしょうか?
ちなみにこのロジックをライブラリ化したのが
以前私が公開したLDGDIになります。
http://www50.tok2.com/home/losedog2/download.htm#ABLIB
※もちろん、こちらはもうちょっと強化されています
使い慣れるとGDIの理解が難しくなりますので、
勤勉な初心者の方にはオススメしませんが..