ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2018年10月23日(火) 00:19

All times are UTC+09:00




新しいトピックを投稿する  トピックへ返信する  [ 2 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2005年7月18日(月) 00:33 
オフライン

登録日時: 2005年7月17日(日) 09:36
記事: 36
住所: 千葉県松戸市
この関数、結構便利だと思います。
コード:
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 hOrgDC As Long
	hOrgDC=GetDC(hWnd)
	hDC=CreateCompatibleDC(hOrgDC)
	hBmp=CreateCompatibleBitmap(hOrgDC,x,y)
	SelectObject(hDC,hBmp)
	ReleaseDC(hWnd,hOrgDC)
EndFunction
解説
hDC
デバイスコンテキストのハンドルを指定します。
hBmp
ビットマップのハンドルを指定します。
x
ビットマップの幅を指定します。
y
ビットマップの高さを指定します。
hWnd
どのウィンドウのクライアント領域に対するデバイスコンテキストかを指定します。
使用法
コード:
Dim hDC As Long
Dim hBmp As Long
C_DC_C_BMP(hDC,hBmp,100,100,hMainWnd)

'---描画処理---

'---不要になったら破棄---
DeleteObject(hBmp)
DeleteDC(hDC)


通報する
ページトップ
投稿記事Posted: 2005年7月19日(火) 22:53 
オフライン

登録日時: 2005年7月03日(日) 10:37
記事: 27
住所: 愛知県岡崎市
> この関数、結構便利だと思います。
> 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の理解が難しくなりますので、
勤勉な初心者の方にはオススメしませんが..

_________________
# まけイヌ (losedog2)
# Home : http://www50.tok2.com/home/losedog2/
# Mail : losedog2@yahoo.co.jp


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 2 件の記事 ] 

All times are UTC+09:00


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[1人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by KONISHI Yohsuke