Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Разработка Windows - приложений в среде Borland. Учебное пособие
.pdf
Проект содержит семь основных текстовых файлов. Файл
workapp.def - файл определений. Файлы workapp.rc и workapp.rh –
описывают ресурсы (меню, кнопки, идентификаторы и т.п.). Файлы
с именем, оканчивающимся на app и расширениями cpp и h – описывают наши классы приложения TWorkApp и главного окна
TSDIDecFrame, являющиеся наследниками классов OWL “Tapplication” и “TDecoratedFrame”. Оставшиеся два файла с именем,
оканчивающимся на
dlgcl, описывают класс диалога TWorkDlgClient,
являющийся наследником базового класса OWL “TDialog”. Следует
отметить, что при генерации имен файлов (классов) AppExpert комбинирует имя проекта (в данном случае work) со словами application
и dialog (или именами классов OWL), сокращая для имен файлов
комбинацию до 8 символов, в результате сокращенные имена файлов могут иметь и другие окончания. Впрочем, можно использовать
и длинные имена, задав соответствующую опцию.
Помимо семи тестовых файлов, AppExpert создал файл проекта
work.ide (по умолчанию не отображается в окне проекта), иконку –
файл с расширением ico и файл внутренней базы данных проекта – с
расширением apx. В файле проекта фиксируется структура проекта
и необходимые настройки. Иконка отображается в главном окне и
в
системах навигации (проводник), а также является кнопкой вызова
системного меню. Из файла базы данных черпает информацию
ClassExpert, речь о котором пойдет ниже.
При переносе проекта в другую папку (на другой компьютер)
следует скопировать перечисленные выше 10 файлов: Work.ide,
Work.apx, WorkApp.def, WorkApp.cpp, WorkApp.h, WrkDlgCl.cpp,
WrkDlgCl.h, WorkApp.rc, WorkApp.rh и applsdi.ico. Необходимо за-
помнить, что если проект называется не “Work”, имена файлов бу-
дут другими.
После переноса проекта на другой компьютер проверьте в на-
стройке проекта пути к папкам библиотек и заголовочных файлов
Borland C++. Для этого выберите первую строчку в окне проекта
(work.exe [AppExpert]), нажмите правую кнопку мыши и в контекст-
ном меню пункт “Edit local options...”. При необходимости смените
пути, заданные в полях “Include:” и “Library:”.
11

Замечание: Созданное приложение (файл work.exe) можно выполнить не только из среды Borland C++. Однако на другом компьютере оно может не найти нужные библиотеки. Вопросы создания
полноценного дистрибутива не входят в задачи данного пособия, но
можно посоветовать использовать при сборке программы статические, а не динамические библиотеки. Для этого выберите первую
строчку в
окне проекта (work.exe [AppExpert]), нажмите правую
кнопку мыши, в контекстном меню выберите пункт “TargetExpert...”
и поставьте переключатель в положение Static (обязательно заново
сгенерируйте приложение Project → Build all). Возможно, этого будет достаточно, но размер приложения несколько увеличится…
Возможные проблемы: В том случае, если на рабочем компьютере Вы ограничены в правах, Borland C++ может не найти необхо
димых библиотек и утилит. Во всяком случае, нужен полный доступ
к папкам, в которых инсталлирован Borland C++. Проекты, созданные в вашей папке вложенной в …\Bc5\Bin, будут работать болееменее нормально. На своем домашнем компьютере Вы, естественно,
имеете права администратора, этого вполне достаточно. Однако не
стоит лениться и создавать иерархию папок «Новая папка»
→ «Новая папка» → «Новая папка» →… Borland C++ может просто не выдержать глумления и перестанет открывать файлы в проекте.
О
ПИСАНИЕ ДАННЫХ
Для того чтобы в дальнейшем можно было работать с пользовательским типом данных, необходимо определить его. Для работы с
базой данных размером в сто записей нам понадобится массив объ-
-
12

ектов типа staff. Описание данных желательно приводить в заголовочном файле. Для этого в окне проекта раскройте (щелкнув по +)
список узла workapp.cpp и выберете файл workapp.h. Откройте
этот файл (двойной щелчок или контекстное меню соответствующего узла в окне проекта → View → Text Edit). В конец файла перед
директивой препроцессора #endif добавьте
описание структуры:
struct staff{ // состав сотрудников, штат
char name[20]; // имя
char job[20]; // должность
int pay; // оклад
};
staff crew[100]; // массив записей
int iCur; // номер текущей записи
int iMax; // количество записей в базе данных
Надежнее будет сразу закрыть и сохранить файл workapp.h.
Д
ОБАВЛЕНИЕ ЭЛЕМЕНТОВ ИНТЕРФЕЙСА
Используемые ниже элементы – это окна, реагирующие на события, связанные с ними, например, выбор или щелчок мышкой.
Каждый элемент является объектом соответствующего класса и
имеет конструктор, определенный набор полей (свойств) и методов.
В последующем некоторые свойства и методы этих классов будут
рассмотрены подробнее. В этом разделе основное внимание мы уде
лим принципам работы с утилитами Resource Workshop и ClassExpert.
По всем этим вопросам можно порекомендовать литературу [6,7].
Добавьте элементы пользовательского интерфейса в Ваш диалог. Для этого выберите в окне проекта файл workapp.rc и запустите редактор ресурсов (двойной щелчок или контекстное меню узла
→ View → Edit Resources). В окне редактора ресурсов раскройте
пункт DIALOG (щелкнув
по +), выберете IDD_CLIENT (2000) и
дважды щелкните мышкой (или выберите пункт контекстного меню
→ Edit…). Должна появиться панель инструментов Controls. Если
ее нет – вызовите на белом фоне контекстное меню и выберите
пункт Control Palette.
-
13

Измените мышкой размеры окна и переместите кнопки OK и
Cancel к правой границе окна (вниз). Добавьте надпись на форму -
щелкните по кнопке “А” на панели инструментов Controls и мышкой задайте место и размеры надписи в диалоговом окне. Дважды
щелкните мышкой по элементу «надпись» в окне диалога, вызвав
окно
свойств элемента – Properties (или выберите соответствующий
пункт контекстного меню элемента). Измените текст в поле Caption
окна свойств на «имя» (без кавычек). Нажмите кнопку OK в окне
свойств (кнопка Apply позволит предварительно увидеть изменения).
Теперь добавьте слева от надписи редактируемое текстовое поле. Щелкните по кнопке “ab|” на панели Controls и мышкой задайте
место и размеры элемента в диалоговом окне – справа от надписи
14

«имя». Дважды щелкните мышкой по элементу «поле» в окне диа-
лога, вызвав окно свойств элемента – Properties (или выберите со-
ответствующий пункт контекстного меню элемента) и уберите текст
из поля Caption (оставьте пустым). Для того чтобы к этому полю
можно было обращаться из программы, то есть, выводить в поле
информацию
или считывать её, необходимо создать программный
объект класса TEdit и присвоить ему имя. Важно запомнить, что соответствующая программная переменная будет указателем на объект
класса. Вызовите контекстное меню для этого элемента «поле» на
форме, выберите пункт ClassExpert, убедитесь, что в панели Classes
выбран класс диалога (TWorkDlgClient), найдите идентификатор
поля в панели Events (события
). Идентификатор элемента управления указан в окне Properties, если Вы ничего не меняли, то для первого созданного поля это будет IDC_EDIT1. Вызовите контекстное
меню для этого идентификатора, а затем выберите пункт Add
instance variable (добавить экземпляр объекта).
В появившемся окне задайте имя EditName и нажмите OK.
Здесь и далее вместо предлагаемых имен возможно задание любых
имен, допустимых в языке С/С++. Естественно, тогда нужно будет
отредактировать фрагменты кода, предлагаемые ниже.
15

Далее добавьте в окно диалога надпись «должность» и соответствующее поле. Не забудьте присвоить имя: ClassExpert → Add in-
stance variable → EditJob, а также надпись «оклад» и соответствующее поле (имя – EditPay).
Внизу окна поместите еще одну надпись, задав Caption – 0
(ноль) и имя (через ClassExpert) – StaticNum. В это место мы будем
выводить
текущей номер записи при просмотре базы данных. Те-
перь окно диалога должно иметь вид:
Наше приложение должно выполнять ряд команд пользователя:
«добавить», «удалить», «сохранить», «сортировать» и так далее. Эти
команды выполняют операции, типичные при работе с базами данных. В программе каждой такой команде соответствует определенная функция. Обычно для задания команды от пользователя требуется нажать на кнопку или выбрать нужный пункт меню.
Начнем с
командных кнопок. Итак, нам потребуется добавить в наш диалог
кнопки, «самостоятельно» написать код соответствующих функций
(так называемых функций – обработчиков событий) и связать каждую такую функцию с событием Click – щелчок (мышкой) на управляющем элементе «командная кнопка».
Выберите на панели Controls элемент «кнопка» и значок “ОК”
и
поместите кнопку в верхнем правом углу окна диалога. Задайте
свойство Caption – «добавить». Теперь выделите кнопку, вызовите
через контекстное меню ClassExpert, убедитесь, что в панели
Classes выбран класс диалога (TWorkDlgClient), найдите идентификатор кнопки в панели Events (события). Если Вы не меняли иден-
тификатор, то для первой созданной кнопки это будет IDC_BUT-
TON1. Далее
раскройте список событий этой кнопки ("+" у иден-
тификатора IDC_BUTTON1) и выберите нужное событие (BN_CLI-
CKED – щелчок по кнопке). Вызовите контекстное меню для этого
события, затем пункт Add handler (добавить функцию обработчик)
16

в контекстном меню и в появившемся окне задайте имя функции
BNClickedAdd. Не забудьте нажать OK.
В нижней панели окна ClassExpert появится заготовка нужной
функции. Она создается как метод Вашего класса TWorkDlgClient,
являющегося наследником базового класса TDialog, и находится в
файле wrkdlgcl.cpp.
void TWorkDlgClient::BNClickedAdd()
{
// INSERT>> Your code here.
}
Добавьте после комментария // INSERT>> Your code here следующий код:
char buff[20];
EditName -> GetText( buff, 20);
strcpy( crew[iMax].name, buff);
EditJob -> GetText( buff, 20);
strcpy( crew[iMax].job, buff);
EditPay -> GetText( buff, 20);
crew[iMax].pay = atoi( buff);
wsprintf( buff, "%i", iMax + 1);
StaticNum -> SetText( buff);
iCur = iMax;
iMax++;
Сначала, с помощью метода GetText класса TEdit, имя сотрудника считывается из редактируемого поля окна диалога EditName в
17

буферный массив buff, размерность которого совпадает с размерностью соответствующего поля name структуры staff. Первым параметром функции GetText должен быть адрес символьного массива,
второй параметр ограничивает количество считываемых символов.
Далее имя, сохраненное в массиве buff, копируется в поле name записи с индексом iCur массива структур crew. Аналогично записывается в
оклад сотрудника хранится как целое число, то значение, предварительно считанное в строку buff, с помощью функции atoi преобразуется в целое число. Если пользователь ввел в поле EditPay неверное
значение, результатом такого преобразования будет ноль. Функция
wsprintf аналогична функции printf, но вместо
вывода на экран монитора, записывает результат форматирования в
строку, указываемую первым параметром. Полученное значение выводится в надпись StaticNum, предназначенную для отображения
текущего номера записи. Для вывода используем функцию SetText
класса TEdit, единственным параметром которой указывается адрес
символьного массива. Индекс последней введенной записи запоминается в переменной iCur. Суммарное количество
сей запоминается в переменной iMax.
ся с нуля, однако при отображении номера текущей записи в поле
StaticNum используется естественная нумерация, начиная с единицы.
мание на тот факт, что считанные из полей диалога
ность» предварительно записываются в буферный массив. Конечно,
можно записать соответствующие данные непосредственно в поля
структуры, например:
однако если поле структуры будет скрытым (private), то непосредственный доступ к нему будет невозможен и использование буферного массива станет необходимым.
справа от надписи StaticNum, отображающей номер записи). Эти
кнопки позволят переходить к предыдущей или следующей записи и
отобразить её в нашем окне. Задайте свойство Caption для этих кнопок "<<" (левая кнопка) и ">>" (правая) и создайте заготовки соот-
массив и значение должности из поля EditJob. Поскольку
форматированного
введенных запи-
Замечание: В рассматриваемом коде нумерация записей ведет-
Если Вам понятен предложенный код, то еще раз обратите вни-
«имя» и «долж-
EditName -> GetText(crew[iMax].name,20);
Поместите еще две кнопки в диалоговое окно (внизу, слева и
18

ветствующих функций-обработчиков BNClickedPrev и BNClickedNext
(через ClassExpert).
Добавьте в тело функции BNClickedPrev после комментария //
INSERT>> Your code here следующий код:
char buff[20];
if(iCur <= 0) return;
iCur--;
EditName -> SetText( crew[iCur].name);
EditJob -> SetText( crew[iCur].job);
wsprintf(buff, "%i", crew[iCur].pay);
EditPay -> SetText( buff);
wsprintf(buff, "%i", iCur + 1);
StaticNum -> SetText( buff);
Поскольку функция BNClickedPrev предназначена нами для
перехода к предыдущей записи, индекс которой на единицу меньше,
чем индекс iCur текущей записи, прежде всего проверяем, не является ли текущая запись самой первой (индекс равен нулю). Далее
уменьшаем на единицу индекс записи и выводим в соответствующие поля окна диалога данные, сохраненные в
массиве crew. Поскольку оклад сотрудника хранится как целое число, а параметром
метода SetText должен быть массив символов, то числовое значение
предварительно записываем в строку buff с помощью функции
wsprintf, как и номер выбранной записи.
Функция BNClickedNext предназначена для отображения сле-
дующей записи, индекс которой на единицу больше, чем индекс
iCur текущей записи. Нужный код мало отличается от кода функции
BNClickedPrev. Необходимо лишь проверить, не является ли теку-
щая запись последней из введенных пользователем. Поэтому вместо
инструкций:
if(iCur <= 0) return;
iCur--;
наберите:
if(iCur >= iMax - 1) return;
iCur++;
19

все остальные инструкции тождественны коду функции BNClickedPrev.
Сохраните все измененные файлы проекта так как бывают сбои.
Затем перейдите в окно проекта и запустите его на исполнение.
Кнопка «добавить» добавляет новую запись в базу данных. Значения берутся из соответствующих полей диалогового окна. Кнопки
"<<" и ">>" позволяют последовательно просматривать
записи,
имеющиеся в базе данных. Между этими кнопками после команды
«добавить» выводится номер последней записи, а после команд
"<<" и ">>" выводится номер текущей записи (нумерация с едини-
цы).
Закройте проект: меню Project → Close project (не закрывайте
окно проекта кнопкой
, закроете только окно проекта, а не сам
проект!!!). Для открытия проекта используйте пункты меню: Project
→ Open project и выберите файл с расширением “ide” (в данном
случае work.ide).
С
ТРУКТУРА ПРИЛОЖЕНИЯ
С помощью интегрированной среды Borland C++ 5 Вы, практически ничего не понимая, создали работоспособное приложение,
содержащее около тысячи строк непонятного кода. Собственно это и
называется визуальное программирование или «программирование
мышкой». Можно и дальше продолжать в том же духе, однако рано
или поздно слепое следование чужим рекомендациям заводит в тупик. Поэтому попробуем
хотя бы чуть-чуть разобраться, что же мы
«наделали». Желающим разобраться глубже, стоит повторить во-
20
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
