Работа с элементами управления. Пример 3
Описать функцию, которая в указанном прямоугольнике строит эллиптическую диаграмму. Количество секторов, их доля в процентах и цвета закрашивания также передаются аргументами вызова функции.
При щелчке правой кнопки мыши появляется диалоговое окно. Пользователь вводит положение и размеры прямоугольника, к который вписывается эллипс.
При щелчке левой кнопки мыши появляется диалоговое окно, в котором пользователь вводит параметры необходимого сектора: его процентную долю от всего эллипса и его цвет. Существует возможность добавить новый сектор и удалить существующий. Также присутвует область, которая показывает заполненность элипса.
В результате возможно получение данного эллипса, разделенного на сектора разных цветов.
Листинг программы
// --- Обязательный включаемый файл
#include <windows.h>
#include <math.h>
#include <windowsx.h>
#include <stdlib.h>
#include "resource.h"
#define PI 3.14156
// --- Описание функции главного окна
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DlgProc1(HWND hDlg1, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DlgProc2(HWND hDlg2, UINT msg, WPARAM wParam, LPARAM lParam);
double CalculateProcentToRad(double Percent);
//===================================================
double Edit[7];
struct TSector
{
double Percent;
int Color;
};
TSector Sectors[20];
int sector_count = 0;
int percent_count = 0;
//==========================================================================
void PrintRect(HDC hDC){
HPEN hpenW1, hpenOldPen;
hpenW1 = CreatePen(PS_SOLID, 1, RGB(0,0,0));
hpenOldPen = SelectPen(hDC, hpenW1);
MoveToEx(hDC, Edit[1], Edit[2], NULL);
LineTo(hDC, (Edit[1]+Edit[4]), Edit[2]);
MoveToEx(hDC, (Edit[1]+Edit[4]), Edit[2], NULL);
LineTo(hDC, (Edit[1]+Edit[4]), (Edit[2]+Edit[3]));
MoveToEx(hDC, (Edit[1]+Edit[4]), (Edit[2]+Edit[3]), NULL);
LineTo(hDC, Edit[1], (Edit[2]+Edit[3]));
MoveToEx(hDC, Edit[1], (Edit[2]+Edit[3]), NULL);
LineTo(hDC, Edit[1], Edit[2]);
SelectPen(hDC, hpenOldPen);
DeletePen(hpenW1);
}
//=========================================================================
void PrintRadPie (HDC hDC, int X0, int Y0, int A, int B, double R1, double R2, int Color){
HBRUSH hBr = CreateSolidBrush(Color);
HBRUSH hBrOld = (HBRUSH)SelectObject(hDC,hBr);
Pie ( hDC, // дескриптор контекста отображения
X0, Y0, // координаты верхнего левого угла
A+X0, B+Y0, // координаты правого нижнего угла
((A/2)*cos(R1) + X0 + (A/2)), (-(B/2)*sin(R1) + Y0 + (B/2)), // координаты начала дуги
((A/2)*cos(R2) + X0 + (A/2)), (-(B/2)*sin(R2) + Y0 + (B/2)) // координаты начала дуги
);
SelectObject(hDC,hBrOld);
DeleteObject(hBr);
}
//===========================================================================
void PrintRadDiagram(HDC hDC, int X0, int Y0, int A, int B, TSector* Sectors, int SectorCount)
{
double R1 = 0;
for(int i=0; i<SectorCount; i++){
double R2 = CalculateProcentToRad(Sectors[i].Percent)+R1;
if(Sectors[i].Percent!=0){
PrintRadPie (hDC, X0, Y0, A, B, R1, R2, Sectors[i].Color);
}
R1 = R2;
}
}
//===========================================================================
double CalculateProcentToRad(double Percent){
double Rad = ((2*PI)*Percent)/100;
return Rad;
}
...
// --- Функция WinMain
int WINAPI WinMain( HINSTANCE hInstance,
...
for(int i=0;i<20;i++){
Sectors[i].Percent = 0;
Sectors[i].Color = 0;
}
Edit[0]=0;
Edit[1]=100;
Edit[2]=100;
Edit[3]=300;
Edit[4]=300;
Edit[5]=255;
Edit[6]=255;
Edit[7]=0;
...
// --- Функция окна
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
InvalidateRect(hWnd,NULL,TRUE);
hDC=BeginPaint(hWnd,&ps);
PrintRect(hDC);
if(sector_count!=0)
PrintRadDiagram(hDC, Edit[1], Edit[2], Edit[4], Edit[3], Sectors, sector_count);
EndPaint(hWnd,&ps);
}; break;
case WM_LBUTTONDOWN:
{
DialogBox(hInst,(LPCTSTR)IDD_DIALOG1,hWnd,(DLGPROC)DlgProc1);
InvalidateRect(hWnd,NULL,TRUE);
UpdateWindow(hWnd);
};
break;
case WM_RBUTTONDOWN:
{
DialogBox(hInst,(LPCTSTR)IDD_DIALOG2,hWnd,(DLGPROC)DlgProc2);
InvalidateRect(hWnd,NULL,TRUE);
UpdateWindow(hWnd);
};
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}; break;
default: return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0l;
}
//==========================================================================
LRESULT CALLBACK DlgProc1(HWND hDlg1, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
{
SetDlgItemInt(hDlg1,IDC_EDIT2,Edit[1],0);
SetDlgItemInt(hDlg1,IDC_EDIT3,Edit[2],0);
SetDlgItemInt(hDlg1,IDC_EDIT4,Edit[3],0);
SetDlgItemInt(hDlg1,IDC_EDIT5,Edit[4],0);
return TRUE;
}; break;
case WM_COMMAND:
{
switch(wParam)
{
case IDOK:
{
Edit[1] = GetDlgItemInt(hDlg1,IDC_EDIT2,FALSE,0);
Edit[2] = GetDlgItemInt(hDlg1,IDC_EDIT3,FALSE,0);
Edit[3] = GetDlgItemInt(hDlg1,IDC_EDIT4,FALSE,0);
Edit[4] = GetDlgItemInt(hDlg1,IDC_EDIT5,FALSE,0);
EndDialog(hDlg1,TRUE);
}; break;
case IDC_CLEAR:
{
SetDlgItemInt(hDlg1,IDC_EDIT2,0,0);
SetDlgItemInt(hDlg1,IDC_EDIT3,0,0);
SetDlgItemInt(hDlg1,IDC_EDIT4,0,0);
SetDlgItemInt(hDlg1,IDC_EDIT5,0,0);
}; break;
case IDCANCEL:
{
EndDialog(hDlg1,TRUE);
}; break;
default: return FALSE;
};
}
default: return FALSE;
};
return TRUE;
}
//==========================================================================
LRESULT CALLBACK DlgProc2(HWND hDlg2, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
{
SetDlgItemInt(hDlg2,IDC_RED,Edit[5],0);
SetDlgItemInt(hDlg2,IDC_GREEN,Edit[6],0);
SetDlgItemInt(hDlg2,IDC_BLUE,Edit[7],0);
SetDlgItemInt(hDlg2,IDC_EDIT2,percent_count,0);
return TRUE;
}; break;
case WM_COMMAND:
{
switch(wParam)
{
case IDOK2:
{
Edit[0] = GetDlgItemInt(hDlg2,IDC_PERCENT,FALSE,0);
Edit[5] = GetDlgItemInt(hDlg2,IDC_RED,FALSE,0);
Edit[6] = GetDlgItemInt(hDlg2,IDC_GREEN,FALSE,0);
Edit[7] = GetDlgItemInt(hDlg2,IDC_BLUE,FALSE,0);
SetDlgItemInt(hDlg2,IDC_EDIT2,percent_count,0);
EndDialog(hDlg2,TRUE);
}; break;
case IDC_SECTOR:
{
if((GetDlgItemInt(hDlg2,IDC_PERCENT,FALSE,0)+percent_count)>100){
MessageBox(NULL,
"Слишком большой процент","Превышен лимит",MB_OK|MB_ICONSTOP);
return FALSE;
}
else {
Sectors[sector_count].Percent = GetDlgItemInt(hDlg2,IDC_PERCENT,FALSE,0);
percent_count += GetDlgItemInt(hDlg2,IDC_EDIT1,FALSE,0);
Sectors[sector_count].Color = RGB(GetDlgItemInt(hDlg2,IDC_RED,FALSE,0),
GetDlgItemInt(hDlg2,IDC_GREEN,FALSE,0),
GetDlgItemInt(hDlg2,IDC_BLUE,FALSE,0)
);
}
sector_count++;
SetDlgItemInt(hDlg2,IDC_EDIT2,percent_count,0);
}; break;
case IDC_DEL_SECTOR:
{
if(percent_count>0){
sector_count--;
percent_count -= (int)Sectors[sector_count].Percent;
SetDlgItemInt(hDlg2,IDC_EDIT2,percent_count,0);
Sectors[sector_count].Percent = 0;
Sectors[sector_count].Color = 0;
}
}; break;
case IDCANCEL2:
{
EndDialog(hDlg2,TRUE);
}; break;
default: return FALSE;
};
}
default: return FALSE;
};
return TRUE;
}
Дата добавления: 2017-01-26; просмотров: 1028;