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

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read