では、少しずつ変化する絵を描くにはどうしたらよいか。要するに、プログラム側 で、今までどんな絵を書いたか覚えておけば良いわけです。そのやりかたとして、 たとえば"どんな描画コマンドをどんな順序で発行したか覚えておく"というやりかた が一つあります。これはCAD系ソフトなどで使われています。メタファイルという のも、この実現手段として使われます。
しかし、もっと単純な方法があります。要は、絵そのものを覚えておけば良いわけ です。つまり、ビットマップとして記憶します。このためには、メモリデバイスコ ンテキストを使います。メモリDCとは、スクリーンDCもしくはプリンタDCとコンパ チブルなように、メモリ上に作られた仮想的なDCであり、ここに描画しても、当然 それだけでは画面にもどこにも出ません。適切なタイミングでスクリーンDC等に コピーする必要があります。
例として、乱数を使って線を引き続けるプログラムを作成します。要点だけ説明します。
まず、WM_INITDIALOGのタイミングで以下を実行します。
hdc=GetDC(hDlg);/*スクリーンDCを取得*/ hMemDC = CreateCompatibleDC(hdc); /* スクリーンDCとコンパチブルなメモリDCを作成 */ hDDBitmap = CreateCompatibleBitmap(hdc, XDISP, YDISP); /* DDBを作成 */ hOldBitmap = (HBITMAP)SelectObject(hMemDC, hDDBitmap);/*メモリDCにDDBを選択*/ ReleaseDC(hDlg, hdc);DDBとは、デバイスにどっぷり依存したビットマップです。つまり色数は画面モード と共通であり、サイズはCreateCompatibleBitmap()の引数で指定した通りになります。
あとは、これを塗りつぶしたり
BitBlt(hMemDC, 0, 0, XDISP, YDISP, NULL, 0, 0, WHITENESS);線を引いたりするのは、好きなタイミングでできます。
LineTo(hMemDC, rand()%XDISP, rand()%YDISP);WM_PAINTが来たら、メモリDCの内容をスクリーンDCにコピーします。
case WM_PAINT: hdc = BeginPaint(hDlg, &ps); BitBlt(hdc, 0, 0, XDISP, YDISP, hMemDC, 0, 0, SRCCOPY); EndPaint(hDlg, &ps);メモリDCが必要なくなったら削除します。
SelectObject(hMemDC, hOldBitmap); DeleteDC(hMemDC); DeleteObject(hDDBitmap);これを忘れると、システムリソースがどんどん減っていきます。
実行結果
#define chgsize(hwnd,x,y) SetWindowPos(hwnd,NULL,0,0,x,y,SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE)のようなマクロ定義をして、これを使っています。
ただし、読み込んだドキュメントのサイズに自動的に合わせるような機能は、 つけないほうが良いと思います。たとえば次回BMPファイルのビュアーを作りますが、 読み込んだBMPのサイズにあわせてダイアログのサイズを自動で変更した場合、 BMPが1*1ドットのような極端に小さい場合、もしくは10000*10000ドットみたいに 極端に大きなファイルを読んだ場合どうなるでしょうか?
その1とその3の組合せというのも考えられますね。 (ユーザーにサイズ変更させ、そのサイズを取得する)
一つ上のページに戻る