Лабораторная работа № 4. Работа с таймером 2
Цель:Изучить способы обработки событий в WinAPI. Рассмотреть функции KillTimer, SetTimer, InvalidateRect для создания анимации.
Краткие теоретические сведения:
Функция InvalidateRect добавляет прямоугольник области обновления определяемого окна. Область модификации представляет собой часть клиентской области окна, что переписывается заново. Функция InvalidateRect добавляет прямоугольник области обновления определяемого окна. Область модификации представляет собой часть клиентской области окна, что переписывается заново.
SetTimer создает таймер с заданным значением времени ожидания.
KillTimer уничтожает заданный таймер.
Задание:
4.1. Машинка (рис 3) движется по клиентской области слева направо, когда уходит за область, то вновь появляется слева или разворачивается и возвращается.
Дополнительные эффекты для учебной практики:
движение с ускорением/замедлением;
изменение цвета при приближении к стенке;
движение по наклонной;
видно вращение колес;
выезд за область постепенный, по частям машины.
Рис 3. Машинка
Сообщения:
WM_CREATE – создать таймер;
WM_PAINT – нарисовать машинку в текущей позиции;
WM_TIMER – изменить текущую позицию машинки и сообщить о необходимости обновить клиентскую область.
4.2.Светофор (рис 4). Обеспечить переключение цветов.
Рис 4. Светофор
4.3. В клиентской области расположены три круга разных цветов. Щелчок левой кнопкой мыши по кругу приводит к его «миганию» (увеличение/уменьшение диаметра). Щелчок правой кнопкой мыши по кругу останавливает мигание.
Сообщения:
WM_CREATE – создать таймер;
WM_PAINT – нарисовать три круга в соответствующем состоянии;
WM_TIMER – изменить состояния кругов и сообщить о необходимости обновить клиентскую область;
WM_LBUTTONDOWN – добавить соответствующий круг к «мигающим» (функция GetPixel() позволит определить цвет пикселя, на который попал курсор мыши, и, следовательно, узнать, в область какого круга попал курсор мыши);
WM_RBUTTONDOWN – удалить соответствующий круг из «мигающих».
4.4. График функции.
Нарисовать график функции y=f(x) на отрезке [a,b]. График масштабируется в зависимости от размеров клиентской области. Щелчок по графику приводит к отображению значений (x,y). Проверить для различных функций.
4.5. Шарик катится по синусоиде туда и обратно.
Анализ реализации алгоритма:
4.1.Для движения автомобиля по наклонной плоскости используется объект класса XFORM, позволяющий изменить систему координат. Чтобы показать вращение колес, применяются соответствующие тригонометрические функции. Используютс специальные переменные при обработке сообщения WM_TIMER, придавая ускорение объекту.
Исходный код:
#ifndef CREATE_CAR
#define CREATE_CAR
class Car
{
private:
double x;
double y;
double colour;
int rad;
int marg;
public:
Car(double x1, double y1, double a1, int radi);
void DrawingCar(HDC hDC);
void ChangeX( double dif);
void SetX (double x1);
double GetColour();
void ChangeColour( int dif);
void SetColour (int c1);
double GetX();
friend BOOL MyLine(HDC hDC, int x1, int y1, int x2, int y2);
};
#endif
Результат:В ходе выполнения работы была разработана программа, создающая машинку, которая отвечает требованиям поставленной задачи. Результат работы можно найти в Приложении 2 (WinApi).
4.2.Изображается несколько возможных состояний светофора. Переключение осуществляется с помощью счетчика, обработываемого в WM_TIMER.
Исходный код:
class TrafficLight
{
private:
int width;
int marg;
int rad;
public:
TrafficLight(int width1, int marg1);
int GetRad();
void Circle(HDC hDC, RECT R, int TOP, HBRUSH hBrush);
void DrawingTrafficLight(HDC hDC, RECT R);
};
Посредством данного кода прорисовывается светофор.
Результат:В ходе выполнения работы была разработана программа, создающая светофор, в соответствии с рис. 3. Результат работы можно найти в Приложении 2 (WinApi).
4.3.Используя специально описанную структуру Circle, будем по нажатию соответствующей клавиши мыши изменять значения ее полей. Для работы с неколькими кругами используем вектор заданного типа Circle. Нажатие левой клавиши мыши обрабатывается посредтсвом WM_LBUTTONDOWN, правой клавиши - WM_RBUTTONDOWN.
Исходный код:
class Circle
{
private:
int x, y, red, green, blue, radi;
CircleCondition condition;
public:
Circle (int x, int y, int r, int g, int b, int ra=50, CircleCondition condition1 = NoBlinkStandart): x(x), y(y), red(r), green(g), blue(b), radi(ra), condition(condition1) {}
void DrawingCircle(HDC hdc);
void CheckOnBlinkingToStart(int xMs, int yMs, int dif);
void CheckOnBlinkingToStop(int xMs, int yMs, int dif);
void ChangeStateWhileBlinking(int dif);
int GetRad();
void SetRad(int r);
CircleCondition GetCondition();
};
Программа выполнена с использованием классов.
Результат:В ходе выполнения работы была разработана программа, создающая круги, в соответствии с поставленным условием. Результат работы можно найти в Приложении 2 (WinApi).
4.4.Изображается график и оси. Для того, чтобы определить, в какую часть клиентской области указал мышью пользователь, рассматривается цвет соответствующего пикселя. Если он совпадает с цветом графика, то, просчитываются координаты графика и выводятся на экран.
Исходный код:
class Table
{
private:
int quan; //количество разбиений
int a;//собственно отрезок
int b;
RECT R;
int marg;
double cell;//размер клетки
public:
Table(RECT R1, int marg1, int a1, int b1);
friend BOOL DrawLine(HDC hdc, int x0, int y0, int x, int y);
double GetCell();
int GetMarg();
vector <int> DrawingTable(HDC hdc);
};
class Function
{
private:
double cell;
int marg;
int a;
int b;
public:
Function(double cell1, int marg1, int a1, int b1):cell(cell1), marg(marg1), a(a1), b(b1){}
void Drawing(HDC hdc, vector<int> Point, double (*Func)(double));
bool HitTheTarget(int x, int y, vector<int> Point, double (*Func)(double));
vector <double> GetCoordinates(int x, int y, vector<int> Point, double (*Func)(double));
void DrawCoordinates(HDC hDC, int xMs, int yMs, vector <double> P);
};
Результат:В ходе выполнения работы была разработана программа, создающая необходимый график функции. Результат работы можно найти в Приложении 2 (WinApi).
4.5.Произвольно определяя координату x, рассчитывается координату y с помощью функции синуса. Рассчитанные координаты считаются центром круга. Радиус-вектор перемещается, при помощи тригонометрические функции.
Исходный код:
class Ball
{
int x, y, R;//радиус и координаты
bool distination;
public:
Ball (int x): R(x) {}
void SetXY ( vector<double> P);
void DrawingBall(HDC hdc);
void ShowRadius(HDC hdc);
};
Также в задаче используются классы, представленные в 4.4.
Результат:В ходе выполнения работы была разработана программа, создающая синусоиду и катящийся по ней шарик. Результат работы можно найти в Приложении 2 (WinApi).
Выводы:Использовав функции InvalidateRect, SetTimer, KillTimer, а также функции BeginPaint, EndPaint, MessageBox, Ellipse и другие, изученные ранее, научилась обрабатывать события.
С#
Лабораторная работа №1. Простейшее приложение Windows Forms
Цель:Изучить способы работы с текстовыми файлами в C#. Рассмотреть создание диаграмм, меню, диалоговых окон средствами C#.
Краткие теоретические сведения:
C# стремится предоставить основные возможности C++ в более удобной и простой для использования форме. Снижение сложности велось по двум основным направлениям. Во-первых – отказ от "сложных" средств языка С++, таких, как например, управление памятью вручную. Второе направление снижения сложности – замена "сложных" средств С++ сходными, но более простыми для понимания конструкциями. Множественное наследование С++ превратилось в простое наследование плюс интерфейсы. Современные версии C# поддерживают шаблоноподобные обобщенные классы, которые, по мнению разработчиков C#, проще шаблонов С++. Кроме того, C# предоставляет обширные библиотеки, позволяющие многим программистам сосредоточиться не на написании нового кода, а на соединении уже имеющихся компонентов.
Класс Form представляет собой заготовку формы, от которой наследуются классы форм приложения. Помимо множества унаследованных элементов, в этом классе определено большое количество собственных элементов. В библиотеке .NET нет специального класса для представления диалоговых окон. Вместо этого устанавливаются определенные значения свойств в классе обычной формы. В диалоговом окне можно располагать те же элементы управления, что и на обычной форме. Для вывода линий, геометрических фигур, текста и изображений необходимо создать экземпляр класса Graphics, описанного в пространстве имен System.Drawing.
Задание: Разработайте приложение Windows Forms при помощи MS Visual Studio C#.
При реализации интерфейса следуйте рекомендациям стандарта CUI (Common User Interface).
Программа должна иметь главное меню, строку состояния и клиентскую область (область рисования).
Главное меню приложения обязательно должно содержать следующие команды (в формате Подменю/Команда):
– File/Open - выбор файла
– File/Quit - завершение приложения после подтверждения пользователя
– Help/About - вывод диалогового окна которое печатает условие задачи и информацию о разработчике (ФИО студента, группа, курс, факультет, ВУЗ)
– (команды) - команды необходимые для решения вашей задачи, например, View/Fonts для выбора шрифта, View/Colors для настройки цвета и т.п.
Постройте диаграмму опроса в сети отображающую процентное соотношение проголосовавших.
Входные данные хранятся в текстовом файле. Первая строка файла содержит наименование опроса. Каждая последующая строка файла содержит количество проголосовавших, затем, через пробел и до конца строки текст, соответствующий опции опроса.
Для выбора файла входных данных использовать стандартный диалог.
Анализ реализации алгоритма:
Для создания макета диалогового окна используется панель элементов. Чтобы разрабатываемое приложение соответствовало стандартам Graphical User Interface, предусматривается наличие строки меню. Используются специальные классы C#, такие как openFileDialog, для обеспечения взаимодействия приложения и файловой системы, тем самым предоставляя пользователю возможность указать файл с исходными данными. При работе с текстовыми файлами предусматриваются и обрабатываются возможные исключительные ситуации. С помощью средств обработки статистики, обозначаемых как Chart на панели элементов (доступно только при наличии библиотек Microsoft.NET 4.0 и выше), визуализируются полученные данные в виде круговой и столбчатой диаграмм.
Исходный код:
public class FileDiagramDataProvider : IDataProvider<DiagramData>
{
private readonly string _filename;
public FileDiagramDataProvider(string filename)
{
_filename = filename;
}
public DiagramData Get()
{
var dd = new DiagramData();
using (var reader = new StreamReader(new FileStream(_filename, FileMode.Open, FileAccess.Read), Encoding.GetEncoding("windows-1251")))
{
dd.Name = reader.ReadLine();
var nodes = new List<Node>();
var s = reader.ReadLine();
while (s != null)
{
var sSplitted = s.Split(' ');
if (sSplitted.Length > 1)
{
var node = new Node { Name = s, Value = int.Parse(sSplitted[0]) };
nodes.Add(node);
}
s = reader.ReadLine();
}
dd.Nodes = nodes;
}
return dd;
}
}
При помощи данного класса происходит считывание информации из файла.
Результат:В ходе выполнения работы была разработана программа, создающая круговую диаграмму, на основе предоставляемой информации. Результат работы можно найти в Приложении 3 (C#).
Выводы: Я изучила способы работы с текстовыми файлами в C#. Рассмотрела создание диаграмм, меню, диалоговых окон средствами C#.