Creating Shapes and Lines

Windows CE enables you to draw lines and a variety of filled shapes. A line is a set of highlighted pixels on a raster display or a set of dots on a printed page identified by two points, a starting point and an ending point. In Windows CE, the pixel located at the starting point is always included in the line, and the pixel located at the ending point is always excluded.

You can draw a series of connected line segments by calling the Polyline function and supplying an array of points that specify the ending point of each line segment.

Note Windows CE does not support the LineTo or the MoveToEx function. However, you can call the Polyline function in Windows CE to achieve the same results that you would get in Windows-based desktop platforms if you called the MoveToEx function and then made one or more calls to the LineTo function.

Filled shapes are geometric shapes that Windows CE outlines with the current pen and fills with the current brush. Windows CE supports four filled shapes: ellipse, polygon, rectangle, and round rectangle, which is a rectangle with rounded corners.

A Windows CE–based application uses filled shapes in a variety of ways. Spreadsheet applications, for example, use filled shapes to construct charts and graphs; drawing applications enable users to draw figures and illustrations using filled shapes.

An ellipse is a closed curve defined by two fixed points—f1 and f2—such that the sum of the distances—d1 + d2—from any point on the curve to the two fixed points is constant. The following illustration shows an ellipse drawn by using the Ellipse function.

When calling Ellipse, supply the coordinates of the upper-left and lower-right corners of the ellipse bounding rectangle. A bounding rectangle is the smallest rectangle that completely surrounds the ellipse.

A polygon is a filled shape with straight sides. Windows CE uses the currently selected pen to draw the sides of the polygon and the current brush to fill it. Windows CE fills all enclosed regions within the polygon with the current brush.

Note Windows CE does not support multiple fill modes. When it fills a polygon, it fills all subareas created by intersecting lines within the polygon.

A rectangle is a four-sided polygon whose opposing sides are parallel and equal in length and whose interior angles are 90 degrees. Although you can call the Polygon function to draw a rectangle if you supply it with all four sides, it is easier to call the Rectangle function. This function requires only the coordinates of the upper-left and the lower-right corners.

You can call the RoundRect function to draw a rectangle with rounded corners. Supply this function with the coordinates of the lower-left and upper-right corners of the rectangle and the width and height of the ellipse used to round each corner.

You can call the FillRect function to paint the interior of a rectangle. You can call the FillRgn function to fill a region using the specified brush.

Because Windows CE does not support paths, many line-drawing functions available on Windows-based desktop platforms are not available in Windows CE. Windows CE does not support functions to draw an arc, beizer curve, chord, pie, polypolygon, or polypolyline. However, you can approximate these shapes using existing Windows CE drawing functions. For example, you can create an arc by calling the Ellipse function with an appropriately defined clipping region.

Note The Ellipse and RoundRect functions require significant GDI computation. To increase your application performance, use these functions sparingly.

The following code example shows how to create shapes and lines using the Rectangle, Ellipse, Polygon, and RoundRect functions.

VOID DrawRandomObjects (HWND hwnd)
{
  HDC hDC;                  // Handle to the display device context 
  RECT rect;                // A RECT structure that contains the 
                            // window's client area coordinates
  POINT pt[4];              // Four dimensional POINT structure array
  HBRUSH hBrush,            // Handle to the new brush object 
         hOldBrush;         // Handle to the old brush object 
  TCHAR szDebug[80];        // A debug message string

  int x1, y1, x2, y2, x3, y3, x4, y4, 
                            // The coordinates of four points
      iRed, iGreen, iBlue,  // Indicate the Red, Green, Blue component 
                            // color of the brush
      iObject;              // An integer indicates the type of objects

  // Retrieve the handle to the display device context.
  if (!(hDC = GetDC (hwnd)))
    return;

  // Retrieves the coordinates of a window's client area. 
  GetClientRect (hwnd, &rect);

  // Avoid divide by zero errors when the window is small.
  if (rect.right == 0) 
    rect.right++;
  if (rect.bottom == 0) 
    rect.bottom++;

  // Generate three random numbers.
  iRed = rand() % 255;
  iGreen = rand() % 255;
  iBlue = rand() % 255;

  // Create a solid brush object and select it into the device context.
  hBrush = CreateSolidBrush (RGB(iRed, iGreen, iBlue));

  if (hOldBrush = SelectObject (hDC, hBrush))
  {
    // Randomly generates four points.
    x1 = rand() % rect.right;
    y1 = rand() % rect.bottom;
    x2 = rand() % rect.right;
    y2 = rand() % rect.bottom;
    x3 = rand() % rect.right;
    y3 = rand() % rect.bottom;
    x4 = rand() % rect.right;
    y4 = rand() % rect.bottom;

    // Randomly generate an integer to indicate the type of objects.
    iObject = rand() % 4;

    switch (iObject)
    {
      case 0:
        wsprintf (szDebug, TEXT("Rectangle(%d ,%d, %d, %d)\n"), 
                  x1, y1, x2, y2);

        // Draws a rectangle.
        Rectangle (hDC, x1, y1, x2, y2);

        break;

      case 1:
        wsprintf (szDebug, TEXT("Ellipse(%d, %d, %d, %d)\n"), 
                  x1, y1, x2, y2);

        // Draws an ellipse.
        Ellipse (hDC, x1, y1, x2, y2);

        break;

      case 2:
        wsprintf (szDebug, TEXT("RoundRect (%d, %d, %d, %d, %d, %d)\n"),
                  x1, y1, x2, y2, x3, y3);

        // Draws a rectangle with rounded corners. 
        RoundRect (hDC, x1, y1, x2, y2, x3, y3);

        break;

      case 3:
        pt[0].x = x1;
        pt[0].y = y1;
        pt[1].x = x2;
        pt[1].y = y2;
        pt[2].x = x3;
        pt[2].y = y3;
        pt[3].x = x4;
        pt[3].y = y4;

        wsprintf (szDebug, 
                  TEXT("Chord(%d, %d, %d, %d, %d, %d, %d, %d)\n"),
                  x1, y1, x2, y2, x3, y3, x4, y4);

        // Draws a polygon.
        Polygon(hDC, pt, 4);

        break;

      default:
        break;
    }

    // Select the old brush into the device context.
    SelectObject (hDC, hOldBrush);

    // Delete the brush object and free all resources associated with
       it.
    DeleteObject (hBrush);
  }

  ReleaseDC (hwnd, hDC);
  return;
}