Draw the US flag using GDI

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


Comments

  • Coincidence?

    Posted by Legacy on 07/11/2002 12:00am

    Originally posted by: Peter O.

    "Date Posted: September 10, 2001"
    
    

    It was merely a coincidence that the code was posted a day before the tragedies.

    To the author: Amazing code.

    Reply
  • Generic flag drawing library?

    Posted by Legacy on 10/16/2001 12:00am

    Originally posted by: Eugene Epshteyn

    Wouldn't it be neat to have a source code library that would draw a flag of any country? (At least those that don't have many complex elements.)

    --Eugene

    Reply
  • Very significant

    Posted by Legacy on 10/12/2001 12:00am

    Originally posted by: Vernero Cifagni

    Your code is very good and significant. Yours is a flag round which all sensible people should gather. I am Italian, and I have decided to put an American flag in every "About" box in my programmes, in honour of those who died one month ago in America, and of those who will die in defense of all of us. My best congratulations, and never mind insults.
    Vernero

    Reply
  • Very Good GDI Example

    Posted by Legacy on 10/11/2001 12:00am

    Originally posted by: Mark Henri

    A perfect example of GDI programming with a timely subject. The concepts could be used to create a myriad of of other graphics or reports.

    Thanks,

    Reply
  • Very Good GDI Example

    Posted by Legacy on 10/11/2001 12:00am

    Originally posted by: Mark Henri

    A perfect example of GDI programming with a timely subject. The concepts could be used to create a myriad of of other graphics or reports.

    Thanks,

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • U.S. companies are desperately trying to recruit and hire skilled software engineers and developers, but there is simply not enough quality talent to go around. Tiempo Development is a nearshore software development company. Our headquarters are in AZ, but we are a pioneer and leader in outsourcing to Mexico, based on our three software development centers there. We have a proven process and we are experts at providing our customers with powerful solutions. We transform ideas into reality.

  • When individual departments procure cloud service for their own use, they usually don't consider the hazardous organization-wide implications. Read this paper to learn best practices for setting up an internal, IT-based cloud brokerage function that service the entire organization. Find out how this approach enables you to retain top-down visibility and control of network security and manage the impact of cloud traffic on your WAN.

Most Popular Programming Stories

More for Developers

RSS Feeds

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