Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛАБ_ПОА_2012.doc
Скачиваний:
2
Добавлен:
03.05.2019
Размер:
8.49 Mб
Скачать

Проектирование приложения. Выбор, размещение и задание свойств компонентов. Коды классов, функций и обработчиков событий.

Сохраните модуль главной формы под именем 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.

  1. Выделите Action1. В Инспекторе Объектов указанным ниже свойствам объекта действия Action1 присвойте следующие значения: CaptionДобавить, Hintдобавить заявку, ImageIndex0, NameA_add, ShortCutCtrl+A. Для Action2: CaptionВыбрать, Hintвыбрать заявку, ImageIndex1, NameA_del, ShortCutCtrl+B. Для Action3: CaptionОчистить, Hintочистить очередь, ImageIndex2, NameA_clr, ShortCutCtrl+C. Для Action4: CaptionО программе, ImageIndex3, NameA_help, ShortCutCtrl+D. Для Action5: CaptionО разработчике, ImageIndex4, NameA_wrt, ShortCutCtrl+E.

  2. Для работы с файлами в среде Builder предусмотрены стандартные действия – вывести в файл и ввести из файла. Относятся они, например, к окнам редактирования и выполняют форматированный ввод-вывод. В нашем же случае нужно оперировать с информацией, связанной с полями структуры Node, что требует использования неформатированного ввода-вывода. Отметим далее, что поля структуры содержат ссылки на участки памяти, где находится подлежащая сохранению информация. Следовательно, в данном приложении не могут быть использованы стандартные действия с файлами. Поэтому в компонент ImageList1 добавьте изображения из файлов fileopen и filesave, в компоненте ActionList1 добавьте два новых действия, дайте им имена A_fopen и A_fsave и свяжите с соответствующими изображениями. В Инспекторе Объектов для A_fopen присвойте: CaptionОткрыть, Hintвывести очередь, ShortCutCtrl+ G. Подобным же образом для A_fsave: CaptionСохранить, Hintсохранить очередь, ShortCutCtrl+ F.

  3. Теперь нужно перейти к разработке обработчиков событий для нестандартных действий. Но чтобы иметь возможность отладки обработчиков в процессе разработки, необходимо разместить на форме необходимые для этого компоненты. Поэтому закроем окно Редактирование Form1->ActionList1. Затем, руководствуясь рис.6.1 и содержимым файла LR_6.h (см. ниже), разместим на форме групповое окно GroupBox1 (страница Стандарт, CaptionДобавляемая заявка) с однострочными окнами редактирования LabeledEdit1..4 (страница Дополнительно), метку Label1 (страница Стандарт, CaptionСписок заявок), LabeledEdit5 (EditLabel/CaptionКоличество заявок), GroupBox2 (CaptionВыбранная (удаляемая) заявка) с LabeledEdit6..9, таблицу строк StringGrid1 (страница Дополнительно). Перенесите также на форму (страница Диалоги) компоненты SaveDialog1 и OpenDialog1.

  4. Сделайте на компоненте ActionList1 двойной щелчок, чтобы попасть в Редактор Действий (окно Редактирование Form1->ActionList1). Чтобы перейти в обработчик события выполнения какого-либо действия, например, A_add, сделайте на нем двойной щелчок. Имя обработчика - A_addExecute. Коды обработчиков представлены ниже (в файле реализации модуля LR_6 главной формы Form1).

  5. Перенесите на форму компонент MainMenu1 (страница Стандарт). В свойство Images компонента MainMenu1 внесите ImageList1. Двойным щелчком на компоненте MainMenu1 перейдите в окно Form1-> MainMenu1 Конструктора Меню и создайте меню согласно рис.6.2. В свойство Action разделов Открыть, Сохранить, Добавить, Выбрать, Очистить, О программе, О разработчике внесите соответственно значения A_fopen, A_fsave, A_add, A_del, A_clr, A_help, A_wrt. Как показывает Инспектор Объектов, при этом в разделы меню переносятся свойства соответствующего объекта действия.

  6. Со страницы Win32 перенесите на форму инструментальную панель - компонент ToolBar. По умолчанию он расположится вверху, поскольку его свойство Align по умолчанию равно alTop. Установите Align=alNone, чтобы можно было сократить ширину и расположить ее под меню. В свойство Hint впишите инструментальная панель, в свойство Images внесите ImageList1, в ShowHinttrue. Щелкните правой кнопкой мыши на компоненте ToolBar1 и из всплывшего меню выберите команду Новая кнопка. В свойство Action кнопки внесите A_fopen, а в свойство ShowHinttrue. Повторите эту команду еще для шести кнопок, внося в свойство Action соответственно A_fsave, A_add, A_del, A_clr, A_help, A_wrt, в свойство ShowHinttrue. Отметим, что свойства и обработчики событий объекта действия будут перенесены на соответствующие кнопки инструментальной панели

  1. На рис.6.4 и рис.6.5 представлены дополнительные формы «О программе» и «О разработчике» с деревьями компонентов. Для включения в проект новой пустой формы достаточно выполнить команду Файл/Новый/Форма или нажать соответствующую быструю кнопку. Модулям дополнительных форм Form2 и Form3 даны соответственно имена LR_6_1 и LR_6_2. На каждой из форм размещены компонент Memo1 (страница Стандарт) и кнопка Button1 с надписью Закрыть. Ниже представлены заголовочные файлы и файлы реализации модулей. Ввод текста в Memo осуществляется в окне Редактора строки списка, для перехода в которое нужно нажать кнопку с многоточием около свойства Lines в окне Инспектора Объектов.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]