24.11.2014 Views

Программирование на С++ - eDrive

Программирование на С++ - eDrive

Программирование на С++ - eDrive

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Федеральное агентство по образованию<br />

_________________________________________<br />

Санкт-Петербургский государственный<br />

электротехнический университет «ЛЭТИ»<br />

____________________________________________________________<br />

<strong>Программирование</strong><br />

<strong>на</strong> <strong>С++</strong><br />

Методические указания<br />

к лабораторным работам<br />

Санкт-Петербург<br />

Издательство СПбГЭТУ «ЛЭТИ»<br />

2007


УДК 681.3.016 (018)<br />

<strong>Программирование</strong> <strong>на</strong> <strong>С++</strong>: Методические указания к лабораторным<br />

работам / Сост.: В. М. Водовозов, Ф. В. Чмиленко. СПб.: Изд-во СПбГЭТУ<br />

«ЛЭТИ», 2007. 40 с.<br />

Даны задания и предложены средства алгоритмизации и объектноориентированного<br />

программирования в среде C++ Builder массивов и классов<br />

данных, библиотек STL, DLL и LIB, работы с текстовыми и медиафайлами,<br />

базами данных, потоками и справочными системами.<br />

Пред<strong>на</strong>з<strong>на</strong>чены для студентов специальностей 180400, 180100 и<br />

180500.<br />

Утверждено<br />

редакционно-издательским советом университета<br />

в качестве методических указаний<br />

© СПбГЭТУ «ЛЭТИ», 2007


Содержание<br />

Общие требования................................................................................................... 4<br />

Работа 1. Массивы................................................................................................... 6<br />

Работа 2. Групповая обработка данных................................................................ 8<br />

Работа 3. Классы...................................................................................................... 9<br />

Работа 4. Перегрузка ............................................................................................. 11<br />

Работа 5. Библиотека STL .................................................................................... 13<br />

Работа 6. Библиотеки LIB и DLL......................................................................... 15<br />

Работа 7. Файловые операции.............................................................................. 18<br />

Работа 8. Подключение базы данных.................................................................. 20<br />

Работа 9. Управление базой данных ................................................................... 22<br />

Работа 10. Управление медиафайлами................................................................ 24<br />

Работа 11. <strong>Программирование</strong> по алгоритму..................................................... 27<br />

Работа 12. Наследование ...................................................................................... 29<br />

Работа 13. Потоки.................................................................................................. 31<br />

Работа 14. Справоч<strong>на</strong>я система WinHelp............................................................ 34<br />

Работа 15. Справоч<strong>на</strong>я система HelpScribble ..................................................... 37<br />

Список рекомендуемой литературы.................................................................... 40


4<br />

Общие требования<br />

Настоящий лабораторный цикл пред<strong>на</strong>з<strong>на</strong>чен для выработки <strong>на</strong>чальных <strong>на</strong>выков<br />

программирования <strong>на</strong> языке <strong>С++</strong> в среде <strong>С++</strong> Builder с использованием<br />

базовых з<strong>на</strong>ний теоретического курса. Его основной задачей является оз<strong>на</strong>комление<br />

студентов с объектно-ориентированным стилем программирования.<br />

Все работы выполняются индивидуально по вариантам, приведенным в<br />

табл. 1 с комментариями в табл. 2. Каждая работа оформляется в виде отдельного<br />

проекта с ориги<strong>на</strong>льными программными объектами и интерфейсом<br />

пользователя. Работы предусматривают:<br />

– концептуальное представление решения <strong>на</strong> бумаге с выполнением предварительных<br />

расчетов и подготовкой эскизов интерфейса;<br />

– определение области допустимых входных и выходных данных;<br />

– алгоритмизацию решения задачи;<br />

– подготовку спецификации будущей программы в виде таблицы разрабатываемых<br />

классов, функций и переменных с указанием их типов и <strong>на</strong>з<strong>на</strong>чения;<br />

– кодирование <strong>на</strong> языке <strong>С++</strong>;<br />

– отладку программы при допустимых и недопустимых входных данных и<br />

организацию защиты программы от ошибок пользователя;<br />

– оформление отчета.<br />

Каждым исполнителем составляется отчет, содержащий:<br />

– титульный лист;<br />

– цель работы;<br />

– ориги<strong>на</strong>льные тексты разработанных функций и спецификацию.<br />

Защита отчета выполняется <strong>на</strong> компьютере <strong>на</strong> основе исходных текстов программ.<br />

В ходе защиты:<br />

– описывается состав и работа программы;<br />

– раскрывается смысл и <strong>на</strong>з<strong>на</strong>чение каждой позиции спецификации;<br />

– решаются предлагаемые преподавателем задачи и даются ответы <strong>на</strong> дополнительные<br />

вопросы.<br />

Работу, которую не удается защитить, следует переделать.


Кнопка<br />

управления<br />

Операция <strong>на</strong>д<br />

строкой<br />

(a – Vector0,<br />

b – Vector1)<br />

5<br />

Задания<br />

Статистическая<br />

операция <strong>на</strong>д<br />

расчетным<br />

столбцом<br />

1 Button a 2 + b сумма / среднее + +<br />

2 BitBtn a + b 2 сумма · среднее > ++<br />

3 SpeedButton a 2 – b сумма + среднее – –<br />

4 ToolBar a – b 2 сумма – среднее < – –<br />

5 Button a 2 · b сумма 2 * &<br />

6 BitBtn a · b 2 среднее 2 = = *<br />

7 SpeedButton a 2 / b SQR (среднее) / !<br />

8 ToolBar a / b 2 SQR (сумма) % ~<br />

9 Button (a + b) 2 сумма / макс & +<br />

10 BitBtn (a – b) 2 сумма · макс &= –<br />

11 SpeedButton (a · b) 2 сумма + макс && &<br />

12 ToolBar (a / b) 2 сумма – макс || !<br />

13 Button √ (a) + b сумма / мин ^ ++<br />

14 BitBtn a + √ (b) сумма · мин ^= +<br />

15 SpeedButton √ (a) – b сумма + мин | – –<br />

16 ToolBar a – √ (b) сумма – мин |= –<br />

17 Button √ (a) · b среднее / макс >>= &<br />

18 BitBtn a · √ (b) среднее · макс >> *<br />

19 SpeedButton √ (a) / b среднее + макс


6<br />

Работа 1. Массивы<br />

Задание<br />

Для з<strong>на</strong>комства со средствами формирования и отображения массивов данных<br />

разработать приложение, форма которого отображает таблицу с тремя<br />

столбцами и произвольно изменяемым числом строк. Предоставить пользователю<br />

возможность заполнения первых двух столбцов таблицы вручную<br />

или с помощью генератора случайных чисел. Третий столбец должен вычисляться<br />

как результат заданной в табл. 1 операции <strong>на</strong>д строкой.<br />

Рекомендации<br />

1. Создание формы с таблицей. Подготовить проект с формой для отображения<br />

и ввода табличных данных. Поместить в нее элемент управления<br />

StringGrid с панели визуальных компонентов Additional и задать его свойства<br />

ColCount = 3 и RowCount = 10, FixedCols = 0 и FixedRows = 1. В группе<br />

Options установить в true свойства goEdition и goAlwaysShowEditor, a<br />

goRangeSelect – в false. В конструкторе формы организовать заполнение<br />

заголовка таблицы, <strong>на</strong>пример, так:<br />

StringGrid1–>Rows [0]–>Append (“Vector0”);<br />

StringGrid1–>Rows [0]–>Append (“Vector1”);<br />

StringGrid1–>Rows [0]–>Append (“Vector2”);<br />

Испытать приложение, вводя в ячейки таблицы произвольные числа.<br />

2. Подготовка массивов. В классе формы объявить три вещественных статических<br />

массива и целочисленную переменную для хранения числа строк<br />

таблицы, <strong>на</strong>пример:<br />

double myVector0 [256], myVector1 [256], myVector2 [256]; int gridRows;<br />

Дополнить класс функцией, передающей содержимое столбца таблицы в<br />

массив, и функцией, выполняющей обратное действие, и определить эти<br />

функции в файле кода формы, <strong>на</strong>пример:<br />

void __fastcall TForm1::MyVectorToGrid (double* vec, int col)<br />

{ for (int i = 0; i < gridRows; ++i)<br />

StringGrid1–>Cells [col][i+1] = FloatToStr (vec [i]); }<br />

3. Формирование массивов. Дополнить класс формы функцией, заполняющей<br />

массив случайными числами, и определить ее, <strong>на</strong>пример, так:<br />

void __fastcall TForm1::MyFill (double* vec)


{ for (int i = 0; i < gridRows; ++i) vec [i] = random (100); }<br />

7<br />

Для того, чтобы пользователь мог задавать число строк таблицы и заполнять<br />

ее случайными данными, поместить в форму поле и предусмотренную<br />

вариантом кнопку управления (см. табл. 1). Функция, обрабатывающая<br />

<strong>на</strong>жатие кнопки – обработчик – может выглядеть так:<br />

gridRows = StrToInt (Edit1–>Text);<br />

StringGrid1–>RowCount = gridRows + 1;<br />

MyFill (myVector0);<br />

MyFill (myVector1);<br />

MyVectorToGrid (myVector0, 0);<br />

MyVectorToGrid (myVector1, 1);<br />

4. Вычисления. Дополнить форму второй кнопкой с обработчиком, выполняющим<br />

заданную операцию <strong>на</strong>д строкой. Результат вычисления помещать<br />

в третий массив и выводить в третий столбец таблицы. Учитывая, что<br />

данные таблицы могут произвольно меняться пользователем, перед выполнением<br />

расчета <strong>на</strong>до передавать их в массивы. Пример реализации построчного<br />

сложения элементов массивов может выглядеть так:<br />

void __fastcall TForm1::Button2Click (TObject *Sender) {<br />

{ MyGridToVector (myVector0, 0);<br />

MyGridToVector (myVector1, 1);<br />

for (int i=0; i


double *myVector0;<br />

gridRows = StrToInt (Edit1–>Text);<br />

myVector0 = new double [gridRows];<br />

delete [] gridRows;<br />

8<br />

6. Запретить пользователю редактирование расчетного массива в третьем<br />

столбце таблицы, для чего воспользоваться обработкой событий компонента<br />

StringGrid.<br />

Работа 2. Групповая обработка данных<br />

Задание<br />

Для освоения приемов групповой обработки и сортировки массивов взять за<br />

основу предыдущую работу (<strong>на</strong>пример, сохранив проект и форму под новыми<br />

име<strong>на</strong>ми в новой папке, File.Save Project As…, File.Save As…). Добавить<br />

в форму три <strong>на</strong>дписи для отображения результатов групповой обработки<br />

расчетного массива: поиска максимального и минимального з<strong>на</strong>чений и выполнения<br />

заданной в табл. 1 статистической операции. Организовать сортировку<br />

расчетного массива.<br />

Рекомендации<br />

1. Групповые вычисления. К вычислениям предыдущей работы добавить поиск<br />

и вывод в форму максимального и минимального з<strong>на</strong>чений расчетного<br />

массива, <strong>на</strong>пример:<br />

#include <br />

…<br />

double stat = MaxValue (myVector2, gridRows–1);<br />

Label1–>Caption = "Максимум " + FloatToStr (stat);<br />

Разработать, также, функцию для выполнения заданной статистической<br />

операции <strong>на</strong>д расчетным массивом с выводом ее результата в форму.<br />

2. Сортировка массива методом «пузырька». Дополнить форму третьей<br />

кнопкой с обработчиком, выполняющим сортировку методом «пузырька»<br />

по возрастанию данных расчетного массива. Алгоритм метода использует<br />

два цикла: внешний цикл с инкрементом и внутренний с декрементом:<br />

for (int i = 0; i < gridRows–1; ++i) for (int j= gridRows–1; j>i; – –j)<br />

if (myVector2 [j] < myVector2 [j–1]) Перестановка<br />

Перестановку элементов в функции сортировки целесообразно проводить,<br />

передавая данные в отдельную функцию вида


9<br />

void MySwap (double &a, double &b)<br />

3. Сортировка строк методом «пузырька». Реорганизовать сортировку расчетного<br />

массива в сортировку строк, в ходе которой элементы первого и<br />

второго массивов следуют за соответствующими элементами расчетного<br />

массива. Для этого функция перестановки вызывается трижды, и при каждом<br />

вызове ей передаются данные следующего массива.<br />

4. Быстрая сортировка массива. Дополнить форму четвертой кнопкой с обработчиком,<br />

выполняющим сортировку расчетного массива в убывающем<br />

порядке с использованием библиотечной функции qsort:<br />

qsort ((void*) myVector2, gridRows, sizeof (double), MySortFunc);<br />

Текст функции сравнения элементов массива, предусмотренный синтаксисом<br />

qsort, может быть, <strong>на</strong>пример, таким:<br />

int MySortFunc( const void *a, const void *b)<br />

{ return *(double*) a > *(double*) b ? –1 : 1; }<br />

Задачи<br />

1. Разработать функцию сортировки методом «пузырька» по убыванию з<strong>на</strong>чений<br />

массива.<br />

2. Разработать функцию сортировки qsort по возрастанию з<strong>на</strong>чений массива.<br />

3. Разработать функцию сортировки qsort произвольно выбираемого<br />

пользователем массива.<br />

4. Разработать функцию сравнения элементов массива qsort, возвращающую<br />

один из трех результатов: 1 при a > b, –1 при a < b, 0 при a = b.<br />

5. Разработать функции поиска минимального и максимального элементов<br />

массива без использования файла заголовка Math.hpp.<br />

Работа 3. Классы<br />

Задание<br />

Чтобы <strong>на</strong>учиться создавать и использовать авторский класс, разработать проект<br />

с формой, а<strong>на</strong>логичной предыдущей работе. В этом проекте все действия<br />

<strong>на</strong>д массивами – их формирование, выполнение групповых операций и сортировка<br />

с использованием функции qsort – должны выполняться средствами<br />

авторского класса.


10<br />

Рекомендации<br />

1. Объявление класса. Для разработки авторского класса ввести в проект новый<br />

модуль (Unit) из библиотеки шаблонов (File.New) и подключить его<br />

(File.Include Unit Hdr…) к форме, а форму – к нему. Объявление класса поместить<br />

в файл заголовка модуля, <strong>на</strong>пример:<br />

class MyClass<br />

{ private:<br />

double vec [256];<br />

int rows, col;<br />

void MyGridToVector ();<br />

void MyVectorToGrid ();<br />

void MyFill ();<br />

public:<br />

MyClass (int gridCol, int fill);<br />

~MyClass ();<br />

// массив<br />

// число строк и столбец<br />

// конструктор<br />

// деструктор<br />

void MyStringOp (MyClass &c1, MyClass &c2); // операция <strong>на</strong>д строкой<br />

double MyMax ();<br />

// максимальный элемент<br />

double MyMin ();<br />

// минимальный элемент<br />

AnsiString MyStatOp ();<br />

// операция <strong>на</strong>д столбцом<br />

void MySort (); };<br />

2. Определение класса. В файле кода модуля определить методы класса взамен<br />

соответствующих функций предыдущей работы. В конструкторе задается<br />

число строк и номер столбца. Здесь же массив может заполняться или<br />

считываться из таблицы в зависимости от з<strong>на</strong>чения параметра fill (1, –1, 0):<br />

col = gridCol;<br />

int r = StrToInt (Form1–>Edit1–>Text);<br />

rows = r;<br />

if (fill = = 1) MyFill ();<br />

else if (fill = = –1) MyGridToVector ();<br />

В деструкторе массив возвращается в таблицу вызовом функции<br />

MyVectorToGrid. Функции MyVectorToGrid, MyGridToVector и MyFill не нуждаются<br />

в параметрах, так как работают с массивом vec, <strong>на</strong>пример:<br />

void __fastcall TForm1::MyVectorToGrid ()<br />

{ for (int i=0; iStringGrid1–>Cells [col][i+1] = vec [i]; }<br />

Заданную операцию <strong>на</strong>д элементами строк, <strong>на</strong>пример, их сложение, можно<br />

выполнить в цикле:<br />

for (int i=0; i


11<br />

Для статистических операций удобно использовать функции из Math.hpp:<br />

AnsiString MyClass::MyStatOp ()<br />

{ return FloatToStrF (Mean (vec, rows–1), ffFixed, 5, 2); }<br />

Не отличается новизной и функция сортировки:<br />

qsort ((void*) vec, rows, sizeof (double), MySortFunc);<br />

3. Использование класса. Объекты класса создаются в обработчиках соответствующих<br />

кнопок. В частности, <strong>на</strong>жатие первой кнопки ведет к созданию<br />

первых двух массивов:<br />

int r = StrToInt (Edit1–>Text);<br />

StringGrid1–>RowCount = r + 1;<br />

MyClass myVector0 (0, 1), myVector1 (1, 1);<br />

Обработчик второй кнопкой управляет уже тремя массивами:<br />

MyClass myVector0 (0, –1), myVector1 (1, –1), myVector2 (2, 0);<br />

myVector2.MyStringOp (myVector0, myVector1);<br />

Label1–>Caption = "Максимум " + FloatToStr (myVector2.MyMax ());<br />

Label2–>Caption = "Минимум " + FloatToStr (myVector2.MyMin ());<br />

Label3–>Caption = "Операция " + myVector2.MyStatOp ();<br />

В свою очередь, сортировке подлежит только расчетный массив:<br />

MyClass myVector2 (2, –1);<br />

MyVector2.MySort ();<br />

Задачи<br />

1. Заменить статический массив vec ди<strong>на</strong>мическим, внеся соответствующие<br />

изменения в конструктор и деструктор класса.<br />

2. В классе по мере возможности использовать константные функции.<br />

3. Временно включив в конструктор и деструктор функцию ShowMessage,<br />

демонстрировать их вызовы и объяснить их причину.<br />

Работа 4. Перегрузка<br />

Задание<br />

Для овладения техникой перегрузки операторов и функций создать проект с<br />

формой, поддерживающей интерфейс пользователя и все операции предыдущей<br />

работы. Операцию <strong>на</strong>д строкой выполнить с помощью заданного в<br />

табл. 1 перегруженного для этой цели двухместного оператора, а операцию<br />

<strong>на</strong>д расчетным столбцом – с помощью заданного в табл. 1 перегруженного


12<br />

одноместного оператора. Предусмотреть два полиморфных метода сортировки:<br />

один по возрастанию, а другой по убыванию или возрастанию данных<br />

расчетного массива в зависимости от аргумента.<br />

Рекомендации<br />

1. Определение класса. Для перегрузки следует в классе предыдущей работы<br />

заменить методы MyStatOp и MyStringOp методами operator и ввести дополнительный<br />

метод сортировки с параметром, <strong>на</strong>пример:<br />

MyClass MyClass::operator + (const MyClass &c)<br />

{ col = 2;<br />

for (int i=0; iCaption = "Операция " + !myVector2;<br />

… }<br />

void __fastcall TmyForm::Button4Click (TObject *Sender)<br />

{ … myVector2.MySort (true); … }


13<br />

Задачи<br />

1. Заменить статический массив vec ди<strong>на</strong>мическим, внеся в программу соответствующие<br />

коррективы. Во-первых, в конструкторе следует выделять<br />

память массиву (vec = new double [rows]), а в деструкторе ее освобождать<br />

(delete [] vec). При этом вызов функции MyVectorToGrid выносится из деструктора<br />

в обработчики кнопок, для чего ее объявление перемещается в<br />

открытый раздел класса. Например, обработчик первой кнопки дополнится<br />

вызовами:<br />

MyClass myVector0(0, 1), myVector1(1, 1);<br />

myVector0.MyVectorToGrid ();<br />

myVector1.MyVectorToGrid ();<br />

Во-вторых, требуется перегрузить операторы индексации [] и присваивания<br />

=, а также создать конструктор копирования:<br />

double& operator [] (int i) { return vec[i]; }<br />

MyClass& operator = (const MyClass& c)<br />

{ if (this == &c) return *this;<br />

for (int i=0; i


14<br />

вать дополнительную операцию – поиск информации с использованием библиотеки<br />

STL.<br />

Рекомендации<br />

1. Подключение библиотеки STL. Создать форму в соответствии с заданием,<br />

а<strong>на</strong>логичную предыдущим работам. Включить в файл кода формы заголовочные<br />

файлы библиотеки STL для работы с контейнером vector и с алгоритмами,<br />

а также определить пространство имен std:<br />

#include <br />

#include <br />

using namespace std;<br />

2. Создание векторов. В классе формы объявить три вещественных вектора и<br />

итератор, функцию заполнения вектора данными и функции передачи данных<br />

из вектора в таблицу и обратно, <strong>на</strong>пример:<br />

vector myVector0, myVector1, myVector2;<br />

vector ::iterator vi;<br />

void __fastcall MyFill (vector &vec);<br />

void __fastcall MyVectorToGrid (vector &vec, int col);<br />

void __fastcall MyGridToVector (vector &vec, int col,);<br />

Задать размер вектора можно следующим образом:<br />

int size = StrToInt (Edit1–>Text);<br />

StringGrid1–>RowCount = size + 1;<br />

myVector0.resize (size);<br />

Заполнение вектора случайными числами и вывод его в таблицу проводят<br />

с помощью итератора:<br />

int i=0;<br />

for (vi=vec.begin (); vi!=vec.end (); ++vi)<br />

StringGrid1–>Cells [col][++i] = FloatToStr (*vi);.<br />

С этой же целью в функции может использоваться обычный цикл со счетчиком:<br />

for (unsigned i = 0; i < vec.size (); i++) vec [i] = random (100);<br />

3. Вычисления. Предусмотрен<strong>на</strong>я заданием математическая операция <strong>на</strong>д<br />

векторами размером myVector2.size () выполняется а<strong>на</strong>логично прежним<br />

работам. Групповые операции удобно проводить с помощью итератора и<br />

соответствующих алгоритмов STL, <strong>на</strong>пример так:


double stat = *max_element (myVector2.begin (), myVector2.end ());<br />

Label1–>Caption = "Максимум " + FloatToStr (stat);<br />

stat = *min_element (myVector2.begin (), myVector2.end ());<br />

Label2–>Caption = "Минимум " + FloatToStr (stat);<br />

for (vi=myVector2.begin (), stat = 0; vi!=myVector2.end (); ++vi) stat += *vi;<br />

Label3–>Caption = "Операция " + FloatToStr (stat);<br />

15<br />

4. Сортировка. Для сортировки по возрастанию данных расчетного вектора<br />

применить алгоритм sort библиотеки STL.<br />

5. Поиск информации. Добавить в форму элементы ввода и отображения результата<br />

и кнопку с обработчиком, выполняющим поиск данных в расчетном<br />

векторе, <strong>на</strong>пример, следующим образом:<br />

double what = StrToFloat (Edit1–>Text);<br />

vi = find (myVector2.begin (), myVector2.end (), what);<br />

if (vi != myVector2.end ()) Label1–>Caption = "Найден " + FloatToStr (*vi);<br />

Задачи<br />

1. Выполнить сортировку по убыванию данных расчетного вектора.<br />

2. Выполнить сортировку вектора, произвольно выбираемого пользователем.<br />

3. Создать вариант программы, в котором вместо контейнера vector используется<br />

контейнер valarray, и для математических операций использовать<br />

встроенные возможности этого контейнера.<br />

Работа 6. Библиотеки LIB и DLL<br />

Задание<br />

Для освоения статической и ди<strong>на</strong>мической компоновки разработать две библиотеки.<br />

В первой библиотеке сохранить три функции: функцию, заполняющую<br />

массив случайными числами, функцию, передающую содержимое<br />

столбца таблицы в массив, и функцию, выполняющую обратное действие.<br />

Использовать эту библиотеку для статической компоновки в новом проекте,<br />

отвечающем заданию первой работы. Для второй библиотеки разработать<br />

форму «О программе», содержащую сведения о <strong>на</strong>звании и авторе работы:<br />

фамилию, группу, вариант, текущую дату и логотип. Использовать эту библиотеку<br />

в качестве библиотеки ди<strong>на</strong>мической компоновки в том же проекте.<br />

Рекомендации<br />

1. Разработка библиотеки с функциями. Создать проект библиотеки командой<br />

меню File.New из шабло<strong>на</strong> DLLWizard <strong>на</strong> языке <strong>С++</strong> с использованием


16<br />

VCL. Сохранить файлы проекта под ориги<strong>на</strong>льными име<strong>на</strong>ми, <strong>на</strong>пример<br />

myDLLLIB1.cpp, myDLLLIB1.bpr. Создать, также, файл заголовка с помощью<br />

шабло<strong>на</strong> File.New.Header File с объявлением требуемых функций, <strong>на</strong>пример:<br />

#include <br />

extern "C" void __declspec (dllexport) MyFill (double *v, int cz);<br />

extern "C" void __declspec (dllexport)<br />

MyVectorToGrid (double *v, int c, int sz, TStringGrid *sg);<br />

extern "C" void __declspec (dllexport)<br />

MyGridToVector (double *v, int c, int sz, TStringGrid *sg);<br />

Лексема __declspec со спецификатором класса памяти dllexport включается<br />

для совместимости разрабатываемой библиотеки с компиляторами Microsoft<br />

C/C++. Сохранить этот файл (<strong>на</strong>пример, myDLLLIB1.h), включить его<br />

в проект через меню Project.Add To Project и подключить к модулю библиотеки<br />

(File.Include Unit Hdr…). В файле кода модуля определить объявленные<br />

функции, <strong>на</strong>пример:<br />

void MyGridToVector (double *v, int c, int sz, TStringGrid *sg)<br />

{ for(int i=0; iCells [c][i+1]); }<br />

Скомпоновать проект (Project.Build…) и убедиться, что в папке проекта<br />

сформировались два файла: библиотека статической компоновки<br />

myDLLLIB1.lib и библиотека ди<strong>на</strong>мической компоновки myDLLLIB1.dll.<br />

2. Статическая компоновка. Создать проект с формой, отвечающей заданию<br />

первой работы, но без функций передачи столбца в массив, массива в<br />

столбец и заполнения массива. Добавить в проект файл библиотеки статической<br />

компоновки (Project.Add To Project), подключить к форме его файл<br />

заголовка и организовать вызовы необходимых функций, <strong>на</strong>пример:<br />

#include "myDLLLIB1.h"<br />

void __fastcall TForm1::Button1Click (TObject *Sender)<br />

{ int r = StrToInt (Edit1–>Text);<br />

MyFill (myVector0, r);<br />

MyFill (myVector1, r);<br />

MyVectorToGrid (myVector0, 0, r, StringGrid1);<br />

MyVectorToGrid (myVector1, 1, r, StringGrid1); }<br />

Убедиться в идентичности приложения первой работе.<br />

3. Разработка библиотеки с формой. Создать новый проект библиотеки с<br />

помощью шабло<strong>на</strong> DLLWizard и сохранить его в одной папке с только что


17<br />

подготовленным приложением, <strong>на</strong>пример, как myDLLLIB2.cpp,<br />

myDLLLIB2.bpr. Создать, далее, файл заголовка с объявлением требуемой<br />

функции, <strong>на</strong>пример:<br />

extern "C" void __declspec (dllexport) MyAbout (char *s);<br />

Сохранить этот файл (<strong>на</strong>пример, myDLLLIB2.h), включить его в проект и<br />

подключить к модулю библиотеки. Подготовить, также, форму «О программе»<br />

(File.New.Form) с рисунком-логотипом и тремя <strong>на</strong>дписями. Две<br />

<strong>на</strong>дписи оставить пустыми для <strong>на</strong>звания работы и даты, а третью заполнить<br />

сведениями об авторе. Сохранить форму (<strong>на</strong>пример, под именем<br />

myDLLForm.cpp), включить ее в проект и подключить к модулю библиотеки.<br />

В файле кода модуля определить объявленную функцию, <strong>на</strong>пример:<br />

void MyAbout (char *s)<br />

{ Form1 = new TForm1 (0);<br />

Form1–>Label1–>Caption = s;<br />

Form1–>Label2–>Caption = DateToStr (Date ());<br />

Form1–>ShowModal ();<br />

delete Form1; }<br />

Скомпоновать проект и убедиться, что в папке проекта сформировались<br />

файлы библиотеки LIB и DLL.<br />

4. Ди<strong>на</strong>мическая компоновка. В форму подготовленного приложения добавить<br />

кнопку «О программе» и кодировать ее обработчик:<br />

void __fastcall TForm1::Button3Click (TObject *Sender)<br />

{ HINSTANCE dllp = LoadLibrary (“myDLLLIB2.dll”);<br />

if (dllp)<br />

{ void (__stdcall *p) (char *s);<br />

p = (void (__stdcall *) (char *)) GetProcAddress (dllp, “_MyAbout”);<br />

if (p) p (“Библиотеки LIB и DLL”);<br />

else ShowMessage (“Нет функции MyAbout”);<br />

FreeLibrary (dllp); }<br />

else ShowMessage (“Нет файла myDLLLIB2.dll”); }<br />

Здесь функция LoadLibrary возвращает указатель <strong>на</strong> переменную типа HInstance<br />

из библиотеки Windows API и загружает файл DLL. Функция Get-<br />

ProcAddress присваивает з<strong>на</strong>чение указателя функции DLL. Затем вызывается<br />

рабочая функция и библиотека выгружается из памяти функцией<br />

FreeLibrary. В заключение испытать приложение c библиотеками.


18<br />

Задачи<br />

1. Выполнить обратную задачу: использовать первую библиотеку для статической<br />

компоновки, а вторую – для ди<strong>на</strong>мической компоновки.<br />

2. Создать новую библиотеку myDLLLIB3.lib, воспользовавшись командой<br />

меню File.New из шабло<strong>на</strong> Library, и применить еe для статической компоновки<br />

вместо myDLLLIB1.lib.<br />

Работа 7. Файловые операции<br />

Задание<br />

Для приобретения <strong>на</strong>выков управления файловым обменом создать проект по<br />

заданию первой работы и дополнить форму шестью кнопками. Первая из них<br />

пред<strong>на</strong>з<strong>на</strong>че<strong>на</strong> для сохранения расчетного массива в текстовом файле, вторая<br />

– для заполнения этого массива из файла, третья – для записи в файл всей<br />

таблицы, четвертая – для заполнения таблицы из файла, пятая – для дополнения<br />

файла активной строкой таблицы, а шестая – для сохранения в файле заголовков<br />

столбцов таблицы.<br />

Рекомендации<br />

1. Создание интерфейса пользователя. Поместить в форму, а<strong>на</strong>логичную<br />

форме первой работы, необходимые кнопки и компоненты SaveDialog и<br />

OpenDialog с вкладки Dialogs панели компонентов. Установить у этих<br />

компонентов свойства по умолчанию: расширение DefaultExt (обычно<br />

TXT), фильтр Filter (Текстовые файлы | *.txt) и папку InitialDir.<br />

2. Запись массива в файл. Обработчик первой из новых кнопок сохраняет в<br />

файле содержимое расчетного массива методом SaveToFile класса TString-<br />

List, <strong>на</strong>пример, так:<br />

if (SaveDialog1–>Execute ())<br />

StringGrid1–>Cols [2]–>SaveToFile (SaveDialog1–>FileName);<br />

3. Чтение файла в массив. А<strong>на</strong>логичным образом обработчик второй кнопки<br />

читает содержимое файла в расчетный массив методом LoadFromFile.<br />

4. Запись таблицы в файл. Для записи в файл всей таблицы можно воспользоваться<br />

переменной типа AnsiString и функциями для файловых операций<br />

FileCreate, FileWrite, FileClose:<br />

AnsiString f;<br />

for (int j=0; jRowCount; ++j)


19<br />

for (int i=0; iColCount; ++i)<br />

f += StringGrid1–>Cells [i][j] + '\n';<br />

if (!SaveDialog1–>Execute ()) return;<br />

int file = FileCreate (SaveDialog1–>FileName);<br />

if (FileWrite (file, f.c_str (), f.Length ()) == –1) ShowMessage ("Не записать");<br />

FileClose (file);<br />

5. Чтение файла в таблицу. Читать таблицу удобно с помощью TStringList:<br />

TStringList *f = new TStringList;<br />

int k = 0;<br />

if (!OpenDialog1–>Execute ()) return;<br />

f–>LoadFromFile (OpenDialog1–>FileName);<br />

for (int j=0; jRowCount; ++j)<br />

for (int i=0; iColCount; ++i)<br />

if (k < f–>Count) StringGrid1–>Cells [i][j] = f–>Strings [k++];<br />

delete f;<br />

6. Добавление строки в файл. Чтобы добавить в файл активную строку текущей<br />

таблицы, можно воспользоваться функциями файловых операций<br />

FileOpen, FileWrite, FileSeek, FileClose:<br />

AnsiString f = "";<br />

for (int i=0; iColCount; ++i)<br />

f += StringGrid1–>Cells [i][StringGrid1–>Row] + '\n';<br />

if (!SaveDialog1–>Execute ()) return;<br />

int file = FileOpen (SaveDialog1–>FileName, fmOpenWrite);<br />

if (file == –1) return;<br />

if (FileSeek (file,0,2) == –1 || FileWrite (file, f.c_str (), f.Length ()) == –1)<br />

ShowMessage("Неудача");<br />

FileClose (file);<br />

7. Запись заголовка таблицы в файл. Для проведения этой операции полезно<br />

воспользоваться способностью компонента TStringList формировать многострочные<br />

текстовые файлы в формате «имя=з<strong>на</strong>чение», где свойством<br />

Values задается произвольное имя параметра, которому присваивается<br />

з<strong>на</strong>чение, <strong>на</strong>пример:<br />

TStringList *sl = new TStringList;<br />

sl–>Values ["Заголовок 0"] = StringGrid1–>Cells [0][0];<br />

sl–>Values ["Заголовок 1"] = StringGrid1–>Cells [1][0];<br />

sl–>Values ["Заголовок 2"] = StringGrid1–>Cells [2][0];<br />

if (!SaveDialog1–>Execute ()) return;<br />

AnsiString fn = SaveDialog1–>FileName;


sl–>SaveToFile (fn);<br />

delete sl;<br />

ShellExecute (Handle, "open", fn.c_str (), NULL, NULL, SW_RESTORE);<br />

20<br />

Последняя строка этого примера сразу же открывает созданный файл текстовым<br />

редактором.<br />

Задачи<br />

1. Исключить ошибку при вводе пользователем имени несуществующего<br />

файла в окне открытия файла.<br />

2. Организовать вывод сообщений об ошибке ввода неверного имени файла.<br />

3. Выполнить чтение заголовков столбцов таблицы из файла с помощью<br />

компонента TStringList.<br />

4. Выполнить запись заголовков столбцов таблицы в файл с помощью компонента<br />

TStringList.<br />

Работа 8. Подключение базы данных<br />

Задание<br />

Для организации связи приложения со стандартной базой данных и з<strong>на</strong>комства<br />

со средствами отображения и обновления базы данных из приложения<br />

C++ Builder создать проект с интерфейсом пользователя, а<strong>на</strong>логичным первым<br />

работам. Подключить к нему базу данных Microsoft Access и открыть<br />

доступ к ее полям.<br />

Рекомендации<br />

1. Создание базы данных. Для выполнения последующих задач подготовить в<br />

Microsoft Access базу данных с таблицей из трех полей для хранения числовых<br />

данных взамен массивов в предыдущих работах.<br />

2. Элементы управления таблицами. Создав новый проект <strong>С++</strong> Builder, поместить<br />

в форму таблицу DBGrid и кнопочную панель DBNavigator с<br />

вкладки Data Controls панели визуальных компонентов. Поз<strong>на</strong>комиться с<br />

элементом DBNavigator, с помощью литературы перевести <strong>на</strong>звания его<br />

кнопок в свойстве Hints и установить в true свойство ShowHint.<br />

3. Модуль данных. Для работы с невидимыми элементами управления включить<br />

в проект модуль данных Data Module из коллекции шаблонов<br />

(File.New). Связать модуль данных с формой (File.Include Unit Hdr…).<br />

4. Подключение базы данных. Для того, чтобы подключить к форме базу данных,<br />

поместить в модуль данных компонент ADOConnection с вкладки


21<br />

ADO панели визуальных компонентов. Его редактор свойства Connection-<br />

String предлагает сформировать строку соединения или прочесть ее из<br />

предварительно созданного файла. Для формирования такой строки, следует<br />

<strong>на</strong>жать <strong>на</strong> кнопку Build и <strong>на</strong> вкладке Поставщик данных выбрать провайдера<br />

Microsoft OLE DB Provider for ODBC Drivers. На вкладке<br />

Подключение этого же ок<strong>на</strong> в поле переключателя Использовать строку<br />

подключения <strong>на</strong>жать <strong>на</strong> кнопку Сборка для выбора источника данных.<br />

5. Файловый источник данных. Источник данных – это текстовый файл, выполняющий<br />

роль посредника при связи различных приложений с конкретной<br />

базой данных. Применительно к новой базе данных такой источник<br />

отсутствует. Для его создания рядом с полем Имя DSN <strong>на</strong>жать кнопку<br />

Создать, выбрать строку Microsoft Access Driver, затем <strong>на</strong>жать кнопку<br />

Далее. После этого вводится произвольное имя нового файла источника, в<br />

качестве которого можно использовать имя приложения или базы данных.<br />

Затем <strong>на</strong>жать кнопки Далее и Готово. В следующем окне указывается база<br />

данных под кнопкой Выбрать и <strong>на</strong>жимается кнопка ОК. Вслед за этим в<br />

окне Файловый источник данных <strong>на</strong>до выбрать созданный источник и вернуться<br />

<strong>на</strong> вкладку Подключение. После проверки связи кнопкой<br />

Проверить подключение осуществляется выход из <strong>на</strong>строек источника<br />

данных. Свойство LoginPromt объекта ADOConnection установите в false<br />

для открытия базы данных без пароля, а свойство Connected – в true.<br />

6. Виртуаль<strong>на</strong>я таблица. Для работы с таблицей базы данных добавить в модуль<br />

данных элемент управления ADOTable с вкладки ADO. Его свойство<br />

Connection инициализировать именем элемента связи ADOConnection, в<br />

свойстве TableName выбрать имя таблицы базы данных и установить в true<br />

свойство Active, открывающее таблицу.<br />

7. Источник данных элементов управления формы. Для подключения ADO-<br />

Table к DBGrid дополнить модуль данных источником DataSource с вкладки<br />

DataAccess. В его свойстве DataSet выбрать имя элемента ADOTable, а<br />

в свойстве DataSource таблицы DBGrid – имя элемента DataSource. В итоге<br />

элемент DBGrid отобразит содержимое таблицы базы данных. DBNavigator<br />

подключить к ADOTable через тот же DataSource а<strong>на</strong>логично DBGrid.<br />

8. Работа с таблицей. Установив в true свойства dgEditing и dgAlwaysShow-<br />

Editor, запустить приложение и ввести в поля данных таблицы произволь-


22<br />

ные числа. Корректировать, добавлять и удалять записи можно как через<br />

таблицу DBGrid, так и с помощью панели DBNavigator.<br />

Задачи<br />

1. Сохранить файловый источник данных в одной папке с приложением, чтобы<br />

приложение вместе с базой данных и файловым источником данных<br />

было удобно перемещать <strong>на</strong> новое место.<br />

2. С той же целью в строке подключения заменить абсолютный путь к базе<br />

данных <strong>на</strong> относительный, <strong>на</strong>пример:<br />

Properties=“DBQ=myDatabase7.mdb;DefaultDir=;Driver={Microsoft Access Driver<br />

(*.mdb)}”<br />

2. Изменить строку подключения базы данных, заменив поставщика данных<br />

Microsoft OLE DB Provider for ODBC Drivers поставщиком Microsoft Jet OLE<br />

DB Provider.<br />

Работа 9. Управление базой данных<br />

Задание<br />

Для изучения возможностей управления базой данных через запросы SQL<br />

организовать выполнение математических и групповых операций и поиск<br />

информации в подключенной базе данных а<strong>на</strong>логично тому, как это делалось<br />

в предыдущих работах с массивами.<br />

Рекомендации<br />

1. Формирование таблицы. Для подготовки таблицы с заданным числом записей<br />

дополнить модуль данных элементом управления ADOCommand с<br />

вкладки ADO панели визуальных компонентов и подключить его к<br />

ADOConnection свойством Connection. Обработчик элемента управления,<br />

формирующего таблицу, включает два запроса действия:<br />

TADOCommand *ac = DataModule1–>ADOCommand1;<br />

ac–>CommandText = "DELETE * FROM myTable1";<br />

ac–>Execute ();<br />

for (int i=0; iText); ++i)<br />

{ ac–>CommandText =<br />

"INSERT INTO myTable1 (Vector0, Vector1) VALUES (" +<br />

FloatToStr (random (100)) + "," + FloatToStr (random (100)) + ")";<br />

ac–>Execute (); }<br />

DataModule1–>ADOTable1–>Requery ();


23<br />

В этом фрагменте первым запросом элемент управления ADOCommand<br />

удаляет все записи из таблицы, а затем в цикле выполняет запрос <strong>на</strong><br />

заполнение новыми случайными данными записей, количество которых<br />

указано в поле Edit1. Аргументы текста ADOCommand соединены<br />

оператором сложения, образуя команду SQL. По завершении выполнения<br />

запросов действия ADOTable обновляется.<br />

2. Расчетное поле. Обработчик, заполняющий расчетное поле суммой данных<br />

двух полей может выглядеть так:<br />

DataModule1–>ADOCommand1–>CommandText =<br />

"UPDATE myTable1 SET Vector2 = Vector0 + Vector1";<br />

DataModule1–>ADOCommand1–>Execute ();<br />

DataModule1–>ADOTable1–>Requery ();<br />

Более сложные выражения строятся с использованием операторов и функций<br />

SQL, приведенных в табл. 2.<br />

3. Групповые операции. Чтобы вывести минимальное, максимальное и требуемое<br />

статистическое з<strong>на</strong>чение вычисляемого поля <strong>на</strong>до подготовить запрос<br />

с группировкой. С этой целью поместить в модуль данных элемент<br />

управления ADOQuery с вкладки ADO. Соединив его с ADOConnection<br />

свойством Connection, в свойство SQL занести SQL-выражение вида<br />

SELECT MIN (Vector2) AS Минимум, MAX (Vector2) AS Максимум,<br />

AVG (Vector2) AS Операция FROM имяТаблицы<br />

Открыть запрос, установив в true его свойство Active. Добавить в модуль<br />

данных и связать с ADOQuery новый источник DataSource, а в форму – три<br />

элемента управления DBText с вкладки Data Controls, в которых инициализировать<br />

свойства DataSource и DataField. В обработчике кнопки управления<br />

вычислениями обновить этот запрос:<br />

DataModule1–>ADOQuery1–>Requery ();<br />

5. Сортировка. Для сортировки записей таблицы по возрастанию з<strong>на</strong>чений<br />

расчетного поля потребуется еще од<strong>на</strong> кнопка с обработчиком типа:<br />

DataModule1–>ADOTable1–>Sort = "Vector2 ASC";<br />

6. Поиск данных. Последняя кнопка в паре с <strong>на</strong>дписью пред<strong>на</strong>з<strong>на</strong>че<strong>на</strong> для<br />

поиска требуемых пользователю данных расчетного поля, <strong>на</strong>пример:


24<br />

DataModule1–>ADOTable1–>Filter = "Vector2 = " + Edit1–>Text;<br />

if (DataModule1–>ADOTable1–>FindFirst () = = true)<br />

Label1–>Caption = "Есть " + Edit1–>Text;<br />

else Label1–>Caption = "Нет " + Edit1–>Text;<br />

Задачи<br />

1. Блокировать возможность редактирования расчетного поля.<br />

2. Выполнить сортировку по убыванию данных расчетного поля.<br />

3. Организовать заполнение полей случайными числами с помощью функции<br />

RND языка SQL. Эта функция без параметров возвращает случайное число<br />

в диапазоне от 0 до 1. Результат можно округлять через редактор полей<br />

компонента ADOTable.<br />

Работа 10. Управление медиафайлами<br />

Задание<br />

Для освоения техники управления графическими и звуковыми файлами создать<br />

приложение, демонстрирующее <strong>на</strong> экране графические файлы разных<br />

форматов. Предоставить пользователю возможность редактирования таких<br />

файлов и музыкального сопровождения демонстрации. Подготовить з<strong>на</strong>чок и<br />

курсор приложения.<br />

Рекомендации<br />

1. Подготовка файлов. Для отладки приложения потребуется несколько графических<br />

файлов форматов .bmp, .ico, .wmf или .jpg, и аудиофайл формата<br />

.wav, .mid, или .rmi. Эти файлы <strong>на</strong>до разместить в папке приложения.<br />

2. Разработка интерфейса пользователя. Создать новый проект, в форму<br />

которого поместить элемент управления Image вкладки Additional панели<br />

визуальных компонентов для отображения иллюстраций, <strong>на</strong>дпись для вывода<br />

в форму имени файла, поле для задания расширения файла с текстом<br />

по умолчанию «*.bmp» и кнопку для перехода к следующему файлу.<br />

3. Подготовка класса формы. Для работы с jpg-файлами подключить к файлу<br />

кода формы файл заголовка jpeg.hpp, а для организации поиска файлов –<br />

FileCtrl.hpp. В состав класса формы включить функцию поиска первого<br />

графического файла, а также три переменных, описывающих путь к файлу,<br />

указатель <strong>на</strong> иллюстрацию и результат поиска, <strong>на</strong>пример, такие:<br />

void FirstPicture ();<br />

AnsiString myPath;


TImage *im;<br />

TSearchRec sr;<br />

25<br />

Инициализировать переменные в конструкторе формы:<br />

myPath = "";<br />

im = Image1;<br />

im–>AutoSize = false;<br />

im–>Proportional = true;<br />

FirstPicture ();<br />

3. Первый файл. В последней строке конструктора вызывается функция отображения<br />

первого графического файла в папке приложения:<br />

void TForm1::FirstPicture ()<br />

{ if (FindFirst (myPath + Edit1–>Text, faAnyFile, sr) == 0)<br />

{ im–>Picture–>LoadFromFile (myPath + sr.Name);<br />

Label1–>Caption = sr.Name; } }<br />

4. Следующие файлы. Обработчик кнопки перехода <strong>на</strong> следующий файл текущей<br />

папки может быть таким:<br />

if (FindNext (sr) == 0)<br />

{ im–>Picture–>LoadFromFile (myPath + sr.Name);<br />

Label1–>Caption = sr.Name; }<br />

5. Поиск файлов. Добавить в форму вторую кнопку, пред<strong>на</strong>з<strong>на</strong>ченную для<br />

поиска файлов в других папках. Обработчик кнопки поиска файлов открывает<br />

стандартное окно поиска папки с файлами и вновь вызывает функцию<br />

отображения первого файла папки:<br />

if (SelectDirectory ("Выбор папки", "", myPath))<br />

{ myPath += "\\"; FirstPicture (); }<br />

6. Подключение редактора. Добавить в форму третью кнопку, пред<strong>на</strong>з<strong>на</strong>ченную<br />

для вызова графического редактора и кодировать ее обработчик:<br />

AnsiString f = myPath + sr.Name;<br />

ShellExecute (Handle, "open", f.c_str (), NULL, NULL, SW_RESTORE);<br />

7. Аудио сопровождение. Добавить в форму четвертую кнопку и элемент<br />

управления MediaPlayer с панели System, пред<strong>на</strong>з<strong>на</strong>ченные для звукового<br />

сопровождения демонстрации. Пример обработчика кнопки, открывающего<br />

в элементе MediaPlayer первый из аудиофайлов формата .wav в папке<br />

приложения:


26<br />

TSearchRec media;<br />

if (FindFirst ("*.wav", faAnyFile, media) == 0)<br />

{ MediaPlayer1–>FileName = media.Name;<br />

MediaPlayer1–>Open (); }<br />

8. З<strong>на</strong>чок и курсор приложения. Открыть графический редактор Image Editor<br />

в меню Tools пакета C++ Builder. В подменю File.Open открыть текущий<br />

файл ресурсов проекта (.res). Далее через меню Resource.New.Icon создать<br />

новый з<strong>на</strong>чок и, выделив его, открыть окно редактора (Resource.Edit), <strong>на</strong>рисовать<br />

или импортировать з<strong>на</strong>чок и закрыть окно. Через меню Resource.Rename<br />

<strong>на</strong>звать з<strong>на</strong>чок, <strong>на</strong>пример, MYICON. и сохранить его. Затем<br />

через меню Resource.New.Cursor создать новый курсор, открыть окно<br />

редактора (Resource.Edit), <strong>на</strong>рисовать или импортировать курсор и закрыть<br />

окно. Через меню Resource.Rename <strong>на</strong>звать курсор, <strong>на</strong>пример, MY-<br />

CURSOR. Сохранить файл ресурсов и закрыть Image Editor. Вернувшись в<br />

среду <strong>С++</strong> Builder, вновь открыть проект с обновленным файлом ресурсов<br />

и дополнить конструктор формы строками:<br />

const TCursor cur = 5;<br />

// свобод<strong>на</strong>я константа<br />

Screen–>Cursors [cur]=LoadCursor (HInstance, "MYCURSOR");<br />

Cursor = cur;<br />

// новый курсор<br />

Icon–>Handle = LoadIcon (HInstance, "MYICON"); // новый з<strong>на</strong>чок<br />

Перестроить проект и открыть приложение с ориги<strong>на</strong>льным з<strong>на</strong>чком и<br />

курсором.<br />

Задачи<br />

1. Реорганизовать обработчик кнопки перехода, чтобы по достижении последнего<br />

файла в папке вывод иллюстраций <strong>на</strong>чи<strong>на</strong>лся с<strong>на</strong>чала.<br />

2. Реорганизовать обработчик кнопки перехода, чтобы по достижении последнего<br />

файла в папке выдавалось сообщение об отсутствии файлов.<br />

3. Заменить поле задания расширения файла <strong>на</strong> поле со списком допустимых<br />

типов файлов.<br />

4. Организовать процедуру поиска аудиофайлов, а<strong>на</strong>логичную поиску графических<br />

файлов.<br />

5. Пользуясь Image Editor, создать файл з<strong>на</strong>чка и подключить его к приложению<br />

через меню Project.Options <strong>на</strong> вкладке Application кнопкой Load Icon<br />

либо методом LoadFromFile (имяФайла.ico) объекта Icon.<br />

6. В Image Editor создать файл курсора и подключить его к приложению методом<br />

LoadCursorFromFile (имяФайла.cur) вместо метода LoadCursor.


27<br />

Работа 11. <strong>Программирование</strong> по алгоритму *<br />

Задание<br />

Для овладения конструированием программ по схемам алгоритмов разработать<br />

приложение по заданному преподавателем алгоритму. Организовать<br />

отображение результата в форме в виде диаграммы, а также вывод электронного<br />

отчета с этой же диаграммой и сведениями об авторе. Пример алгоритма<br />

дан <strong>на</strong> рисунке, а комментарии к нему – в соответствующем файле технического<br />

задания.<br />

Начало<br />

Ввод<br />

Исходные<br />

данные<br />

Предварительный<br />

расчет<br />

Да<br />

i>N<br />

Нет<br />

Нет<br />

Отчет<br />

j=1<br />

Да<br />

Нет<br />

j>k<br />

Да<br />

Промежуточный<br />

расчет<br />

Основной<br />

расчет<br />

Отчет<br />

Вывод<br />

Конец<br />

*<br />

Идея работы предложе<strong>на</strong> Д. В. Замятниным.


28<br />

Рекомендации<br />

1. Разработка интерфейса пользователя. Создать проект и разместить в<br />

форме необходимые поля для ввода данных, кнопки Расчет и Отчет и элемент<br />

управления Chart с вкладки Additional. В редакторе свойства Series-<br />

List элемента управления Chart <strong>на</strong>жать кнопку Add столько раз, сколько серий<br />

диаграммы должно быть выведено <strong>на</strong> экран. Здесь же полезно воспользоваться<br />

кнопкой Title, чтобы подписать каждую кривую. Оси распределяются<br />

между сериями диаграммы <strong>на</strong> вкладке Series в разделе General<br />

2. Разработка функций. В файле кода формы объявить требуемые функции.<br />

Программировать эти функции и обработчик кнопки Расчет, перенося необходимые<br />

фрагменты текста из технического задания и редактируя их.<br />

3. Построение диаграмм. В класс формы добавить функцию построения диаграммы<br />

и определить ее в файле кода формы, используя метод AddXY<br />

компонента Series, <strong>на</strong>пример:<br />

void TmyForm1::myPlot (double point, double time)<br />

{ Series1–>AddXY (time, point); }<br />

Вызовом этой функции завершать каждую итерацию расчета.<br />

4. Формирование отчета. Выбрать в меню File команду New и <strong>на</strong> вкладке<br />

New открыть Report. Подключить отчет к форме и форму к отчету<br />

(File.Include Unit Hdr…). В списке свойств отчета Bands установить в true<br />

свойство HasTitle, а в свойстве ReportTitle указать имя автора, группу и вариант.<br />

С вкладки QReport панели компонентов поместить в заголовок отчета<br />

два элемента управления QRSysData и инициализировать свойство<br />

Data первого из них константой qrsReportTitle, а второго – константой<br />

qrsDate. Полосу данных занять элементом управления QRImage. В редакторе<br />

свойства Chart элемента управления QRChart кнопкой Add добавить<br />

необходимое число серий диаграммы Series.<br />

5. Управление отчетом. Подготовить обработчик события отчета OnNeed-<br />

Data, в котором свойство Chart диаграммы отчета инициализировать диаграммой<br />

из формы, а каждую серию диаграммы отчета – соответствующей<br />

серией диаграммы формы. Открывать отчет из главной формы с использованием<br />

метода Preview, <strong>на</strong>пример:<br />

void __fastcall TQuickReport1::QuickRepNeedData (TObject *Sender,<br />

bool &MoreData)<br />

{ QRChart1–>Chart–>Assign (myForm1–>Chart1);


29<br />

Series1–>Assign (myForm1–>Series1); }<br />

void __fastcall TmyForm1::Button2Click (TObject *Sender)<br />

{ QuickReport1–>Preview (); }<br />

Задачи<br />

1. Используя метод Clear компонента Series, предоставить пользователю<br />

возможность пересчета данных с обновлением диаграммы при повторном<br />

<strong>на</strong>жатии кнопки Расчет.<br />

2. Организовать проверку корректности исходных и расчетных данных, используя<br />

константы MAXDOUBLE и MINDOUBLE или MAXFLOAT и MIN-<br />

FLOAT из файла заголовка values.h.<br />

3. Организовать защиту программы от аварийного завершения, используя<br />

механизм обработки исключений.<br />

4. Выполнить сохранение исходных данных в текстовом файле и чтение их из<br />

файла с помощью компонентов TStringList, TSaveDialog и TOpenDialog.<br />

Работа 12. Наследование<br />

Задание<br />

Для освоения техники взаимодействия базовых и производных классов создать<br />

проект, в котором в<strong>на</strong>чале реализовать базовый (Shape) и производный<br />

(Circle) классы по данному ниже описанию. Затем разработать собственный<br />

производный класс фигуры, заданной в табл. 1, c теми же методами, что и<br />

Circle: рисованием, закрашиванием и перемещением.<br />

Рекомендации<br />

1. Базовый класс. Для создания классов в дополнение к форме ввести в проект<br />

новый модуль (Unit) из библиотеки шаблонов (File.New) и подключить<br />

(File.Include Unit Hdr…) его к форме, а форму – к нему. В файле заголовка<br />

модуля объявить абстрактный базовый класс Shape:<br />

class Shape<br />

{ protected:<br />

TColor penColor, brushColor;<br />

public:<br />

Shape (TColor p, TColor b) { penColor = p; brushColor = b; }<br />

virtual void Draw () = 0;<br />

virtual void Move (int x, int y) = 0;<br />

virtual void Fill () = 0;<br />

static void Clear (); };


30<br />

В файле кода модуля определить статическую функцию Clear класса<br />

Shape, управляющую удалением изображения из элемента Image:<br />

void Shape::Clear () {<br />

{ Form1–>Image1–>Canvas–>Brush–>Color = clWhite;<br />

TRect myRect =<br />

Rect (0, 0, Form1–>Image1–>Width, Form1–>Image1–>Height);<br />

Form1–>Image1–>Canvas–>FillRect (myRect); }<br />

2. Производный класс-образец. В том же файле заголовка модуля объявить<br />

производный класс Circle:<br />

class Circle : Shape<br />

{ int cx, cy, rad;<br />

public:<br />

Circle (int x, int y, int r, TColor p, TColor b) :<br />

cx (x), cy (y), rad (r), Shape (p, b) {}<br />

void Draw ();<br />

void Move (int x, int y);<br />

void Fill (); };<br />

В конструкторе класса переменные x, y и r задают коорди<strong>на</strong>ты центра и радиус<br />

окружности, а p и b – цвета линии и заливки, передаваемые конструктору<br />

базового класса. Функция Draw рисует окружность, Move перемещает<br />

ее, а Fill закрашивает. В файле кода модуля <strong>на</strong>до определить эти методы<br />

класса Circle:<br />

void Circle::Draw ()<br />

{ Form1–>Image1–>Canvas–>Pen–>Color = penColor;<br />

TRect myRect = Rect (cx – rad/2, cy – rad/2, cx + rad/2, cy + rad/2);<br />

Form1–>Image1–>Canvas–>Ellipse (myRect); }<br />

void Circle::Move (int x, int y)<br />

{ cx += x; cy += y; }<br />

void Circle::Fill ()<br />

{ Form1–>Image1–>Canvas–>Brush–>Color = brushColor;<br />

Form1–>Image1–>Canvas–>FloodFill (cx, cy, penColor, fsBorder); }<br />

3. Применение класса Circle. В классе формы объявить указатель <strong>на</strong> объект<br />

базового класса:<br />

Shape *myShape;<br />

в конструкторе создать соответствующий объект:<br />

myShape = (Shape*) new Circle (100, 150, 10, clGray, clYellow);


31<br />

а в деструкторе удалить его:<br />

delete myShape;<br />

В форму проекта поместить элемент рисования Image, необходимые поля<br />

и три кнопки. Обработчик первой из них очищает канву и рисует:<br />

Shape::Clear ();<br />

myShape–>Draw ();<br />

обработчик второй смещает рисунок <strong>на</strong> расстояния, указанные в полях:<br />

Shape::Clear ();<br />

myShape–>Move (StrToInt (Edit1–>Text), StrToInt (Edit2–>Text));<br />

myShape–>Draw ();<br />

а обработчик третьей закрашивает фигуру:<br />

myShape–>Fill ();<br />

4. Разработка и применение заданного класса. В дополнение к классу Circle<br />

разработать производный от Shape класс предусмотренной вариантом фигуры<br />

и выполнить все операции – рисование, закрашивание и перемещение<br />

– одновременно для двух объектов: окружности и заданной фигуры. Для<br />

рисования рекомендуются такие методы класса Canvas, как Polyline, Polygon,<br />

Rectangle, RoundRect, Ellipse.<br />

Задачи<br />

1. Используя компонент ColorBox, предоставить пользователю возможность<br />

задания цвета закрашивания.<br />

2. Организовать рисование фигур из <strong>на</strong>чальной позиции, а не из текущих коорди<strong>на</strong>т.<br />

3. Реализовать перемещение закрашенных фигур.<br />

4. Ограничить область движения фигур границами канвы.<br />

5. Реализовать раздельное движение фигур вместо совместного движения.<br />

6. Исключить ввод пользователем некорректных данных в поля.<br />

Работа 13. Потоки<br />

Задание<br />

Для з<strong>на</strong>комства с многопоточным приложением создать проект, в котором<br />

бесконечное число раз рисуется фигура, задан<strong>на</strong>я в табл. 1, с переменными<br />

размерами и коорди<strong>на</strong>тами и с информацией о количестве <strong>на</strong>рисованных фи-


32<br />

гур. Три кнопки должны управлять программой: первая – запускать процесс<br />

рисования, вторая – прекращать его, а третья – приоста<strong>на</strong>вливать и продолжать<br />

рисование.<br />

Рекомендации<br />

1. Бесконечное рисование. Создать проект и поместить в его форму элемент<br />

Image и кнопку, запускающую рисование. Например, окружность произвольного<br />

размера в случайной позиции формы можно <strong>на</strong>рисовать так:<br />

TImage *im = Form1–>Image1;<br />

int cx = random (im–>Width), cy = random (im–>Height),<br />

rad = random (im–>Height / 4);<br />

TRect myRect = Rect (cx – rad/2, cy – rad/2, cx + rad/2, cy + rad/2);<br />

im–>Canvas–>Ellipse (myRect);<br />

Открыв приложение, демонстрировать возможность заполнения формы серией<br />

разнокалиберных фигурок, многократно <strong>на</strong>жимая кнопку запуска.<br />

Вернуться в проект, заключить отлаженный фрагмент кода рисования в<br />

бесконечный цикл, <strong>на</strong>пример,<br />

while(1) { Рисование }<br />

и убедиться, что остановить его удается лишь через меню Run.Program<br />

Reset (Ctrl F2) в среде Builder C++.<br />

2. Создание потока. Добавить в проект модуль класса потока (Thread Object)<br />

из библиотеки шаблонов (File.New…). После задания имени класса потока<br />

в поле Class Name ок<strong>на</strong> диалога New thread object проект дополнится модулем,<br />

который <strong>на</strong>до подключить к форме, а форму подключить к модулю<br />

(File.Include Unit Hdr…). В шаблон исполнительной функции Execute перенести<br />

код бесконечного цикла из обработчика кнопки, включив в тело<br />

цикла выражения выхода из цикла и блокировки:<br />

void __fastcall myThread::Execute ()<br />

{ while (1)<br />

{ if (Terminated) break;<br />

Form1–>Image1–>Canvas–>Lock ();<br />

Рисование<br />

Form1–> Image1–>Canvas–>Unlock (); } }<br />

Здесь myThread – это имя, присвоенное классу потока при его создании,<br />

Execute – автоматически создан<strong>на</strong>я исполнитель<strong>на</strong>я функция потока, а<br />

Terminated – перемен<strong>на</strong>я, указывающая <strong>на</strong> прекращение выполнения пото-


33<br />

ка. Методы Lock и Unlock управляют блокировкой доступа других потоков<br />

к канве при рисовании.<br />

3. Запуск и завершение бесконечного цикла. Класс формы дополнить указателем<br />

<strong>на</strong> поток, <strong>на</strong>пример:<br />

myThread *mt;<br />

В опустевшем обработчике кнопки запуска создать поток, не запуская его<br />

(аргумент конструктора CreateSuspended = true), разрешить потоку освобождать<br />

память при завершении работы свойством FreeOnTerminate, после<br />

чего запустить поток <strong>на</strong> выполнение методом Resume:<br />

void __fastcall TForm1::Button1Click (TObject *Sender)<br />

{ mt = new myThread (true);<br />

mt–>FreeOnTerminate = true;<br />

mt–>Resume (); }<br />

Поместить в форму вторую кнопку, пред<strong>на</strong>з<strong>на</strong>ченную для завершения рисования<br />

остановкой выполнения потока методом Terminate:<br />

void __fastcall TForm1::Button2Click (TObject *Sender)<br />

{ mt–>Terminate (); }<br />

Метод Terminate уста<strong>на</strong>вливает в истинное з<strong>на</strong>чение переменную Terminated,<br />

тем самым прекращая цикл выполнения потока. Испытать приложение,<br />

убедившись в возможности управления запуском и остановкой процесса<br />

рисования.<br />

4. Вывод текста в потоке. Поместить в форму <strong>на</strong>дпись для счетчика числа<br />

<strong>на</strong>рисованных фигур. Дополнить класс потока переменной-счетчиком и<br />

функцией, выполняющей вывод в <strong>на</strong>дпись з<strong>на</strong>чения этого счетчика, а в<br />

файле кода модуля потока определить эту функцию, <strong>на</strong>пример:<br />

long myCount;<br />

void __fastcall myOutput ();<br />

void __fastcall myThread::myOutput ()<br />

{ Form1–>Label1–>Caption = myCount++; }<br />

В исполнительную функцию потока включить вызов функции синхронизации<br />

вывода данных в потоке, применение которой исключает конфликты<br />

взаимодействия потоков:<br />

Synchronize (myOutput);


34<br />

5. Приостановка и продолжение выполнения потока. Дополнить форму<br />

третьей кнопкой, обработчик которой приоста<strong>на</strong>вливает и продолжает выполнение<br />

потока:<br />

void __fastcall TForm1::Button3Click (TObject *Sender)<br />

{ if (mt–>Suspended) { mt–>Resume (); Button3–>Caption = "Пауза"; }<br />

else { mt–>Suspend (); Button3–>Caption = "Продолжить"; } }<br />

Функция Suspend задает паузу в выполнении потока, уста<strong>на</strong>вливая переменную<br />

Suspended, тогда как функция Resume продолжает выполнение<br />

потока. Для исключения несвоевременного вызова рассматриваемого обработчика<br />

полезно дополнить все обработчики командами управления доступом<br />

к кнопкам. При этом <strong>на</strong>жатие кнопки запуска должно препятствовать<br />

повторному запуску (Enabled = false), разрешая завершение и приостановку<br />

рисования (Enabled = true), а <strong>на</strong>жатие кнопки завершения – препятствовать<br />

повторному завершению и приостановке, разрешая лишь новый<br />

запуск.<br />

Задачи<br />

1. Запретить освобождение памяти потоком при завершении его работы с<br />

внесением соответствующих изменений в программу.<br />

2. Используя элемент управления Timer и функции Now и TimeToStr, организовать<br />

вывод в форму времени работы потока.<br />

3. Организовать прерывание выполнения потока не только кнопкой, но и<br />

клавишей .<br />

Работа 14. Справоч<strong>на</strong>я система WinHelp<br />

Задание<br />

Для овладения конструированием справочных систем в формате WinHelp<br />

подготовить справку к одному из ранее созданных приложений, включающего<br />

несколько форм. Справоч<strong>на</strong>я система долж<strong>на</strong> состоять из пяти разделов,<br />

первый из которых описывает <strong>на</strong>з<strong>на</strong>чение приложения и сведения об авторе,<br />

второй содержит руководство по запуску, управлению, закрытию приложения<br />

и обработке возникающих ошибок кнопки управления, а остальные поясняют<br />

<strong>на</strong>з<strong>на</strong>чение элементов ввода и отображения информации формы и<br />

двух любых ее кнопок. Система долж<strong>на</strong> содержать оглавление, гиперссылки<br />

между разделами и поддерживать индексацию (поиск) по ключевым словам.<br />

Справка долж<strong>на</strong> вызываться <strong>на</strong>жатием клавиши F1.


35<br />

Рекомендации<br />

1. Структура файла справки. В Microsoft Word подготовить файл исходного<br />

текста справки и сохранить его в формате .rtf. Каждый раздел справки<br />

должен иметь заголовок. Следующий за заголовком текст раздела <strong>на</strong>до завершать<br />

символом «разрыв станицы», то есть число страниц равно числу<br />

разделов.<br />

2. Заголовки. Все заголовки оформить одним из стилей «Заголовок», <strong>на</strong>пример,<br />

стилем «Заголовок 1». После <strong>на</strong>бора текста следует пометить заголовки<br />

разделов сносками. Для этого нужно установить курсор перед первой<br />

буквой заголовка и из меню Вставка выбрать команду Ссылка.Сноска. В<br />

открывшемся диалоговом окне Сноски в группе Положение нужно установить<br />

Сноски внизу текста, а в группе Формат в поле Другой ввести символ<br />

#, используя шрифт Times New Roman, и <strong>на</strong>жать кнопку Вставить. В результате<br />

в документ будет вставле<strong>на</strong> сноска с тегом #, и в нижней части<br />

ок<strong>на</strong> документа появится окно ввода текста сноски. В этом окне после<br />

символа сноски следует ввести идентификатор помечаемого раздела<br />

справки, <strong>на</strong>пример IDH_1.<br />

3. Ключевые слова. Далее для каждого раздела <strong>на</strong>до создать сноску с тегом К,<br />

в которой задается список ключевых слов данного раздела для организации<br />

Указателя справочной системы. Разделителем элементов списка служит<br />

точка с запятой.<br />

4. Име<strong>на</strong> разделов. Кроме того, для каждого раздела <strong>на</strong>до создать сноску с<br />

тегом $, под которой задается имя раздела, которое будет применяться для<br />

идентификации его в списке поиска и в списке просмотренных тем ок<strong>на</strong><br />

хронологии справочной системы. Имя может совпадать с заголовком.<br />

5. Гиперссылки. Разделы справки должны содержат гиперссылки <strong>на</strong> другие<br />

разделы. Во время подготовки текста справочной информации гиперссылки<br />

следует выделять двойным подчеркиванием. Сразу за гиперссылкой <strong>на</strong>до<br />

поместить без пробела идентификатор раздела справки, <strong>на</strong> который будет<br />

выполняться переход. Вставленный идентификатор оформляется как<br />

скрытый текст Microsoft Word.<br />

6. Создание проекта. Сохранив подготовленный rtf-файл в одной папке с<br />

приложением, для которого создается справоч<strong>на</strong>я система, следует создать<br />

проект справочной системы. Для этого запускается программа Microsoft<br />

Help Workshop (hcw.exe) в папке $BCB$\Help\Tools\. В ее меню File командой<br />

New <strong>на</strong>до открыть окно диалога Project File Name и указать тип созда-


36<br />

ваемого файла – Help Project. Далее следует перейти в папку с приложением<br />

и rtf-файлом справки и в поле Имя файла ввести произвольное имя<br />

проекта справочной системы. Файлу проекта присваивается расширение<br />

.hpj.<br />

5. Подключение rtf-файла к проекту. Для того чтобы добавить в этот проект<br />

файл справки, <strong>на</strong>жимается кнопка Files, а затем кнопка Add в диалоговом<br />

окне Topic Files. Следующее окно Открытие файла позволяет выбрать rtfфайл.<br />

6. Свойства. Под кнопкой Options <strong>на</strong> вкладке General указывается идентификатор<br />

раздела, который будет вызываться по умолчанию, а также заголовок<br />

ок<strong>на</strong> справочной системы. Далее <strong>на</strong>до определить числовые з<strong>на</strong>чения<br />

для идентификаторов разделов – контексты. Для этого в окне, открываемом<br />

кнопкой Map, <strong>на</strong>жимается кнопка Add. Затем в поле Topic ID диалогового<br />

ок<strong>на</strong> Add Map Entry вводится идентификатор раздела справки, а в<br />

поле Mapped numeric value – соответствующее идентификатору произвольное<br />

уникальное числовое з<strong>на</strong>чение, <strong>на</strong>пример, IDH_1 и 1.<br />

7. Компиляция. После того, как будет подготовлен файл проекта, следует выполнить<br />

компиляцию, <strong>на</strong>жав в окне проекта кнопку Save and Compile. В<br />

итоге <strong>на</strong> экран выводится сообщение о результатах компиляции.<br />

8. Содержание. Полноцен<strong>на</strong>я справоч<strong>на</strong>я система нуждается в файле содержания<br />

(расширение .cnt) с <strong>на</strong>званиями тем и разделов справки, пред<strong>на</strong>з<strong>на</strong>ченным<br />

для управления <strong>на</strong>вигацией в справочной системе. Для его создания<br />

в программе Help Workshop готовится новый проект командой<br />

File.New, в котором задается новый тип создаваемого файла – Help Contents.<br />

В поле Default filename задается произвольное имя файла содержания.<br />

Разделы содержания формируются кнопками Add Below и Add Above.<br />

Для добавления темы необходимо установить переключатель в строку<br />

Heading и заполнить поле <strong>на</strong>звания темы Title. Для добавлении каждого<br />

раздела <strong>на</strong>жимается переключатель Topic и заполняются поля <strong>на</strong>звания<br />

раздела Title, идентификатора раздела Topic ID, <strong>на</strong>пример IDH_5, файла<br />

справки Help file и типа ок<strong>на</strong> Window type – main.<br />

9. Подключение cnt-файла к проекту. Чтобы подключить файл содержания,<br />

<strong>на</strong>до в проекте справочной системы <strong>на</strong>жать кнопку Options и в открывшемся<br />

окне <strong>на</strong> вкладке Files в поле Contents file ввести имя cnt-файла. затем<br />

файл справочной системы <strong>на</strong>до сохранить и повторно компилировать.


37<br />

10. Подключение справки к приложению. Теперь справку нужно подключить<br />

к приложению. Для этого в C++ Builder через меню Projects.Options <strong>на</strong><br />

вкладке Applications следует указать имя созданного файла справки, а в<br />

свойствах HelpContext формы и кнопок – числовые з<strong>на</strong>чения идентификаторов<br />

разделов справки, заданные под кнопкой Map. Если форма имеет<br />

меню Справка, то в обработчик пункта Справка <strong>на</strong>до поместить вызов<br />

справочной системы, <strong>на</strong>пример:<br />

Application–>HelpJump ("IDH_1");<br />

11. Испытать приложение, <strong>на</strong>жимая в форме и <strong>на</strong> кнопках клавишу .<br />

Задачи<br />

1. В файле проекта (.hpj) задать характеристики главного ок<strong>на</strong> справочной<br />

системы, <strong>на</strong>жав кнопку Windows в главном окне Microsoft Help Workshop.<br />

Для этого в поле Create a window named ок<strong>на</strong> Create a window ввести main,<br />

после чего <strong>на</strong> вкладках Position, Buttons и Color установить размеры, кнопки<br />

и цвет ок<strong>на</strong> справки и выполнить компиляцию проекта.<br />

2. Создать справочную систему, организовав вызов различных разделов<br />

справки из поля ввода и таблицы.<br />

Работа 15. Справоч<strong>на</strong>я система HelpScribble<br />

Задание<br />

Для овладения конструированием справочных систем в формате HTML разработать<br />

справочную систему к одному из ранее созданных приложений.<br />

Справоч<strong>на</strong>я система долж<strong>на</strong> удовлетворять всем требованиям предыдущей<br />

работы.<br />

Рекомендации<br />

1. Интерфейс пользователя HelpScrible. Запустить программу HelpScribble и<br />

оз<strong>на</strong>комиться с ее интерфейсом пользователя. В центре ок<strong>на</strong> <strong>на</strong>ходится область<br />

содержания справки, слева – оглавление Topic Grid, а вверху – меню,<br />

панели инструментов и поле со списком заголовков разделов. Основу разработки<br />

составляет проект, который создается командой меню Project.New,<br />

сохраняется командами Project.Save и Project.Save As в файлах с<br />

расширением .hsc, открывается командой Project.Open и компилируется в<br />

файл справочной системы с расширением .chm, который затем подключается<br />

к приложению.


38<br />

2. Заголовки и текст разделов. Чтобы создать новый проект, следует после<br />

запуска HelpScribble сразу печатать заголовок первого раздела в поле со<br />

списком вместо текста . В оглавлении ему автоматически присваивается<br />

ID 10. Вслед за заголовком в области содержания справки можно<br />

печатать текст раздела или вставить туда через буфер обме<strong>на</strong> ранее<br />

подготовленный текст. Через меню Topic.New создаются следующие разделы<br />

и тоже заполняются текстом. Командами этого же меню разделы<br />

удаляются, переименовываются и перенумеровываются. Через оглавление<br />

можно всегда возвратиться к ранее созданному разделу для редактирования.<br />

Для этой же цели служит меню Go to topic и поле со списком заголовков.<br />

Оформление и правка текста выполняется командами меню Text.<br />

3. Гиперссылки. Выделить слово или фрагмент текста одного из разделов, которому<br />

<strong>на</strong>до <strong>на</strong>з<strong>на</strong>чить гиперссылку. Затем в оглавлении открыть контекстное<br />

меню того раздела, к которому обраще<strong>на</strong> гиперссылка, и выбрать<br />

пункт Create Link. Создан<strong>на</strong>я таким образом гиперссылка будет окраше<strong>на</strong><br />

в зеленый цвет, перечеркнута и помече<strong>на</strong> справа номером связанного с ней<br />

раздела. Для перехода по гиперссылке <strong>на</strong>до вызвать контекстное меню<br />

этого номера раздела и выбрать пункт Follow Link to #.<br />

4. Компиляция проекта. Сохранить проект через меню Project.Save. Затем<br />

компилировать его в меню Project.Make. На вкладке General ок<strong>на</strong> Project<br />

Options можно создать заголовок ок<strong>на</strong> справочной системы, а <strong>на</strong> вкладке<br />

Compiler выбрать HTML Help. В результате первый раздел созданной системы<br />

откроется в окне Справка, и в папке будет сохранен ее файл с расширением<br />

.chm.<br />

5. Ключевые слова. Открыть редактор ключевых слов Index Editor соответствующей<br />

командой меню Editors и кнопкой New Keword вставить первое<br />

ключевое слово или фразу в список Index. Двойным щелчком или кнопкой<br />

Add Topic связать ключевое слово с разделом, перенеся имя раздела из<br />

списка Other topics в список Topics related to this keyword. А<strong>на</strong>логично создаются<br />

и связываются с разделами другие ключевые слова. Кнопка Delete<br />

пред<strong>на</strong>з<strong>на</strong>че<strong>на</strong> для удаления ключевых слов из списка Index, а кнопка<br />

Change Keyword – для их изменения. Кнопкой Remove Topic удаляется<br />

выделенный раздел из списка Topics related to this keyword.<br />

6. Содержание. Открыть редактор содержания Contents Editor соответствующей<br />

командой меню Editors. Кнопкой поля Title открыть оглавление и


39<br />

требуемый заголовок включить в содержание кнопкой Add. Переключателем<br />

Header вкладки Contents <strong>на</strong>з<strong>на</strong>чить этот заголовок заголовком содержания.<br />

А<strong>на</strong>логично создаются другие заголовки содержания и при необходимости<br />

переименовываются в поле Title. Уровни иерархии разделов задаются<br />

кнопками со стрелками вправо и влево. Связь заголовков содержания<br />

с темами справочной системы задается переключателем Link to this help file<br />

и поле Topic.<br />

7. Подключение справки к приложению. После добавления ключевых слов и<br />

содержания, а также после каждого изменения проект следует вновь компилировать,<br />

открывать и тестировать справочный файл. Затем <strong>на</strong>до вернуться<br />

в проект C++ Builder и для подключения справки к приложению в<br />

обработчик кнопки Справка или пункта Справка меню Справка поместить<br />

вызов справочной системы, <strong>на</strong>пример:<br />

WinExec ("myHelp.chm", SW_RESTORE);<br />

Функция WinExec имеет два параметра: имя выполняемого файла и режим<br />

открытия ок<strong>на</strong>. Возможно, также, применение других функций.<br />

Задачи<br />

1. Командой Insert Link меню Help Tools добавить в справочную систему гиперссылку,<br />

открывающую один из сайтов Интернета.<br />

2. Командой Insert Bitmap меню Help Tools добавить в справочную систему<br />

рисунок.


40<br />

Список рекомендуемой литературы<br />

Архангельский А. Я. <strong>Программирование</strong> в C++ Builder 6. М.: Бином, 2003.<br />

Водовозов В. М., Пожидаев А. К. Конструирование приложений для Windows:<br />

Учеб. пособие. СПб.: Изд-во СПбГЭТУ «ЛЭТИ», 2004.<br />

Водовозов В. М., Чмиленко Ф. В. Объектно-ориентированное программирование<br />

<strong>на</strong> <strong>С++</strong>: Учеб. пособие. СПб.: Изд-во СПбГЭТУ «ЛЭТИ», 2007.<br />

Культин Н. Б. Самоучитель <strong>С++</strong> Builder. СПб.: БХВ-Петербург, 2005.<br />

Курсовое программирование <strong>на</strong> <strong>С++</strong>: Методические указания к курсовой работе<br />

/ Сост.: В. М. Водовозов, А. К. Пожидаев. СПб.: Изд-во СПбГЭТУ<br />

«ЛЭТИ», 2004.<br />

Павловская Т. А. С/<strong>С++</strong>. <strong>Программирование</strong> <strong>на</strong> языке высокого уровня:<br />

Учебник. СПб.: Питер, 2003.<br />

Редактор<br />

Подписано в печать . Формат 60×84 1/16.<br />

Бумага офсет<strong>на</strong>я. Печать офсет<strong>на</strong>я. Печ. л. 2,5.<br />

Гарнитура «Times». Тираж 150 экз. Заказ .<br />

Издательство СПбГЭТУ «ЛЭТИ»<br />

197376, С.-Петербург, ул. Проф. Попова, 5

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!