Добавил:
nyan
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include <windows.h>
#include <math.h>
#include <tchar.h>
#include <stdio.h>
#include "resource.h"
#include "wingdi.h"
//прототипы функции
void Polygon_OnDC(HWND);
void Ellipse_OnDC(HWND);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Line_Paint(HWND);
inline int ym(double);
inline int xn(double);
TCHAR cname[] = _T("Class"); //имя класса окна
TCHAR title[] = _T("Sinusoid"); //заголовок окна
struct POINT2 {
double x, y;
};
void Polygon_OnDC(HWND hwnd)
{
RECT rc;
GetClientRect(hwnd,&rc); //дает размеры клиентской области окна <hwnd>
//размеры окна в мировых координатах и в пикселях
LONG xLeft;
LONG xRight;
LONG yBottom;
LONG yTop;
LONG nLeft;
LONG nRight;
LONG mBottom;
LONG mTop;
xLeft = -20; xRight = 20; yBottom = -20; yTop = 20;
nLeft = rc.left; nRight = rc.right; mBottom = rc.bottom; mTop = rc.top;
double masht; //коэффициент угловой деформации при переходе
//от мировых к экранным координатам
masht = (xRight-xLeft)*(mBottom-mTop)/(yTop-yBottom)/(nRight-nLeft);
HDC hdc;
hdc = GetDC(hwnd);
HBRUSH hbrush, hbrushOld;
HPEN hpen1, hpen2, hpenOld;
hpen1 = CreatePen(PS_SOLID,1,RGB(0,255,255));
hpenOld = (HPEN)SelectObject(hdc,hpen1);
int nb, ne, mb, me;
//рисуем ось OX
nb = xn(xLeft * 10); mb = ym(0);
MoveToEx(hdc, nb, mb, NULL);
ne = xn(xRight * 10); me = ym(0);
LineTo(hdc,ne,me);
//рисуем ось OY
nb = xn(0); mb = ym(yBottom * 10);
MoveToEx(hdc, nb, mb, NULL);
ne = xn(0); me = ym(yTop * 10);
LineTo(hdc,ne,me);
POINT2 Vt[16];
Vt[0].x = 43; Vt[0].y = 23;
Vt[1].x = 58; Vt[1].y = 9;
Vt[2].x = 58; Vt[2].y = 29;
Vt[3].x = 79; Vt[3].y = 30;
Vt[4].x = 64; Vt[4].y = 44;
Vt[5].x = 79; Vt[5].y = 58;
Vt[6].x = 58; Vt[6].y = 59;
Vt[7].x = 58; Vt[7].y = 78;
Vt[8].x = 43; Vt[8].y = 65;
Vt[9].x = 27; Vt[9].y = 78;
Vt[10].x = 27; Vt[10].y = 59;
Vt[11].x = 6; Vt[11].y = 59;
Vt[12].x = 20; Vt[12].y = 44;
Vt[13].x = 7; Vt[13].y = 30;
Vt[14].x = 27; Vt[14].y = 29;
Vt[15].x = 27; Vt[15].y = 9;
POINT P[16];
for(int i=0; i<16; i++)
{
P[i].x = xn(Vt[i].x * 0.75 - 32); P[i].y = ym(Vt[i].y * 1.5 - 66);
}
hpen2 = CreatePen(PS_SOLID,2,RGB(255,0,0));
SelectObject(hdc,hpen2);
hbrush = CreateSolidBrush(RGB(0,200,255));
hbrushOld = (HBRUSH)SelectObject(hdc,hbrush);
Polygon(hdc, P, 16);
SelectObject(hdc,hbrushOld);
DeleteObject(hbrush);
SelectObject(hdc,hpenOld);
DeleteObject(hpen1);
DeleteObject(hpen2);
LOGFONT lf;
HFONT hFont, hFontOld;
double dx, dy, alf;
for(int j=0; j<1; j++)
{
dx = Vt[j+1].x - Vt[j].x;
dy = Vt[j+1].y - Vt[j].y;
alf = atan2(dy*masht,dx);
memset(&lf, 0, sizeof(LOGFONT));
wcscpy_s(lf.lfFaceName, L"Courier New");
lf.lfHeight = 18;
lf.lfWeight = FW_BOLD;
lf.lfEscapement = LONG(573*alf);
hFont = CreateFontIndirect(&lf);
if(j == 0)
hFontOld = (HFONT)SelectObject(hdc, hFont);
else
SelectObject(hdc, hFont);
SetBkColor(hdc,RGB(192,192,192));
SetTextColor(hdc,RGB(255,255,255));
TextOut(hdc,xn(Vt[j].x - 1.25*sin(alf)),
ym(Vt[j].y + 1.25*cos(alf)), _T(" Polygon "),9);
}
SelectObject(hdc, hFontOld);
DeleteObject(hFont);
ReleaseDC(hwnd, hdc);
HRGN hrgn1 = CreateRectRgn(nLeft,mTop,nRight,mBottom);
HBRUSH hbrush1 = CreateSolidBrush(RGB(0xC0,0xC0,0xC0));
FillRgn(hdc,hrgn1,hbrush1);
DeleteObject(hbrush1);
DeleteObject(hrgn1);
}
void Ellipse_OnDC(HWND hwnd)
{
RECT rc;
GetClientRect(hwnd,&rc); //дает размеры клиентской области окна <hwnd>
//размеры окна в мировых координатах и в пикселях
LONG xLeft;
LONG xRight;
LONG yBottom;
LONG yTop;
LONG nLeft;
LONG nRight;
LONG mBottom;
LONG mTop;
xLeft = -80; xRight = 80; yBottom = -80; yTop = 80;
nLeft = (5*rc.left + rc.right)/8;
nRight = (5*rc.right + rc.left)/6;
mBottom = (7*rc.bottom + rc.top)/8;
mTop = (7*rc.top + rc.bottom)/8;
HDC hdc = GetDC(hwnd);
//создание прямоугольной области поля вывода
HRGN hrgn1 = CreateRectRgn(nLeft,mTop,nRight,mBottom);
//заливаем выделенную область белым цветом
HBRUSH hbrush1 = CreateSolidBrush(RGB(0xFF,0xFF,0xFF));
FillRgn(hdc,hrgn1,hbrush1);
//ограничиваем область вывода изображения
SelectClipRgn(hdc,hrgn1);
LOGFONT lf;
HFONT hFont1, hFontOld;
//создаем шрифт, выбираем его в контекст устройства и рисуем надпись
memset(&lf, 0, sizeof(LOGFONT));
wcscpy_s(lf.lfFaceName, L"Arial");
lf.lfHeight = 35;
lf.lfWeight = FW_BOLD;
lf.lfEscapement = 900;
hFont1 = CreateFontIndirect(&lf);
hFontOld = (HFONT)SelectObject(hdc, hFont1);
TextOut(hdc,xn(-30), ym(-20), _T(" E l l i p s e "),16);
HPEN hpen1, hpenOld;
hpen1 = CreatePen(PS_SOLID,1,RGB(0,255,255));
hpenOld = (HPEN)SelectObject(hdc,hpen1);
int nb, ne, mb, me;
//рисуем ось OX
nb = xn(xLeft); mb = ym(0);
MoveToEx(hdc, nb, mb, NULL);
ne = xn(xRight); me = ym(0);
LineTo(hdc,ne,me);
//рисуем ось OY
nb = xn(0); mb = ym(yBottom);
MoveToEx(hdc, nb, mb, NULL);
ne = xn(0); me = ym(yTop);
LineTo(hdc,ne,me);
//размеры эллипса
double x1 = -20, x2 = 20, y1 = -20, y2 = 20;
HPEN hpen2 = CreatePen(PS_SOLID,2,RGB(255,0,0));
SelectObject(hdc,hpen2);
HBRUSH hbrush2, hbrushOld;
hbrush2 = CreateSolidBrush(RGB(0,200,255));
hbrushOld = (HBRUSH)SelectObject(hdc,hbrush2);
//Ellipse(hdc, xn(x1), ym(y1), xn(x2), ym(y2));
float xSt, yStr, xEn, yEn;
xSt=-20;
yStr=-10;
xEn=20;
yEn=-10;
Chord(hdc, xn(x1), ym(y1), xn(x2), ym(y2), xn(xSt), ym(yStr), xn(xEn), ym(yEn));
//восстанавливаем контекст по умолчанию и уничтожаем созданные GDI-объекты
SelectObject(hdc,hbrushOld);
DeleteObject(hbrush1);
DeleteObject(hbrush2);
SelectObject(hdc,hpenOld);
DeleteObject(hpen1);
DeleteObject(hpen2);
SelectObject(hdc, hFontOld);
DeleteObject(hFont1);
DeleteObject(hrgn1);
ReleaseDC(hwnd, hdc);
}
//главная функция
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdParam,
int nCmdShow)
{
//регистрация класса окна приложения
//------------------------------------------------------------------------
WNDCLASS wc; // структура для регистрации класса окна приложения
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WndProc; //функция окна
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance; //дескриптор приложения
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = (LPCTSTR)IDR_MENU1;
wc.lpszClassName = cname; //имя класса окна
if(!RegisterClass(&wc)) //регистрация класса окна приложения
return 0;
//создание окна приложения
//------------------------------------------------------------------------
HWND hWnd; // дескриптор окна приложения
hWnd = CreateWindow(cname, //имя класса окна
title, //заголовок окна
WS_OVERLAPPEDWINDOW, // стиль окна
CW_USEDEFAULT, // x
CW_USEDEFAULT, // y
CW_USEDEFAULT, // Width
CW_USEDEFAULT, // Height
NULL, //дескриптор окна-родителя
NULL, //дескриптор меню
hInstance, //дескриптор приложения
NULL);
if(!hWnd)
return 0;
// Рисуем окно.
//--------------------------------------------------------------------------
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
// Запускаем цикл обработки сообщений
MSG msg; // структура для работы с сообщениями
//-------------------------------------------------------------------------
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg); // Посылает сообщение функции WndProc()
}
return 0;
}
//функция окна, принимающая сообщения
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message)
{
//сообщение при обновлении окна
case WM_PAINT:
Line_Paint(hWnd); //функция рисования
break;
//сообщение при закрытии окна
case WM_DESTROY:
PostQuitMessage(0); //выход из цикла сообщений
break;
//сообщения от кнопок меню
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FILE_EXIT:
PostQuitMessage(0);
break;
case ID_CLEAN:
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_GRAPH_EL:
Ellipse_OnDC(hWnd);
break;
case ID_GRAPH_POL:
Polygon_OnDC(hWnd);
break;
}
break;
//обработка сообщений по умолчанию
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}
//размеры поля вывода в мировой системе координат
double xLeft, xRight, yBottom, yTop;
//размеры поля вывода в пикселях в клиентской области
//окна приложения
int nLeft, nRight, mBottom, mTop;
//функция вызывается на сообщение WM_PAINT
void Line_Paint(HWND hwnd)
{
RECT rc;
GetClientRect(hwnd,&rc); //дает размеры клиентской области окна <hwnd>
//размеры окна в мировых координатах и в пикселях
xLeft = -80; xRight = 80; yBottom = -80; yTop = 80;
//nLeft = 500; nRight = 50; mBottom = 150; mTop = 20;
nLeft = rc.left; nRight = rc.right; mBottom = rc.bottom; mTop = rc.top;
//создаем массивы точек для аргумента x и функции y = sin(x)
const int N = 50;
double corX[N], corY[N];
double x, y, dx = (xRight - xLeft)/(N-1);
for(int i=0; i<N; i++)
{
x = xLeft + dx*i; y = sin(x)*sin(x);
corX[i] = x; corY[i] = y;
}
//создаем массивы точек для аргумента x и функции y = (exp(-x))/2
const int M = 50;
double cor2X[M], cor2Y[M];
double x1, y1, dx1 = (xRight - xLeft)/(N-1);
for(int i=0; i<M; i++)
{
x1 = xLeft + dx1*i; y1 = (exp(-x1))/2;
cor2X[i] = x1; cor2Y[i] = y1;
}
HDC hdc; //дескриптор контекста устройства
PAINTSTRUCT ps; //структура для работы контеста
//получаем контекст устройства <hdc> для окна <hwnd>
hdc = BeginPaint(hwnd, &ps);
HBRUSH hbrush, hbrushOld; //дескрипторы кистей
HPEN hpen1, hpen2, hpen3, hpen4, hpenOld; //дескрипторы перьев
//создаем кисть <hbrush1>, стиль - сплошной, цвет - синий
hbrush = CreateSolidBrush(RGB(0,0,200));
//выбираем кисть <hbrush> в контекст устройства <hdc>,
//запоминаем дескриптор старой кисти <hbrushOld>
hbrushOld = (HBRUSH)SelectObject(hdc,hbrush);
//создаем перо <hpen1>, стиль - сплошной, толщина 3 пиксела, цвет - ярко-желтый
hpen1 = CreatePen(PS_SOLID,3,RGB(255,255,0));
//выбираем перо <hpen1> в контекст устройства <hdc>,
//запоминаем дескриптор старого пера <hpenOld>
hpenOld = (HPEN)SelectObject(hdc,hpen1);
//рисуем прямоугольник с границей
Rectangle(hdc,nLeft,mBottom,nRight,mTop);
/*
//создаем перо <hpen2>, стиль - сплошной, толщина 1 пиксел, цвет - ярко-голубой
hpen2 = CreatePen(PS_SOLID,1,RGB(0,255,255));
//выбираем перо <hpen2> в контекст устройства <hdc>
SelectObject(hdc,hpen2);
int nb, ne, mb, me;
POINT pt;
//рисуем ось OX
nb = xn(xLeft); mb = ym(0);
MoveToEx(hdc, nb, mb, &pt);
ne = xn(xRight); me = ym(0);
LineTo(hdc,ne,me);
//рисуем ось OY
nb = xn(0); mb = ym(yBottom);
MoveToEx(hdc, nb, mb, &pt);
ne = xn(0); me = ym(yTop);
LineTo(hdc,ne,me);
//рисуем график по двум массивам
//создаем перо <hpen3>, стиль - сплошной, толщина 2 пиксел, цвет - ярко-красный
hpen3 = CreatePen(PS_SOLID,2,RGB(255,0,0));
//выбираем перо <hpen3> в контекст устройства <hdc>
SelectObject(hdc,hpen3);
nb = xn(corX[0]); mb = ym(corY[0]);
MoveToEx(hdc, nb, mb, &pt);
for( int i=1; i<N; i++)
{
nb = xn(corX[i]); mb = ym(corY[i]);
LineTo(hdc,nb,mb);
}
//создаем перо <hpen3>, стиль - сплошной, толщина 2 пиксел, цвет - ярко-красный
hpen4 = CreatePen(PS_SOLID,2,RGB(255,255,0));
//выбираем перо <hpen3> в контекст устройства <hdc>
SelectObject(hdc,hpen4);
nb = xn(cor2X[0]); mb = ym(cor2Y[0]);
MoveToEx(hdc, nb, mb, &pt);
for( int i=1; i<M; i++)
{
nb = xn(cor2X[i]); mb = ym(cor2Y[i]);
LineTo(hdc,nb,mb);
}
*/
SelectObject(hdc,hbrushOld); //выбираем старую кисть <hbrushOld> в контекст устройства <hdc>
DeleteObject(hbrush); //уничтожаем кисть <hbrush>
/*
SelectObject(hdc,hpenOld); //выбираем старое перо <hpenOld> в контекст устройства <hdc>
DeleteObject(hpen1); //уничтожаем перо <hpen1>
DeleteObject(hpen2); //уничтожаем перо <hpen2>
DeleteObject(hpen3); //уничтожаем перо <hpen3>
DeleteObject(hpen4);*/
EndPaint(hwnd, &ps); //освобождаем контекст устройства <hdc> в окне <hwnd>
}
//переход от x к пикселю n
inline int xn(double x)
{
return (int)((x - xLeft)/(xRight - xLeft)*(nRight - nLeft)) + nLeft;
}
//переход от y к пикселю m
inline int ym(double y)
{
return (int)((y - yBottom)/(yTop - yBottom)*(mTop - mBottom)) + mBottom;
}