Программирование на С++ - eDrive
Программирование на С++ - eDrive
Программирование на С++ - eDrive
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