3.4.3 Adding a WM_PAINT Case

The WM_PAINT message informs your application when it should redraw all or part of its client area. To handle this message, add the following statement to the window procedure:

case WM_PAINT:
    {
    TEXTMETRIC tm;
    int nDrawX;
    int nDrawY;
    char szText[300];

    /* Set up a device context to begin painting. */

    hDC = BeginPaint(hWnd, &ps);

    /*
     * Get the size characteristics of the current font.
     * This information will be used for determining the
     * vertical spacing of text on the screen.
     */

    GetTextMetrics(hDC, &tm);

    /*
     * Initialize drawing position to 1/4 inch from the top
     * and from the left of the upper-left corner of the client
     * area of the main windows.
     */

    nDrawX = GetDeviceCaps(hDC, LOGPIXELSX) / 4;   /* 1/4 inch */
    nDrawY = GetDeviceCaps(hDC, LOGPIXELSY) / 4;   /* 1/4 inch */

    /*
     * Send characters to the screen. After displaying each
     * line of text, advance the vertical position for the next
     * line of text. The pixel distance between the top of
     * each line of text is equal to the standard height of the
     * font characters (tmHeight), plus the standard amount of
     * spacing (tmExternalLeading) between adjacent lines.
     */



    lstrcpy(szText, "These characters are being painted using ");
    TextOut(hDC, nDrawX, nDrawY, szText, lstrlen(szText));
    nDrawY += tm.tmExternalLeading + tm.tmHeight;

    lstrcpy(szText, "the TextOut() function, which is fast and ");
    TextOut(hDC, nDrawX, nDrawY, szText, lstrlen(szText));
    nDrawY += tm.tmExternalLeading + tm.tmHeight;

    lstrcpy(szText, "allows programmer control of placement and ");
    TextOut(hDC, nDrawX, nDrawY, szText, lstrlen(szText));
    nDrawY += tm.tmExternalLeading + tm.tmHeight;

    lstrcpy(szText, "formatting details. However, TextOut() ");
    TextOut(hDC, nDrawX, nDrawY, szText, lstrlen(szText));
    nDrawY += tm.tmExternalLeading + tm.tmHeight;

    lstrcpy(szText, "does not provide any automatic formatting.");
    TextOut(hDC, nDrawX, nDrawY, szText, lstrlen(szText));
    nDrawY += tm.tmExternalLeading + tm.tmHeight;

    /*
     * Put text in a 5-inch by 1-inch rectangle and display it.
     * First define the size of the rectangle around the text.
     */

    nDrawY += GetDeviceCaps(hDC, LOGPIXELSY) / 4;  /* 1/4 inch */
    SetRect(&rcTextBox,
        nDrawX,
        nDrawY,
        nDrawX + (5 * GetDeviceCaps(hDC, LOGPIXELSX)),   /* 5" */
        nDrawY + (1 * GetDeviceCaps(hDC, LOGPIXELSY))    /* 1" */
    );

    /* Draw the text within the bounds of the above rectangle. */

    lstrcpy(szText, "This text is being displayed with a single "
                "call to DrawText(). DrawText() isn't as fast "
                "as TextOut(), and it is somewhat more "
                "constrained, but it provides numerous optional "
                "formatting features, such as the centering and "
                "line breaking used in this example.");
    DrawText(hDC,
        szText,
        lstrlen(szText),
        &rcTextBox,
        DT_CENTER | DT_EXTERNALLEADING | DT_NOCLIP
            | DT_NOPREFIX | DT_WORDBREAK);

    /*
     * Paint the next object immediately below the bottom
     * of the above rectangle in which the text was drawn.
     */

    nDrawY = rcTextBox.bottom;

    /*
     * The (x,y) pixel coordinates of the objects about to
     * be drawn are below, and to the right of, the current
     * coordinate (nDrawX,nDrawY).
     */

    /* Draw a red rectangle. */

    hOldBrush = SelectObject(hDC, hRedBrush);
    Rectangle(hDC,
        nDrawX,
        nDrawY,
        nDrawX + 50,
        nDrawY + 30);

    /* Draw a green ellipse. */

    SelectObject(hDC, hGreenBrush);
    Ellipse(hDC,
        nDrawX + 150,
        nDrawY,
        nDrawX + 150 + 50,
        nDrawY + 30);

    /* Draw a blue pie shape. */

    SelectObject(hDC, hBlueBrush);
    Pie(hDC,
        nDrawX + 300,
        nDrawY,
        nDrawX + 300 + 50,
        nDrawY + 50,
        nDrawX + 300 + 50,
        nDrawY,
        nDrawX + 300 + 50,
        nDrawY + 50);

    nDrawY += 50;

    /* Restore the old brush. */

    SelectObject(hDC, hOldBrush);









    /* Select a "---" pen, and save the old value. */

    nDrawY += GetDeviceCaps(hDC, LOGPIXELSY) / 4;  /* 1/4 inch */
    hOldPen = SelectObject(hDC, hDashPen);

    /* Move to a specified point. */

    MoveTo(hDC, nDrawX, nDrawY);
    /* Draw a line. */

    LineTo(hDC, nDrawX + 350, nDrawY);

    /* Select a "..." pen. */

    SelectObject(hDC, hDotPen);

    /* Draw an arc connecting the line. */

    Arc(hDC,
        nDrawX,
        nDrawY - 20,
        nDrawX + 350,
        nDrawY + 20,
        nDrawX,
        nDrawY,
        nDrawX + 350,
        nDrawY);

    /* Restore the old pen. */

    SelectObject(hDC, hOldPen);

    /* Tell Windows you are done painting. */

    EndPaint(hWnd,  &ps);
    }
    break;

Note:

If you “hard-code” strings by using functions such as lstrcpy, it may be difficult to translate your application into other languages. If you plan to distribute your application in more than one language, use string tables instead of hard-coded strings. For more information about string tables, see the Microsoft Windows Programmer's Reference, Volume 4.