Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Visual C++ 6. Руководство Разработчика [rus]

.pdf
Скачиваний:
303
Добавлен:
16.08.2013
Размер:
4.96 Mб
Скачать

/*

*Sine.с

*Программа, которая рисует синусоиду.

*Построена на базе файла swp.c.

*/

#include <windows.h> #include <math.h>

#define

pi 3.14159265359

: char

LRESULT

CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

szProgName[]="ProgName";

 

int WINAPI WinMain (HINSTANCE hlnst, HINSTANCE hPrelnst, , ,., LPSTR IpszCmdLine, int nCmdShow)

{

HWND hWnd;

MSG IpMsg; WNDCLASS wcApp;

wcApp.lpszClassName

= szProgName; wcApp.hlnstance

= hlnst;

 

wcApp.lpfnWndProc

= WndProc;

 

 

 

wcApp.hCursor

 

= LoadCursor(NULL, IDC_ARROW); wcApp.hlcon

=

NULL; wcApp.lpszMenuName = NULL;

 

 

 

wcApp.hbrBackground

= GetStockObject(WHITE_BRUSH); wcApp.

= 0;

 

style

= CS_HREDRAW | CS_VREDRAW; wcApp.cbClsExtra

 

wcApp.cbWndExtra

= 0; if (IRegisterClass(SwcApp)) return 0;

 

hWnd = CreateWindow(szProgName, "A Sine Wave",

WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL,.(HMENU)NULL, (HANDLE)hlnst, (LPSTR)NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);

while (GetMessage(&lpMsg, 0, 0 , 0) ) { TranslateMessage(SlpMsg); DispatchMessage(SlpMsg);

}

return (IpMsg.wParam) ;

}

LRESULT CALLBACK WndProc(HWND hWnd, DINT messg, WPARAM wParam, LPARAM IParam) {

HOC hdc; PAINTSTRUCT ps; double y; int i;

{

switch (messg) { case WM_PAINT:

hdc=BeginPaint(hWnd, Sps) ;

/* построение осей координат */ MoveToEx(hdc, 100, 50, NULL); LineTo(hdc, 100, 350); MoveToEx(hdc, 100, 200, NULL); LineTo(hdc, 500, 200); MoveToEx(hdc, 100, 200, NULL); /* построение синусоиды */

for (i=0; i < 400; i++) {

у = 120.0*sin(pi*i*(360.0/400.0)/180.0) LineTo(hdc, i+100, (int)(200.0-y));

}

ValidateRect (hWnd, NULL); EndPaint (hWnd, Sps); break; case WM_DESTROY:

301

PostQuitMessage (0); break;

default:

return (DefWindowProc (hWnd, messg, wParam, IParam) ) ; break; } return (0);

}

Если проанализировать текст файла SINE. С и сравнить его с текстом рассмотренного ранее файла SWP.C, то можно увидеть, что внесенные изменения действительно незначительны.

Обратите внимание, что в процедуре WndProc( ) определяются две новые переменные: double у; int i;

Оси координат строятся с помощью функций MoveToEx( ) и LineTo( ) :

/* построение осей координат */ MoveToEx(hdc, 100, 50, NULL); LineTo (hdc, 100, 350);

MoveToEx (hdc, 100, 200, NULL) ; LineTo (hdc, 500, 200);

MoveToEx (hdc, 100, 200, NULL) ;

Синусоида рисуется в цикле for. Ее амплитуда составляет 120 пикселей относительно горизонтальной оси. Для построения синусоиды используется функция sin( ) , объявленная в файле МАТН.Н. Константа piнеобходима для преобразования значений углов из градусов в радианы.

/* построение синусоиды */ for(i=0;i < 400; i++)

{

у = 120. 0*sin(pi*i* (360.0/400.0)/180.0); LineTo(hdc, i+100, (int)(200.0-y));

Окно программы показано на рис. 17.15. Поскольку в приложении не делалось никаких предположений о возможных размерах экрана, на мониторах с разной разрешающей способностью физические размеры изображения могут оказаться разными, что, как правило, нежелательно. Ниже, на примере приложения PIE.C, вы увидите, как можно избежать этого недостатка.

Рис. 17.15. Синусоида, выведенная на экран программой SINE.C

Создание диаграмм

302

Круговые диаграммы широко применяются в коммерческих приложениях при создании различного рода презентаций. В представленной ниже программе будут объединены многие приемы, рассмотренные в этой и предыдущей главах. В частности, в программе задействованы меню и разработанные нами диалоговые окна Aboutи PieChartData. В окне ввода данных пользователю будет предложено задать до десяти значений, определяющих размеры секторов. На основании введенных целочисленных значений будут вычислены угловые размеры секторов в пропорции к общему размеру круга — 360 градусов. Минимальный размер сектора — 1 градус. Для закрашивания секторов определен массив IColor[] с набором цветов. Пользователь может также ввести подпись к диаграмме.

Для работы над данным приложением необходимо иметь четыре файла: PIE.H, PIE.RC, PIE.Cи PIE.CUR. Последний, содержащий изображение указателя мыши, вы можете разработать самостоятельно с помощью редактора ресурсов.

Ниже показан текст файла заголовков PIE.H, в котором содержатся идентификаторы команд меню и элементов управления диалоговых окон:

#define IDM_ABOUT 10 #define IDM_INPUT 20 #define IDM EXIT 30 #define DM_TITLE 160 #define DM_P1161 #define DM_P2162 #define DM_P3163 #define DM_P4164 #define DM_P5165 #define DM_P6166 #define DM_P7167 #define DM_P8168 #define DM_P9169 #define DM_P10170

В файле ресурсов PIE.RC описываются меню и два диалоговых окна (более подробно об этих ресурсах говорилось в предыдущей главе), а также ряд вспомогательных ресурсов.

#include "resource.h"

 

#define APSTUDIO_READONLY_SYMBOLS

 

/////////////////////////////////////

 

#include "pie.h"

 

#define APST0DIO_HIDDEN_SYMBOLS

 

#include "windows. h"

 

tundef APSTUDIO_HIDDEN_SYMBOLS

 

//////////////////////////////////////

 

tundef APSTUDIO_READONLY_SYMBOLS

 

//////////////////////////////////////

 

// Ресурсы для английского (США) языка

-

#if !defined(AFX_RESOURCE_DLL) || defined (AFX_TARG_END)

tifdef _WIN32

 

LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

 

tpragma code_page (1252)

 

#endif //_WIN32

 

////////////////////////////////////////

 

//

 

// Указатель мыши

 

//

 

PIECURSOR CURSOR DISCARDABLE "pie.cur"

 

////////////////////////////////////////

 

//

 

// Меню

 

303

//

PIEMENU MENU DISCARDABLE BEGIN

POPUP "Pie_Chart_Data"

 

BEGIN

 

 

MENUITEM

"About...",

IDM_ABOUT

MENUITEM

"Input...",

IDM_INPUT

MENUITEM

"Exit",

IDM EXIT

END

 

 

END

 

 

/////////////////////////////////////////

// Диалоговые окна

//

ABOUTDLGBOX DIALOG DISCARDABLE 50,300, 180, 84

STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE I WS_CAPTION I WS_SYSMENU CAPTION "About"

FONT 8, "MS Sans Serif" BEGIN

CTEXT "Microsoft СPie Chart Program", -1,3, 29,176,10

CTEXT "by William H. Murray and Chris H. Pappas", -1, 3, 16,176,10 PUSHBUTTON "ОК", IDOK, 74,51,32,14

END

PIEDLGBOX DIALOG DISCARDABLE 93,37,195,159

STYLE DS_MODALFRAME | WS_POPUP I WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Pie Chart Data"

FONT 8, "MS Sans Serif" BEGIN

GROUPBOX "Chart Title:",100, 5, 3, 182, 30, WSJTABSTOP GROUPBOX "Pie Wedge Sizes:",101, 3, 34,187, 95,WS_TABSTOP LTEXT "Title: ", -1,10,21,30,8

EDITTEXT DMJTITLE, 40,18,140, 12

LTEXT "Wedge #1:", -1, 10, 50, 40,8, NOT WS_GROUP LTEXT "Wedge #2:", -1, 10, 65, 40,8. NOT WS_GROUP LTEXT "Wedge #3:", -1, 10, 80, 40, 8, NOT WS_GROUP LTEXT "Wedge t4: ", -1, 10, 95, 40, 8, NOT WS_GROUP LTEXT "Wedge #5:", -1, 10, 110, 40,8, NOT WS_GROUP LTEXT "Wedge #6:", -1, 106,50, 40,8, NOT WS_GROUP LTEXT "Wedge #7:", -1, 106,65, 40,8. NOT WS_GROUP LTEXT "Wedge #8:", -1, 106,80, 40,8, NOT WS_GROUP LTEXT "Wedge #9:", -1, 106,95, 40, 8, NOT WS_GROUP LTEXT "Wedge #10:", -1,102, 110, 45,8, NOT WS_GROUP EDITTEXT DM_P1, 55, 45, 30,12

EDITTEXT DM_P2, 55, 60, 30, 12

EDITTEXT DM_P3, 55, 75, 30, 12

EDITTEXT DM_P4, 55, 90, 30, 12

EDITTEXT DM_P5, 55, 105, 30, 12

EDITTEXT DM_P6, 150, 44, 30,12

EDITTEXT DM_P7, 150, 61, 30,12

EDITTEXT DM_P8, 150, 76, 30,12

EDITTEXT DM_P9, 149,91, 30,12

EDITTEXT DM_P10, 149,106,30, 12 PUSHBUTTON "ОК", IDOK, 39,135, 24,14

PUSHBUTTON "Cancel", IDCANCEL, 122, 136,34,14 END

tifdef APSTUDIO_INVOKED

304

///////////////////////////////////////////

1 TEXTINCLUDE DISCARDABLE BEGIN

"resource.h\0" END

2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""pie.h""\r\n"

"#define APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""windows.h""\r\n".

"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" "\0"

END

3 TEXTINCLUDE DISCARDABLE

BEGIN

 

"\r\n"

 

"\0" END

 

#endif

// APSTUDIO_INVOKED

#endif

// Ресурсы для английского (США) языка

Следует помнить, что файл PIE.RC— это просто текстовый эквивалент описаний меню и диалоговых окон, созданных с помощью редактора ресурсов (см. предыдущую главу).

Файл PIE.С содержит основной текст программы. Несмотря на достаточно большой его размер, вы легко можете найти здесь знакомые блоки из файла SWP.C.

/*

*PIE.С

*Создание круговых диаграмм.

*/

#include <windows.h> #include <string.h> #include <math.h> #include "pie.h"

#define radius

180

#define maxnurawedge 10 #define pi 3.14159265359

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK PieDlgProc(HWND, UINT, WPARAM, LPARAM);

char szProgName[] = "ProgName"; char szApplName[] = "PieMenu"; char szCursorName[] = "PieCursor";

char szTString[80] = "(piechart title area)"; unsigned int iwedgesize[maxnumwedge] = {5,20,10,15};

long IColor[maxnumwedge] = {OxOL,OxFFL, 'OxFFOOL, OxFFFFL, OxFFOOOOL, OxFFOOFFL, OxFFFFOOL, OxFFFFFFL, OxSOSOL, Ox808080L); int WINAPI WinMain(HINSTANCE hlnst, HINSTANCE hPrelnst,

LPSTR IpszCmdLine,

int nCmdShow) {

 

HWND hWnd;

 

 

MSG IpMsg;

 

 

WNDCLASS wcApp;

 

= hlnst;

wcApp.lpszClassName = szProgName; wcApp.hlnstance

wcApp.lpfnWndProc

= WndProc;

 

wcApp.hCursor

= LoadCursor (hlnst, szCursorName);

wcApp.hlcon

= Ldadlcon(hlnst,szProgName); wcApp.lpszMenuName =

szApplName;

 

wcApp.hbrBackground = GetStockObject(WHITE_BRUSH); wcApp.style

=

= CS_HREDRAW | CS_VREDRAW; wcApp.cbClsExtra = 0; wcApp.cbWndExtra

0; if (IRegisterClass(SwcApp)) return 0;

 

305

hWnd = CreateWindow(szProgName, "PieChart Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL, (HMENU)NULL, (HANDLE)hlnst, (LPSTR)NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); while (GetMessage(SlpMsg, 0, 0, 0)) {

TranslateMessage(SlpMsg); DispatchMessage(SlpMsg); ) return(IpMsg.wParam); }

BOOL CALLBACK AboutDlgProc(HWND hdlg, UINT messg, WPARAM wParam, LPARAM IParam) I

switch (messg) { case WM_INITDIALOG: break;

case WM_COMMAND: switch (wParam)

{

case IDOK: EndDialog(hdlg, TRUE), break; default: return FALSE; } break; default:

return FALSE; } return TRUE;

}

BOOL CALLBACK PieDlgProc(HWND hdlg, UINT messg, WPARAM wParam, LPARAM IParam) {

switch (messg) { case WM_INITDIALOG:

return FALSE; case WM_COMMAND: switch (wParam) { case IDOK:

GetDlgltemText(hdlg, DMJTITLE, szTString, 80); iWedgesize[0] = GetDlgltemlnt(hdlg, DM_P1, NULL, 0) iWedgesize[l] = GetDlgltemlnt(hdlg, DM_P2, NULL, 0) iWedgesize[2] = GetDlgltemlnt(hdlg, DM_P3, NULL, 0) iWedgesize[3] = GetDlgltemlnt(hdlg, DM_P4, NULL, 0) iWedgesize[4] = GetDlgltemlnt(hdlg, DM_P5, NULL, 0) iWedgesize[5] = GetDlgltemlnt(hdlg, DM_P6, NULL, 0) iWedgesize[6] = GetDlgltemlnt(hdlg, DM_P7, NULL, 0) iWedgesize[7] = GetDlgltemlnt(hdlg, DM_P8, NULL, 0) iWedgesize[8] - GetDlgltemlnt(hdlg, DM_P9, NULL, 0) iWedgesize[9] = GetDlgltemlnt(hdlg, DM_P10, NULL, 0); EndDialog(hdlg, TRUE); break;

case IDCANCEL:

EndDialog(hdlg, FALSE); break; default:

return FALSE; } break; default:

return FALSE; } return TRUE;

}

LRESULT CALLBACK WndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM IParam) {

HDC hdc; PAINTSTRUCT ps; HBRUSH hBrush;

static HINSTANCE hlnstl, hlnst2; static int xClientView, yClientView;

unsigned int iTotalwedge[maxnumwedge+1]; int i, iNWedges; iNWedges = 0;

ford = 0; i. < maxnurawedge; i++) {

if<iWedgesize[i] != 0) iNWedges++; } iTotalwedge[0] = 0;

306

for(i = 0; i < iNWedges; i++)

iTotalwedge[i+1] = iTotalwedge[i] + iWedgesize[i]; switch (messg) (

case WM_SIZE:

xClientView - LOWORD(IParam); yClientView = HIWORD(IParam); break; case WM_CREATE:

hlnstl = ((LPCREATESTRUCT) IParam)->hlnstance; hlnst2 = ((LPCREATESTRUCT) IParam)->hlnstance; break; case WM_COMMAND:

switch (wParam) { case IDM_ABOUT:

DialogBox(hlnstl, "AboutDlgBox", hWnd, (DLGPROC) AboutDlgProc)i break/case IDM_INPUT:

DialogBox(hlnst2, "PieDlgBox", hWnd, (DLGPROC) PieDlgProc); InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); break; case IDM_EXIT:

SendMessage(hWnd, WM_CLOSE, 0, OL); break; default:

break; }

break; case WM_PAINT:

hdc = BeginPaint(hWnd, Sps); SetMapMode(hdc, MM_ISOTROPIC); SetWindowExtExfhdc, 500, 500, NULL);

SetViewportExtEx(hdc, xClientView, -yClientView, NULL); SetViewportOrgEx(hdc, xClientView/2, yClientView/2, NULL); if(xClientView > 200)

TextOut(hdc, strlen (szTString) * (-8/2), 240, szTString, strlen (szTString));

for(i= 0; i < iNWedges; i++){ ' hBrush = CreateSolidBrush.(lCo;l.or [i]) ; SelectObject(hdc, hBrush); Pie(hdc, -200, 200, 200, - 20:0,,.. :

(int)(radius*cos(2*pi*iTotalWedge[i]/

iTotalWedgeJiNWedges])),

(int)(radius*sin(2*pi*iToialWedge[iJ/

ITotalWedge[iNWedges])),

(int)(radius*cos(2*pi*iTotalWedge[i+1]/ iTotalWedge tiNWedges])), (int)(radius*sin(2*pi*iTotalWedge[i+l]/ iTotalWedge[iNWedges]))); } ValidateRect (hWnd, NULL);

EndPaint (hWnd, Sps); 1 break; case WM_DESTROY: PostQuitMessage (0);

break; default:

return (DefWindowProc (hWnd, messg, wParam, IParam) ) ;

)

return(0);

)

Ниже мы несколько подробнее проанализируем содержимое приведенных файлов.

Файл PIЕ.Н

Файл заголовков приложения содержит уникальные идентификаторы команд меню. Обратите внимание на идентификаторы с префиксом ом_, представляющие поля диалогового окна, в которые пользователь будет вводить значения.

Файл РIЕ.RС

307

Файл ресурсов приложения содержит команду подключения указателя мыши (piecursor), а также описания меню (piemenu) и двух диалоговых окон (aboutdlgbox и piedlgbox). На рис. 17.16 показано диалоговое окно About.

Рис. 17.16. Окно About

Процесс создания этих окон был рассмотрен в предыдущей главе. В описании диалогового окна для каждого элемента управления задаются его размеры и координаты на экране. Редактор ресурсов вычисляет эти значения автоматически. Впрочем, вы можете просто ввести данный файл в текстовом виде, а редактор скомпилирует его и воссоздаст описанные в нем ресурсы.

Файл РIЕ.С

Программа, записанная в файле PIE.C, создает круговую диаграмму, содержащую до десяти секторов. Если в меню выбрать команду Input, откроется диалоговое окно PieChartData, в котором пользователь может установить число секторов и задать их относительную ширину, а также ввести заголовок диаграммы. Эти данные передаются в программу после щелчка на кнопке ОК. Информация, поступающая от диалоговых окон, обрабатывается в ветви caseIDOKпосредством процедуры PieDlgProcO. Текст заголовка возвращается функцией GetDlgltemText(), а числовые значения — функцией GetDlgltemlnt(). Последняя принимает четыре аргумента. Первые два — это дескриптор окна и идентификатор элемента управления. Третий аргумент является указателем на булеву переменную, устанавливаемую в TRUEпри успешном завершении функции. В нашем случае для простоты его значение задано равным null. Четвертый аргумент определяет, следует ли вводимое значение интерпретировать как знаковое (аргумент не равен нулю) или беззнаковое (аргумент равен нулю). Введенные значения сохраняются в глобальном массиве iWedgesize[ ].

Основная работа выполняется в процедуре WndProc(), где обрабатываются пять сообщений: wm_size, wm_create, wm_command, wm_paintи wmjdestroy. Сообщение wm_sizeпосылается всякий раз, когда изменяются размеры окна приложения. Информация о размерах сохраняется в переменных xciientviewи yClientViewи впоследствии, при обработке сообщения wm_paint, используется для настройки масштаба диаграммы.

В процессе обработки сообщения wm_create создаются два дескриптора приложения, hlnstlи hlnst2, которые затем передаются функции DialogBox(), генерирующей экземпляры двух диалоговых окон.

При выборе какой-либо команды меню генерируется сообщение wm_command. Если это сообщение имеет подтип IDM_ABOUT, открывается окно About, а если подтип idm_input— окно ввода данных. При получении сообщения idm_exitприложение закрывает свое главное окно и завершает работу.

Код рисования непосредственно диаграммы содержится в блоке обработки сообщения wm_paint. По умолчанию в системе установлен режим отображения мм_техт. В этом режиме

308

координаты объектов отсчитываются (в пикселях) начиная с верхнего левою угла окна, имеющего координаты 0,0. Вот почему в программе SINE.C вид изображения будет меняться всякий раз при изменении разрешения экрана. В программе PINE.C устанавливается режим отображения mm_isotropic.

SetMapMode(hdc, MM_ISOTROPIC) ; SetWindowExtEx(hdc, 500, 500, NULL);

SetViewportExtEx(hdc, xClientView, -yClientView, NULL); SetViewportOrgEx(hdc, xClientView/2,

yClientView/2, NULL);

Режимы отображения, существующие в Windows, перечислены в табл. 17.4.

Таблица 17.4. Режимы отображения

Режим Описание

mm_anisotropic Одной логической единице соответствует произвольная физическая единица; масштабирование по осям х и у независимое

mm_hienglish

Одной логической единице соответствует 0,001 дюйма; ось у направлена снизу вверх

 

 

mm_himetric

Одной логической единице соответствует 0,01 мм; ось у направлена снизу вверх

 

 

mm_isotropic

Одной логической единице соответствует произвольная физическая единица; масштаб по осям х и у

одинаков

 

 

mm_loenglish

Одной логической единице соответствует 0,01 дюйма; ось у направлена снизу вверх

 

 

mm_lometric

Одной логической единице соответствует 0,1 мм; ось у направлена снизу вверх

 

 

MM_TEXT

Одной логической единице соответствует один пиксель; ось у направлена сверху вниз (это режим по

умолчанию)

 

 

 

MM_TWIPS

Одной логической единице соответствует 1/20 точки принтера (1/1440 дюйма); ось у направлена

снизу вверх

 

 

 

Режим mm_isotropic позволяет программисту самостоятельно выбирать масштаб изображения по осям х и у. Функция SetWindowExtEx( ) задает размеры окна по горизонтали и вертикали (в нашем примере они равны 500). Эти логические размеры автоматически преобразуются системой в соответствии с физическими размерами экрана. В функции SetviewportExtEx( ) устанавливается размер области просмотра (в пикселях). Отрицательное значение координаты у означает, что ось у направлена снизу вверх. Система сравнивает размеры окна и области просмотра и вычисляет соотношение между логическими единицами и пикселями. Функция SetViewportOrgEx( ) устанавливает координаты точки начала области просмотра (в пикселях). В нашем примере это будет центр окна. После вызова этих функций все последующие координаты можно указывать в логических единицах.

Заголовок диаграммы выводится уже с учетом текущего режима отображения. Если размеры окна слишком малы, заголовок не показывается вообще.

if (xClientView > 200)

TextOutfhdc, strlen(szTString)*(-8/2) , 240, szTString,. ,,1" strlen (szTString) );

Прежде чем приступать к построению секторов диаграммы, давайте вернемся к началу процедуры WndProc и выясним, каким образом вычисляются относительные размеры секторов.

В следующем фрагменте определяется, из скольких секторов будет состоять круг:

iNWedges=0;

for(i=0;i < maxnumwedge; i++)

{ if (iWedgesizeli] != 0) iNWedges++;}

Приращение переменой iNWedgesвыполняется каждый раз, когда в массиве iWedgesize [i] обнаруживается ненулевое значение. Таким образом, по окончании цикла будет известно число секторов диаграммы.

Накопительные размеры секторов хранятся в массиве iTotalWedge[] . Эти значения необходимы для вычисления границ между секторами. Например, если пользователь ввел в

качестве размеров секторов значения 5, 10, 7 и 20, то в массиве iTotalWedge[] .. будут представлены значения 0, 5, 15, 22 и 42. Вот как они получаются:

iTotalWedge[0] = 0;

for(i= 0; i < iNWedges; i++)

309

iTotalWedge[i+l] = iTotalWedge [i]+ iWedgesize [i];

Элементы массива iTotalWedge[ ] используются для вычисления начального и конечного углов каждого сектора. Вспомните, что функция Pie( ) принимает девять параметров. Первый является дескриптором контекста устройства. Следующие четыре определяют координаты прямоугольника, в который вписывается эллипс. В нашем примере выбраны координаты - 200,200 и 200,-200. Оставшиеся четыре параметра определяют координаты начальной и конечной точек сектора. Координата х вычисляется с помощью функции cos( ) , а координата у

— с помощью функции sin( ) . Так, начальную координату х первого сектора можно определить как произведение радиуса окружности на косинус значения 2*pi*iTotalWedge[0] . Коэффициент 2*piздесь необходим для преобразования градусов в радианы. Координаты конечной точки сектора определяются по тому же алгоритму, но для их вычисления используется следующий элемент массива iTotalWedge[] — iTotalWedge[1 ]. Чтобы все секторы вписались в круг, значение координаты делится на общий накопительный размер всех секторов — iTotalWedge [iNWedges].

for(i = 0; i < iNWedges; i++) {

hBrush = CreateSolidBrush(lColor [i]) ; SelectObject (hdc, hBrush);

Pie(hdc, -200, 200, 200, -200, (int)(radius*cos (2*pi*iTotalWedge [i]/

iTotalWedge [iNWedges] )), (int)(radius*sin (2*pi*iTotalWedge [i]/

iTotalWedge [ iNWedges] )), (int)(radius*cos(2*pi*iTotalWedge[i+l] / iTotalWedge [iNWedges] ),

(int)(radius*sin(2*pi*iTotalWedge[i+l] / , iTotalWedge [ iNWedges ]);

}

Весь цикл повторяется столько раз, сколько указано в переменной iNWedges. Диаграмма, представленная на рис. 17.18, строится по умолчанию, а показанная на рис. 17.19 — на основании значений, введенных пользователем.

Рис. 17.18. Диаграмма, построенная по умолчанию

310