ИСХОДНЫЕ ФАЙЛЫ DPIPE
draw.cpp
#include "draw_func.h"
#include <windows.h> #include <cstring>
/// Числовой тип
using NumericalType = long double;
int main () {
HANDLE hPipe; /// Дескриптор канала
int foreColor = WHITE, backColor = BLACK; /// Стандартные цвета char buffer[512]; /// Буфер
DWORD dwRead; /// Число действительно прочитанных байт
/// Создаем именованный канал (512 байт - размер сообщения) hPipe = CreateNamedPipe("\\\\.\\pipe\\GraphPipe", PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 512, 512, NMPWAIT_USE_DEFAULT_WAIT, NULL);
while (hPipe != INVALID_HANDLE_VALUE) { /// Пока канал активен
if (ConnectNamedPipe(hPipe, NULL)) { /// Если клиент подключился
/// Принимаем сообщение
while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) !=
FALSE) {
buffer[dwRead] = '\0'; /// Ставим знак конца строки
/// Определяем команду клиента
///(сравнение со строками отсортировано по частоте использования) if (strncmp(buffer, "DrawPoint", 9) == 0) {
NumericalType x, y; |
|
int |
size = 3, color = foreColor; |
sscanf(buffer + 10, "%Le %Le %d %d", &x, &y, &size, &color); |
|
GraphLib::DrawPoint(x, y, size, color); |
|
} |
(strncmp(buffer, "DrawText", 8) == 0) { |
else if |
|
char |
*p; |
int |
x, y, color = foreColor; |
/// |
Перебираем пробелы |
p = |
strchr(buffer, ' '); |
p = |
strchr(p + 1, ' '); |
p = |
strchr(p + 1, ' '); |
/// |
До четвертого: (там где начинается текст) |
p = |
strchr(p + 1, ' '); |
sscanf(buffer + 9, "%d %d %d", &x, &y, &color); |
|
GraphLib::DrawText(x, y, p + 1, color); |
|
} |
(strncmp(buffer, "DrawLinesAndValues", 18) == 0) { |
else if |
|
int |
n = 6; |
sscanf(buffer + 19, "%d", &n); |
|
GraphLib::DrawLinesAndValues(n); |
|
} |
(strncmp(buffer, "DrawLine", 8) == 0) { |
else if |
|
int |
x1, y1, x2, y2, color = foreColor; |
sscanf(buffer + 9, "%d %d %d %d %d", &x1, &y1, &x2, &y2, |
&color);
GraphLib::DrawLine(x1, y1, x2, y2, color);
}
else if (strncmp(buffer, "InitDrawPanel", 13) == 0) { sscanf(buffer + 14, "%d %d", &foreColor, &backColor);
GraphLib::InitDrawPanel(foreColor, backColor);
}
else if (strncmp(buffer, "ClearDevice", 11) == 0) {
40
GraphLib::ClearDevice();
}
else if (strncmp(buffer, "InitGraph", 9) == 0) { NumericalType MinXC, MaxXC, MinYC, MaxYC; NumericalType MaxXin, MaxYin, MarginLeft, MarginTop; MaxXin = 0.6L;
MaxYin = 0.6L; MarginLeft = 0.25L;
MarginTop = 0.2L;
sscanf(buffer + 10, "%Le %Le %Le %Le %Le %Le %Le %Le", &MinXC, &MaxXC, &MinYC, &MaxYC, &MaxXin, &MaxYin,
&MarginLeft, &MarginTop);
GraphLib::InitGraph(MinXC, MaxXC, MinYC, MaxYC, MaxXin, MaxYin, MarginLeft, MarginTop);
}
else if (strncmp(buffer, "DrawChartBorder", 15) == 0) { GraphLib::DrawChartBorder();
}
else if (strncmp(buffer, "DrawAxes", 8) == 0) { GraphLib::DrawAxes();
}
}
}
DisconnectNamedPipe(hPipe); /// Отсоединяемся с клиентом
}
return 0;
}
41
draw_func.h
///------------------
///Библиотека функций отрисовки (H)
///------------------
#include |
<graphics.h> |
|
|
|
#ifndef _MGRAPH_LIB_ |
|
|
|
|
#define _MGRAPH_LIB_ |
|
|
|
|
namespace |
GraphLib { |
|
|
|
using |
NumericalType = long double; |
|
||
void |
InitDrawPanel(int foreColor, int backColor); |
|
||
void |
InitGraph( |
MinXC, |
|
|
NumericalType |
|
|
||
NumericalType |
MaxXC, |
|
|
|
NumericalType |
MinYC, |
|
|
|
NumericalType |
MaxYC, |
|
|
|
NumericalType |
COEF_MAX_X_IN, |
|
||
NumericalType |
COEF_MAX_Y_IN, |
|
||
NumericalType |
COEF_MARGIN_LEFT_IN, |
|
||
NumericalType |
COEF_MARGIN_TOP_IN); |
|
||
void |
ClearDevice(); |
|
|
|
void |
CloseWindow(); |
|
|
|
void |
DrawPoint(NumericalType x, NumericalType y, int size = 3, int color = 15); |
|||
void |
DrawChartBorder(int color = LIGHTBLUE); |
|
||
void |
DrawAxes(); |
x1, int y1, int x2, int y2, int color); |
||
void |
DrawLine(int |
|||
void |
DrawLinesAndValues(int |
iDisplayedValues = 6); |
||
void |
DrawText(int |
x, int y, |
char *textString, int |
color); |
}
#endif
42
draw_func.cpp
///------------------
///Библиотека функций отрисовки (CPP)
///------------------
#include <graphics.h>
#include <cstring> namespace GraphLib {
/// Числовой тип
using NumericalType = long double;
/// Ширина и высота окна вывода графики const unsigned int MWINDOW_WIDTH = 700; const unsigned int MWINDOW_HEIGHT = 700;
/// Размер буфера для экспоненциальной записи числа const unsigned int SIZE_OF_BUFFER = 20;
/// Количество отображаемых значений unsigned int Displayed_Values = 6;
///Коэффициенты размера графика
NumericalType COEF_MAX_X = 0.6L; NumericalType COEF_MAX_Y = 0.6L;
///Коэффициенты расположения графика
NumericalType COEF_MARGIN_LEFT = 0.25L; NumericalType COEF_MARGIN_TOP = 0.2L;
///Максимальные значения координат для графика
NumericalType MaxX;
NumericalType MaxY;
/// Отступы
NumericalType margin_left; NumericalType margin_top;
/// Стандартные цвета int ForeColor = WHITE; int BackColor = BLACK;
/// Минимальные и максимальные координаты
NumericalType MinXCoordinate;
NumericalType MaxXCoordinate;
NumericalType MinYCoordinate;
NumericalType MaxYCoordinate;
/// Функции
void InitDrawPanel(int foreColor, int backColor); void ClearDevice();
void CloseWindow();
void DrawPoint(NumericalType, NumericalType, int size = 3, int color = WHITE); void InitGraph(
NumericalType MinXC,
NumericalType MaxXC,
NumericalType MinYC,
NumericalType MaxYC,
NumericalType COEF_MAX_X_IN,
NumericalType COEF_MAX_Y_IN,
NumericalType COEF_MARGIN_LEFT_IN,
NumericalType COEF_MARGIN_TOP_IN);
void DrawChartBorder(int color = LIGHTBLUE); void DrawAxes();
void DrawText(int x, int y, char *textString, int color); void DrawLinesAndValues(int iDisplayedValues = 6);
void DrawLine(int x1, int y1, int x2, int y2, int color);
}
/// Запуск окна вывода графики (стартовая функция)
void GraphLib::InitDrawPanel(int foreColor, int backColor) { initwindow(
MWINDOW_WIDTH, /// Ширина
MWINDOW_HEIGHT, /// Высота
43
(const char *)"", /// Заголовок
0, /// Отступ слева
0, /// Отступ сверху false, /// Флаг дебага false /// Флаг закрытия
);
BackColor = backColor; ForeColor = foreColor;
settextstyle(SANS_SERIF_FONT, 0, 1); setfillstyle(SOLID_FILL, ForeColor); setbkcolor(BackColor); setcolor(ForeColor);
}
/// Инициализация графика void GraphLib::InitGraph(
NumericalType MinXC, /// Минимальный X NumericalType MaxXC, /// Максимальный X NumericalType MinYC, /// Минимальный Y NumericalType MaxYC, /// Максимальный Y
NumericalType COEF_MAX_X_IN, /// Коэффициент размера по X NumericalType COEF_MAX_Y_IN, /// Коэффициент размера по Y NumericalType COEF_MARGIN_LEFT_IN, /// Коэффициент расположения по X NumericalType COEF_MARGIN_TOP_IN) /// Коэффициент расположения по Y
{
MinXCoordinate = MinXC;
MaxXCoordinate = MaxXC;
MinYCoordinate = MinYC;
MaxYCoordinate = MaxYC; COEF_MAX_X = COEF_MAX_X_IN; COEF_MAX_Y = COEF_MAX_Y_IN; MaxX = getmaxx() * COEF_MAX_X; MaxY = getmaxy() * COEF_MAX_Y;
COEF_MARGIN_LEFT = COEF_MARGIN_LEFT_IN; COEF_MARGIN_TOP = COEF_MARGIN_TOP_IN; margin_left = getmaxx() * COEF_MARGIN_LEFT; margin_top = getmaxy() * COEF_MARGIN_TOP;
}
/// Очистка окна
void GraphLib::ClearDevice() { cleardevice();
}
/// Закрытие окна
void GraphLib::CloseWindow() { closegraph(CURRENT_WINDOW);
}
/// Рисование линии
void GraphLib::DrawLine(int x1, int y1, int x2, int y2, int color) { setcolor(color);
/// Расчет относительной координаты X int kX1 = (x1 - MinXCoordinate)
* MaxX / (MaxXCoordinate - MinXCoordinate); int kX2 = (x2 - MinXCoordinate)
* MaxX / (MaxXCoordinate - MinXCoordinate);
/// Расчет относительной координаты Y int kY1 = (y1 - MinYCoordinate)
*MaxY / (MaxYCoordinate - MinYCoordinate); int kY2 = (y2 - MinYCoordinate)
*MaxY / (MaxYCoordinate - MinYCoordinate);
///Если выход за границы, то нормализация
kX1 = (kX1 < 0) ? 0 : (kX1 > MaxX ? MaxX : kX1);
kX2 = (kX2 < 0) ? 0 : (kX2 > MaxX ? MaxX : kX2);
kY1 = (kY1 < 0) ? 0 : (kY1 > MaxY ? MaxY : kY1);
44
kY2 = (kY2 < 0) ? 0 : (kY2 > MaxY ? MaxY : kY2);
/// Отрисовка line(
margin_left + kX1, margin_top + MaxY - kY1, margin_left + kX2, margin_top + MaxY - kY2
);
}
/// Рисование точки
void GraphLib::DrawPoint(NumericalType x, NumericalType y, int size, int color)
{
setfillstyle(SOLID_FILL, color);
/// Расчет относительной координаты X int kX = (x - MinXCoordinate)
* MaxX / (MaxXCoordinate - MinXCoordinate);
/// Расчет относительной координаты Y int kY = (y - MinYCoordinate)
* MaxY / (MaxYCoordinate - MinYCoordinate); fillellipse(
margin_left + kX, margin_top + MaxY - kY, size,
size
);
}
/// Рисование границы графика
void GraphLib::DrawChartBorder(int color) { setcolor(color);
rectangle( margin_left - 5, margin_top - 5,
margin_left + MaxX + 5, margin_top + MaxY + 5
);
}
/// Рисование осей
void GraphLib::DrawAxes() {
setcolor(ForeColor); int kX = MaxX * (
1.0L - MaxXCoordinate / (MaxXCoordinate - MinXCoordinate)
);
int kY = MaxY * MaxYCoordinate / (MaxYCoordinate - MinYCoordinate);
///Коррекция расположения отображаемых осей и их символов
///X
kX = (kX < 0) ? 0 : (kX > MaxX ? MaxX : kX);
/// Y
kY = (kY < 0) ? 0 : (kY > MaxY ? MaxY : kY);
/// Ось X
bar(margin_left + kX - 1, margin_top, margin_left + kX + 1, margin_top + MaxY);
/// Обозначение оси X
outtextxy(margin_left + MaxX + 10, margin_top + kY - 10, (char *)"X");
/// Ось Y
bar(margin_left, margin_top + kY - 1, margin_left + MaxX, margin_top + kY + 1);
/// Обозначение оси Y
outtextxy(margin_left + kX - 1, margin_top - 30, (char *)"Y");
}
void GraphLib::DrawText(int x, int y, char *textString, int color) {
45
setcolor(color); outtextxy(x, y, textString);
}
void GraphLib::DrawLinesAndValues(int iDisplayedValues) { Displayed_Values = iDisplayedValues;
///RDX - Реальная разница между двумя точками (X) NumericalType rdx = MaxX / (Displayed_Values - 1);
///RDY - Реальная разница между двумя точками (Y)
NumericalType rdy = MaxY / (Displayed_Values - 1);
///DX - Отображаемая разница между двумя точками (X)
NumericalType dx = (MaxXCoordinate - MinXCoordinate) / (Displayed_Values - 1); if (dx < 0) {
dx = -dx;
}
/// DY - Отображаемая разница между двумя точками (Y)
NumericalType dy = (MaxYCoordinate - MinYCoordinate) / (Displayed_Values - 1); if (dy < 0) {
dy = -dy;
}
///Размер шага для отображаемых линий (X)
NumericalType StepX = MinXCoordinate;
///Размер шага для отображаемых линий (Y)
NumericalType StepY = MaxYCoordinate;
///Буфер для работы с экспоненциальной записью числа char Buff[SIZE_OF_BUFFER];
///Тип линии: пунктир
setlinestyle(DOTTED_LINE, 1, 1);
/// Рисовать промежуточные линии с промежуточными значениями for (int i = 0; i < Displayed_Values; i++) {
setcolor(ForeColor);
sprintf(Buff, "%Le", StepX); /// X settextjustify(CENTER_TEXT, VCENTER_TEXT); outtextxy(
margin_left + (rdx + 2) * i,
margin_top + MaxY + 25 + 20 * (i % 2 != 0), Buff
);
sprintf(Buff, "%Le", StepY); /// Y settextjustify(RIGHT_TEXT, VCENTER_TEXT); outtextxy(
margin_left - 20, margin_top + (rdy + 1) * i, Buff
);
setcolor(DARKGRAY); line( /// Линия X
margin_left + (rdx + 0.5) * i - 1, margin_top + MaxY,
margin_left + (rdx + 0.5) * i - 1, margin_top - 4
);
line( /// Линия Y margin_left - 1,
margin_top + (rdy + 0.6) * i - 2, margin_left + MaxY + 10, margin_top + (rdy + 0.6) * i - 2
);
StepX += dx; StepY -= dy;
}
}
46