ウィンドウの描画

ウィンドウが作成されました。 次に、その中に何かを表示します。 Windows の用語では、これはウィンドウの描画と呼ばれます。 比喩を混ぜ合わせるために、ウィンドウは空白のキャンバスであり、それを埋めるのを待っています。

プログラムがウィンドウの外観を更新するために描画を開始することがあります。 それ以外の場合は、ウィンドウの一部を再描画する必要があることをオペレーティング システムから通知されます。 これが発生すると、オペレーティング システムはウィンドウに WM_PAINT メッセージを送信します。 ウィンドウの塗りつぶす必要がある部分は、 更新領域と呼ばれます。

ウィンドウを初めて表示するときは、ウィンドウのクライアント領域全体を塗りつぶす必要があります。 したがって、ウィンドウを表示すると、常に少なくとも 1 つのWM_PAINT メッセージが表示されます。

ウィンドウの更新領域を示す図

お客様は、クライアント領域の描画のみを担当します。 タイトル バーを含む周囲のフレームは、オペレーティング システムによって自動的に塗りつぶされます。 クライアント領域の描画が完了したら、更新リージョンをクリアします。これにより、何かが変更されるまで 別のWM_PAINT メッセージを送信する必要がないことをオペレーティング システムに通知します。

次に、ユーザーが別のウィンドウを移動して、ウィンドウの一部を隠すとします。 隠れた部分が再び表示されると、その部分が更新領域に追加され、ウィンドウに別の WM_PAINT メッセージが表示されます。

2 つのウィンドウが重なったときに更新領域がどのように変化するかを示す図

ユーザーがウィンドウを拡大すると、更新リージョンも変更されます。 次の図では、ユーザーがウィンドウを右に引き伸ばします。 ウィンドウの右側にある新しく公開された領域が更新領域に追加されます。

ウィンドウのサイズを変更したときに更新領域がどのように変化するかを示す図

最初のサンプル プログラムでは、描画ルーチンは非常に単純です。 クライアント領域全体を単に純色で塗りつぶします。 それでも、この例は重要な概念の一部を示すために十分です。

switch (uMsg)
{
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);

        // All painting occurs here, between BeginPaint and EndPaint.

        FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

        EndPaint(hwnd, &ps);
    }
    return 0;
}

BeginPaint 関数を呼び出して、描画操作を開始します。 この関数は、再描画要求に関する情報を PAINTSTRUCT 構造体に入力します。 現在の更新リージョンは、PAINTSTRUCTrcPaint メンバーで指定されます。 この更新リージョンは、クライアント領域に対して相対的に定義されます。

クライアント領域の原点を示す図

描画コードには、次の 2 つの基本的なオプションがあります。

  • 更新リージョンのサイズに関係なく、クライアント領域全体を塗りつぶします。 更新リージョンの外部にあるものは、すべてクリップされます。 つまり、オペレーティング システムでは無視されます。
  • 更新領域内のウィンドウの部分だけを描画して最適化します。

常にクライアント領域全体を描画すると、コードが簡単になります。 ただし、複雑な描画ロジックがある場合は、更新リージョン外の領域をスキップする方が効率的です。

次のコード行は、システム定義のウィンドウの背景色 (COLOR_WINDOW) を使用して、更新領域を単一の色で塗りつぶします。 COLOR_WINDOWによって示される実際の色は、ユーザーの現在の配色によって異なります。

FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

この例では FillRect の詳細は重要ではありませんが、2 番目のパラメーターは塗りつぶす四角形の座標を示します。 この場合、更新領域全体 (PAINTSTRUCTrcPaint メンバー) を渡します。 最初の WM_PAINT メッセージでは、クライアント領域全体を塗りつぶす必要があるため、 rcPaint にはクライアント領域全体が含まれます。 後続 のWM_PAINT メッセージでは、 rcPaint には小さな四角形が含まれる場合があります。

FillRect 関数は、非常に長い間 Windows グラフィックスを利用してきたグラフィックス デバイス インターフェイス (GDI) の一部です。 Windows 7 では、ハードウェア アクセラレーションなどの高性能グラフィックス操作をサポートする Direct2D という名前の新しいグラフィックス エンジンが導入されました。 Direct2D は、Windows Vista では Windows Vista のプラットフォーム更新プログラム を使用し、Windows Server 2008 では Windows Server 2008 のプラットフォーム更新プログラムを使用することもできます。 (GDI は引き続き完全にサポートされています)。

描画が完了したら、 EndPaint 関数を呼び出します。 この関数は、ウィンドウ自体の描画が完了したことを Windows に通知する更新領域をクリアします。

次へ

ウィンドウを閉じる