67.2.2 Using Lines and Curves to Draw a Pie Chart

You can use the line and curve functions to draw a pie chart. The primary function used to draw pie-charts is the AngleArc function which requires that you supply the coordinates of the center of the pie, the radius of the pie, a start angle, and a sweep angle. This section contains sample code which displays a dialog in which the user can enter these values. The dialog (and corresponding output) is shown in the following illustration:

Pie-Chart Dialog

The following excerpt from the application's resource file shows the dialog template:

AngleArc DIALOG 6, 18, 160, 100

STYLE WS_DLGFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION

CAPTION "Pie Chart"

FONT 8, "MS Sans Serif"

BEGIN

EDITTEXT IDD_X, 18, 22, 25, 12, ES_AUTOHSCROLL

LTEXT "X", 102, 4, 24, 9, 8

EDITTEXT IDD_Y, 18, 39, 25, 12, ES_AUTOHSCROLL

LTEXT "Y", 104, 5, 42, 12, 8

LTEXT "Center", 105, 19, 11, 23, 8

EDITTEXT IDD_RADIUS, 103, 9, 32, 12, ES_AUTOHSCROLL

EDITTEXT IDD_STARTANGLE, 103, 31, 32, 12, ES_AUTOHSCROLL

EDITTEXT IDD_SWEEPANGLE, 103, 53, 32, 12, ES_AUTOHSCROLL

LTEXT "Radius", 109, 73, 11, 25, 8

LTEXT "Start Angle", 110, 59, 33, 42, 8

LTEXT "Sweep Angle", 111, 55, 55, 43, 8

PUSHBUTTON "OK", IDD_OK, 9, 82, 40, 14

PUSHBUTTON "Cancel", IDD_CANCEL, 110, 82, 40, 14

END

The following excerpt from the application's source file shows the dialog procedure:

int APIENTRY ArcDlgProc(HWND hDlg, WORD message, LONG wParam, LONG lParam)

{

CHAR chWidth[4];/* array that receives control-window input */

int iCount, i;/* array-size and count variables */

switch (message) {

case WM_INITDIALOG:

return FALSE;

case WM_COMMAND:

switch (wParam){

/* If user pressed the OK button, retrieve the data */

/* which was entered in the various AngleArc controls. */

/* The ClearBits function clears the bits in an array. */

/* The GetStrLngth function retrieves the length of the*/

/* string which was stored in the array. And, the */

/* RetrieveInput function retrieves the value entered */

/* by the user in one of the dialog controls. */

case IDD_OK:

/* Retrieve the x-coordinate of the arc's center. */

ClearBits(chWidth, 4);

GetDlgItemText(hDlg, IDD_X, chWidth, 4);

iCount = GetStrLngth(chWidth);

iX = (int)RetrieveInput(chWidth, iCount);

/* Retrieve the y-coordinate of the arc's center. */

ClearBits(chWidth, 4);

GetDlgItemText(hDlg, IDD_Y, chWidth, 4);

iCount = GetStrLngth(chWidth);

iY = (int)RetrieveInput(chWidth, iCount);

/* Retrieve the radius of the arc. */

ClearBits(chWidth, 4);

GetDlgItemText(hDlg, IDD_RADIUS, chWidth, 4);

iCount = GetStrLngth(chWidth);

dwRadius = (DWORD)RetrieveInput(chWidth, iCount);

/* Retrieve the start angle. */

ClearBits(chWidth, 4);

GetDlgItemText(hDlg, IDD_STARTANGLE, chWidth, 4);

iCount = GetStrLngth(chWidth);

eStartAngle = (float)RetrieveInput(chWidth, iCount);

/* Retrieve the sweep angle. */

ClearBits(chWidth, 4);

GetDlgItemText(hDlg, IDD_SWEEPANGLE, chWidth, 4);

iCount = GetStrLngth(chWidth);

eSweepAngle = (float)RetrieveInput(chWidth, iCount);

EndDialog(hDlg, FALSE);

return TRUE;

/* If user presses the CANCEL button, close the dlg. */

case IDD_CANCEL:

EndDialog(hDlg, FALSE);

return TRUE;

} /* end switch (wParam) */

break;

default:

return (FALSE);

} /* end switch (message) */

UNREFERENCED_PARAMETER(lParam);

}

In order to draw the pie chart, the values entered by the user are passed to the AngleArc function. And, in order to fill the pie chart with a pattern, the call to the AngleArc function is embedded in a path bracket. The following excerpt from the application's source file shows how the path bracket was defined and how the AngleArc function was called:

case (IDM_ANGLEARC):

DialogBox((HANDLE) GetModuleHandle(NULL),

(LPTSTR)"AngleArc",

hWnd, (DLGPROC)ArcDlgProc);

hdc = GetDC(hWnd);

BeginPath(hdc);

SelectObject(hdc, GetStockObject(GRAY_BRUSH));

MoveToEx(hdc, iX, iY, NULL);

AngleArc(hdc, iX, iY, dwRadius, eStartAngle,

eSweepAngle);

LineTo(hdc, iX, iY);

EndPath(hdc);

StrokeAndFillPath(hdc);

ReleaseDC(hWnd, hdc);

break;