Коды классов, функций и обработчиков событий
Сохраните модуль главной формы под именем LR_6, а проект – под именем PR_LR_6.
Для размещения классов в проекте использован модуль, не связанный с формой. Чтобы создать такой модуль, нужно выполнить команду Файл/Новый/Другое… и открывшемся окне Новые элементы на странице Новый щелкнуть на пиктограмме Модуль. Модулю дано имя f_6. В заголовочном файле этого модуля f_6.hнаходятся объявления: структурного типа Node для данных заявки, класса data объекта – заявка и класса queue объекта - очередь заявок. В файле реализации модуля f_6.cpp – реализации классов (определения функций-элементов классов).
Заголовочный файлf_6.h модуля f_6 (без формы)
//---------------------------------------------------------------------------
#ifndef f_6H
#define f_6H
//---------------------------------------------------------------------------
//структура для данных
struct Node
{
char* name; //фамилия и.о.
char* model; //название устройства
char* work; //описание работ
int priority; //приоритет
};
//---------------------------------------------------------------------------
//класс - заявка
class data
{
public:
data(); //конструктор с умолчанием
data(const data &c); //конструктор копии
void set_dat(Node*); //установка данных
Node* get_dat(){return d;} //возвращает указатель на данные
data& operator=(const data& x);//перегруженная операция присваивания
~data(); //деструктор
private:
Node* d; //указатель на структуру с данными
};
//---------------------------------------------------------------------------
// класс - очередь заявок
class queue
{
public:
queue(); //конструктор
void insert(int i, Node*);//добавление i-той заявки в очередь
data del(); //выборка заявки из очереди
void queue_clear(); //удаление очереди
data get_mas_dat(int i){return dat[i];}//возврат i-той эаявки
void set_size(int s){size=s;}//задать количество заявок в очереди
int get_size(){return size;}//возврат количества заявок в очереди
~queue(); //деструктор
private:
data* dat; //указатель на данные (заявку)
int size; //количество заявок в очереди
};
//--------------------------------------------------------------------------
#endif
Файл реализацииf_6.cpp модуля f_6 (без формы)
//---------------------------------------------------------------------------
#pragma hdrstop
#include "f_6.h"
#include<string.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
//конструктор с умолчанием класса заявка
//примем, что количество символов
// в любом из полей заявки - не более 50
data::data()
{
d=new Node;
d->name=new char[50];
d->model=new char[50];
d->work=new char[50];
d->priority=0;
}
//---------------------------------------------------------------------------
//конструктор копии класса заявка
data::data(const data& c)
{
d=new Node;
d->name = new char[50];
strcpy(d->name,c.d->name);
d->model = new char[50];
strcpy(d->model,c.d->model);
d->work = new char[50];
strcpy(d->work,c.d->work);
d->priority=c.d->priority;
}
//---------------------------------------------------------------------------
//установка данных
void data::set_dat(Node*pd)
{
strcpy(d->name,pd->name);
strcpy(d->model,pd->model);
strcpy(d->work,pd->work);
d->priority=pd->priority;
}
//---------------------------------------------------------------------------
//перегруженная операция присваивания
data& data::operator=(const data& x)
{
if(&x==this) return *this;
strcpy(d->name,x.d->name);
strcpy(d->model,x.d->model);
strcpy(d->work,x.d->work);
d->priority=x.d->priority;
return *this;
}
//---------------------------------------------------------------------------
//деструктор класса заявка
data::~data()
{
delete[]d->name;
delete[]d->model;
delete[]d->work;
delete d;
}
//---------------------------------------------------------------------------
//примем, что максимальное количество заявок в очереди - 20
const N=20;
//---------------------------------------------------------------------------
//конструктор класса очередь заявок
queue::queue()
{
dat= new data[N];
size=0;
}
//---------------------------------------------------------------------------
//добавление элемента в очередь
void queue::insert(int i, Node*pd)
{
dat[i].set_dat(pd);
size++;
}
//---------------------------------------------------------------------------
//выборка элемента из очереди
data queue::del()
{
int m=0;
int pm=dat[0].get_dat()->priority;
for(int i=1; i<size; i++)
if(pm<dat[i].get_dat()->priority)
{
pm=dat[i].get_dat()->priority;
m=i;
}
data dm = dat[m];
for(int i=m; i<size-1; i++) dat[i]=dat[i+1];
size--;
data dt;
dat[size]=dt;
return dm;
}
//---------------------------------------------------------------------------
//удаление очереди
void queue::queue_clear()
{
if(!size) return;
data dt=this->del();
queue_clear();
}
//---------------------------------------------------------------------------
//деструктор класса очередь заявок
queue::~queue()
{
delete[]dat;
size=0;
}
//---------------------------------------------------------------------------
Замечания
1.В приложении используется композиция классов: в классе queue данное-элемент data* dat – указатель на объект класса data. При создании объекта класса queue вызову конструктора этого класса предшествуют вызовы конструкторов класса data N раз – по числу элементов в массиве для очереди.
2.Очередь формируется с начала массива; при выборке заявки из очереди последующие заявки сдвигаются к началу очереди. Следовательно, началом очереди является первый элемент массива (с индексом 0), а концом – элемент массива с индексом size-1, где size – количество заявок в очереди.
В предыдущей лабораторной работе было продемонстрировано использование диспетчера действийActionList. В данной работе продолжено использование этого компонента, вначале – в общем виде, затем – применительно к работе с очередью заявок с приоритетами в модели обслуживания клиентов компьютерного сервиса.
Проектирование функциональной части интерфейса произвольного приложения с использованием диспетчера действийActionList состоит из следующих шагов.
1.Проектирование начинается с составления списка действий, которые необходимо выполнять пользователю при работе с данным приложением и которые должны быть ему доступны через разделы меню, инструментальные панели, кнопки и другие элементы управления. Нетрудно видеть, что этот список должен содержать следующие действия: а) сохранить очередь в файле; б) вывести очередь из файла; в) добавить заявку в очередь; г) выбрать (удалить) заявку из очереди; д) уничтожить очередь; е) перейти от выполнения приложения к его проектированию. Кроме того, пользователь должен иметь возможность получить информацию о работе с приложением и его разработчике.
2.Для тех нестандартных действий, которые должны быть доступны из быстрых кнопок инструментальной панели, готовится список пиктограмм на кнопках в компоненте ImageList.
3.На главную форму переносится компонент диспетчер действийActionList. Он связывается с компонентом ImageList. В диспетчере действийActionListформируется список стандартных и нестандартных действий.
4.Каждому действию задается набор характеристик: Name (имя), Caption (надпись), ShortCut («горячие» клавиши), ImageIndex(номер изображения в ImageList), Hint (текст подсказки). Для нестандартных действий все эти характеристики записываются пользователем. Для стандартных действий они заносятся автоматически. Но если для характеристик стандартных действий нужен русский язык, то и они заносятся пользователем. Комбинации «горячих» клавиш также обычно требуют корректировки.
5.Записываются обработчики событий выполнения для всех нестандартных действий. Стандартные действия обрабатываются автоматически и для многих из них достаточно задать некоторые свойства обработки. Но в общем случае и они требуют корректировки, а иногда надо писать обработчики событий выполнения и для стандартных действий.
6.На форму переносится компонент MainMenu1 – главное меню, связывается с ImageList, в компоненте формируется меню и в его разделах даются ссылки на действия, описанные в ActionList.
7.На форме создается инструментальная панель ToolBar. Панель связывается с ImageList, а в её кнопках даются ссылки на действия, описанные в ActionList.
Перейдем к проектированию приложения для работы с очередью приоритетов, используя диспетчер действийActionList.
1.Перенесите на форму со страницы Win32 компонент ImageList1. Двойным щелчком на компоненте или щелчком правой кнопкой мыши и выбором команды контекстного меню Редактор ImageList перейдите в окно редактора списков изображений Form1->ImageList1 ImageList. В окне редактора можно добавить в список изображение, удалить изображение из списка, очистить весь список. Нажмите кнопку Добавить. Перейдите в окно файлов изображений командой …\Program Files\Common Files\Borland Shared\Images\Buttons. Выберите файл clear. Нажмите кнопку Открыть. На вопрос в окне Confirm ответьте утвердительно (Yes). В окне Образы выделите серое изображение щелчком мыши на нем и нажмите кнопку Удалить. В окне Образы останется яркое изображение с индексом 0. Снова нажмите кнопку Добавить. Повторите описанные выше действия для файлов delete, insert, help, npadwrit. Затем с помощью мыши расставьте изображения в окне Образы в следующем порядке: insert – 0, delete – 1, clear – 2, help – 3, npadwrit – 4. После всех этих действий нажмите кнопку Ок. Теперь все пять изображений с соответствующими индексами окажутся загруженными в компонент ImageList1.
2.Перенесите на форму со страницы Стандарт компонентActionList1и в его свойстве Images сошлитесь на компонент ImageList1. Сделайте на компоненте ActionList1двойной щелчок, чтобы попасть в Редактор Действий (окно Редактирование Form1->ActionList1), позволяющий вводить и упорядочивать действия. Щелчок правой кнопкой мыши на окне редактирования или щелчок на маленькой кнопке со стрелкой вниз правее первой быстрой кнопки окна редактирования позволяет выбрать одну из команд: Новое действие или Новое стандартное действие. Первая из них относится к вводу нового действия любого типа. Введите Новое действие. При этом в колонке Категории: окна редактирования появится (Все действия), а в колонке Действия: появится Action1. Еще четырежды повторите ввод Новое действие, что вызовет в колонке Действия: появление Action2,Action3,Action4 и Action5.
3.Выделите Action1. В Инспекторе Объектов указанным ниже свойствам объекта действия Action1присвойте следующие значения: Caption –Добавить, Hint –добавить заявку, ImageIndex –0, Name –A_add, ShortCut –Ctrl+A. Для Action2: Caption –Выбрать, Hint –выбрать заявку, ImageIndex –1, Name –A_del, ShortCut –Ctrl+B. Для Action3: Caption –Очистить, Hint –очистить очередь, ImageIndex –2, Name –A_clr, ShortCut –Ctrl+C. Для Action4: Caption –О программе, ImageIndex –3, Name –A_help, ShortCut –Ctrl+D. Для Action5: Caption –О разработчике, ImageIndex –4, Name –A_wrt, ShortCut –Ctrl+E.
4.Для работы с файлами в среде Builder предусмотрены стандартные действия – вывести в файл и ввести из файла. Относятся они, например, к окнам редактирования и выполняют форматированный ввод-вывод. В нашем же случае нужно оперировать с информацией, связанной с полями структуры Node, что требует использования неформатированного ввода-вывода. Отметим далее, что поля структуры содержат ссылки на участки памяти, где находится подлежащая сохранению информация. Следовательно, в данном приложении не могут быть использованы стандартные действия с файлами. Поэтому в компонент ImageList1 добавьте изображения из файлов fileopen и filesave, в компоненте ActionList1 добавьте двановых действия, дайте им имена A_fopen и A_fsaveи свяжите с соответствующими изображениями. В Инспекторе Объектов для A_fopen присвойте: Caption –Открыть,Hint –вывести очередь, ShortCut –Ctrl+ G. Подобным же образом для A_fsave:Caption –Сохранить,Hint –сохранить очередь, ShortCut –Ctrl+ F.
5.Теперь нужно перейти к разработке обработчиков событий для нестандартных действий. Но чтобы иметь возможность отладки обработчиков в процессе разработки, необходимо разместить на форме необходимые для этого компоненты. Поэтому закроем окно Редактирование Form1->ActionList1. Затем, руководствуясь рис.6.1 и содержимым файла LR_6.h (см. ниже), разместим на форме групповое окно GroupBox1 (страница Стандарт, Caption – Добавляемая заявка) с однострочными окнами редактирования LabeledEdit1..4 (страница Дополнительно), метку Label1 (страница Стандарт, Caption – Список заявок), LabeledEdit5 (EditLabel/Caption – Количество заявок), GroupBox2 (Caption – Выбранная (удаляемая) заявка) с LabeledEdit6..9, таблицу строк StringGrid1 (страница Дополнительно). Перенесите также на форму (страница Диалоги) компоненты SaveDialog1 и OpenDialog1.
6.Сделайте на компоненте ActionList1двойной щелчок, чтобы попасть в Редактор Действий (окно Редактирование Form1->ActionList1). Чтобы перейти в обработчик события выполнения какого-либо действия, например, A_add, сделайте на нем двойной щелчок. Имя обработчика - A_addExecute. Коды обработчиков представлены ниже (в файле реализации модуля LR_6 главной формы Form1).
7.Перенесите на форму компонент MainMenu1 (страница Стандарт). В свойствоImages компонента MainMenu1внесите ImageList1. Двойным щелчком на компоненте MainMenu1перейдите в окно Form1->MainMenu1 Конструктора Меню и создайте меню согласно рис.6.2. В свойство Action разделов Открыть, Сохранить, Добавить, Выбрать, Очистить, О программе, О разработчике внесите соответственно значения A_fopen, A_fsave, A_add, A_del, A_clr, A_help, A_wrt. Как показывает Инспектор Объектов, при этом в разделы меню переносятся свойства соответствующего объекта действия.
8.Со страницы Win32 перенесите на форму инструментальную панель - компонентToolBar. По умолчанию он расположится вверху, поскольку его свойство Align по умолчанию равно alTop. Установите Align=alNone, чтобы можно было сократить ширину и расположить ее под меню. Полезно также воспользоваться свойством Constraints. В свойство Hint впишите инструментальная панель, в свойство Imagesвнесите ImageList1, в ShowHint – true. Щелкните правой кнопкой мыши на компоненте ToolBar1 и из всплывшего меню выберите команду Новая кнопка. В свойство Actionкнопки внесите A_fopen, а в свойство ShowHint – true. Повторите эту команду еще для шести кнопок, внося в свойство Actionсоответственно A_fsave, A_add, A_del, A_clr, A_help, A_wrt, в свойство ShowHint – true. Отметим, что свойства и обработчики событий объекта действия будут перенесены на соответствующие кнопки инструментальной панели.
9.На рис.6.4 и рис.6.5 представлены дополнительные формы «О программе» и «О разработчике» с деревьями компонентов. Для включения в проект новой пустой формы достаточно выполнить команду Файл/Новый/Форма или нажать соответствующую быструю кнопку. Модулям дополнительных форм Form2и Form3даны соответственно имена LR_6_1и LR_6_2. На каждой из форм размещены компонент Memo1(страница Стандарт)и кнопка Button1с надписьюЗакрыть. Ниже представлены заголовочные файлы и файлы реализации модулей. Ввод текста в Memo осуществляется в окне Редактора строки списка, для перехода в которое нужно нажать кнопку с многоточием около свойства Lines в окне Инспектора Объектов.
Дата добавления: 2020-10-14; просмотров: 372;