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)
                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);
            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);



Download demo project - 12 Kb


  • 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.

  • 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.)


  • 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.

  • 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.


  • 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.


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

Top White Papers and Webcasts

  • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

  • On-demand Event Event Date: November 17, 2015 Although enterprise adoption of open source has accelerated, some are still wary of it. But not all open source technologies are the same: some are designed with enterprises in mind. In this webinar, we'll discuss trends in open source development, innovation impacts, and what it means for the future.

Most Popular Programming Stories

More for Developers

RSS Feeds

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