Вы можете использовать функции линии и кривой, чтобы рисовать круговую диаграмму. Первая функция, используемая, чтобы рисовать круговые диаграммы - это функция AngleArc, которая требует, чтобы Вы дали ей координаты центра диска диаграммы, радиус диска диаграммы, начального угла и угла развертки. Ниже - диалоговое окно, которое пользователь может использовать, чтобы ввести эти значения.
Ниже - получающаяся круговая диаграмма.
Шаблон диалогового окна, находящийся в сценарии ресурса приложения (.RC файл) определяет особенности предшествующего диалогового окна (его высоту, органы управления, которые он содержит, и его стиль), следующим образом.
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 |
Процедура диалогового окна, находящаяся в исходном файле приложения, извлекает данные (координаты центра, радиус дуги и начальный угол и угол развертки) следуя этими шагами:
Нижеследующий типовой код показывает процедуру диалогового окна.
void ClearBits(LPTSTR, int); int GetStrLngth(LPTSTR); DWORD RetrieveInput(LPTSTR, int); BOOL CALLBACK ArcDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHAR chInput[4]; // получает управляемые окном вводимые данные int cch; // размер массива и переменная подсчета switch (uMsg) { case WM_INITDIALOG: return FALSE; case WM_COMMAND: switch (wParam) { // Если пользователь нажал кнопку OK, извлекаем // данные, которые были введены в различные AngleArc // органы управления. case IDD_OK: // Извлекаем координату x центра дуги. ClearBits(chInput, sizeof(chInput)); GetDlgItemText(hdlg, IDD_X, chInput, sizeof(chInput)); cch = GetStrLngth(chInput); nX = (int)RetrieveInput(chInput, cch); // Извлекаем координату y центра дуги. ClearBits(chInput, sizeof(chInput)); GetDlgItemText(hdlg, IDD_Y, chInput, sizeof(chInput)); cch = GetStrLngth(chInput); nY = (int)RetrieveInput(chInput, cch); // Извлекаем радиус дуги. ClearBits(chInput, sizeof(chInput)); GetDlgItemText(hdlg, IDD_RADIUS, chInput, sizeof(chInput)); cch = GetStrLngth(chInput); dwRadius = (DWORD) RetrieveInput(chInput, cch); // Извлекаем начальный угол. ClearBits(chInput, sizeof(chInput)); GetDlgItemText(hdlg, IDD_STARTANGLE, chInput, sizeof(chInput)); cch = GetStrLngth(chInput); xStartAngle = (float) RetrieveInput(chInput, cch); // Извлекаем угол развертки. ClearBits(chInput, sizeof(chInput)); GetDlgItemText(hdlg, IDD_SWEEPANGLE, chInput, sizeof(chInput)); cch = GetStrLngth(chInput); xSweepAngle = (float) RetrieveInput(chInput, cch); EndDialog(hdlg, FALSE); return TRUE; // Если пользователь нажал кнопку CANCEL, то // закрываем диалоговое окно. case IDD_CANCEL: EndDialog(hdlg, FALSE); return TRUE; } // конец переключателя (wParam) break; default: return FALSE; } // конец переключателя (message) UNREFERENCED_PARAMETER(lParam); } void ClearBits(LPTSTR cArray, int iLength) { int i; for (i = 0; i < iLength; i++) cArray[i] = 0; } int GetStrLngth(LPTSTR cArray) { int i = 0; while (cArray[i++] != 0); return i - 1; } DWORD RetrieveInput(LPTSTR cArray, int iLength) { int i, iTmp; double dVal, dCount; dVal = 0.0; dCount = (double) (iLength - 1); // Преобразуем данные введенные в ASCII в значения с плавающей точкой. for (i = 0; i < iLength; i++) { iTmp = cArray[i] - 0x30; dVal = dVal + (((double)iTmp) * pow(10.0, dCount--)); } return (DWORD) dVal; }
|
Чтобы нарисовать каждый раздел круговой диаграммы, перешлите значения, введенные пользователем в функцию AngleArc. Чтобы заполнить круговую диаграмму, используя текущую кисть, включите вызов AngleArc в группу пути. Нижеследующий образец кода показывает определенную группу пути и вызов AngleArc.
int nX; int nY; DWORD dwRadius; float xStartAngle; float xSweepAngle; hdc = GetDC(hwnd); BeginPath(hdc); SelectObject(hdc, GetStockObject(GRAY_BRUSH)); MoveToEx(hdc, nX, nY, (LPPOINT) NULL); AngleArc(hdc, nX, nY, dwRadius, xStartAngle, xSweepAngle); LineTo(hdc, nX, nY); EndPath(hdc); StrokeAndFillPath(hdc); ReleaseDC(hwnd, hdc); |