アークピットのホームページに戻る

WinAPIトピックのトップページに戻る

APIトピックの各章に移動する

ダウンロードのページに移動する
ダウンロードができ
ない場合の対処法
 

ページ移動

1-3-10. WM_PAINT

 ApHelloのプロシージャの、WM_PAINT メッセージの処理を説明します。
LRESULT CALLBACK ApHelloProc(HWND hWnd,UINT uMsg
                                      ,WPARAM wParam,LPARAM lParam)
{
    static HFONT hFont;
    static UINT  idFormat = IDM_CENTER;
    static LPSTR pHello   = "Hello World.";

    switch (uMsg)
    {
                 :
        case WM_PAINT:
        {
            HDC         hdc;
            PAINTSTRUCT ps;
            RECT        rc;
            UINT        w;

            hdc = BeginPaint(hWnd,&ps);
            if (hdc)
            {
                GetClientRect(hWnd,&rc);
                SetBkMode(hdc,TRANSPARENT);
                SetTextColor(hdc,RGB(0,0,255));
                SelectObject(hdc,hFont);
                switch (idFormat)
                {
                    case IDM_LEFT:   w = DT_LEFT;   break;
                    case IDM_CENTER: w = DT_CENTER; break;
                    case IDM_RIGHT:  w = DT_RIGHT;  break;
                }
                DrawText(hdc,pHello,strlen(pHello)
                            ,&rc,DT_SINGLELINE|DT_VCENTER|w);
            }
            EndPaint(hWnd,&ps);
            return 0;
        }
                 :
 ApHelloにとっては、WM_PAINT メッセージがすべてと言っても良いぐらい重要な部分です。しかしこの部分は、GDIと描画の分野ですので、詳細は省きます。SetBkMode 関数で文字だけ描画して文字の背景は抜くモードに設定します。そして、SetTextColor 関数で、文字の色を青に設定し、SelectObject 関数で、WM_CREATE で作成したフォントを選択します。最後に、DrawText 関数でメッセージを表示します。

描画とHDCBeginPaint

 描画は、HDCのデバイステキストのハンドルで行ないます。このハンドルがないとWindowsでは描画はできません。ユーザが勝手に描画することは御法度です。HDCの手順に従って描画する必要があります。なぜでしょうか。GUIと関係があります。Windowsは、ウィンドウが普通は描画対象ですが、その対象は、常に表示されているとは限らないからです。描画しようとしているエリアの上に、別のウィンドウが重なり、隠れているかもしれません。WindowsのHDCは、これを考慮します。もし隠れている部分があれば、クリップを設定して、複数に分けて描画して、ちゃんと見える部位にしか表示しません。またHDCには、各種のペンやブラシなどのオブジェクトが、関連付けられています。SelectObject でそれを設定します。よって描画する場合は、通常は座標だけ指定すれば、事足ります。

BeginPaintとEndPaint

 WM_PAINT メッセージでHDCを取得するのが、BeginPaint 関数です。この関数が、他のHDCを取得する関数と違うのは、描画しないといけない範囲を得ることができることです。GetDC,GetWindowDC などはすべてのエリアが対象になります。BeginPaint 関数のパラメータの、PAINTSTRUCT 構造体の rcPaint メンバに矩形域を設定します。ただし、このHDCでクライアントエリア全体を描画できます。その中で、rcPaint には、崩れたので再描画が必要なエリアを設定します。例えば、上にあったウィンドウを移動したので、WM_PAINT が発生しました。そのウィンドウで隠れていたエリアが、rcPaint に設定されます。しかし rcPaint エリアだけ描画するか、クライアントエリア全体を描画するかは、プログラマの自由です。一般に、rcPaint エリアだけを描画する方が高速ですが、コードは面倒です。描画スピードが気にかかるかたは検討してください。ApHelloの場合は、全体を描画します。BeginPaint 関数をつかったら、最後に、EndPaint しなければいけません。

ページ移動