ホームに戻る
 18、描画

描画にはデバイスコンテキストというものを使用します。
デバイスコンテキストの管理はOSが行うので、
描画の際に用いるメモリ領域のことを気にする必要は無く、
プログラムではこのデバイスコンテキストに対して描画APIを用いる
というような形になってきます。
デバイスコンテキストの取得は以下のように
対象となるウィンドウハンドルを渡して行う。

HDC GetDC(HWND hWnd);

失敗すると NULL を返す。
使い終わった場合には解放する必要がある。

int ReleaseDC(HWND hWnd , HDC hDC);

解放されないと 0 を返す。

描画に際しては以上のデバイスコンテキストに行えばよいのですが、
描画と更新は区別され描画だけでは更新が行われません。
更新は WM_PAINT メッセージでの処理で行います。

更新するためには WM_PAINT を呼べば良いわけですが、
プログラム側から SendMessage などで MW_PAINT を送ってはいけません。
WM_PAINT は特殊なメッセージでプログラム側から呼ぶことができません。
例えばプログラムを実行してからウィンドウを一度隠し、
再びウィンドウを表示する際に WM_PAINT はキューに呼ばれます。
再描画が必要な時に自動的に呼び出されるのが WM_PAINT です。
もしプログラム側から更新をしたい場合には無効領域というものを定めます。
無効領域の指定に InvalidateRect というAPIを用います。
対象となるウィンドウのハンドル、更新領域、背景消去の有無を指定。

BOOL InvalidateRect(HWND hWnd , CONST RECT *lpRect , BOOL bErase);

ウィンドウハンドルは NULL で全ウィンドウが対象になる。
更新領域は NULL で指定したウィンドウ全体が対象になる。
背景消去は TRUE で一旦画面をクリアする。FALSE で上書きになる。

無効領域を指定すると WM_PAINT メッセージがキューに呼ばれます。
無効領域はリージョンで指定することもできます。
リージョン指定の場合は InvalidateRgn を用います。
キューを通したくない場合は無効領域を指定して UpdateWindow を用います。

更新の処理は以下の例のように BeginPaint と EndPaint を用います。
下の例でたとえ「描画」のところで何もしていなくても、
更新するという意味で BeginPaint と EndPaint に意味はあります。
もちろんここで描画を行っても問題はありません。

HDC hdc;
PAINTSTRUCT ps;

case WM_PAINT:
hdc = BeginPaint(hWnd , &ps);
// 描画
EndPaint(hWnd , &ps);
return 0;

注意する点は WM_PAINT 内で GetDC を呼ばないこと。
WM_PAINT 内で GetDC を得て描画しても無効領域は更新されません。
逆に WM_PAINT 以外の描画では必ず GetDC を呼ぶようにします。

inserted by FC2 system