Win32 App Painting the Window - yoshimune/LearningDirectX11 GitHub Wiki
This page refers to 【Painting the Window】
ウィンドウの作成は完了しました。何か表示したいところです。Windowsの用語では、ウィンドウペインティングと呼ばれています。
時々、プログラムがウィンドウの外観を更新するためにペイントを開始することがあります。一方、OSはウィンドウの一部を再描画するよう通知します。このとき、OSはウィンドウに対してWM_PAINTメッセージを送信します。書き換えるウィンドウの一部は更新領域と呼ばれます。
ウィンドウが最初に表示されたとき、ウィンドウのクライアントエリア全体がペイントされます、したがって、少なくとも1つのVM_PAINTは常に受け取っています。タイトルバーが含まれるフレームの周囲はOSにより自動でペイントされます。クライアントエリアのペイントが完了した後、更新領域をクリアします。これによりなにか変更があるまで別のVM_PAINTメッセージを送信する必要が無いことがOSに通知されます。
ユーザーが別のウィンドウを動かしたため、ウィンドウの一部が隠れたとします。隠れた場所が再び見えるようになったとき、その一部は更新領域に追加されます。また、ウィンドウは別のWM_PAINTメッセージを受け取ります。
更新領域は、ユーザーがウィンドウを拡張した場合もまた変更されます。
今回の例では、ペインティングルーチンはとてもシンプルです。クライアントエリア全体を単色で塗りつぶすだけです。それでも、この例は重要な概念のうちいくつかを示すのに十分です。
switch (uMsg)
{
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
return 0;
}
BeginPaintによってペイントオペレーションが開始されます。この関数はPAINTSTRUCT構造体に再ペイントリクエストの情報を入力します。現在の更新領域はPAINTSTRUCTのrcPaintメンバーから与えられます。この更新領域はクライアントエリアと関連して定義されます。
ペインティング命令は2つのp@うションを持ちます。
- 更新領域のサイズに関係なくクライアントエリア全体をペイントする。更新領域外にあるものは全て切り捨てられます。つまり、OSはそれを無視します。
- 更新領域内のウィンドウ部分だけをペイントし最適化します。
もし、常にクライアントエリア全体をペイントする場合、コードはより単純になります。もし複雑なペインティングロジックを使った場合、更新領域以外の部分のペイントをスキップしてより効率的になります。
続くコードでは、システム定義のウィンドウ背景色(COLOR_WINDOW)を使って、更新領域を単色で塗りつぶしています。実際の色はユーザーの現在のカラースキーマに依存したCOLOR_WINDOWで指定されています。
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
FillRectの詳細はこの例では重要ではありません。しかし、二番目の引数が塗りつぶし矩形の座標を提供しています。この例では、更新領域全体(PAINTSTRUCTのrcPaintメンバー)を渡しています。最初のWM_PAINTメッセージでは、クライアントエリア全体がペイントを必要としているため、rcPaintが全てのクライアントエリアを含みます。WM_PAINTのサブシーケンスメッセージでは、rcPaintはより小さな矩形を含むでしょう。
ペインティングが終了したらEndPaint関数を呼び出します。この関数は更新領域をクリアします。また、Windowsにウィンドウのペイントが完了したことを通知します。