24.11.2014 Views

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

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

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

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Федеральное агентство по образованию<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!