dcsimg

Draw the US flag using GDI

WEBINAR:
On-Demand

Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame


Environment: Win32 (VC++ 6 project)

Just for fun, or perhaps even useful, here is a function to draw the US flag to a given HDC, in a given RECT. Looks best on a hi-rez device. Would look great embedded as a static control in a dialog, as a backdrop for an MDI app, a screensaver, or draw it to printer DC for a hardcopy. Cheers!

////////////////////////////////////////////////////////////////
//
// Draws the Star-Spangled Banner.
//
// Params:
// hdc   - The patriotic device context.
// pRect - Rect in DC to draw Old Glory to.
//
////////////////////////////////////////////////////////////////
// Sines & cosines for the angles of the five-pointed stars
#define SIN72       0.95106
#define COS72       0.30902
#define SIN144      0.58779
#define COS144     -0.80902
#define STARSIZE    0.67 // scale factor for the size of the stars
void DrawOldGlory(HDC hdc, RECT * pRect)
{
  HPEN hpenOld;
  HBRUSH  hbrRed, hbrWhite, hbrBlue, hbrOld;
  int x0 = pRect->left;
  int y0 = pRect->top;
  int x1 = pRect->right;
  int y1 = pRect->bottom;
  int cx = x1 - x0;
  int cy = y1 - y0;
  int i, j, x, y, xx, yy;
  int cxStarBox, cyStarBox;
  int nOldFillMode;

  // Create some colors for us to work with.
  hbrRed = CreateSolidBrush(RGB(255, 0, 0));
  hbrWhite = CreateSolidBrush(RGB(255, 255, 255));
  hbrBlue = CreateSolidBrush(RGB(0, 0, 128));

  // Hide the default pen so that we don't get
  // black borders around the filled shapes.
  // Whenever a rectangle is drawn, we'll add one pixel to the
  // right and bottom to fill in for the missing pen.
  hpenOld = (HPEN) SelectObject(hdc, GetStockObject(NULL_PEN));

  // Draw white background.
  hbrOld = (HBRUSH) SelectObject(hdc, hbrWhite);
  Rectangle(hdc, x0, y0, x1 + 1, y1 + 1);

  // Draw the seven red stripes.
  SelectObject(hdc, hbrRed);
  for (i = 0; i < 13; i++)
    if ((i & 1) == 0)
      Rectangle(hdc,
                x0,
                y0 + (i * cy) / 13,
                x1 + 1,
                y0 + ((i + 1) * cy) / 13 + 1);

  // Draw blue box.
  // Size it so that it covers two fifths of the flag length and
  // the top seven stripes vertically.
  cxStarBox = (2 * cx) / 5;
  cyStarBox = (7 * cy) / 13 + 1;
  SelectObject(hdc, hbrBlue);
  Rectangle(hdc,
            x0,
            y0,
            x0 + cxStarBox,
            y0 + cyStarBox);

  // Draw fifty stars in the blue box.
  SelectObject(hdc, hbrWhite);
  // We're going to draw the stars with just a five point polygon.
  // Select the 'winding' fill mode so that the centers of the stars
  // get filled too.
  nOldFillMode = SetPolyFillMode(hdc, WINDING);
  // Shrink the blue box rect a bit to give some border around the stars.
  x0 += cxStarBox / 25;
  y0 += cyStarBox / 25;
  cxStarBox *= 23;
  cxStarBox /= 25;
  cyStarBox *= 23;
  cyStarBox /= 25;
  y = y0;
  // Now, divide the box into a grid of 11 x 9 squares and place a star
  // in every other square, like on a checker board.
  for (j = 1; j <= 9; j++)
  {
    yy = y0 + (j * cyStarBox) / 9;
    x = x0;
    for (i = 1; i <= 11; i++)
    {
      xx = x0 + (i * cxStarBox) / 11;
      // Determine 'black' or 'white' square status by checking to see
      // if the sum of 'i' and 'j' is odd or even.
      // This ensures that the square colors of each row are always
      // staggered regardless of whether there is an odd or even number
      // of squares in each row.
      if (((i + j) & 1) == 0)
      {
        // Get the width and height of the current square.
        int w = xx - x;
        int h = yy - y;
        // Use the smaller of the two (width or height) as a basis
        // for the radius of the star.
        double r = (w < h) ? (double)w * STARSIZE : (double)h * STARSIZE;
        // Find the center of the current square.
        int centerX = (x + xx) / 2;
        int centerY = (y + yy) / 2;
        POINT pts[5];

        // Calculate the actual points for the stars by rotating the
        // radius around the center point using the pre-computed
        // sines & cosines.
        pts[0].x = centerX;
        pts[0].y = centerY - (int)(r);
        pts[1].x = centerX + (int)(r * SIN144);
        pts[1].y = centerY - (int)(r * COS144);
        pts[2].x = centerX - (int)(r * SIN72);
        pts[2].y = centerY - (int)(r * COS72);
        pts[3].x = centerX + (int)(r * SIN72);
        pts[3].y = pts[2].y;
        pts[4].x = centerX - (int)(r * SIN144);
        pts[4].y = pts[1].y;

        // Finally, draw the filled polygon.
        Polygon(hdc, pts, 5);
      }
      x = xx;
    }
    y = yy;
  }

  // Clean up.
  SetPolyFillMode(hdc, nOldFillMode);
  SelectObject(hdc, (HBRUSH) hbrOld);
  SelectObject(hdc, (HPEN) hpenOld);

  DeleteObject(hbrBlue);
  DeleteObject(hbrWhite);
  DeleteObject(hbrRed);
}

Downloads

Download demo project - 12 Kb


Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date