Delphi 6 программирование
Мультимедийный таймер
18.4.1.1. Мультимедийный таймерВ ряде практически важных применений (при разработке игр, в системах реального времени для управления внешними устройствам и т. п.) интервал 55 мс может оказаться слишком велик. Современный ПК имеет мультимедийный таймер, период срабатывания которого может быть от 1 мс и выше. Однако этот таймер не имеет компонентного воплощения, поэтому для доступа к нему приходится использовать функции API.
Общая схема его использования такова. Сначала готовится процедура обратного вызова (call back) с таким заголовком:
procedure TimeProc(uID, uMsg: UINT; dwUser, dwi, dw2: DWORD);
stdcall;
Здесь uID - идентификатор события таймера (см. ниже); uMsg - не используется; dwuser - произвольное число, передаваемое процедуре в момент запуска таймера; dwi, dw2 - не используются. Запуск таймера реализуется функцией
function timeSetEnet(uDelay, uResolution: UINT;
IpTimeProc:Pointer;
dwUser: DWORD;
fuEvent: UINT): UINT;
stdcall;
external 'winmm.dll';
Здесь uDelay - требуемый период срабатывания таймера (в мс);
uResolution - разрешение таймера; значение 0 означает, что события срабатывания таймера будут возникать с максимально возможной частотой; в целях снижения нагрузки на систему вы можете увеличить это значение; IpTimeProc - адрес процедуры обратного вызова; dwUser - произвольное число, которое передается процедуре обратного вызова и которым программист может распоряжаться по своему усмотрению; fuEvent - параметр, управляющий периодичностью возникновения события таймера: time_oneshot (0) - событие возникает только один раз через uDelay мс; time_periodic (1) - события возникают периодически каждые uDelay мс. При успешном обращении функция возвращает идентификатор события таймера или 0, если обращение было ошибочным.
Таймер останавливается, и связанные с ним системные ресурсы освобождаются функцией
function timeKillEvent(uID: UINT): UINT;
stdcall; external 'winmm.dll';
Здесь uID - идентификатор события таймера, полученный с помощью timeSetEvent.
В следующем примере иллюстрируется особенность использования мультимедийного таймера.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, For.gif" >
когда еще не существовала Windows
1.1. ВЕРСИЯ 1Первая версия появилась в мае 1995 г., когда еще не существовала Windows 95 (но тем не менее существовала Windows NT). Это единственная версия, работающая под управлением 16-разрядной Windows 3.1 (3.11). В ней впервые была опробована новая модель объектов, позаимствованная из различных объектно-ориентированных языков, и главным образом, из языка C++. Эта модель оказалась настолько революционной, что существовавшие в то время в поздних версиях Turbo Pascal объекты стали не нужны (их возможности полностью поглотила новая модель), а сама новая модель получила название классов. Классы активно используют динамическую память, в связи с чем несколько изменилась нотация языка, а сам язык был назван Object Pascal. По сравнению с Turbo Pascal в него были внесены существенные дополнения и изменения, в том числе (здесь и далее перечисляются лишь наиболее важные, с моей точки зрения, изменения):
Палитра компонентов первой версии состоит из 9 страниц и содержит 79 компонентов. В качестве дополнительных утилит поставлялись система генерации отчетов ReportSmith v.2.5 и входящая в ее состав автономно запускаемая утилита ReportSmith Run Time Viewer, утилита доступа к данным DatabaseDesktop v.5.1 и утилита конфигурации BDE - Database Engine Configuration v.2.5. Кроме того, утилиты WinSighte и WinSpecter предназначались для упрощения отладки разрабатываемых программ в среде 16-разрядных ОС Windows 3-х.
| Назад |
и все последующие версии Delphi
1.2. ВЕРСИЯ 2Вторая и все последующие версии Delphi предназначены для работы под управлением 32-разрядных ОС Windows 95/98/2000/NT (Windows 32). В нее были внесены многочисленные изменения, связанные с переходом на качественно новую ОС, в том числе:
Среда разработки обогатилась Репозиторием Объектов и множеством полезных программ-экспертов (Wizards).
К утилитам добавлена весьма эффективная программа SQL Explorer v.1.02, существенно облегчающая операции с базами данных, и программа переноса данных Data Migration Expert, упрощающая переход к архитектуре клиент-сервер. Утилиты ReportSmith и DatabaseDesktop представлены более совершенными версиями 3.0 и 7.1 соответственно. Утилита Database Engine Configuration предыдущей версии переименована в BDE Configuration v.3.0. Введена утилита Image Editor v.2.0, служащая для создания различного рода изображений (произвольных рисунков, пиктограмм и курсоров), которые можно включать в файл ресурсов и использовать в работающей программе, и утилита SQL Monitor v.1.0, позволяющая просматривать SQL-запросы в процессе выполнения программы.
На 12 страницах галереи компонентов расположены 114 стандартных компонентов. В том числе на странице QReport размещены удобные компоненты для создания отчетов по хранящимся в базах данным. Эти компоненты оказались значительно эффективнее специальной утилиты ReportSmith, в связи с чем эта утилита не входит в поставку версии 3 и выше.
| Назад |
Мне довелось довольно долго работать
1.3. ВЕРСИЯ 3Мне довелось довольно долго работать с вышедшей в июне 1997 г. версией 3, и у меня сложилось мнение, что это одна из наиболее надежных версий Delphi. Основные новшества этой версии:
Состав утилит комплектации Client/Server Suite не изменился по сравнению с предыдущей версией, но изменились названия некоторых из них: BDE Configuration в этой и последующих версиях называется BDE Administrator, a Data Migration Expert - Data Migration Wizard. Ha 13 страницах галереи компонентов размещены 148 стандартных компонента. В модификации 3.5 введены дополнительные компоненты для реализации многозвенных баз данных.
| Назад |
я версия Delphi быстро завоевала
1.4. ВЕРСИЯ 4Появившаяся в июле 1998 г. 4- я версия Delphi быстро завоевала широкую популярность как своими расширенными языковыми возможностями, так и специальной поддержкой многозвенных баз данных и распределенных вычислений. К основным нововведениям этой версии относятся:
| Назад |
В июле 1999 г. вышла
1.5. ВЕРСИЯ 5В июле 1999 г. вышла пятая по счету версия Delphi, основная особенность которой - попытка заменить громоздкий и не всегда быстрый механизм доступа к данным BDE, который традиционно использовался во всех предыдущих версиях, альтернативными механизмами. Для этого, во-первых, в Delphi 5 включена поддержка технологии ADO (ActiveX Data Objects - объекты данных, построенные как объекты ActiveX), которая усиленно развивается корпорацией Microsoft.
Во-вторых, сотрудники Borland и его подразделения InterBase Software Corporation разработали серию компонентов облегченного доступа к данным, хранящимся в таблицах сервера InterBase v.5.5 и выше (страница InterBase палитры компонентов). Эти компоненты также не требуют BDE и, таким образом, создают “облегченное” клиентское место.
Менее значительные изменения, внесенные в версию 5:
| Назад |
й версии. Эту задержку можно
1.6. ВЕРСИЯ 6Версия 6 вышла в мае 2001 г., т. е. почти через 2 года после выхода 5- й версии. Эту задержку можно объяснить тем, что параллельно с работой над новой версией Delphi шла разработка варианта Delphi для ОС Linux - эта система программирования вышла в феврале 2001 г. и получила название Kylix. В результате 6-я версия Delphi имеет уникальную особенность: она способна создавать так называемые'межплатформенные приложения, т. е. программы, которые одинаково успешно могут работать как под управлением Windows 32, так и под Linux. Напомню читателю предысторию, связанную с этой ОС. Еще в самом начале 70-х годов в Bell Laboratories была создана переносимая система UNIX. Переносимость системы, т. е. ее способность миграции на различные аппаратные платформы, обеспечивалась тем, что практически вся она была написана на специально для этой цели разработанном языке С. Более того, почти весь компилятор этого языка был также написан на С! В результате для переноса ОС на новую аппаратную среду нужно было закодировать лишь сравнительно небольшой машинно-зависимый участок С, после чего транслировался исходный код компилятора, а затем и системы в целом. Таким образом, ОС UNIX принципиально существовала в исходных текстах, доступных широкому кругу программистов. Это обстоятельство использовали многие фирмы, создав собственные версии UNIX-подобных ОС, но уже не предоставляя пользователям исходные коды (например, ОС Solaris фирмы Sun).
В 1991 г. финский программист Линус Торвальдс решил создать полностью открытую UNIX-подобную ОС Linux. Полная открытость системы означает, что ее исходный код всегда доступен любому желающему. Для реализации своего замысла Л. Торвальдс привлек широкий круг программистов, опубликовав предварительный исходный код Linux в Интернет и пригласив всех желающих дополнять его своими разработками, но с обязательным условием: публикацией исходного кода этих разработок. Таким образом, эта ОС изначально разрабатывалась (и продолжает разрабатываться!) как полностью открытая и бесплатная система, которую может получить любой желающий [ Как показала практика, бесплатность Linux относительна: некоторые фирмы за относительно небольшую плату (часто ненамного превышающую стоимость носителей информации) не только поставляют весьма громоздкие тексты этой ОС, но и обеспечивают покупателей информационной поддержкой по ее установке и эксплуатации. ]. Не нужно быть провидцем, чтобы понять, как много потребителей (по некоторым оценкам, сегодня этой ОС пользуются около 8 млн. человек) решились отказаться от услуг Microsoft, вечной политикой которой была полная закрытость исходных текстов своих ОС, в пользу Linux, обеспечивающей, по утверждениям специалистов, не меньшую надежность, чем Windows NT, при приблизительно одинаковых возможностях [ Последнее не совсем точно. Тщательно отлаженные механизмы Windows Plug&Play, СОМ, Ас-tiveX, ADO, MTS и т. п. в сочетании с мощными возможностями Office, SQL Server, Internet Information Server и других подобных программ дают конечному пользователю гораздо больше возможностей, но... за плату и без исходных текстов. ]. (Надежность Linux объясняется тем, что большая часть ее пользователей - программисты, которые не только выявляют ошибки, но и устраняют их. В этом смысле говорят, что Linux - самая тщательно отлаженная ОС в мире.)
До появления Kylix единственными средствами программирования для Linux были системы на языках C/C++, Basic, For.gif" >
Файлы инициации
20.5.1. Файлы инициацииФайлы инициации в Delphi связаны с объектами класса TIniFile. Эти объекты не являются глобальными и создаются программно по мере надобности. С каждой программой можно связать сколько угодно файлов инициации.
Физически файл инициации представляет собой обычный текстовый файл, который сохраняется либо в каталоге запуска программы (локальный файл), либо в каталоге запуска Windows (глобальный файл инициации). Файл содержит ряд секций, каждая из которых имеет заголовок и следующие за ним параметры. Заголовок - это произвольный английский текст, заключенный в квадратные скобки. Каждый параметр представлен строкой вида
<ИМЯ_ПАРАМЕТРА>=<ЗНАЧЕНИЕ>
Например:
[Location]
DataBase=C:\mybase Graphics=C:\BITMAP
В этом примере в секции Location файла инициации представлены два параметра с именами DataBase и Graphics. Объекты класса TiniFiie предоставляют удобные средства чтения/записи параметров по именам параметров и секций.
В объекте имеется единственное свойство Filename: String, содержащее имя файла инициации с возможным маршрутом поиска.
Методы класса TIniFile:
| constructor Create(const FileNameString) ; | Создает объект-файл с именем FileName. Это имя автоматически переносится в свойство FileName. Если физический файл существовал, он открывается, если нет создается |
| procedure DeleteKey(const Section,
Ident: String) ; |
Уничтожает значение параметра Ident в секции Section. Если указана несуществующая секция или имя несуществующего параметра, метод создаст секцию и/или установит в ней параметр с пустым значением |
| procedure EraseSection(const Section: String) ; | Удаляет секцию со всеми ее параметрами.
Если секции не существует, возникает исключительная ситуация |
| function ReadBool (const Section,
Ident:.String; Default: Boolean): Boolean; |
Возвращает значение логического параметра Ident в секции section. Возвращает Default, если не существует указанная
секция, или в ней нет нужного параметра, или, наконец, параметр имеет не логическое значение |
| function Readlnteger(const Section, Ident: String; Default:Longint): Longint; | Возвращает значение целого параметра Ident в секции Section, Возвращает Default, если не существует указанная секция, или в ней нет нужного параметра, или, наконец, параметр имеет не целое значение |
| procedure ReadSection (const Section: String; Strings: TStrings); | Помещает в список Strings имена всех параметров из секции Section |
| procedure ReadSections (Strings:
TStrings); |
Помещает в список Strings имена всех
секций файла |
| procedure ReadSectionValues(const Section: String; Strings: TStrings) ; | Помещает в список strings имена всех
значений из секции Section |
| function ReadString(const Section,
Ident, Default: String): String; |
Возвращает значение строкового параметра Ident в секции section. Возвращает Default, если не существует указанная секция, или в ней нет нужного параметра,
или, наконец, параметр не имеет значения |
| procedure WriteBool(const Section,
Ident: String; Value: Boolean); |
Записывает в параметр Ident секции section логическое значение value. |
| procedure Writelnteger(const Sec
tion, Ident: String; Value: Longint) ; |
Записывает в параметр Ident секции Section целое значение Value |
| procedure WriteString(const Section, Ident, Value: String); | Записывает в параметр Ident секции Section строковое значение value |
Инкапсуляция
9.1.1. ИнкапсуляцияКласс представляет собой единство трех сущностей - полей, методов и свойств. Объединение этих сущностей в единое целое и называется инкапсуляцией. Инкапсуляция позволяет во многом изолировать класс от остальных частей программы, сделать его “самодостаточным” для решения конкретной задачи. В результате класс всегда несет в себе некоторую функциональность. Например, класс т For.gif" >
Класс TFont
16.4.1. Класс TFontС помощью класса TFont создается объект-шрифт для любого графического устройства (экрана, принтера, плоттера и т. п.).
Свойства класса:
| property Color: TColor; | Цвет шрифта |
| property Charset: TFontCharSet; | Набор символов. Для русскоязычных программ это свойство обычно имеет значение DEFAULTCHARSET или russian charset. Используйте значение OEMCHARSET для отображения текста MS-DOS (альтернативная кодировка) |
| property FontAdapter: IChangeNotifier; | Поставляет информацию о шрифте в компоненты ActveX |
| property Handle:hFont; | Дескриптор шрифта. Используется при непосредственном обращении к API-функциям Windows |
| property Height: Integer; | Высота шрифта в пикселях экрана |
| property Name: TFontName; | Имя шрифта. По умолчанию имеет значение MS
Sans Serif |
| property Pitch: TFontPitch; | Определяет способ расположения букв в тексте: значение fpFixed задает моноширинный текст, при котором каждая буква имеет одинаковую ширину; значение fpVariabel определяет ропорциональный текст, при котором ширина буквы зависит от ее начертания; fpDefault определяет ширину, принятую для текущего шрифта |
| property PixelPerInch: Integer; | Определяет количество пикселей экрана на один дюйм реальной длины. Это свойство не следует изменять, т. к. оно используется системой для обеспечения соответствия экранного шрифта шрифту принтера |
| property Size: Integer; | Высота шрифта в пунктах (1/72 дюйма). Изменение этого свойства автоматически изменяет свойство Height и наоборот. |
| property Style: TFontStyles; | Стиль шрифта. Может принимать значение как комбинация следующих признаков: fsBold (жирный), fsltalic (курсив), fsUnderline (подчеркнутый), fsStrikeOut (перечеркнутый) |
procedure Assign(Source: TPersistent);
с помощью которого значения свойств шрифтового объекта source присваиваются свойствам текущего шрифта. Метод не изменяет свойство pixeiperinch, поэтому его можно использовать для создания шрифта принтера по экранному шрифту и наоборот.
Конструирование формы
5.1.1. Конструирование формыВы можете самостоятельно сконструировать форму для учебной программы, руководствуясь приведенным выше описанием размещенных на ней компонентов и рисунком 5.1. Для облегчения этого процесса ниже для каждого компонента указаны свойства, значения которых отличаются от умалчиваемых. Компоненты перечислены в порядке их размещения, т. е. вначале подготавливаются свойства формы, потом на форму помещается панель, на нее помещаются кнопки и строка ввода, а метка и многострочный редактор - на свободное место формы над панелью.
Размеры компонентов установлены с учетом разрешения экрана 800х600. Для другого разрешения эти размеры, возможно, потребуется скорректировать.
Форма
| Свойство | Значение |
| Caption
Height Name Position Width |
Учебная программа
375 fmExample poScreenCenter 544 |
| Свойство | Значение |
| Align
BevelOuter Caption Height |
AlBottom
BvNone Удалить 84 |
| Свойство | Значение |
| Kind | bkOk |
| Left | 32 |
| Name | bbRun |
| Тор | 48 |
| Свойство | Значение |
| Kind | bkClose |
| Left | 128 |
| Name | BbClose |
| Тор | 48 |
| Свойство | Значение |
| Name | edinput |
| Left | 128 |
| Text | Удалить |
| Top | 16 |
| Width | 289 |
| Свойство | Значение |
| Align
Caption Name |
alBottom
Удалить IbOutput |
| Свойство | Значение |
| Align | alClient |
| Lines | Удалить |
| Name | mmOutput |
| ScrollBars | ssBoth |
| Wordwrap | False |
Размеры формы Height (Высота) и Width (Ширина) совпадают с умалчиваемыми. Они выбраны так, чтобы форма не казалась слишком маленькой или слишком большой на экранах с разным разрешением - они оптимальны для типичного на сегодня разрешения 800х600. Свойство Position управляет размещением формы относительно границ экрана. Умалчиваемое значение poDesigned потребует разместить форму так, как она была размещена на этапе конструирования, рекомендуемое значение poScreencenter - симметрично по центру экрана.
Свойство Align указывает способ выравнивания размещаемого компонента относительно того контейнера, в котором он размещается. Контейнером называется компонент, предназначенный для размещения в нем других компонентов. Пустая форма представляет собой контейнер, в который помещаются другие компоненты. Таким же контейнером является компонент panel. Мы разместили на форме панель и в ее свойство Align установили значение alBottom (Внизу). После установки этого значения компонент (в данном случае - панель) прижимается к нижней границе формы и растягивается по всей ее длине. Теперь панель и все размещенные на ней компоненты будут примыкать к нижнему краю окна, даже если окно распахивается на весь экран. Если бы мы разместили строку ввода и кнопки не на панели, а непосредственно на форме, они не имели бы свойства перемещения и оставались бы на своих местах при изменении размеров окна [ На самом деле это не совсем так. Компонент действительно не будет перемещаться при стандартных (умалчиваемых) значениях его свойства Anchors. Подробнее об этом см. п. 16.4. ]. В результате значительная часть полностью распахнутого окна осталась бы пустой и не использовалась.
Свойство caption (Заголовок) присуще всем видимым элементам. Для панели оно определяет текст, который размещается в ее центре. Поскольку мы не намерены размещать на панели никаких текстовых сообщений, это свойство у нее следует очистить.
Чтобы панель и расположенная над ней метка воспринимались как единое целое, в свойстве BevelOuter (Внешняя кромка) панели установлено значение bvNone.
Свойства Left (Слева), тор (Сверху) и width (Ширина) определяют положение левого верхнего угла компонента относительно такого же угла своего контейнера и его (компонента) ширину. Указанные в списке значения этих свойств, для строки ввода обеспечат симметричное по горизонтали расположение строки относительно сторон не распахнутого окна (если, разумеется, вы установили рекомендуемую ширину формы 544). К сожалению, симметрия будет нарушена, если окно распахнется. В Delphi есть средства изменения значений указанных свойств непосредственно в работающей программе. Создав обработчик события ОnResize (По изменению размера) для формы, мы при желании могли бы научить программу реагировать на изменение размеров окна и соответствующим образом изменять значение свойства Left для строки ввода.
Свойство Name (Имя) определяет имя, под которым компонент будет известен программе. Я настоятельно рекомендую вам давать компонентам, на которые ссылается код программы, имена “со смыслом” вместо однотипных имен, которые “придумывает” Delphi. Более того, по принятому в современной практике программирования стилю именам обычно предшествует двухбуквенный префикс. Заложенная в префиксе мнемоника служит напоминанием программисту о типе поименованного компонента или его свойства. Например, все возможные значения свойства Align имеют стандартный для Delphi префикс а1 (от Align), за которым следует вполне понятное английское слово: alBottom, alTop, alLeft и т. д. Строка ввода будет непременным участником кода большинства учебных программ, вот почему я предлагаю назвать этот компонент именем edInput: префикс ed - это сокращение английского названия типа компонента Edit, слово Input означает ввод данных в программу. Такими же осмысленными являются предлагаемые имена для метки - от Label, output - вывод программы), многострочного редактора (mm - от Memo), кнопки OK (bb - ОТ BitBtn, Run - пуск программы) и кнопки close. Панель вряд ли будет упоминаться в программном коде, который вы будете писать, поэтому для нее можно оставить созданное Delphi умалчиваемое имя panel1.
Свойство Text (Текст) у компонента Edit определяет текст, который будет содержать строка ввода в момент появления на экране. Следует очистить это свойство, чтобы начальный текст не мешал вводу данных для программы. Точно так же следует очистить свойство Caption у метки и Lines у многострочного редактора. Чтобы очистить свойство mmOutput. Lines, щелкните по этому свойству в окне Инспектора объектов и вызовите диалоговое окно изменения свойства. Затем удалите умалчиваемый текст Memo1 (или mmoutput, если к этому моменту вы уже дали компоненту рекомендуемое имя) и закройте окно кнопкой OK.
Свойство ScrollBars у компонента mmOutput имеет значение ssBoth (Оба). Такое значение заставит Delphi поместить в редактор обе полосы прокрутки - вертикальную и горизонтальную. Наличие полос поможет вам увидеть текст, отсекаемый границами компонента. В то же время для свойства wordwrap (Перенос слов) советую установить значение False, чтобы отказаться от переноса слов на другую строку редактора в длинных текстовых сообщениях. Для этого компонента свойство Align имеет значение alciient, что потребует от компонента занять всю оставшуюся незаполненной часть формы независимо от размеров окна.
Для компонентов BitBtn свойство Kind (Сорт) определяет типовые функции, которые реализует кнопка в диалоговых окнах. Значение bkCiose определит типовую пиктограмму и надпись close, ко-торые Delphi разместит на кнопке, а также типовую функцию закрытия окна, которая будет связана с этой кнопкой. В результате без малейших усилий с нашей стороны мы получили кнопку, которая завершает работу программы. Значение bkOK заставит кнопку BitBtn закрывать диалоговое окно с результатом тгок. Поскольку наша форма не является диалоговым окном, кнопка ок не будет выполнять эту свою функцию: мы использовали значение bkOK только для того, чтобы кнопка получила нужную пиктограмму и надпись.
Массивы
7.2.1. МассивыМассивы в Object Pascal во многом схожи с аналогичными типами данных в других языках программирования. Отличительная особенность массивов заключается в том, что все их компоненты суть данные одного типа (возможно, структурированного). Эти компоненты можно легко упорядочить и обеспечить доступ к любому из них простым указанием его порядкового номера, например:
type
digit = array [0..9] of Char;
matrix = array [byte] of Single;
var
m : matrix;
d : digit;
i : integer;
begin
m[17] := ord(d[i-l])/10;
end.
Описание типа массива задается следующим образом:
<имя типа> = array [ <сп.инд.типов> ] of <тип>;
Здесь <имя типа> - правильный идентификатор; array, of - зарезервированные слова {массив, из); <сп.инд.типов> - список из одного или нескольких индексных типов, разделенных запятыми; квадратные скобки, обрамляющие список, - требование синтаксиса;
<тип> - любой тип Object Pascal.
В качестве индексных типов в Object Pascal можно использовать любые порядковые типы, имеющие мощность не более 2 Гбайт (т. е. Кроме LongWord И Int64)
Определить переменную как массив можно и непосредственно при описании этой переменной, без предварительного описания типа массива, например:
var
a,b : array [1..10] of Real;
Обычно в качестве индексного типа используется тип-диапазон, в котором задаются границы изменения индексов. Так как тип <тип>, идущий в описании массива за словом of, - любой тип Object Pascal, то он может быть, в частности, и другим массивом, например:
type
mat = array [0..5] of array [-2..2] of array [Char] of Byte;
Такую запись можно заменить более компактной:
type
mat = array [0..5,-2..2,char] of Byte;
Глубина вложенности структурированных типов вообще, а следовательно, и массивов - произвольная, поэтому количество элементов в списке индексных типов (размерность массива) не ограничено, однако суммарная длина внутреннего представления любого массива не может быть больше 2 Гбайт. В памяти ПК элементы массива следуют друг за другом так, что при переходе от младших адресов к старшим наиболее быстро меняется самый правый индекс массива.
Если, например,
var
a: array [1..2,1..2] of Byte;
begin
а[1,1] := 1;
а[2,1] := 2 ;
а[1,2] := 3;
а[2,2] := 4;
end.
то в памяти последовательно друг за другом будут расположены байты со значениями 1,3,2,4 . Это обстоятельство может оказаться важным при использовании стандартной процедуры копирования памяти MoveMemory.
В Object Pascal можно одним оператором присваивания передать все элементы одного массива другому массиву того же типа, например:
var
a,b : array [1..5] of Single;
begin
а := b;
end.
После этого присваивания все пять элементов массива а получат те же значения, что и в массиве в. Замечу, что объявление
var
a: array [1..5] of Single;
b: array [1..5] of Single;
создаст разные типы массивов, поэтому оператор
а := b;
вызовет сообщение об ошибке.
Над массивами не определены операции отношения. Нельзя, например, записать
if а = b then ...
Сравнить два массива можно поэлементно, например:
var
a,b : array [1..5] of Single;
eq : Boolean;
i : Byte;
begin
eq := True; for i := 1 to 5 do
if a[i] <> b[i] then
eq := False/if eq then
end.
Динамические массивы
В версии Delphi 4 впервые введены так называемые динамические массивы. При объявлении таких массивов в программе не следует указывать границы индексов:
var
A: array of Integer;
В: array of array of Char;
C: array of array of array of Real;
В этом примере динамический массив а имеет одно измерение, массив в - два и массив с - три измерения. Распределение памяти и указание границ индексов по каждому измерению динамических массивов осуществляется в ходе выполнения программы путем инициации массива с помощью функции setLength. В ходе выполнения такого оператора:
SetLength(А,3);
одномерный динамический массив а будет инициирован, т. е. получит память, достаточную для размещения трех целочисленных значений. Нижняя граница индексов по любому измерению динамического массива всегда равна 0, поэтому верхней границей индексов для а станет 2.
Фактически идентификатор динамического массива ссылается на указатель (см. гл. 9), содержащий адрес первого байта памяти, выделенной для размещения массива. Поэтому для освобождения этой памяти достаточно присвоить идентификатору значение nil (другим способом является использование процедуры Finalize):
var
А,В: array of Integer;
begin
// Распределяем память:
SetLength(A,10) ;
SetLength(B,20) ;
// Используем массивы:
// Освобождаем память:
А := NIL;
Finalize(В);
end;
При изменении длины уже инициированного динамического массива по какому-либо его измерению сначала резервируется нужная для размещения нового массива память, затем элементы старого массива переносятся в новый, после чего освобождается память, выделенная прежнему массиву. Чтобы сократить дополнительные затраты времени, связанные с изменением границ большого динамического массива, следует сразу создать массив максимальной длины.
В многомерных массивах сначала устанавливается длина его первого измерения, затем второго, третьего и т. д. Например:
var
A: array of array of Integer; //Двумерный динамический массив begin
//Устанавливаем длину первого измерения (количество столбцов):
SetLength(A,3) ;
//Задаем длину каждого столбца:
SetLength(A[0],3) ;
SetLength(A[l],3) ;
SetLength(A[2] ,3) ;
end;
Обратите внимание: в отличие от обычных массивов стандартного Паскаля (и Object Pascal), динамические массивы могут иметь разную длину по второму и следующим измерениям. В предыдущем примере определен квадратный массив 3х3. Однако ничто не мешает нам создать, например, треугольный массив:
SetLength(A,3) ;
//Задаем длину каждого столбца:
SetLength(A[0],3) ;
SetLength(A[l],4) ;
SetLength(A[2],5) ;
В многомерных динамических массивах каждый элемент любого из N-1 измерений (N - количество измерений) представляет собой динамический массив и, следовательно, нуждается в инициации. Вот как, например, можно инициировать вещественный кубический массив 3х3х3:
var
A: array of array of array of Real;
i, j: Integer;
begin
SetLength(A,3) ;
for i := 0 to 2 do
begin
SetLength(A[i],3) ;
for j := 0 to 2 do SetLength{A[i,j],3) ;
end;
end;
Модификация формы
3.3.1. Модификация формыПроведем очередную модернизацию нашей первой программы: вставим в ее форму еще один компонент - кнопку - и заставим ее откликаться на событие, связанное с нажатием левой кнопки мыши.
Компонент кнопка изображается пиктограммой на странице standard палитры компонентов. Поместите этот компонент на форму и расположите его ниже метки и посередине формы (Рисунок 3.2).
Настройка Delphi
3.1.1. Настройка DelphiВ процессе работы над проектами программ, описываемых в этой книге, вам понадобится создать множество форм и модулей. Полезно сохранять эти данные в виде дисковых файлов в отдельной папке. Более того, для каждой программы в этой папке имеет смысл создать свою вложенную папку. Тогда, чтобы освободить место на диске для серьезной программы, вам будет достаточно уничтожить основную папку, а чтобы передать ту или иную учебную программу своему коллеге - переписать на дискету содержимое соответствующей вложенной папки. Создайте папку с именем, например, my_delph, а в нем - вложенную папку для вашей первой программы. Чтобы не утруждать себя придумыванием подходящих имен для “безликих” учебных программ, советую использовать для папки имя pgm_1 или что-нибудь подобное.
Второе, что нам предстоит сделать, - это внести изменения в стандартную настройку среды Delphi. Это необходимо для того, чтобы среда автоматически сохраняла на диске последнюю версию создаваемой вами программы. Выберите опцию меню Tools | Environment options и убедитесь, что в появившемся диалоговом окне активна страница preferences. В левом верхнем углу этой страницы в группе Autosave | Options есть переключатели Editor Files и Desktop (в других версиях Delphi эти переключатели располагаются в правом верхнем углу). Активизация переключателей приведет к автоматическому сохранению текста окна кода программы и общего расположения окон Delphi перед началом очередного прогона создаваемой программы, что избавит вас от возможных потерь в случае “зависания” программы. Советую активизировать эти переключатели, щелкнув по каждому мышью. Чтобы следить за ходом компиляции, активизируйте также переключатель Show Compiler progress в группе Compiling and Running. Далее, мне кажется полезным сохранять в коде программы комментарии - текстовые фрагменты, которые не влияют на работу программы, но делают ее текст более понятным. Если вы, как и я, предпочитаете использовать комментарии на русском языке, следует выбрать соответствующий шрифт для отображения кода программы. По умолчанию редактор Delphi использует шрифт Courier New, в котором может не быть символов кириллицы. В этом случае выберите опцию Tools | Editor options и на странице Display в строке Editor Font установите Courier New Cyr (для предыдущих версий страница Display доступна в окне Tools | Environment Options).
Теперь все готово для прогона вашей первой программы. Щелкните клавишу F9: именно таким способом подготовленная Delphi-программа последовательно проходит три главных этапа своего жизненного цикла - этапы компиляции, компоновки и исполнения. На этапе компиляции осуществляется преобразование подготовленного в окне кода текста программы на языке Object Pascal в последовательность машинных инструкций, на этапе компоновки к ней подключаются необходимые вспомогательные подпрограммы, а на этапе исполнения готовая программа загружается в оперативную память и ей передается исполнение.
Как только вы нажмете F9, появится диалоговое окно Save Unit1 As, в котором Delphi попросит вас указать имя файла для модуля Unit1. раз и папку его размещения.
Примечание
Примечание
По умолчанию Delphi предлагает разместить файл модули и проекта в системной папке BIN. Поскольку эта пайка содержит жизненно важные для Delphi файлы, обязательно измените ее на вашу рабочую папку (например, MY_DELPH).
Лучше не идти на поводу у Delphi и не соглашаться с предложенным именем Unit1.раs, а присвоить модулю какое-нибудь более запоминающееся имя. Например, назовем модуль my_ist_u, что, по мысли автора, должно расшифровываться как “мой_первый_модуль” | разумеется, вам в голову может прийти более подходящее имя). Если в окне Save Uniti As вы укажете такое имя и нажмете Enter, Delphi попросит задать имя еще и для проекта программы в целом. Под этим именем будет создан исполняемый ЕХЕ-файл, и здесь нет предела для вашей изобретательности, например, firstpgm - вполне достойное имя для вашей первой Delphi-программы.
Открытые массивы
8.3.1. Открытые массивыObject Pascal поддерживает так называемые открытые массивы, легко решающие проблему передачи подпрограмме одномерных массивов переменной длины.
Открытый массив представляет собой формальный параметр подпрограммы, описывающий базовый тип элементов массива, но не определяющий его размерности и границы:
Procedure MyProc(OpenArray: array of Integer);
Внутри подпрограммы такой параметр трактуется как одномерный массив с нулевой нижней границей. Верхняя граница открытого массива возвращается стандартной функцией High. Используя 0 как минимальный индекс и значение, возвращаемое функцией High, как максимальный индекс, подпрограмма может обрабатывать одномерные массивы произвольной длины.
Procedure TfmExample.bbRunClick(Sender: TObject) ;
{Иллюстрация использования открытых массивов: программа выводит в компонент mmOutput содержимое двух одномерных массивов разной длины с помощью одной процедуры ArrayPrint) Procedure ArrayPrint(aArray: array of Integer);
var
k: Integer;
S: String;
begin
S:=' ';
for k := 0 to High(aArray) do S := S + IntToStr(aArray[k]);
mmOutput.Lines.Add(S) ;
end;
const
A: array [-1..2] of Integer = (0,1,2,3);
B: array [5..7] of Integer = (4,5,6);
begin
ArrayPrint(A);
ArrayPrint (B);
end;
Как видно из этого примера, фактические границы массивов а и в, передаваемых в качестве параметров вызова процедуре ArrayPrint, не имеют значения. Однако размерность открытых массивов (количество индексов) всегда равна 1 - за этим следит компилятор. Если бы, например, мы добавили в программу двумерный массив с
var
С: array,[1..3,1..5] of Integer;
то обращение
ArrayPrint(С)
вызвало бы сообщение об ошибке.
Пиктографические кнопки
2.1.1. Пиктографические кнопкиПиктографические кнопки открывают быстрый доступ к наиболее важным опциям главного меню. По функциональному признаку они разделены на 7 групп. Каждая группа занимает отдельную панельку. В следующей таблице описаны команды, реализуемые стандартным набором пиктографических кнопок (пиктографические кнопки галереи компонентов рассматриваются отдельно в гл. 4).
| Реализуемое кнопкой действие |
| Группа Standard |
Открывает доступ к Репозиторию Объектов. Эквивалент опции File | New | Other (этой кнопки нет в версиях 1, 2 и 3) |
Открывает существующий файл. Эквивалент опции File | Open File |
Сохраняет файл на диске. Эквивалент опции File | Save File (клавиши быстрого доступа Ctrl-S) |
Сохраняв все файлы проекта. Эквивалент опции File | Save All |
Открывает созданный ранее проект программы. Эквивалент опции File | Open Project (клавиши быстрого доступа Ctrl-F11) |
Добавляет новый файл к проекту. Эквивалент опции Project | Add to project (клавиши быстрого доступа Shift-F11) |
Удаляет файл из проекта. Эквивалент опции Project | Remove from Project |
| Группа View |
Выбирает модуль из списка модулей, связанных с текущим проектом. Эквивалент опции View | units (клавиши быстрого доступа Shift-F12) |
Выбирает форму из списка форм, связанных с текущим проектом. Эквивалент опции View | For.gif" >
|
Порядковые типы
7.1.1. Порядковые типыК порядковым типам относятся (см. Рисунок 7.1) целые, логические, символьный, перечисляемый и тип-диапазон. К любому из них применима функция Ord(x), которая возвращает порядковый номер значения выражения X.
Размещение в варианте новых значений
10.5.1. Размещение в варианте новых значенийДля размещения в варианте нового (не предусмотренного стандартным вариантом) значения нужно создать соответствующий класс и поместить в подходящее поле rvarData объект этого класса. Вот как, например, размещаются комплексные данные в модуле VarCmplx:
TComplexVarData = packed record
VType: TVarType;
Reserved1, Reserved2, Reserved3: Word;
VComplex: TComplexData;
Reserved4: Longint;
end;
Такая запись лишь сохраняет 16-байтную структуру TVarData, помещая в поле VComplex ссылку на объект класса TComplexData. Собственно комплексные числа хранятся в полях достаточно сложного класса:
type
TComplexData = class(TPersistent) private
FReal, FImaginary: Double;
end;
В этом классе предусмотрены многочисленные методы, управляющие новыми данными. Так, простой вызов VarComplexCreate приводит к срабатыванию нескольких методов, создающих объект VComplex и наполняющих его поля:
procedure VarComplexCreateInto (var ADest: Variant;
const AComplex: TComplexData);
begin
VarClear(ADest);
TComplexVarData(ADest).VType := VarComplex;
TComplexVarData(ADest).VComplex := AComplex;
end; function VarComplexCreate(const AReal, AImaginary: Double):
Variant;
begin
VarComplexCreateInto(Result,
TComplexData.Create(AReal, AImaginary)) ;
end;
(CM. файл Source\Rtl\Common\VarCmplx.pas).
Примечание
Примечание
Запись в которой размещаются новые данные или ссылка на поддерживающий их обьект, должно обьявляться как packed record.
Секция OPTIONS
21.4.1. Секция OPTIONSСекция [Options] создается или изменяется с помощью кнопки options. Оно содержит общие для всей справочной службы установки и, в частности, определяет умалчиваемую тему, показываемую при открытии HELP-службы, заголовок основного окна, используемый в текстах язык и т. п.
После нажатия кнопки options появляется многостраничное окно, показанное на Рисунок 21.7.
Создание и использование интерфейса
9.4.1. Создание и использование интерфейсаИнтерфейсы представляют собой частный случай описания типов. Они объявляются с помощью зарезервированного слова interface. Например:
type
IEdit = interface
procedure Copy; stdcall;
procedure Cut; stdcall;
procedure Paste; stdcall;
function Undo: Boolean; stdcall;
end;
Такое объявление эквивалентно описанию абстрактного класса в том смысле, что провозглашение интерфейса не требует расшифровки объявленных в нем свойств и методов.
В отличие от классов интерфейс не может содержать поля, и, следовательно, объявляемые в нем свойства в разделах read и write могут ссылаться только на методы. Все объявляемые в интерфейсе члены размещаются в единственной секции public. Методы не могут быть абстрактными (abstract), виртуальными (virtual), динамическими (dynamic) или перекрываемыми (override). Интерфейсы не могут иметь конструкторов или деструкторов, т. к. описываемые в них методы реализуются только в рамках поддерживающих их классов, которые называются интерфейсными.
Если какой-либо класс поддерживает интерфейс (т. е. является интерфейсным), имя этого интерфейса указывается при объявлении класса в списке его родителей:
TEditor = class(TInterfacedObject,IEdit)
procedure Copy; stdcall;
procedure Cut; stdcall;
procedure Paste; stdcall;
function Undo: Boolean; stdcall;
end;
В отличие от обычного класса интерфейсный класс может иметь более одного родительского интерфейса:
type
IMylnterface = interface procedure Delete; stdcall;
end;
TMyEditor = class(TInterfacedObiect, lEdit, IMylnterface)
procedure Copy; stdcall;
procedure Cut; stdcall;
procedure Paste; stdcall;
function Undo:, Boolean; stdcall;
procedure Delete; stdcall;
end;
В любом случае в разделе реализации интерфейсного класса необходимо описать соответствующие интерфейсные методы. Если, например, объявлен интерфейс
IPaint = interface
procedure CirclePaint(Canva: TCanvas; X,Y,R: Integer);
procedure RectPaint(Canva: TCanvas; X1,Y1,X2,Y2: Integer);
end;
и использующий его интерфейсный класс
TPainter = class(TInterfacedObject,IPaint)
procedure CirclePaint(Canva: TCanvas; X,Y,R: Integers);
procedure RectPaint(Canva: TCanvas; X1,Y1,X2,Y2: Integer);
end;
то в разделе implementation следует указать реализацию методов:
procedure TPainter.CirclePaint(Canva: TCanvas;
X,Y,R: Integers; begin
with Canva do
Ellipse(X, Y, X+2*R, Y+2*R) ;
end;
procedure TPainter.RectPaint(Canva: TCanvas;
X1,Y1,X2,Y2: Integer);
begin
with Canva do
Rectangle(XI, Yl, X2, Y2)
end;
Теперь можно объявить интерфейсный, объект класса TPainter, чтобы с его помощью нарисовать окружность и квадрат:
procedure TFor.gif" >
Создание шаблонов без рам
18.1.1. Создание шаблонов без рамПри желании вы может создать шаблоны компонентов и без рам. Описываемый ниже способ можно с одинаковым успехом использовать в версиях от 3-й до 6-й.
Поместите на форму компоненты, которые войдут в шаблон, и нужным образом настройте их свойства. Затем нажмите клавишу Shift и, не отпуская ее, щелкните по каждому шаблонному компоненту - в результате будет выделена группа компонентов. Теперь раскройте пункт Сomponent главного меню Delphi и выберите create component Template (если на форме не будет выделен ни один компонент, этот пункт меню будет недоступен). В ответ на это Delphi развернет окно, показанное на Рисунок 18.1, б, - единственным отличием будет то, что в качестве пиктограммы шаблона будет предложена пиктограмма последнего выделенного компонента. Дальнейшие действия ничем не отличаются от описанных выше.
СТРАНИЦА ACTIVE X
4.7.1 СТРАНИЦА ACTIVE XКомпоненты ActiveX являются “чужими” для Delphi: они создаются другими инструментальными средствами разработки программ (например, C++ или Visual Basic) и внедряются в Delphi с помощью технологии OLE. На странице ActiveX представлены лишь 4 из великого множества ActiveX-компонентов, разрабатываемых повсюду в мире компаниями - производителями программных средств и отдельными программистами. И хотя в книге технология ActiveX и компоненты этой страницы не рассматриваются, я привожу их краткое описание.
Chartfx - интерактивный график. Дает программисту удобное средство включения в программу интерактивных (диалоговых) графиков.
VSSpell - спеллер. Осуществляет орфографическую проверку правильности написания английских слов.
F1Book - электронная таблица. Позволяет создавать и использовать рабочие книги электронных таблиц, подобно тому как это делает MS Excel.
VtChart - мастер диаграмм. Обеспечивает мощные средства построения двух- и трехмерных диаграмм по результатам табличных вычислений.
Страница Data Access
4.8.1. Страница Data AccessВ отличие от предыдущих версий на этой странице собраны компоненты, которые не зависят от используемого доступа к базе данных (большинство компонентов с этой страницы предыдущих версий перекочевали на страницу bde). Они в основном используются в так называемых трехзвенных БД (с сервером приложений). Часть компонентов известны по другим версиям Delphi, часть появилась в версии 6.
Строковый и символьный типы
5.3.1. Строковый и символьный типыСвое знакомство с типами мы начнем со строкового типа String. Этот тип определяет участок памяти переменной длины, каждый байт которого содержит один символ. Для символов в Object Pascal используется тип Char, таким образом, String - это цепочка следующих друг за другом символов Char. Каждый символ в String пронумерован, причем первый символ имеет номер 1. Программист может обращаться к любому символу строки, указывая его порядковый номер в квадратных скобках сразу за именем переменной:
var // Начало раздела описания переменных
S: String;
// Объявление переменной строкового типа
begin
// Начало раздела исполняемых операторов
S := ' Строка символов';
// Переменная S содержит
// значение ”Строка символов”
S[6] := 'и'; // Теперь переменная содержит значение
// ”Строки символов”
end;
// Конец раздела исполняемых операторов
Наличие комментариев избавляет меня от необходимости подробного описания назначения каждой строки текста. Напомню, что программист обязан объявить любой вводимый им идентификатор. Идентификатор s неизвестен Delphi - он введен нами для переменной строкового типа. После его объявления в разделе переменных Delphi выделит для него начальную область памяти минимальной длины и будет контролировать использование этого идентификатора в разделе исполняемых операторов. Например, если в этом разделе встретится выражение
2*S-1
компилятор сразу забьет тревогу, так как строка не может быть участником математических вычислений: она предназначена для хранения символов, а не чисел.
В первом операторе присваивания в переменную s будет помещено значение строковой константы строка символов'. Строковые константы содержат произвольные символы, заключенные в обрамляющие апострофы, причем сами апострофы не входят в значение константы, поэтому после присваивания переменная примет значение Строка символов без апострофов (если понадобится включить в текстовую константу апостроф, он удваивается: ' символ ' ' - апостроф'). После первого присваивания s будет занимать участок памяти длиной 15 байт - по одному байту на каждый символ значения[ На самом деле переменная строкового типа всегда имеет длину 4 байта, которые используются для указания на область памяти, в которой помещается сама строка символов. Подробнее о механизме использования памяти строковыми переменными см. п. 6.3.1. ]. Переменность размера области памяти, выделяемой для размещения строки символов, - характерная особенность типа string. Если бы, например, во втором операторе мы обратились не к 6-му по счету символу, а ко всей строке в целом:
S := 'и';
эта переменная стала бы занимать 1 байт, а следующие за ним 14 байтов оказались бы свободными. Длина строковой переменной в программе меняется автоматически при каждом присваивании переменной нового значения и может составлять от 0 до 2 Гбайт[ Для версии Delphi 1 тип String соответствует “короткой” строке, длина которой не может превышать 255 байт. ] (1 Гигабайт (Гбайт) соответствует константе Gbyte на стр. 84). Над строковым типом определена операция сцепления (+):
S := 'Object'+' Pascal';// S содержит “Object Pascal”
Кроме того, строки можно сравнивать с помощью таких операций отношения:
| Операция | Смысл |
| = | Равно |
| <> | Не равно |
| > | Больше |
| >= | Больше или равно |
| < | Меньше |
| <= | Меньше или равно |
Примечание
Символы <>, <= и >= пишутся слитно, их нельзя разделять пробелами иди комментариями.
Результат применения операции сравнения к двум строкам имеет логический тип, который характеризуется двумя возможными значениям: True (Истина; читается тру) и False (Ложь; читается фоле). Строки сравниваются побайтно, слева направо; каждая пара символов сравнивается в соответствии с их внутренней кодировкой (см. гл. 7).
Все остальные действия над строками осуществляются с помощью нескольких стандартных для Delphi подпрограмм, описанных в гл.7.
Учебная программа COPY.TXT
Создадим программу, в которой текст из строки ввода edinput будет копироваться без изменений в метку lboutput и редактор mmoutput. Для этого загрузите Delphi и выберите опцию File | New | Application [ Как уже говорилось в гл. 2, имеет смысл для каждой учебной программы создавать свой подкаталог и размещать в нем все связанные с программой файлы. Если вы еще не сделали этого, минимизируйте Delphi и создайте с помощью Проводника подкаталог COPYTXT в каталоге для ваших учебных программ. В дальнейшем я не буду напоминать вам о необходимости создания подкаталогов, однако помните, что, если вы не будете этого делать, очень скоро ваш учебный каталог станет представлять собой хаотическое нагромождение никак не связанных друг с другом файлов. ].
Чтобы сообщить программе о том, что в строке ввода edinput подготовлен текст, пользователь должен щелкнуть по кнопке bbRun, поэтому все необходимые действия мы сосредоточим в обработчике события onciick этой кнопки. Дважды щелкните по кнопке bbRun в окне формы, чтобы Delphi автоматически подготовила для вас заголовок обработчика события, и отредактируйте его следующим образом:
procedure TfmExample.bbRunClick(Sender: TObject);
begin
lbOutput.Caption := edInput.Text;
// Повторяем текст в метке mmOutput.Lines.Add(edInput.Text);
// и в многострочном редакторе
edInput.Text := '';
// Очищаем строку ввода edInput.SetFocus;
// Передаем ей фокус ввода
end;
Нажмите F9 для прогона программы, сохраните модуль под именем CopyTxtU.pas, а проект в целом - под именем copyTxt.dpr, и вы увидите окно, показанное на Рисунок 5.4.
Структура проекта
5.2.1. Структура проектаФайл проекта представляет собой программу, написанную на языке Object Pascal и предназначенную для обработки компилятором. Эта программа автоматически создается Delphi и содержит лишь несколько строк. Чтобы увидеть их, запустите Delphi и щелкните по опции Project | View Source главного меню [ В предыдущих версиях Delphi для просмотра кода проекта используйте опцию View | project Source. ]. Delphi покажет окно кода с закладкой Project1, содержащее такой текст:
program Projecti;
uses
For.gif" >
TGauge индикатор величины
18.7.1. TGauge - индикатор величиныКомпонент TGauge предназначен для отображения некоторой изменяющейся числовой величины. Он отличается от TProgress разнообразием форм (см. Рисунок 18.45).
Типы String и ShortString
7.3.1. Типы String и ShortStringНесмотря на разницу во внутреннем представлении, короткие строки ShortString и длинные строки string имеют для программиста одинаковые свойства.
Текущую длину строки можно получить с помощью функции Length. Например, следующий оператор уничтожает все ведомые (хвостовые) пробелы:
while (Length(stS) о 0) and (stS[Length(stS)] = ' ' ) do
SetLentgh(stS, Length (stS) - 1);
В этом примере стандартная процедура setLength устанавливает новую длину строки. К строкам можно применять операцию “+” -сцепление, например:
stS := 'а' + 'b'; // stS содержит "ab"
stS := stS + ' с '; // stS содержит "abc"
Если длина сцепленной строки превысит максимально допустимую длину N короткой строки, то “лишние” символы отбрасываются. Следующая программа, например, выведет символ “I”:
Procedure TfmExamlpe.bbRunClick(Sender: TObject);
var
ssS: String[1];
begin
ssS := '123';
IbOutput := ssS;
end;
Операции отношения =, <>, >, <, >=, <= выполняются над двумя строками посимвольно, слева направо с учетом внутренней кодировки символов. Если одна строка меньше другой по длине, недостающие символы короткой строки заменяются значением #о.
Следующие операции отношения дадут значение True:
'''' < '.'
'А' > '1'
'Object' < ' Object Pascal'
'Пас' > 'Pasc al'
Все остальные действия над строками и символами реализуются с помощью описываемых ниже стандартных процедур и функций (в квадратных скобках указываются необязательные параметры).
Таблица 7.7. Процедуры и функции для работы со строками
| Function AnsiLowerCase(const S: String ): String; | Возвращает исходную строку S, в которой все заглавные буквы заменены на строчные в соответствии с национальной кодировкой Windows (т. е. с учетом кириллицы) |
| Function AnsiUpperCase(const S: String ): String; | Возвращает исходную строку s, в которой все строчные буквы заменены на заглавные в соответствии с национальной кодировкой Windows |
| Function Concat(Sl [, S2, ..., SN]: String ): String; | Возвращает строку, представляющую собой сцепление строк-параметров S1, S2, ... , SN |
| Function Copy(St: String; Index, Count: Integer): String; | Копирует из строки St count символов, начиная с символа с номером Index |
| Procedure Delete(St: String;
Index, Count:" Integers- |
Удаляет count символов из строки St, начиная с символа с номером index |
| Procedure Insert(SubSt:
String; St, Index: Integer); |
Вставляет подстроку SubSt в строку St, начиная с символа с номером Index |
| Function Length(St: String): Integer; | Возвращает текущую длину строки St |
| Function LowerCase(const S:String): String; | Возвращает исходную строку S, в которой все латинские заглавные буквы заменены на строчные |
| procedure OleStrToStrVar(Source: PWideChar; var Dest:String) ; | Копирует “широкую” (двухбайтную) строку в обычную строку Object Pascal |
| Function Pos(SubSt, St:String): Integer; | Отыскивает в строке St первое вхождение подстроки SubSt и возвращает номер позиции, с которой она начинается. Если подстрока не найдена, возвращается ноль |
| Procedure SetLength(St:String; NewLength: Integer); | Устанавливает новую (меньшую) длину NewLength строки St. если NewLength больше текущей длины строки, обращение к SetLength игнорируется |
| function StringOfChar(Ch:Char; Count: Integer):String; | Создает строку, состоящую из Count раз повторенного символа ch |
| function StringToOleStr(const Source: String):PWideChar; | Копирует обычную строку в двухбайтную |
| function StringToWideChar(const Source: String; Dest:PWideChar; DestSize: Integer) : PWideChar; | Преобразует обычную строку в строку с символами UNICODE |
| Function Uppercase(const S:String): String; | Возвращает исходную строку S, в которой все строчные латинские буквы заменены на заглавные |
| Подпрограммы преобразования строк в другие типы | |
| Function StrToCurr(St: String): Currency; | Преобразует символы строки St в целое число типа Currency. Строка не должна содержать ведущих или ведомых пробелов |
| Function StrToDate(St: String): TDateTime; | Преобразует символы строки St в дату. Строка должна содержать два или три числа, разделенных правильным для Windows разделителем даты (в русифицированной версии таким разделителем является “.”). Первое число - правильный день, второе - правильный месяц. Если указано третье число, оно должно задавать год в формате XX или ХХХХ. Если символы года отсутствуют, дата дополняется текущим годом. Например: DateToStr(StrToDate('28.06')) даст строку '28.06.99' (см. ниже пояснения) |
| Function StrToDateTime(St:
String): TDateTime; |
Преобразует символы строки St в дату и время. Строка должна содержать правильную дату (см. StrToDate) и правильное время (см. StrToTime), разделенные пробелом, например: StrToDateTime('28.06 18:23') |
| Function StrToFloat(St:String): Extended | Преобразует символы строки St в вещественное число. Строка не должна содержать ведущих или ведомых пробелов |
| Function StrToInt(St:String): Integer; | Преобразует символы строки St в целое число. Строка не должна содержать ведущих или ведомых пробелов |
| Function StrToIntDef(St:String; Default: Integer):Integer; | Преобразует символы строки St в целое число.
Если строка не содержит правильного представления целого числа, возвращается значение Default |
| Function StrToIntRange(St:String; Min, Max: Longint):Lomgint; | Преобразует символы строки St в целое число и возбуждает исключение ERangeError, если число выходит из заданного диапазона Min.. .мах |
| Function StrToTime(St:String): TDateTime; | Преобразует символы строки St во время.
Строка должна содержать два или три числа, разделенных правильным для Windows раздели телем времени (для русифицированной версии таким разделителем является “:”). Числа задают часы, минуты и, возможно, секунды. За послед ним числом через пробел могут следовать символы “am” или “рm”, указывающие на 12- часовой формат времени |
| Procedure Val(St: String; var
X; Code: Integer); |
Преобразует строку символов St во внутреннее представление целой или вещественной переменной х, которое определяется типом этой переменной. Параметр Code содержит ноль, если преобразование прошло успешно, и тогда в х помещается результат преобразования, в противном случае он содержит номер позиции в строке St, где обнаружен ошибочный символ, и в этом случае содержимое х не меняется. В строке St могут быть ведущие и/или ведомые пробелы. Если St содержит символьное представление вещественного числа, разделителем целой и дробной частей должна быть точка независимо от того, каким символом этот разделитель указан в Windows |
| Подпрограммы обратного преобразования | |
| Function DateTimeToStr(Value: TDateTime): String; Procedure DateTime-ToString(var St: String; For.gif" > |
TOpenDialog и TSaveDialog диалоги
18.5.1. TOpenDialog и TSaveDialog - диалоги открытия и сохранения файловЭти компоненты имеют идентичные свойства и поэтому рассматриваются вместе. Пример окна TOpenDialog показан на Рисунок 18.38.
Свойство FileName: string содержит маршрут поиска и выбранный файл при успешном завершении диалога. Программа может использовать это свойство для доступа к файлу с целью читать из него данные (TOpenDialog) или записывать в него (TSaveDialog). Замечу, что пользователь может ввести произвольное имя и, следовательно, указать несуществующий файл. Для записи это не имеет значения, но при чтении отсутствие файла может привести к краху программы. Чтобы избежать этого, можно проверить существование файла глобальной функцией FileExists, как это сделано в предыдущем примере, или использовать механизм обработки исключительных ситуаций.
TTabSet набор закладок
18.6.1. TTabSet - набор закладокКомпонент TTabSet представляет собой набор закладок. В отличие от компонента TTabControl он не может служить контейнером для размещения других компонентов и поэтому обычно работает совместно с каким-либо компонентом-контейнером (чаще всего - с TNotebook).
Свойства компонента:
| property AutoScroll: Boolean; | Разрешает/запрещает появление стрелок прокрутки, если закладки не умещаются целиком в границах компонента | |
| property Back.gif" > | Содержание | Вперед |
TTimer таймер
18.4.1. TTimer - таймерКомпонент TTimer (таймер) служит для отсчета интервалов реального времени. Его свойство interval определяет интервал времени в миллисекундах, который должен пройти от включения таймера до наступления события onTimer. Таймер включается при установке значения True в его свойство Enabled. Раз включенный таймер все время будет возбуждать события onTimer до тех пор, пока его свойство Enabled не примет значения False.
Следует учесть, что в силу специфики реализации аппаратного таймера персонального IBM-совместимого компьютера минимальный реально достижимый интервал отсчета времени не может быть меньше 55 миллисекунд (этот интервал называется тиком). Более того, любой интервал времени, отсчитываемый с помощью таймера, всегда кратен 55 миллисекундам. Чтобы убедиться в этом, проделайте следующий эксперимент, в котором подсчитывается среднее время между двумя срабатываниями таймера:
BegTime: TDateTime;
procedure TFor.gif" >
Задание идентифицирующей строки
21.3.1. Задание идентифицирующей строки и организация перекрестных ссылокДля задания перекрестных ссылок, реализующих скачок от одного раздела к другому, разделы помечаются уникальными идентифицирующими строками (идентификаторами). Только помеченные идентификаторами разделы можно просматривать в рамках гипертекстовой системы (непомеченные разделы могут быть доступны для просмотра по ключевым словам и в порядке просмотра связанных разделов).
Идентифицирующая строка может содержать любые символы, кроме #, @, !, *, =, >, % и пробелов. Разница в высоте латинских букв (но не кириллицы!) игнорируется. Длина строки - до 255 символов.
В качестве идентификаторов имеет смысл использовать текст заголовка раздела, в котором пробелы заменены символами подчеркивания, - в этом случае вам не придется вспоминать идентификатор при ссылке на него.
Идентификатор задается с помощью сноски “#” в самом начале раздела.
Например:
Назначение_программы
Перекрестная ссылка представляет собой выделенную цветом часть текста, щелчок мышью по которой приводит к смене раздела.
Для кодирования ссылки она выделяется в тексте перечеркнутым или дважды подчеркнутым шрифтом, и сразу за ней без каких либо пробелов указывается идентификатор темы в виде скрытого текста.
На Рисунок 21.1 показано окно редактора Word с фрагментом текста Help-службы.
Раздел перекрестные ссылки связан с идентификатором hypertext, который задан в виде текста сноски “#”, предшествующей первому символу заголовка (для задания сноски выберите в главном меню Word'a Вставка | Сноска, в окне Сноски выберите Другая и введите символ “#” в строке 1, 2, 3).
В тексте раздела указаны две перекрестные ссылки в виде слов ссылка и гипертекст. Эти слова выделены соответственно дважды подчеркнутым и перечеркнутым шрифтом, но в окне справочной службы они будут выглядеть одинаково: выделены зеленым цветом и подчеркнуты одной линией. Сразу за каждой ссылкой следует идентификатор соответствующего раздела.
Поскольку идентификатор выделяется скрытым текстом” в обычном режиме он скрыт и становится виден только в режиме отображения служебных символов после щелчка по кнопке V на инструментальной панели Word.
Заголовок и стандартные директивы
8.2.1. Заголовок и стандартные директивыЗаголовок процедуры имеет вид:
PROCEDURE <имя> [(<сп.ф.п.>)] ;
Заголовок функции:
FUNCTION <имя> [(<сп.ф.п.>)] : <тип>;
Здесь <имя> - имя подпрограммы (правильный идентификатор);
<сп.ф.п.> - список формальных параметров; <тип> - тип возвращаемого функцией результата.
Сразу за заголовком подпрограммы может следовать одна из стандартных директив assembler, external, far, forward, inline, interrupt, near. Эти директивы уточняют действия компилятора и распространяются на всю подпрограмму и только на нее, т. е., если за подпрограммой следует другая подпрограмма, стандартная директива, указанная за заголовком первой, не распространяется на вторую.
assembler - эта директива отменяет стандартную последовательность машинных инструкций, вырабатываемых при входе в процедуру и перед выходом из нее. Тело подпрограммы в этом случае должно реализоваться с помощью команд встроенного Ассемблера.
external - с помощью этой директивы объявляется внешняя подпрограмма.
far - компилятор должен создавать код подпрограммы, рассчитанный на дальнюю модель вызова. Директива near заставит компилятор создать код, рассчитанный на ближнюю модель памяти. Введены для совместимости с Delphi 1, которая использовала сегментную модель памяти.
forward - используется при опережающем описании (см. п. 8.6) для сообщения компилятору, что описание подпрограммы следует где-то дальше по тексту программы (но в пределах текущего прораммного модуля).
inline - указывает на то, что тело подпрограммы реализуется с помощью встроенных машинных инструкций.
interrupt - используется при создании процедур обработки прерываний.
Помимо описанных в Object Pascal можно использовать также стандартные директивы, регламентирующие способ передачи параметров через стек и использование регистров для их передачи - такие директивы используются при работе с ядром Windows. Они перечислены в приводимой ниже таблице. Графа порядок определяет порядок размещения параметров в стеке: слева направо означает размещение в стеке по порядку описания - сначала первый параметр, затем второй и т. д.; справа налево означает размещение с конца перечисления параметров - сначала последний, затем предпоследний и т. д. Графа Очистка определяет, кто будет очищать стек: подпрограмма перед передачей управления в вызывающую программу или программа после получения управления. Графа регистры содержит да, если для передачи параметров помимо стека используются также регистры центрального процессора.
Таблица 8.1. Стандартные директивы, регламентирующие способ передачи параметров через стек и использование регистров для их передачи
| Директива | Порядок | Очистка | Регистры |
| safecall | Справа налево | Подпрограмма | Нет |
| Stdcall | Справа налево | Подпрограмма | Нет |
| Cdecl | Справа налево | Программа | Нет |
| Pascal | Слева направо | Подпрограмма | Нет |
| Register | Слева направо | Подпрограмма | Да |
Примечание
Все фуйкции API ядра Wmdows;скомпилированы .в режиме stidcall, а те, что доддерживают технологию СОМ - в режиме sаfеса11.
Защищенные блоки
16.1.1. Защищенные блокиДля обработки исключений в Object Pascal предусмотрен механизм защищенного блока:
| except
<обработчики исключений> else <операторы> end; |
finally
<операторы> end; |
| Try
<операторы> |
Try
<операторы> |
За словом else. В блоке finally операторы В секции finally. . .end получают управление всегда, независимо от того, возникло ли исключение в секции try.. .finally или нет. Если исключение возникло, все операторы в секции try.. .finally, стоящие за “виновником” исключения, пропускаются, и управление получает первый оператор секции finally... end. Если исключения не было, этот оператор получает управление после выполнения последнего оператора секции try.. .finally.
Обработчики исключений в блоке except имеют такой синтаксис:
on <класс исключения> do <оператор>;
Здесь on, do - зарезервированные слова; <класс исключения> -класс обработки исключения; <оператор> - любой оператор Object Pascal, кроме оператора передачи управления goto на метку вне блока except.
Обратите внимание: имя класса служит своеобразным ключом выбора, а собственно обработка осуществляется оператором, стоящим за do (этот оператор может быть составным, так что обработка исключения может занимать произвольное количество операторов Object Pascal).
Поиск нужного обработчика осуществляется с начала списка вниз до тех пор, пока не встретится класс, способный обрабатывать исключение данного типа. Если подходящего класса не обнаружено, управление передается операторам, стоящим за словом else, а если таковых нет (часть else <операторы> может опускаться), выполняется умалчиваемая обработка исключения.
Если для программиста важен лишь сам факт возникновения исключения и несущественен тип связанной с ним ошибки, он может опустить в секции except.. .end обработчики вместе со словом else, оставив в ней лишь необходимый код реакции на любую ошибку:
try
except
ShowMessage('Ощибка!') ;
end;
Защищенные блоки могут вкладываться друг в друга на неограниченную глубину, т. к. везде, где в предыдущих описаниях использовались <операторы> ИЛИ <оператор>, могут использоваться любые операторы Object Pascal, в том числе и try... except или try...finally:
try
try finally
end;
except
on EMatchError do begin
try try end;
end;
end
end;
ПРЕОБРАЗОВАНИЕ ВАРИАНТОВ К ДАННЫМ ДРУГИХ ТИПОВ
10.2. ПРЕОБРАЗОВАНИЕ ВАРИАНТОВ К ДАННЫМ ДРУГИХ ТИПОВПри участии вариантов в выражениях, а также при присваивании их значений переменным других типов тип размещенных в варианте данных преобразуется по следующим правилам:
Здесь
К целым Отнесены varByte, varSmallInt, varlnteger/ varError;
К вещественным — varSingle, varDouble/ varCurrency;
К строковым -var String, varOleStr.
ПОДПРОГРАММЫ ДЛЯ РАБОТЫ С ВАРИАНТАМИ
10.3. ПОДПРОГРАММЫ ДЛЯ РАБОТЫ С ВАРИАНТАМИДля работы с вариантами можно использовать такие подпрограммы:
Таблица 10.2. Подпрограммы для работы с вариантами
| function VarAsType(const V: Variant; VarType: Integer): Variant; | Преобразует данные варианта V к типу, определяемому параметром VarType |
| procedure VarCast(var Dest: Variant; const Source: Variant; Var
Type: Integer) ; |
Преобразует данные варианта Source к типу,определяемому параметром VarType, и помещает результат в переменную Dest |
| procedure VarClear(var V: Variant) ; | Освобождает динамическую память, если она была связана с вариантом, и дает ему тип varEmpty |
| procedure VarCopy(var Dest: Variant; const Source: Variants; | Копирует параметр Source в вариант Dest |
| function VarFrom-DateTime(DateTime: TDateTime):Variant; | Возвращает вариант, содержащий данные DateTime типа дата-время |
| function VarIsEmpty(const V:
Variant): Boolean; |
Возвращает True, если вариант V не содержит данных |
| function VarIsNull(const V: Vari
ant) : Boolean; |
Возвращает True, если вариант V содержит данные неопределенного типа (varNull) ', |
| function VarToDateTime(const V:
Variant): TDateTime) ; |
Преобразует данные варианта V к типу дата-время |
| function VarToStr(const V: Vari ant) : String; | Преобразует данные варианта V к строке ; |
| function VarType(const V: Variant) : Integer; | Возвращает тип хранящихся в варианте данных i |
ВАРИАНТНЫЕ МАССИВЫ
10.4. ВАРИАНТНЫЕ МАССИВЫЗначением варианта может быть массив данных, такие варианты называются вариантными массивами. (Не путайте с обычным или динамическим массивом, элементами которого являются варианты!) Значениями элементов вариантного массива могут быть любые допустимые для варианта значения, кроме строк varstring. Значениями элементов вариантного массива могут быть и варианты, а это значит, что в таком массиве могут одновременно храниться данные разных типов (и в том числе строки). Например:
var
V: Variant;
begin
// Создаем одномерный вариантный массив с 5 элементами:
V := VarArrayCreate([0, 4], varVariant);
// Наполняем его:
V[0] := 1; //Тип целый
V[1] := 1234.5678; //Тип вещественный
V[2] := 'Hello world'; //Строковый тип
V[3] := True; //Логический тип
//Пятым элементом исходного массива сделаем еще один массив:
V[4] := VarArrayOf([1, 10, 100, 1000]);
Caption := V[2]; //Hello world
IbOutput.Caption := IntToStr(V[4][2]); //200
end;
Все действия с вариантными массивами осуществляются с помощью следующих процедур и функций:
Таблица 10.3. Подпрограммы для работы с вариантными массивами
| function VarArrayCreate(const
Bounds: array of Integer; VarType: Integer): Variant; |
Создает вариантный массив из элементов типа VarType с количеством и границами измерений, указываемых параметром Bounds |
| function VarArrayDimCount(const
A: Variant): Integers; |
Возвращает количество измерений вариантного массива А или 0, если А не массив |
| function VarArrayHighBound(const
A: Variant; Dim: Integer): Integer; |
Возвращает верхнюю границу индекса вариантного массива А по измерению Dim |
| function VarArrayLock(var A:
Variant): Pointer; |
Блокирует массив (предотвращает его возможные изменения размеров) и возвращает указатель на связанные с ним данные |
| function VarArrayLowBound(const
A: Variant; Dim: Integer): Integers; |
Возвращает нижнюю границу индекса вариантного массива А по измерению Dim |
| function VarArrayOf(const Values:
array of Variant): Variants; |
Создает одномерный вариантный массив по перечню значений, содержащихся в открытом массиве Values. Нижняя граница индексов вариантного массива в этом случае равна 0 |
| procedure VarArrayRedim(var A:
Variant; HighBound: Integer) ; |
Изменяет верхнюю границу индекса вариантного
массива А на величину HighBound. Вызов про цедуры игнорируется, если массив был заблоки рован функцией VarArrayLock |
| function VarArrayRef(const A:
Variant): Variants; |
Возвращает ссылку на вариантный массив. Ис
пользуется при обращении к API-функциям |
| procedure VarArrayUnlock(var A:
Variant) |
Отменяет действие функции VarArrayLock |
ПОЛЬЗОВАТЕЛЬСКИЕ ВАРИАНТЫ
10.5. ПОЛЬЗОВАТЕЛЬСКИЕ ВАРИАНТЫСтандартный вариант может хранить только одно из значений, указанных в табл. 10.2. В версии Delphi 6 появились так называемые пользовательские варианты, которые фактически снимают ограничения на характер значений варианта.
Чтобы познакомиться со свойствами новых вариантов, воспользуемся одним из них - вариантом, способным хранить комплексные числа, преобразовывать их в другие типы и осуществлять над ними нужные действия. Как мы увидим дальше, создание пользовательского варианта может быть весьма трудоемким делом - все зависит от сложности хранимых в нем данных. Мы воспользуемся вариантом, созданным разработчиками Delphi и включенным в модуль
VarCmplx.
Создайте такой обработчик bbRunClick:
uses VarCmplx; // Эта ссылка обязательна!
procedure TfmExample.bbRunClick(Sender: TObject);
var
VI, V2: Variants- begin
// Создаем два случайных комплексных числа:
VI := VarComplexCreate(Trunc(Random*1000)/100,
Trunc(Random*1000)/100) ;
V2 := VarComplexCreate(Trunc(Random*1000)/100,
Trunc(Random*1000)/100) ;
with mmOutput.Lines do
begin
// Пустая строка-разделитель
Add ( ' ' ) ;
Add('1-e число: '# 9+V1) ;
Add('2-е число: '#9+V2);
Add('Сложение'#9+(V1+V2));
Add('Вычитание'#9+(V1-V2));
Add('Умножение'# 9+(VI*V2)) ;
Add('Деление'#9#9+(V1/V2))
end
end;
Небольшой комментарий: сложная конструкция Trunc (Random*1000) /100 понадобилась только для того, чтобы реальные и мнимые части комплексных чисел содержали по три значащих цифры.
Вид экрана работающей программы показан на Рисунок 10.1. Как видим, новый вариант легко справляется с поддержкой комплексных чисел: функция VarComplexCreate создает вариант, содержащий комплексное число, а дальнейшее поведение варианта -стандартное (он поддерживает математические операции и преобразование к строковому типу). Однако эта легкость обманчива: исходный текст модуля VarCmplx, который, собственно, и придал варианту дополнительные свойства (по умолчанию располагается в файле Source\Rtl\Common\VarCmplx.pas), содержит более 30000 байт..
На с. 229 показана структура записи TVarData. Два первых байта в этой записи (поле VType) хранят признак значения варианта, остальные 14 могут использоваться для размещения данных.
TDateTimePicker ввод и отображение даты/времени
18.3.10. TDateTimePicker - ввод и отображение даты/времениКомпонент предназначен для ввода и/или отображения даты или времени. На Рисунок 18.26 показаны различные варианты использования компонента.
ДОСТУП К ФАЙЛАМ
11.1. ДОСТУП К ФАЙЛАМФайлы становятся доступны программе только после выполнения особой процедуры открытия файла. Эта процедура заключается в связывании ранее объявленной файловой переменной с именем существующего или вновь создаваемого файла, а также в указании направления обмена информацией: чтение из файла или запись в него.
Файловая переменная связывается с именем файла в результате обращения к стандартной процедуре AssignFile :
AssignFile (<ф.п.>, <имя файла>);
Здесь <ф.п.> - файловая переменная (правильный идентификатор, объявленный в программе как переменная файлового типа);
<имя файла > - текстовое выражение, содержащее имя файла и, если это необходимо, маршрут доступа к нему.
Инициировать файл означает указать для этого файла направление передачи данных. В Object Pascal можно открыть файл для чтения, для записи информации, а также для чтения и записи одновременно.
Для чтения файл инициируется с помощью стандартной процедуры Reset;
Reset (<ф.п.>);
Здесь <ф. п. > - файловая переменная, связанная ранее процедурой AssignFile с уже существующим файлом.
При выполнении этой процедуры дисковый файл подготавливается к чтению информации. В результате специальная переменная-указатель, связанная с этим файлом, будет указывать на начало файла, т. е. на компонент с порядковым номером 0.
Примечание
Примечание
Если делается попытка иницийровать чтение из несуществующего файла, возбуждается исключительная ситуация.
Чтобы проверить, существует ли дисковый файл, можно использовать стандартную функцию FileExists, которая возвращает Truе, если указанный при обращении этой функции файл существует, и False - если не существует.
Например
begin
if FileExists(FileName) then
..... // Файл существует
else ..... // Файл не существует
end ;
В Object Pascal разрешается обращаться к типизированным файлам, открытым процедурой Reset (т. е. для чтения информации), с помощью процедуры write (т. е. для записи информации). Такая возможность позволяет легко обновлять ранее созданные типизированные файлы и при необходимости расширять их. Для текстовых файлов, открытых процедурой Reset, нельзя использовать процедуру Write ИЛИ WriteLn.
Стандартная процедура
Rewrite (<ф.п.>);
инициирует запись информации в файл, связанный с файловой переменной <ф.п.>. Процедурой Rewrite нельзя инициировать запись информации в ранее существовавший дисковый файл: при выполнении этой процедуры старый файл (если он был) уничтожается и никаких сообщений об этом в программу не передается. Новый файл подготавливается к приему информации, и его указатель принимает значение 0.
Стандартная процедура
Append (<ф.п.>)
инициирует запись в ранее существовавший текстовый файл для его расширения, при этом указатель файла устанавливается в его конец. Процедура Append применима только к текстовым файлам, т. е. их файловая переменная должна иметь тип TextFile (см. выше). Процедурой Append нельзя инициировать запись в типизированный или нетипизированный файл. Если текстовый файл ранее уже был открыт с помощью Reset или Rewrite, использование процедуры Арpend приведет к закрытию этого файла и открытию его вновь, но уже для добавления записей.
ПРОЦЕДУРЫ И ФУНКЦИИ ДЛЯ РАБОТЫ С ФАЙЛАМИ
11.2. ПРОЦЕДУРЫ И ФУНКЦИИ ДЛЯ РАБОТЫ С ФАЙЛАМИНиже описываются процедуры и функции, которые можно использовать с файлами любого вида. Специфика работы с типизированными, текстовыми и нетипизированными файлами рассматривается в следующих разделах.
Таблица 11.1. Подпрограммы для работы с файлами
| Procedure AssignFile(var F; FileName:
String) ; |
Связывает файловую переменную f с именем файла FileName |
| function ChangeFileExt
(const FileName, Ex tension: String): Strings; |
Изменяет существующее расширение файла на расширение, заданное параметром Extension |
| Procedure ChDir(Path:
String); |
Изменяет текущий каталог: path - строковое выражение, содержащее путь к устанавливаемому по умолчаниюкаталогу |
| Procedure CloseFile
(var F) ; |
Закрывает файл, однако связь файловой переменной F с именем файла, установленная ранее процедурой Assign-File, сохраняется. При создании нового или расширении старого файла процедура обеспечивает сохранение в файле всех новых записей и регистрацию файла в каталоге. Функции процедуры CloseFile выполняются автоматически по отношению ко всем открытым файлам при нормальном завершении программы. Поскольку связь файла с файловой переменной сохраняется, файл можно повторно открыть без дополнительного использования Процедуры AssignFile |
| function DateTime-ToFileDate(DateTime: TDateTime): Integer; | Преобразует значение DateTime в системный формат времени создания (обновления) файла |
| Function DiskFree(D:
Byte): Longint; |
Возвращает объем в байтах свободного пространства на указанном диске: D - номер диска (0 - устройство по умолчанию, 1 - диск А ,2- диск В и т, д.). Функция возвращает значение -1, если указан номер несуществующего диска |
| function Delete-
File(const FileName: String): Boolean; |
Уничтожает файл с именем (и, возможно, маршрутом доступа) FileName. Возвращает True, если операция прошла успешно |
| Function DiskSize(D:
Byte) : Longing; |
Возвращает объем в байтах полного пространства на указанном диске: d - номер диска (0 - устройство по умолчанию, 1 - диск А ,2- диск Д и т. д.). Функция возвращает значение -1, если указан номер несуществующего диска |
| Function EOF (var F) :
Boolean; |
Тестирует конец файла и возвращает True, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении - что файл исчерпан |
| Procedure Erase(var
F); |
Уничтожает файл f. Перед выполнением процедуры не
обходимо закрыть файл (см. замечание ниже) |
| function FileAge(const
FileName: String): In teger; |
Для файла FileName возвращает время его последнего обновления (в системном формате) или -1, если такого файла не существует |
| function ExcludeTrai-
lingBack.gif" > |
ТЕКСТОВЫЕ ФАЙЛЫ
11.3. ТЕКСТОВЫЕ ФАЙЛЫТекстовые файлы связываются с файловыми переменными, принадлежащими к стандартному типу TextFiie. Текстовые файлы предназначены для хранения текстовой информации. Именно в такого типа файлах хранятся, например, исходные тексты программ. Компоненты (записи) текстового файла могут иметь переменную длину, что существенно влияет на характер работы с ними.
Текстовый файл трактуется в Object Pascal как совокупность строк переменной длины. Доступ к каждой строке возможен лишь последовательно, начиная с первой. При создании текстового файла в конце каждой строки ставится специальный признак eoln (End Of LiNe - конец строки), а в конце всего файла - признак eof (End Of File - конец файла). Эти признаки можно протестировать одноименными логическими функциями (см. ниже). При формировании текстовых файлов используются следующие системные соглашения:
eoln - последовательность кодов #13 (cr) и #10 (lf);
EOF -КОД #26.
Примечание
Примечание
В Delphi 6 при создании межплатформенных приложений признаком конца строки считается один символ LF(#10)
Для доступа к записям применяются процедуры Read, ReadLn, write, writebn. Они отличаются возможностью обращения к ним с переменным числом фактических параметров, в качестве которых могут использоваться символы, строки и числа. Первым параметром в любой из перечисленных процедур должна стоять файловая
переменная. Обращение осуществляется к дисковому файлу, связанному С Переменной Процедурой AssignFile.
Таблица 11.2. Подпрограммы для работы с текстовыми файлами
| Function Eoln(var
F: TextFile): Boolean; |
Тестирует маркер конца строки и возвращает True, если конец строки достигнут |
| Procedure Read(var
F: TextFile; V1 [, V2,...,Vn ]); |
Читает из текстового файла последовательность символьных представлении переменных Vi типа char. String, а также любого целого или вещественного типа, игнорируя признаки EOLN |
| Procedure ReadLn
(var F: TextFile; [VI [, V2, ...,Vn]]); |
Читает из текстового файла последовательность символьных представлении переменных Vi типа char, String, а также любого целого или вещественного типа с учетом границ строк |
| Function
SeekEof(var F: Text): Boolean; |
Пропускает все пробелы, знаки табуляции и маркеры конца строки eoln до маркера конца файла eof или до первого значащего символа и возвращает True, если маркер eof обнаружен |
| Function SeekEoln
(var F: TextFile): Boolean; |
Пропускает все пробелы и знаки табуляции до маркера конца строки eoln или до первого значащего символа и возвращает True, если маркер обнаружен |
| Procedure Write(var
F: Text; PI [, P2,..., Pn] ) ; |
Записывает символьные представления параметров Pi в текстовый файл |
| Procedure WriteLn
(var F: Text; [PI [, P2, ..., Pn]]); |
Записывает символьные представления параметров Pi и при знак конца строки eoln в текстовый файл |
Следующая программа “зависнет”, т. к. никогда не будет прочитана вторая строка файла:
procedure TfmExample.bbRunClick(Sender: TObject);
var
F: TextFile;
S: String;
begin
AssignFile(F,'example.pas');
Reset(F);
while- not EOF(F) do
begin
Read(P,S); // Ошибка! Бесконечный цикл!
mmOutput.Lines.Add(S)
end;
CloseFile(F)
end;
При вводе численных переменных процедура Read вначале выделяет подстроку во входном потоке по следующему правилу: все ведущие пробелы, символы табуляции и маркеры конца строк eoln пропускаются; после выделения первого значащего символа, наоборот, любой из перечисленных символов или символ eof служат признаком конца подстроки. Выделенная таким образом подстрока затем рассматривается как символьное представление числовой константы соответствующего типа и преобразуется во внутреннее представление, а полученное значение присваивается переменной. Если в подстроке был нарушен требуемый формат представления числовой константы, возникает исключительная ситуация. Если при пропуске ведущих пробелов встретился символ eof, переменная получает значение 0. В Object Pascal не предусмотрен ввод шестнадцатеричных констант.
Процедура Read прекрасно приспособлена к вводу чисел. При обращении к ней за вводом очередного целого или вещественного числа процедура “перескакивает” маркеры конца строк, т. е. фактически весь файл рассматривается ею как одна длинная строка, содержащая текстовые представления чисел. В сочетании с проверкой конца файла функцией eof процедура Read позволяет организовать простой ввод массивов данных, например, так:
const
N = 1000; // Максимальная длина ввода
var
F : TextFile;
М : array [1..N] of Real;
i : Integer;
begin
AssignFile(F, 'prog.dat');
Reset(F);
i := 1;
while not EOF(f) and (i <= N) do
begin
Read(F, M[i]);
inc (i) end;
CloseFile(F) ;
end.
Процедура ReadLn идентична процедуре Read за исключением того, что после считывания последней переменной оставшаяся часть строки до маркера eoln пропускается, поэтому следующее обращение к ReadLn начинается с первого символа новой строки. Кроме того, эту процедуру можно вызвать без параметров v i „ что приведет к пропуску всех символов текущей строки вплоть до eoln. Если в обработчике bbRunClick (см. пример на предыдущей странице) заменить Read на ReadLn, программа выведет в окно компонента mmout-put все строки из текстового файла example . раs.
Процедура write обеспечивает вывод в текстовый файл группы переменных. Любой элемент списка вывода может иметь форму
OutExpr [ : MinWidth [ : DecPlaces ] ]
Здесь OutExpr - выводимое выражение; MinWidth, DecPlaces - выражения типа integer (квадратные скобки означают возможность отсутствия заключенных в них параметров). Параметр MinWidth, если он присутствует, указывает минимальную ширину поля, в которое будет записываться символьное представление значения OutExpr. Если символьное представление имеет меньшую длину, чем MinWidth, оно будет дополнено слева пробелами, если большую длину, то MinWidth игнорируется и в файл помещается необходимое число символов. Параметр DecPlaces задает количество десятичных знаков в дробной части вещественного числа. Он может использоваться только совместно с MinWidth и только по отношению к выводимому выражению одного из вещественных типов.
Если ширина поля вывода не указана, соответствующий параметр выводится вслед за предыдущим без какого-либо их разделения. Символы и строки передаются выводному файлу без изменений, но снабжаются ведущими пробелами, если задана ширина поля вывода и эта ширина больше требуемой для вывода.
При выводе логических выражений в зависимости от их значения выводятся слова True или False. (Ввод логических констант процедурами Read или ReadLn не предусмотрен.)
Вещественные числа выводятся в экспоненциальном формате, если не указан параметр Decpiaces, в противном случае выбирается формат представления числа с фиксированной точкой. Если подпараметр MinWidth опущен, принимается его значение по умолчанию (23). Если Minwidth меньше 10, считается, что он равен 10. Если подпараметр Decpiaces равен нулю, ни дробная часть числа, ни десятичная точка не выводятся. При отрицательном значении Decpiaces этот параметр игнорируется и число выводится в экспоненциальном формате с учетом Minwidth. Если значение Decpiaces больше 18, принимается значение 18. Следует учесть, что при указании подпараметра Decpiaces вещественное число всегда будет выводиться в формате с фиксированной точкой и требуемым количеством знаков в дробной части, даже если значение подпараметра Minwidth окажется недостаточным для размещения целой части: в этом случае значение Minwidth автоматически увеличивается.
Процедура writebn полностью идентична процедуре Write за исключением того, что выводимая последовательность символов автоматически завершается маркером eoln (свое название процедура получила от Write Line - писать строку). При вызове WriteLn можно опускать параметры Vi-в этом случае в файл передается пустая строка.
ТИПИЗИРОВАННЫЕ ФАЙЛЫ
11.4. ТИПИЗИРОВАННЫЕ ФАЙЛЫДлина любого компонента типизированного файла строго постоянна, что дает возможность организовать прямой доступ к каждому из них (т. е. доступ к компоненту по его порядковому номеру).
Перед первым обращением к процедурам ввода-вывода указатель файла стоит в его начале и указывает на первый компонент с номером 0. После каждого чтения или записи указатель сдвигается к следующему компоненту файла. Переменные в списках ввода-вывода должны иметь тот же тип, что и компоненты файла. Если этих переменных в списке несколько, указатель будет смещаться после каждой операции обмена данными между переменными и дисковым файлом.
Таблица 11.3. Подпрограммы для работы с типизированными файлами
| Function FilePos
(var F): Longint; |
Возвращает текущую позицию в файле, т. е. номер компонента, который будет обрабатываться следующей операцией ввода-вывода |
| Function FileSize
(var F): Longint; |
Возвращает количество компонентов файла. Чтобы переместить указатель в конец типизированного файла, можно написать:
seek (FileVar, FileSize(FileVar)); |
| Procedure Seek(var F; N: Longint) ; | Смещает указатель файла F к требуемому компоненту: n - номер компонента файла (первый компонент файла имеет номер 0) |
| Procedure Read(var
F, VI,..., Vn) ; |
Читает данные из типизированного файла f:
v< - переменные такого же типа, что и компоненты файла |
| Procedure
Write(var F,P1, ...,Pn) |
Записывает данные в типизированный файл
р: Pi - выражения такого же типа, что и компоненты файла |
НЕТИПИЗИРОВАННЫЕ ФАЙЛЫ
11.5. НЕТИПИЗИРОВАННЫЕ ФАЙЛЫНетипизированные файлы объявляются как файловые переменные типа File и отличаются тем, что для них не указан тип компонентов. Отсутствие типа делает эти файлы, с одной стороны, совместимыми с любыми другими файлами, а с другой - позволяет организовать высокоскоростной обмен данными между диском и памятью.
При инициации нетипизированного файла процедурами Reset или Rewrite можно указать длину записи нетипизированного файла в байтах. Например, так:
var
F: File;
begin
AssignFile(F,'myfile.dat');
Reset(f,512);
end.
Длина записи нетипизированного файла указывается вторым параметром при обращении к процедурам Reset или Rewrite, в качестве которого может использоваться выражение типа Longint. Если длина записи не указана, она принимается равной 128 байтам.
Object Pascal не накладывает каких-либо ограничений на длину записи нетипизированного файла за исключением требования положительности и ограничения максимальной длины 2 Гбайт (для Delphi 1 длина записи ограничивается 65535). Для обеспечения максимальной скорости обмена данными рекомендуется задавать длину, которая была бы кратна длине физического сектора дискового носителя информации (512 байт). Однако операции обмена данными с дисковыми устройствами в среде Windows кэшируются, т. е. осуществляются через промежуточный буфер памяти, поэтому обычно задают Recsize = 1, что позволяет обмениваться с файлом блоками любой длины начиная с одного байта.
При работе с нетипизированными файлами могут применяться все процедуры и функции, доступные типизированным файлам, за исключением Read и write, которые заменяются соответственно высокоскоростными Процедурами BlockRead И BlockWrite:
Procedure BlockRead(var F: File; var Buf; Count: Integer [;
var AmtTransferred: Integer]) ;
Procedure BlockWrite(var F: File; var Buf; Count: Integer [;
var AmtTransferred: Integer]);
Здесь Buf - буфер: имя переменной, которая будет участвовать в обмене данными с дисками; count - количество записей, которые должны быть прочитаны или записаны за одно обращение к диску;
AmtTransferred - необязательный параметр, содержащий при выходе из процедуры количество фактически обработанных записей.
За одно обращение к процедурам может быть передано до count*RecSize байт, где RecSize - длина записи нетипизированного файла. Передача идет начиная с первого байта переменной Buf. Программист должен позаботиться о том, чтобы длина внутреннего представления переменной Buf была достаточной для размещения всех count*Rec3ize байт при чтении информации с диска. Если при чтении указана переменная недостаточной длины или если в процессе записи на диск не окажется нужного свободного пространства, возникнет ошибка ввода-вывода, которую можно заблокировать, указав необязательный параметр AmtTransferred.
После завершения процедуры указатель смещается на count записей. Процедурами Seek, FilePos И FileSize можно обеспечить доступ к любой записи нетипизированного файла.
СРЕДСТВА WINDOWS ДЛЯ РАБОТЫ С ФАЙЛАМИ
11.6. СРЕДСТВА WINDOWS ДЛЯ РАБОТЫ С ФАЙЛАМИОперационная система Windows имеет собственные средства работы с файлами, которые становятся доступны программе Delphi после ссылки на модуль Windows. Поскольку файловые средства Object Pascal реализуют подавляющее большинство программных запросов, в табл. 11.4 приводится лишь краткая информация о назначении соответствующих API-функций. За подробной информацией обращайтесь к справочной службе в файлах WIN32. hlp или WIN32SDK.HLp (для версии б
Эти файлы расположены В каталоге Programs Files | Common Files |
Borland Share | MSHelp).
Таблица 11.4. Средства Windows для работы с файлами
| AreFileApisANSI | Определяет, будут ли файловые операции использовать кодовую страницу ansi |
| CopyFile | Копирует содержимое одного файла в другой |
| CreateDirectory | Создает новый каталог на диске Создает новый каталог на диске |
| CreateDirectoryEx | Создает новый или открывает существующий файл |
| CreateFile | Связывает асинхронный ввод/вывод с файлом, что дает возможность получить извещение о завершении асинхронной операции |
| CreateIoCompletionPort | Определяет, переопределяет или уничтожает определение логического устройства ms-dos |
| DefineDosDevice DeleteFile | Уничтожает файл (в табл. 8.1 указан более удобный интерфейс вызова этой API-функции) операций |
| FileIOCompletionROutine | Связывает асинхронный ввод/вывод с подпрограммой для слежения за окончанием асинхронных |
| FindClose | Освобождает память, выделенную функциям Find FirstFile - FindNextFile |
| FindCloseChangeNotification | Освобождает память, выделенную функциям Find-FirstChangeNotification FindNextChangeNotification |
| FindFirstChangeNotification | Требует от Windows известить программу об изменении состояния каталога |
| FindFirstFile | Ищет первый файл из группы файлов |
| FindNextChangeNotifi-
cation |
Требует от Windows известить программу об очередном изменении состояния каталога |
| FindNextFile | Ищет следующий файл |
| FlushFileBuffers | Очищает файловый буфер |
| GetBinaryType | Определяет, является ли файл исполняемым и, если является, возвращает его тип |
| GetCurrentDirectory | Возвращает умалчиваемый каталог |
| GetDiskFreeSpace | Возвращает свободное дисковое пространство в байтах |
| GetDriveType | Возвращает тип диска (сменный, удаленный и т. п.) |
| GetFileAttributes | Возвращает атрибуты файла |
| GetFileInformationBy Handle | Возвращает системную информацию о файле |
| GetFileSize | Возвращает размер файла в байтах |
| GetFileType | Возвращает тип файла |
| GetFullPathName | По короткому имени файла в формате ms-dos и windows 16 возвращает его полное имя в формате windows 32 |
| GetLogicalDrives | Возвращает битовую 32-разрядную маску, определяющую текущий диск |
| GetLogicalDriveStrings | Возвращает список всех дисков, зарегистрированных в Windows |
| GetQueuedCompletion Status | Требует от Windows выполнения асинхронного ввода/вывода и приостанавливает работу программы до завершения операций |
| GetShortPathName | Возвращает короткое имя файла в формате MS-DOS^Windows 16) |
| GetSystemDirectory | Возвращает имя системного каталога Windows для размещения библиотек, драйверов, шрифтов и т. п. |
| GetTempFileName | Возвращает уникальное имя файла для временного хранения данных |
| GetTempPath | Возвращает маршрут поиска каталога, предназначенного для хранения временно используемых файлов |
| Ge tVolumeIn fo rmat ion | Возвращает информацию о файловой подсистеме в целом и об указанном каталоге |
| GetWindowsDirectory | Возвращает полное имя каталога Windows для размещения прикладных программ, файлов инициализации, файлов помощи и т. п. |
| LockFile | Защищает файл от доступа к нему из других программ |
| LockFileEx | Устанавливает способ использования файла другими программами |
| MoveFile | Переименовывает файл или каталог (с подкаталогами) |
| MoveFileEx | Переименовывает файл |
| OpenFile | Открывает существующий файл |
| QueryDosDevice | Получает информацию об именах дисков (устройств), используемых в MS-DOS |
| ReadFile | Читает данные из файла |
| ReadFileEx | Реализует асинхронное чтение данных из файла |
| RemoveDirectory | Удаляет пустой каталог |
| SearchPath | Ищет файл в заданном каталоге (каталогах) |
| SetCurrentDirectory | Устанавливает умалчиваемый каталог |
| SetEndOfFile | Перемещает файловый указатель в конец файла |
| SetFileApisToANSI | Предписывает Windows использовать кодовую страницу
ANSI при файловых операциях |
| SetFileApisToOEM | Предписывает Windows использовать кодовую страни .
MS-DOS при файловых операциях |
| SetFileAttributes | Устанавливает атрибуты файла |
| SetFilePointer | Перемещает файловый указатель на нужную позицию |
| SetHandleCount | Устанавливает количество файлов, одновременно используемых программой |
| SetVolumeLabel | Устанавливает новую метку тома (носителя информации) |
| UnlockFile | Снимает с файла защиту, установленную функцией LockFile |
| UnlockFileEx | Снимает с файла защиту, установленную функцией LockFileEx |
| WriteFile | Записывает данные в файл |
| WriteFileEx | Реализует асинхронную запись в файл |
Создание/открытие файла
11.7.1. Создание/открытие файлаВначале файл создается обращением к функции
function FileCreate(FileName: String): Integer;
или открывается с помощью
function FileOpen(const FileName:
String; Mode: LongWord): Integer;
В обеих функциях FileName - имя файла, возможно, с маршрутом доступа. Параметр Mode определяет режим доступа к файлу и может принимать одно из следующих значений: fmOpenRead - только чтение; fmOpenWrite - только Запись; fmOpenReadWrite - чтение и запись. с помощью операции or эти константы можно комбинировать с одной из следующих регулирующих совместный доступ к файлу нескольких Программ: fmShareExclusive - совместный доступ Запрещен; fmShareDenyWrite - Другим Программам запрещается запись; fmShareDenyRead - другим программам запрещается чтение; fmSchareDenyNone - совместный доступ неограничен. Обе функции возвращают дескриптор созданного (открытого) файла или 0, если операция оказалась неуспешной.
ОТОБРАЖЕНИЕ ФАЙЛОВ В ПАМЯТЬ
11.7. ОТОБРАЖЕНИЕ ФАЙЛОВ В ПАМЯТЬДля работы с файлом динамической подкачки страниц виртуальной памяти в Windows 32 используется механизм отображения файлов в адресное пространство программы. Соответствующие функции API доступны любой программе и могут применяться к любому файлу (кстати, таким способом загружается в адресное пространство процесса исполняемый файл). В результате отображения программа может работать с файловыми данными как с данными, размещенными в динамической памяти. Такая возможность не только в большинстве случаев повышает скорость работы с данными, но и предоставляет программисту уникальные средства обработки сразу всех записей файла. Например, он может единственным оператором проверить входит ли заданный образец поиска в любую строку текстового файла. Отображение файла осуществляется в три приема.
ОБЪЕКТНАЯ МОДЕЛЬ РАБОТЫ С ФАЙЛАМИ
11.8. ОБЪЕКТНАЯ МОДЕЛЬ РАБОТЫ С ФАЙЛАМИВ Delphi используется абстрактный класс TStream (поток данных), который является основой для работы с файлами как с объектами. В случае объектов совершенно не важно, что именно является носителем информации - дисковый ли файл, ленточный носитель или оперативная память. В специализированных потомках TStream определены стандартные методы Read, write и seek, открывающие полный доступ к файловому объекту. Сам объект создается конструктором и уничтожается деструктором.
Примечание
Примечание
Поток не, учитывает специфику хранящихся в файле данных, т. е. по существу работает с данными, как если бы хранились в не типизированном файле.
В следующем примере файл с именем, хранящимся в Editl.Text,
копируется В файл Edit2 . Text.
procedure TFor.gif" >
TComboBox раскрывающийся список выбора
18.1.11. TComboBox - раскрывающийся список выбораКомбинированный список TComboBox представляет собой комбинацию списка TListBox и редактора TEdit, и поэтому большинство его свойств и методов заимствованы у этих компонентов. Существуют пять модификаций компонента, определяемые его свойством style:
csSimple, csDropDown, csDropDownList, csOwnerDrawFixed И csOwner DrawVariabie. В первом случае список всегда раскрыт, в остальных он раскрывается после нажатия кнопки справа от редактора (Рисунок 18.7). В модификации csDropDownList редактор работает в режиме отображения выбора и его нельзя использовать для ввода новой строки (в других модификациях это возможно). Модификации csOwnerDrawFixed и csOwnerDrawVariable используются программной прорисовки элементов списка. Используемые для этого свойства и методы полностью совпадают со свойствами и методами TListBox аналогичного назначения.
Фактически “своими” у компонента являются лишь свойства и события, связанные с раскрытием списка:
property DropDownCount: Integer;
property DroppedDown: Boolean;
property OnDropDown: TNotifyEvent;
TMonthCalendar календарь
18.3.11. TMonthCalendar - календарь
Как видно из рисунка слева, компонент предназначен для выбора или отображения даты. Он очень похож на календарь, который появляется В компоненте TDateTimePicker (при значении dmComboBox В свойстве DateMode), но в отличие от последнего может отображать одновременно несколько смежных месяцев - в зависимости от своих размеров.
Свойства компонента:
| property CalColors: TMonthCalColors; | С компонентом связан объект класса
TMonthCalColors, имеющий такие свойства:Back.gif" > |
TSplitter компонент для изменения размеров
18.2.11. TSplitter - компонент для изменения размеровКомпонент TSplitter предназначен для ручного (с помощью мыши) управления размерами контейнеров TPanel1, TGroupBox или подобных им во время прогона программы. Визуально он представляет собой небольшую вертикальную или горизонтальную полосу, располагающуюся между двумя соседними контейнерами или на “свободной” стороне одного их них.
Непременным условием правильной работы компонента является выравнивание контейнера (контейнеров), размерами которого (которых) он управляет, вдоль одной из сторон окна или охватывающего контейнера. Для примера на Рисунок 18.14 показаны две панели, разделенные компонентом TSpiitter. Нижняя панель имеет Align = alBottom, верхняя в этом случае может иметь выравнивание alBottom или alciient. Между ними помещен TSplitter с выравниванием alBottom.
Свойства компонента:
| property Beveled: Boolean; | Управляет трехмерным изображением компонента. Если False, компонент виден как узкая полоска фона между разделяемыми им компонентами него |
| NaturalNumber = 1..High(Integer) ; | Содержит минимальный размер любого из компонентов, которые разделяет TSplitter. |
| property MinSize: Natural-Number; | Если выравнивание aiLeft или aiRight - минимальная ширина компонента слева и справа от TSplitter, еСЛИ alTop или alBottom -минимальная высота компонента выше или ниже отнего |
СТРУКТУРА МОДУЛЕЙ
12.1. СТРУКТУРА МОДУЛЕЙМодуль имеет следующую структуру:
Unit <имя>;
interface
<интерфейсная часть> implementation
<исполняемая часть> initialization < нициирующая часть> finalization <завершающая часть>
end.
Здесь unit - зарезервированное слово (единица); начинает заголовок модуля; <имя> - имя модуля (правильный идентификатор); interface - зарезервированное слово (интерфейс); начинает интерфейсную часть модуля; implementation - зарезервированное слово (выполнение); начинает исполняемую часть; initialization -зарезервированное слово (инициация); начинает инициирующую часть модуля; finalization - зарезервированное слово (завершение);
начинает завершающую часть модуля; end - зарезервированное слово - признак конца модуля.
Таким образом, модуль состоит из заголовка и четырех составных частей, любая из которых может быть пустой.
ЗАГОЛОВОК МОДУЛЯ И СВЯЗЬ МОДУЛЕЙ ДРУГ С ДРУГОМ
12.2. ЗАГОЛОВОК МОДУЛЯ И СВЯЗЬ МОДУЛЕЙ ДРУГ С ДРУГОМЗаголовок модуля состоит из зарезервированного слова unit и следующего за ним имени модуля. Для правильной работы среды Object Pascal и возможности подключения средств, облегчающих разработку крупных программ, это имя должно совпадать с именем дискового файла, в который помещается исходный текст модуля. Если, например, имеем заголовок
Unit Global;
то исходный текст соответствующего модуля должен размещаться в дисковом файле global. pas. Имя модуля служит для его связи с другими модулями и основной программой. Эта связь устанавливается специальным предложением
Uses <сп.модулей>
Здесь uses - зарезервированное слово (использует); <сп.модулей> -список модулей, с которыми устанавливается связь; элементами списка являются имена модулей, отделяемые друг от друга запятыми, например:
Uses Windows, SysUtils, MyUnit;
Если объявление uses используется, оно должно открывать раздел описаний основной программы. Модули могут использовать другие модули. Предложение uses в модулях может следовать либо сразу за зарезервированным СЛОВОМ interface, либо Сразу за словом implementation, либо, наконец, и там, и там (т. е. в модуле допускаются два предложения uses).
ИНТЕРФЕЙСНАЯ ЧАСТЬ
12.3. ИНТЕРФЕЙСНАЯ ЧАСТЬИнтерфейсная часть открывается зарезервированным словом interface. В этой части содержатся объявления всех глобальных объектов модуля (типов, констант, переменных и подпрограмм), которые должны стать доступными основной программе и/или другим модулям. При объявлении глобальных подпрограмм в интерфейсной части указывается только их заголовок, например:
Unit Cmplx;
interface type
Complex = record
re,im: Real end;
Function AddC(x,y: Complex): Complex;
Function MulC(x,y: Complex): Complex;
Если теперь в другом модуле написать предложение Uses Cmplx; то в нем станут доступными тип Сomplex и две процедуры - AddС и МulС из модуля Cmplx.
ИСПОЛНЯЕМАЯ ЧАСТЬ
12.4. ИСПОЛНЯЕМАЯ ЧАСТЬИсполняемая часть начинается зарезервированным словом implementation и содержит описания подпрограмм, объявленных в интерфейсной части. В ней могут объявляться локальные для модуля объекты - вспомогательные типы, константы, переменные и подпрограммы, а также метки, если они используются в инициирующей части.
Описанию подпрограммы, объявленной в интерфейсной части модуля, в исполняемой части должен предшествовать заголовок, в котором можно опускать список формальных переменных (и тип результата для функции), так как они уже описаны в интерфейсной части. Но если заголовок подпрограммы приводится в полном виде, т. е. со списком формальных параметров и объявлением результата, он должен совпадать с заголовком, объявленным в интерфейсной части, например:
Unit Cmplx;
Interface type
Complex = record
re,im: real
end;
Function AddC(x,y: Complex): Complex;
Function MulC(x,y: Complex): Complex;
Implementation
Function AddC(x,y: Complex): Complex;
begin
end; Function MulC;// Вариант описания подпрограммы без
// повторения списка параметров
begin
end;
end.
Примечание
Примечание
Хотя допускается краткое объявление заголовка подпрограммы ( как в предшествующем примере—функции Mul(), тем не менее использовать такую форму в серьезной программе не рекомендуется: перечень параметров непосредственно в заголовке подпрограммы облегчает чтения кода и понимания деталей реализации алгоритма.
Повторение заголовка в исполняемой части должно быть полным и точным. Если бы мы использовали заголовок
Function AddC(x,z: Complex): Complex; begin
end;
компилятор немедленно известил бы нас о несовпадении заголовка с объявлением функции в интерфейсной части (второй параметр должен иметь имя у).
ИНИЦИИРУЮЩАЯ И ЗАВЕРШАЮЩАЯ ЧАСТИ
12.5. ИНИЦИИРУЮЩАЯ И ЗАВЕРШАЮЩАЯ ЧАСТИИнициирующая и завершающая части чаще всего отсутствуют
Вместе с начинающим их словами initialization и finalization.
В инициирующей части размещаются операторы, которые исполняются до передачи управления основной программе и обычно используются для подготовки ее работы. Например, в них могут инициироваться переменные, открываться нужные файлы и т. д. В завершающей части указываются операторы, выполняющиеся после завершения работы основной программы (в них освобождаются выделенные программе ресурсы, закрываются файлы и т. д.). Если несколько модулей содержат инициирующие части, эти части выполняются последовательно друг за другом в порядке перечисления модулей в предложении uses главной программы. Если несколько модулей содержат завершающие части, эти части выполняются последовательно друг за другом в порядке, обратном перечислению модулей в предложении uses главной программы.
ДОСТУП К ОБЪЯВЛЕННЫМ В МОДУЛЕ ОБЪЕКТАМ
12.6. ДОСТУП К ОБЪЯВЛЕННЫМ В МОДУЛЕ ОБЪЕКТАМПусть, например, мы создаем модуль, реализующий арифметику комплексных чисел (такая арифметика ни в стандартном Паскале, ни в Object Pascal не предусмотрена, но в Delphi 6 введен пользовательский вариант, который реализует действия над комплексными
Числами - см. п. 10.5 и модуль Source\Rtl\Common\VarCmplx.pas Каталога размещения Delphi). Арифметика комплексных чисел реализуется четырьмя функциями:
Unit Cmplx;
//---------------------------
Interface
//---------------------------
type
Complex = record
re,im: real end; Function AddC (x,y: Complex): Complex;
Function SubC (x,y: Complex): Complex;
Function MuiC (x,y: Complex): Complex;
Function DivC (x,y: Complex): Complex;
const
с : Complex = (re : 0.1; im : -1);
//---------------------------
Implementation
//---------------------------
Function AddC (x,y: Complex): Complex;
// Сложение комплексных чисел
begin
Result.re := x.re + y.re;
Result.im := x.im + y.im
end; //AddC
Function SubC (x,y: Complex): Complex;
// Вычитание комплексных чисел
begin
Result.re := x.re - y.re;
Result.im := x.im - y.im
end; //SubC
Function MulC (x,y: Complex): Complex;
// Умножение комплексных чисел
begin
Result.re := x.re * y.re - x.im * y.im;
Result.im := x.re * y.im + x.im * y.re
end; //MulC
Function DivC (x,y: Complex): Complex;
// Деление комплексных чисел
var
z: Real;
begin
z := sqr(y.re) + sqr(y.im);
// Защищаем программу от краха в случае, когда z=0:
try- Result, re := (x.re * у.re + x.im * y.im) / z;
Result.im := (x.re * y.im - x.im * y.re) / z;
except
Result.re := l.le309;
Result.im := l.le309;
end
end
{Div.C};
end.
Чтобы создать такой модуль, следует вызвать опцию File | New I unit[ В Delphi 1 для этого используется опция File | New | Unit, в версиях 2...5 - опция File |
New и выбор пиктограммы на закладке New окна Репозитория. ]. Текст модуля следует сохранить в файле cmplx.pas: имя файла должно совпадать с именем модуля - только в этом случае Delphi сможет автоматически найти модуль и следить за его обновлением.
После создания модуля его имя нужно упомянуть в предложении uses того модуля, в котором будут использоваться вновь созданные подпрограммы, типы, константы (в нашем модуле - тип complex, подпрограммы Addc, subc. Mule, Dive и константа с). Пусть, например, при каждом щелчке по кнопке bbRun учебной программы создается пара случайных комплексных чисел, над которыми осуществляются все четыре арифметических действия. Тогда обработчик bbRunClick мог бы быть таким:
implementation
uses Cmplx;
{$R *.DFM}
procedure Tform1.bbRunClick(Sender: TObject);
var
x,y,z: Complex;
procedure Output(Operation: Char);
//Осуществляет нужное действие и выводит результат в mmOutput
var
S: String;
begin
case Operation of
'+': z := AddC(x,y) ;
'-': z := SubC(x,y) ;
'*': z := MulC(x,y) ;
'/': z := DivC(x,y) ;
end;
S := '('+For.gif" >
ТИПЫ МОДУЛЕЙ В DELPHI
12.7. ТИПЫ МОДУЛЕЙ В DELPHIНаиболее распространенным типом модуля в Delphi является форма - модуль со связанным с ним окном. Интерфейсная часть такого модуля обычно содержит объявление нового класса и автоматически обновляется Delphi в ходе конструирования окна. В интерфейсной части модуля-формы содержится также объявление объекта для соответствующего оконного класса. Например, для нашей учебной программы модуль содержит объявление класса TfmExamie и объекта fmExampie. Большинство типовых модулей в репозитории содержат заготовки для создания диалоговых окон.
Помимо форм в репозитории содержатся также не связанные с видимыми окнами модули. Кроме уже рассмотренного выше модуля общего назначения, к ним относятся модули данных, модули динамических библиотек, пакеты и модули потоков.
Модули данных имеют связанные с ними окна, однако, эти окна никогда не появляются на экране. Необходимость в окнах вызвана тем, что компоненты доступа к данным страницы можно вставить только в форму, хотя все они не имеют видимого воплощения в работающей программе. Невидимое окно модуля данных предназначено для размещения этих компонентов и связанных с ними объектов-полей. Разумеется, для размещения компонентов и полей можно использовать и обычное окно-форму, однако в этом случае пиктограммы компонентов загромождают видимое пространство окна и затрудняют его конструирование. В Delphi 5, 6 модули данных способны отображать реляционные связи между сущностями базы данных в виде диаграмм.
Модули динамических библиотек предназначены для создания широко используемых в Windows динамически связываемых библиотек DLL (Dynamic-Link Libraries). DLL служат универсальным средством согласования подпрограмм, написанных на разных языках программирования. В Windows содержится множество DLL, написанных на языке Си или на языке ассемблера, что ничуть не мешает Delphi-программам использовать их. Модули динамических библиотек предназначены для разработки DLL с помощью Object Pascal. Такие DLL затем смогут использовать программы, созданные с помощью других языков программирования.
Пакеты - это особым образом откомпилированные DLL, оптимизированные для совместного использования Delphi-программами, или средой Delphi, или и программами, и средой. В отличие от DLL пакеты могут хранить и передавать программе типы (включая классы) и данные. Они разработаны специально для хранения компонентов, разного рода экспертов, редакторов сложных свойств и т. п. Например, в пакете VCL60 .bpl содержатся основные компоненты Delphi.
Модули потоков предназначены для реализации так называемых потоков команд[ В Delphi существуют также потоки данных - см.п. 11.4. ] - фрагментов программы, которые исполняются параллельно с другими фрагментами, разделяя с ними время процессора и остальные системные ресурсы. Механизм потоков используется в 32-разрядных Windows и не поддерживается в Delphi 1. К сожалению, в текущей реализации Delphi 32 потоки не могут связываться с собственными видимыми компонентами, так как библиотека визуальных компонентов VCL (Visual Component Library) не поддерживает работу с потоками. Вот почему модуль потока не имеет связанного с ним окна.
TScrollBar управление значением величины
18.1.12. TScrollBar - управление значением величины
Компонент TScrollBar представляет собой стандартный для Windows управляющий элемент, похожий на полосу прокрутки окна. Обычно он используется для визуального управления значением числовой величины.
Свойства компонента:
| TSrollBarKind = (sbHorizontal, sbVertical) ; property Kind: TScrollBarKind;
property LargeChange: TScroll-Barinc; |
Определяет ориентацию компонента: sbHorizontal - бегунок перемещается по горизонтали; sbVertical - бегунок перемещается по вертикали “Большой” сдвиг бегунка (при щелчке мышью рядом с концевой кнопкой) |
| property Max: Integer; | Максимальное значение диапазона изменения числовой величины |
| property Min: Integers; | Минимальное значение диапазона изменения числовой величины |
| property PageSize: Integers; | Определяет размер позиции табуляции бегунка |
| property Position: Integers;property SmallChange: TScroll-Barinc; | Текущее значение числовой величины “Малый” сдвиг бегунка (при щелчке мышью по концевой кнопке) |
procedure SetParams(APosition, AMax, AMin: Integer);
можно сразу установить свойства Position, мах и Min.
С компонентом связано два события:
type TScrollEvent = procedure(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer) of objects;
property OnScroll: TScrollEvent;
property OnChange: TNotifyEvent;
Первое возникает при любом изменении свойства position, второе -при изменении параметров методом Setparams.
Подобно TButton компонентом полностью управляет Windows поэтому у него нет свойства Color.
TStaticText метка для отображения текста
18.2.12. TStaticText - метка для отображения текстаЭтот компонент во всем подобен своему “двоюродному брату” TLabel за исключением двух обстоятельств. Во-первых, он порожден от TwinControl и, таким образом, имеет Windows-окно. Это обстоятельство может быть необходимым условием правильного взаимодействия со связанным свойством FocusControl управляющим элементом, если это внешний для Delphi элемент ActiveX. Во-вторых, в его свойстве
type TStaticBorderStyle = (sbsNone, sbsSingle, sbsSunken) ;
property BorderStyle: TStaticBorderStyle;
добавлено значение sbsSunken, которое создает иллюзию “вдавлен-ности” компонента. Все остальные свойства и методы компонента совпадают со свойствами и методами TLabel.
TTreeView дерево иерархии
18.3.12. TTreeView - дерево иерархииКомпонент TTreeView служит для показа ветвящихся иерархических структур, таких как дерево наследования объектов или файловая структура диска. Он содержит связанные узлы, каждый из которых может содержать пиктограмму, текст и произвольный объект (подобно спискам TStringList - см. п. 14.3.2). Любой узел может иметь собственный список подузлов (Рисунок 18.27), которые можно раскрывать или закрывать щелчком мыши на пиктограмме узла.
РЕАЛИЗАЦИЯ
13.2. РЕАЛИЗАЦИЯДля создания DLL в Object Pascal введено зарезервированное слово Library, которым должен начинаться текст библиотеки. За словом Library следует правильный идентификатор, но в отличие от объявления модуля он не обязан совпадать с именем файла: имя DLL определяется именем DLL-файла, а не идентификатором, следующим за Library.
Структура текста DLL повторяет структуру обычной программы с тем исключением, что раздел исполняемых операторов в DLL играет ту же роль, что и инициирующая часть модуля: операторы этой части исполняются только один раз в момент загрузки библиотеки в память. Каждое очередное обращение с требованием загрузить библиотеку наращивает на единицу ее счетчик ссылок, но не приводит к выполнению операторов исполняемой части.
В разделе описаний DLL могут объявляться типы (в том числе и классы), константы и переменные, но они остаются скрытыми от вызывающей программы и могут использоваться только внутри DLL. В разделе описаний помимо стандартных для обычной программы объявлений используется специальный раздел объявления экспортируемых подпрограмм. Этот раздел начинается зарезервированным словом Exports, за которым через запятую перечисляются имена экспортируемых подпрограмм, например:
Library MyLibrary;
Function MyFunc (...):...;
begin
end;
Procedure MyProc;
begin
end;
Exports
MyFunc, MyProc;
begin
end.
Раздел Exports помогает компилятору и компоновщику создать специальный заголовок DLL-модуля, в котором перечисляются имена подпрограмм и адреса их точек входа. В DLL может быть несколько списков Exports, но перечисляемые в них подпрограммы должны быть описаны где-то выше по тексту библиотеки.
Помимо имени подпрограммы в заголовок DLL помещается также ее порядковый номер, точнее, присвоенный ей целочисленный индекс. Это позволяет вызывающей программе ссылаться не на имя, а на индекс подпрограммы и тем самым уменьшить затраты времени на установление с ней связи. Индекс присваивается подпрограмме по порядку ее появления в списках Exports: первая подпрограмма в первом списке получает индекс 0, следующая - 1 и т. д. Программист может изменить умалчиваемую индексацию и явно указать индекс подпрограммы, добавив за ее именем в списке Exports слово index и целое число без знака в диапазоне от 0 до 32767:
Expots
MyFunc index 1, MyProc index 2;
Программист может определить внешнее имя экспортируемой подпрограммы отличным от ее настоящего имени. Для этого в списке Exports добавляется слово name и внешнее имя в апострофах:
Exports
MyFunc index I name 'NEWFUNC';
Вызывающая программа может ссылаться или на имя экспортируемой подпрограммы, или на ее индекс. При вызове по имени программа просматривает имена в таблице имен в поисках нужного. Так как имена могут состоять из длинных наборов символов и самих имен в таблице может быть много, процесс поиска имени медленнее, чем процесс поиска индекса. Поэтому опытные программисты предпочитают ссылаться не на имя, а на индекс подпрограммы.
Замечу, что в отличие от модулей Delphi не компилирует DLL автоматически в режимах make или build, т. к. справедливо рассматривает ее как другую программу, никак не связанную в момент компиляции с основной программой.
ПРИМЕР
13.3. ПРИМЕРРассмотрим пример создания DLL, в котором иллюстрируются различные приемы объявления экспортируемых подпрограмм. Для примера выбран модуль cmpix, описанный в гл. 12. В его состав входят 4 процедуры, реализующие действия с комплексными числами. Вариант соответствующей DLL показан ниже.
Для создания заготовки библиотечного модуля выберите опцию меню File | New | Unit или в окне репозитория щелкните по пиктограмме Da. В ответ Delphi откроет специальное окно проекта с длинным комментарием, в котором указывается на необходимость вставить ссылку на модуль ShareMem, если библиотека экспортирует длинные строки в параметрах обращения к подпрограммам или как результат функций. Эта ссылка должна быть первой как в предложении uses библиотеки, так и в uses файла проекта программы, которая использует эту библиотеку. Если подпрограммы библиотеки экспортируют строки ShortString или PChar, ссылаются на ShareMem не обязательно. Сразу же сохраните проект под именем Сmpix, чтобы Delphi автоматически исправила имя библиотеки в предложении Library.
Library Cmplx;
uses
SysUtils, Classes;
{$R *.RES}
type
TComplex = record Re, Im: Real;
end; function AddC(x, y: TComplex): TComplex; stdcall;
begin
Result.Im := x.Im + y.Im;
Result.Re := x.Re + y.Re end;
function SubC(x, y: TComplex): TComplex;
stdcall;
begin
Result.Im := x.Im - y.Im;
Result.Re := x.Re - y.Re
end;
function MulC(x, у: TComplex): TComplex;
stdcall;
begin
Result.Re := x.Re * y.Re + x.Im * y.Im;
Result.Im := x.Re * y.Im - x.Im * y.Re
end;
function DivC(x, y: TComplex): TComplex;
stdcall;
var
z: Real;
begin
z := sqr(y.Re) + sqr(y.Im);
try
Result.Re := (x.Re * y.Re + x.Im * y.Im)/z;
Result.Im := (x.Re * y.Im - x.Im * y.Re)/z
except
Result.Re := le+309;
Result.Im := le+309
end
end;
Exports
AddC index 1 name 'ADDC' resident,
SubC index 2,
MulC index 3,
DivC index 4;
begin
end.
Обратите внимание: все функции нашей DLL используют соглашение stdcall, которое обеспечивает совместимость новых функций с функциями API Windows 32. Мы могли бы не указывать это соглашение; в этом случае компилятор использовал бы более эффективное соглашение register, но обращение к нашей DLL из программ, написанных на других языках программирования, в общем случае стало бы невозможным.
Если вы создали DLL для "внешнего" исользования (внеDelphi), объявляйте подпрограммы с директивой stdcall или safecall!
Для использования подпрограмм из DLL необходимо описать их как внешние, добавив за словом External имя библиотеки в апострофах:
Procedure MyProc; External 'MyDLL';
Как уже говорилось, подпрограмма вызывается по имени или по индексу. В нашем примере из библиотеки MyDLL вызывается подпрограмма с внешним именем 'мургос'. Если нужно сослаться на индекс подпрограммы, за именем библиотеки указывается слово index и индекс:
Procedure MyProc; External 'MyDLL' index 2;
В этом случае имя, под которым подпрограмма будет известна программе, может не совпадать с ее внешним DLL-именем. Впрочем, программист может и явно переопределить имя подпрограммы, даже если он ссылается на ее внешнее имя:
Procedure MyProc; External 'MyDLL' Name 'ExtName';
В этом варианте предполагается, что экспортируется процедура с внешним именем ' ExtName '.
После любого из указанных выше объявлений экспортируемая подпрограмма становится доступна программе и может вызываться в ней как обычная подпрограмма Object Pascal.
ИСПОЛЬЗОВАНИЕ
13.4. ИСПОЛЬЗОВАНИЕ13.4.1. Статическая загрузка
В следующей программе используется библиотека Сmpix, описанная на предыдущей странице.
type
TComplex = record Re, Im: Real;
end;
function ADDC(x, y: TComplex): TComplex; stdcall; External 'Cmplx' ;
function SubC(x, y: TComplex): TComplex; stdcall; External 'Cmplx' ;
function MulC(x, y: TComplex): TComplex; stdcall; External 'Cmplx' ;
function DivC(x, y: TComplex): TComplex; stdcall; External 'Cmplx';
procedure TfmExample.bbRunClick(Sender: TObject);
var
x,y,z: TComplex;
..... // Далее смотри текст обработчика bbRunClick в п.12.6 end; end.
Обратите внимание: библиотечная функция cmpixAdd имеет внешнее имя addc. Именно так (заглавными буквами) описана эта функция в приведенном выше примере. Если бы мы использовали function AddC(x, у: TComplex): TComplex; stdcall; External
'Cmplx';
компоновщик не смог бы ее идентифицировать.
ВКЛЮЧЕНИЕ В БИБЛИОТЕКУ ФОРМ
13.5. ВКЛЮЧЕНИЕ В БИБЛИОТЕКУ ФОРМНесмотря на то, что DLL не имеет собственной формы, с ее помощью можно вызывать формы из связанных с библиотекой модулей. Для этого в библиотеке используется ссылка uses на связанные модули-формы и объявляются экспортируемые из DLL подпрограммы, в которых реализуется вызов соответствующих форм.
В следующем примере иллюстрируется техника включения в DLL формы и использования ее в вызывающей программе.
Текст DLL
library DLLWithFor.gif" >
TControlBar инструментальная панель
18.2.13. TControlBar - инструментальная панельКомпонент служит удобным контейнером для размещения инструментальных панелей TTооlBаr (см. п. 18.3.16). Он активно использует технологию Drag&Dock для управления положением панелей. На Рисунок 18.15 показан компонент TControlBar с двумя помещенными на него панелями TTооlваг.
Если вы захотите повторить пример, проделайте следующее.
TGroupBox панель группирования
18.1.13. TGroupBox - панель группирования
Этот компонент служит контейнером для размещения дочерних компонентов и представляет собой прямоугольное окно с рамкой и текстом в разрыве рамки. Обычно с его помощью выделяется группа управляющих элементов, объединенных по функциональному назначению. Свойства и методы этого класса целиком унаследованы им от своих предков TCustomControi и TWincontrol и описаны в гл. 17.
TListView список просмотра
18.3.13. TListView - список просмотраКомпонент TListView предназначен для показа и выбора нескольких элементов. Каждый элемент может содержать пиктограмму и текст и подобно TTreeView иметь список связанных с ним подэлементов. В отличие от TTreeview в TListView допускается не более одного уровня вложенности подэлементов. TListView показывает свои элементы в одной или нескольких колонках, с крупными или мелкими пиктограммами, а также в виде “отчетов”, представляющих элементы в двухмерной таблице: по вертикали изображаются элементы верхнего уровня, по горизонтали - вложенные подэлементчатели, упрощающие множественный выбор элементов.
Компонент может наполняться как на этапе конструирования, ты. Рядом с элементами могут показываться независимые переклютак и на этапе прогона программы
Выполните следующую несложную программу, которая продемонстрирует вам основные особенности использования компонента.
На Пустую форму положите компоненты TListView, TImageList, TComboBox И TCheckBox.
TApplicationEvents обработчик сообщений Windows
18.2.14. TApplicationEvents - обработчик сообщений WindowsКомпонент TApplicationEvents впервые введен в версии Delphi 5. В отличие от остальных компонентов страницы Additional он не имеет видимого эквивалента в работающей программе. Его основное и единственное назначение - служить приемником многочисленных сообщений, которые windows посылает работающей программе.
Лишь очень немногие программы нуждаются в специальной (не умалчиваемой) обработке сообщений - примером могут служить программы, эмулирующие клавиатуру DOS (подробнее см. п. 17.6.3) или фильтрующие ввод пользователя (в учебных целях, например).
Следующая простая программа познакомит вас с примером использования компонента. В ней фильтруется ввод программы в компонент TEdit так, чтобы запретить появление в нем любых цифр.
THeaderControl управляющий заголовок
18.3.14. THeaderControl - управляющий заголовокКомпонент THeaderControl представляет собой многоколончатый заголовок с регулируемыми размерами колонок (секций). Каждая колонка (секция) заголовка может содержать текст и/или графику. Компонент способен обрабатывать событие onResize, которое возникает при каждом изменении размеров любой секции. В ходе обработки этого события программа обычно соответствующим образом изменяет линейные размеры столбцов таблицы или подобной структуры, с которой связан компонент.
В программе, окно которой показано на Рисунок 18.30, компонент THeaderControl используется для управления положением и линейными размерами трех других компонентов. Для реализации программы выполните следующее:
TRadioGroup группа зависимых переключателей
18.1.14. TRadioGroup - группа зависимых переключателейКомпонент класса TRadioGroup представляет собой специальный контейнер, предназначенный для размещения зависимых переключателей класса TRadioButton. Каждый размещаемый в нем переключатель помещается в специальный список items и доступен по индексу, что упрощает обслуживание группы.

Свойства компонента:
| property Columns: Integers; | Определяет количество столбцов переключателей |
| property Itemlndex: Integer; | Содержит индекс выбранного переключателя |
| property Items: TStrings; | Содержит список строк с заголовками элементов. Добавление/удаление элементов достигается добавлением/удалением строк списка items (см. п. 16.3.1) |
case RadioGroupl.Itemlndex of
0: ...; //Выбран 1-й переключатель
1: ...; //Выбран 2-й переключатель
else
..... //Не выбран ни один переключатель
end;
КОНСТАНТЫ ПРОСТЫХ ТИПОВ И ТИПА STRING
15.1. КОНСТАНТЫ ПРОСТЫХ ТИПОВ И ТИПА STRINGОбъявление таких констант обычно не вызывает трудностей, так как в качестве их значения используются нетипизированные константы или их идентификаторы.
Примеры объявлений:
type
colors = (white, red, black);
{ ----- Правильные объявления: ----- } const
CurrCol colors = red;
Name String = 'Вирт H.' ;
Year Word = 1989;
X Real = 0.1;
Min Integer =0;
Max Integer = 10;
Days 1..31 = 1;
Answer Char = 'Y';
{----- Неправильные объявления: ----- }
Mass : array [Min..Max] of Real;
{Нельзя использовать типизированные константы в качестве границ диапазона} a,b,c : Byte =0;
{Нельзя использовать список идентификаторов}
КОНСТАНТЫМАССИВЫ
15.2. КОНСТАНТЫ-МАССИВЫВ качестве начального значения типизированной константы-массива используется список констант, отделенных друг от друга запятыми; список заключается в круглые скобки, например:
type
colors = (white, red, black) ;
const
ColStr : array [colors] of String [5] =('white', 'red', 'blak');
Vector : array [1..5] of Byte = (0,0,0,0,0);
При объявлении массива символов можно использовать то обстоятельство, что все символьные массивы и строки в Object Pascal хранятся в упакованном формате, поэтому в качестве значения массива-константы типа char допускается задание символьной строки соответствующей длины. Два следующих объявления идентичны:
const
Digit : array [0..9] of Char =
('0', '1', '2', ' 3 ', ' 4'•, '5', '6', '7', '8', '9');
DigChr: array [0..9] of Char = '0123456789';
При объявлении многомерных констант-массивов множество констант, соответствующих каждому измерению, заключается в дополнительные круглые скобки и отделяется от соседнего множества запятыми. В результате образуются вложенные структуры множеств, причем глубина вложения должна соответствовать количеству измерений (размерности) массива. Самые внутренние множества констант связываются с изменением самого правого индекса массива.
Следующая программа выведет в компонент mmoutput три строки с монотонно увеличивающимися целыми числами:
Procedure TfmExample.bbRunClick(Sender: TObject);
var
i, j, k, 1 : Byte;
S: String;
const
Matr : array [1..3, 1..5] of Byte =
((0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10,11,12,13,14));
Cube : array [0..1, 0..1, 0..2] of Integer =
(((О ,1 ,2 ),(3 ,4 ,5 )), ((6 ,7 ,8 ),(9 ,10,11)));
Mas4 : array [0..1, 0..1, 0..1, 0..1] of Word =
((((О ,1 ),(2 ,3 )),
((4 ,5 ), (6 ,7 ))), (((8 ,9 ), (10,11)), ((12,13), (14,15))));
begin
S:=' ';
for i := I to 3 do for j := 1 to 5 do
S := S + IntToStr(Matr[i,j]) +' ';
mmOutput.Lines.Add(S);
S: = '';
for i := 0 to 1 do for j := 0 to 1 do
for k := 0 to 2 do
S := S + IntToStr(Matr[i,j,k]) +' ';
mmOutput.Lines.Add(S);
S:=''; for i := 0 to 1 do
for j := 0 to 1 do
for k := 0 to 1 do
for l := 0 to 1 do
S := S + IntToStr(mas4[i,j,k,l]:3);
mmOutput.Lines.Add(S) ;
end;
Количество переменных в списке констант должно строго соответствовать объявленной длине массива по каждому измерению.
КОНСТАНТЫЗАПИСИ
15.3. КОНСТАНТЫ-ЗАПИСИОпределение константы-записи имеет следующий вид:
<идентификатор> : <тип> = (<сп.знач.полей>)
Здесь <идентификатор> - идентификатор константы; <тип> - тип записи; <сп. знач. полей> - список значений полей.
Список значений полей представляет собой список из последовательностей вида: имя поля, двоеточие и константа. Элементы списка отделяются друг от друга двоеточиями, например:
type
Point = record
X, Y : Real end;
Vect = array [0..1] of Point;
Month = (Jan, Feb, Mar, Apr, May, Jun, Jly, Aug, Sep, Oct, Nov, Dec) ;
Date = record
D : 1..31;
M : month;
Y : 1900..1999 end;
const
Origon : Point = (X : 0; Y : -1) ;
Line : Vector =
((X : -3.1; Y : 1.5), (X : 5.9; Y : 3.0));
SomeDay : Date = (D : 16; M : May; Y : 1997);
Поля должны указываться в той последовательности, в какой они перечислены в объявлении типа. Если в записи используется хотя бы
одно поле файлового типа, такую запись нельзя объявить типизированной константой. Для записей с вариантными полями указывается только один из возможных вариантов констант. Например:
type
For.gif" >
КОНСТАНТЫМНОЖЕСТВА
15.4. КОНСТАНТЫ-МНОЖЕСТВАЗначение типизированной константы-множества задается в виде правильного конструктора множества, например:
type
Days = set of 1..31;
Digc = set of ' 0 ' . . ' 9 ';
Error = set of 1..24;
const
WorkDays : Days = [1..5, 8..12, 15..19, 22..26, 29, 30];
EvenDigits: Digc = ['0', '2', '4', '6', '8'];
ErrorFlag : Error= [];
КОНСТАНТЫУКАЗАТЕЛИ
15.5. КОНСТАНТЫ-УКАЗАТЕЛИЕдинственным значением типизированной константы-указателя может быть только nil, например:
const pR : ^Real = NIL;
ИНИЦИАЦИЯ ПЕРЕМЕННЫХ
15.6. ИНИЦИАЦИЯ ПЕРЕМЕННЫХВо всех 32-разрядных версиях Delphi при объявлении глобальных переменных разрешается одновременно присваивать им значения (инициировать). Речь идет о глобальных переменных, объявляемых в интерфейсной или исполняемой частях модулей (переменные, объявляемые в теле процедуры, называются локальными, их инициировать нельзя).
Инициированная переменная получает присвоенное ей значение один раз - в момент старта программы; в дальнейшем она хранит последнее присвоенное ей значение. Пример инициации переменной:
unit Unit1.
implementation var
MyVar: Integer = 10;
end.
Инициировать переменные следует с учетом тех же ограничений и по тем же правилам, что и типизированные константы.
TPanel панель
18.1.15. TPanel - панель
Компонент TPanel (панель) представляет собой контейнер общего назначения. В отличие от TGroupBox он не имеет заголовка и поэтому менее удобен для функционального группирования элементов. С другой стороны, его свойство Caption отображается в виде текстовой строки и может использоваться для вывода сообщений. Компоненты этого класса часто помещаются на форму для того, чтобы располагать вставленные в них дочерние компоненты вдоль одной из сторон окна независимо от изменения размеров этого окна (см. учебный пример в гл. 5).
Компонент имеет развитые средства создания различных эффектов трехмерности за счет использующихся в нем двух кромок -внешней и внутренней (см. п. 17.4).
Свойства компонента:
| type TAlignment = (taLeftJustify, taRightJustify, taCenter) ; property Alignment: TAlignment; | Определяет выравнивание текста относительно границ компонента |
| type TBevelCut = (bvNone, bvLow-ered, bvRaised, bvSpace) ; | Определяет вид внутренней кромки: bvNone - кромки нет; bvLowered - вдавленная кромка; bvRaised - приподнятая кромка; bvSpace - то же, что и bvRaised |
| property BevelInner: TPanelBevel; | Определяет вид внешней кромки |
| property BevelOuter: TPanelBevel; type TBevelWidth = l..MaxInt; | Определяет толщину кромок |
| property BevelWidth: TBevelWidth; TBorderStyle = bsNone..bsSingle; property BorderStyle: TBorderStyle; | Определяет стиль рамки: bsNone - нет рамки; bsSingle - компонент по периметру обводится линией толщиной в 1 пиксель |
| property FullRepaint: Boolean; | Разрешает/запрещает перерисовку панели и всех ее дочерних элементов при изменении ее размеров |
| property Locked: Boolean; | Используется при работе с объектами OLE |
TStatusBar информационная панель
18.3.15. TStatusBar - информационная панельКомпонент TStatusBar предназначен для создания панелей состояния, которые обычно располагаются в нижней части основной формы. Компонент может иметь несколько секций, а также кнопку изменения размеров окна, в которое он помещен.
TValueListEditor специализированный редактор строк
18.2.15. TValueListEditor - специализированный редактор строкЭтот компонент введен в версии 6 и предназначен для редактирования списков строк вида имя=значение. Такие списки широко используются в реестре Windows и файлах инициализации. Наконец. начиная с версии 5 Delphi по умолчанию в таком формате хранит файлы описания форм dfm. Если на пустую форму положить компонент TValueListEditor, диалог TOpenDialog и кнопку TBitBtn, то после загрузки в редактор файла Example. dfm (для учебной формы, описанной в гл. 5) получим экран, показанный на Рисунок 18.17. Обработчик нажатия кнопки имеет такой вид:
procedure TFor.gif" >
КЛАСС EXCEPTION ОБРАБОТКА ИСКЛЮЧЕНИЙ
16.1. КЛАСС EXCEPTION - ОБРАБОТКА ИСКЛЮЧЕНИЙКласс Exception является прямым потомком базового класса тоь-ject. Вместе со своими потомками он предназначен для обработки исключительных ситуаций (исключений), возникающих при некорректных действиях программы: например, в случае деления на ноль, при попытке открыть несуществующий файл, при выходе за пределы выделенной области динамической памяти и т. п. В этом разделе рассматриваются основные свойства исключений и их использование для повышения надежности программ.
Примечание
Примечание
При работе в среде Delphi эксперименты с исключениями плохо прослеживаются, т. к. при каждом исключении среда; перехватывает управление программой. В этом случае бывает полезно отменить такое поведение среды. Для этого вызовите опцию Tools. [.- -Debugger Options и на странице Languaqe Exception уберите флажок в переключателе Stop on delphi. Exceptions (для шэсдьиуш-лх версий Delphi выберите опцию меню Tools | Environent: Options и на странице Preference уберите флажок в персключателе Break on exception).
КЛАСС TLIST СПИСКИ
16.2. КЛАСС TLIST - СПИСКИКласс TList позволяет создать набор из произвольного количества элементов и организовать индексный способ доступа к ним, как это делается при работе с массивом. Списки отличаются от массивов двумя важными особенностями. Во-первых, их размер может динамически меняться в ходе работы программы, фактически ограничиваясь лишь доступной памятью. Во-вторых, в списках могут храниться элементы разных типов.
Технически списки представляют собой массивы нетипизированных указателей на размещенные в динамической памяти элементы. Эти массивы размещаются в куче - отсюда возможность динамического изменения размеров списков; с другой стороны, входящие в списки нетипизированные указатели позволяют ссылаться на произвольные элементы.
Свойства класса:
| property List: pPointerList; | Возвращает указатель на массив элементов списка |
| property Capacity: Integers; | Содержит количество элементов массива указателей списка. Всегда больше Count. Если при добавлении очередного элемента Count стало равно Capacity, происходит автоматическое расширение списка на 16 элементов |
| property Count: Integer; | Количество элементов списка. Это свойство изменяется при добавлении или удалении элемента |
| property Items(Index: Integer): Pointers; | Возвращает указатель на элемент списка по его индексу. Самый первый элемент списка имеет индекс 0 |
type
pPointerList = PPointerList;
TPointerList = array [0..MaxListSize] of Pointer;
Константа MaxListSize для Delphi 1 ограничена значением 16379 элементов. Для старших версий Delphi она ограничивается доступной памятью.
Следует учесть, что свойство count определяет количество помещенных в список элементов, в то время как capacity - текущую емкость списка. Если при добавлении очередного элемента обнаруживается, что емкость списка исчерпана, происходит наращивание емкости на фиксированную величину (для count < 5 - на 4 элемента, для 4 < count < 8 - на 8, для Count > 7 - на 16). При этом сначала резервируется память для размещения расширенного массива указателей, затем в нее копируется содержимое старого массива, после чего старый массив указателей уничтожается (занимаемая им память возвращается Windows).
Примечание
Примечание
Если вы заранее знаете, сколько элементов необходимо поместить :в список, установите в начале работы нужное значение в свойство Саpacity - это снизит непроизводительные затраты времени на расширение списка.
Методы класса:
| function Add(Item:
Pointer): Integer; procedure Clear; |
Добавляет элемент item в конец ci;
вращает его индекс Очищает список, удаляя из него вес Не освобождает память, связанную удаленным элементом. Устанавлив: ства Count и Capacity значение 0 |
| procedure Delete(Index:Integer); | Удаляет из списка элемент с индекс все элементы, расположенные за удаляемым, смещаются на одну позицию вверх |
| class procedure Er
ror(const Msg: Stringy; Data: Integer); virtual; |
Возбуждает исключение ElistErr метрами Msg и Data |
| procedure Ex
change (Indexl, Index2:Integer) ; |
Меняет местами элементы с индексами index1 иI ndex2 |
| function Expand: TList; function Extract(Item: Pointer): Pointer; | Расширяет массив, увеличивая Capacity Удаляет из списка элемент Item |
| function First: Pointer; | Возвращает указатель на самый первый элемент списка |
| function IndexOf(Item:Pointer): Integer; | Отыскивает в списке элемент Item и возвращает его индекс |
| procedure Insert(Index:
Integer; Item: Pointer) ; |
Вставляет элемент Item в позицию Index списка: новый элемент получает индекс Index, все элементы с индексами Index и больше увеличивают свой индекс на 1. При необходимости расширяет список |
| function Last: Pointer; | Возвращает указатель на последний элемент
списка |
| procedure Move(Curlndex,
Newlndex: Integers; |
Перемещает элемент в списке с позиции CurIndex в позицию Newlndex. Все элементы старого списка с индексами от Curlndex-1 до Newlndex уменьшают свой индекс на 1 |
| procedure Pack; | Упаковывает список: удаляет пустые элементы в конце массива индексов |
| function Remove(Item:
Pointer): Integer; |
Отыскивает в списке элемент Item и удаляет его |
| procedure Sort(Compare: rListSortCompare); | Сортирует коллекцию с помощью функции Compare |
Например:
var
List: TList;
Item: Pointer;
Value: AnyType;
begin
List := TList.Create; // Создаем список
Item := New(Value); // Размещаем в куче данные
List.Add(Item); // Добавляем элемент к списку .....
List.Remove(Item); // Удаляем элемент из списка
Dispose(Item); // Удаляем его из кучи
List.Free; // Удаляем ненужный список
end;
Метод sort сортирует список по критерию, устанавливаемому функцией compary. Тип TListSortCompare определен следующим образом:
TListSortCompare = function(Iteml, Item2: Pointer): Integer;
Таким образом, функция compare получает указатели на два элемента списка. Результат сравнения:
В следующем примере в список List помещается 20 случайных вещественных чисел, равномерно распределенных в диапазоне 0...1.
Список сортируется по возрастанию чисел и отображается в компоненте mmOutput (многострочный редактор из учебной формы fmExample).
type
PDouble = ^Double;
Function Comp(Iteml, Item2:. Pointer): Integer;
// С помощью этой функции реализуется сортировка чисел
begin
if PDouble(Iteml)^ < PDouble(Item2) ^ then
Result := -1 else
if PDouble(Iteml^ > PDouble (Item2) ^ then
Result := 1 else
Result := 0 end;
procedure TfmExample.bbRunClick(Sender: TObject);
// Обработчик нажатий кнопки bbRun выполняет основную работу
var
k: Integer;
List: TList;
pD: PDouble;
begin
List := TList.Create; // Создаем список
for k := 1 to 20 do // Наполняем его
begin
New(pD); // Резервируем память
pD^ := Random; // Помещаем в нее случайное число
List.Add(pD); // Добавляем к списку
end/List. Sort (Comp) ; // Сортируем список по возрастанию mmOutput.Lines.Clear;
{ Очищаем редактор mmOutput. В следующем цикле наполняем mmOutput и уничтожаем элементы List }
for k := 0 to List.Count-1 do
begin
pD := List[k]; // Очередное число из списка
mmOutput. Lines .Add (FloatToStr (pD^ );
{Помещаем в mmOutput}
Dispose(pD) // Уничтожаем число
end;
List.Free; // Уничтожаем список
end;
КЛАССЫ TSTRINGS И TSTRINGLIST НАБОРЫ СТРОК И ОБЪЕКТОВ
16.3. КЛАССЫ TSTRINGS И TSTRINGLIST НАБОРЫ СТРОК И ОБЪЕКТОВ16.3.1. TStrings
Абстрактный класс TStrings инкапсулирует поля и методы для работы с наборами строк. От него порождены многочисленные специализированные потомки, обслуживающие наборы строк в таких компонентах, как TComboBox, TListBox, TRichEdit и др. Эти классы
(TComboBoxStrings, TListBoxStrings, TRichEditStrings и др.) объявляются в разделах Implementation соответствующих модулей (Stdctris, Сomctris и др.) и поэтому скрыты от браузера Delphi и не включены в Help-службу. Единственным доступным наследником TStrings является TStringList - полнофункциональный класс общего назначения.
Замечательной особенностью TStrings и его потомков является то обстоятельство, что элементами наборов служат пары строка-объект, в которых строка - собственно строка символов, а объект - объект любого класса Delphi. Такая двойственность позволяет сохранять в TStrings объекты с текстовыми примечаниями, сортировать объекты, отыскивать нужный объект по его описанию и т. д. Кроме того, в качестве объекта может использоваться потомок от TStrings, что позволяет создавать многомерные наборы строк.
Свойства класса:
| property Capacity: Integer; | Текущая емкость набора строк |
| property CommaText: String; | Служит для установки или получения всего набора строк в виде единой строки с кавычками и запятыми (см. ниже пояснения) Текущее количество строк в наборе. |
| property Count: Integer; | Интерпретирует все строки списка в виде одной длинной строки |
| property DelimitedText: String; | Каждая строка окружается символами QuoteChar и отделяется от соседней символом Delimiter |
| property Delimiter: Char; | Символ для выделения строк в свойстве DelimitedText |
| property Names[Index: Integer] : String; | Для строки с индексом Index возвращает часть Name, если это строка вида Name=Value, в противном случае возвращает пустую строку |
| property Objects[Index: Integer] : TObject; | Открывает доступ к объекту, связанному со строкой с индексом Index |
| property QuoteChar: Char; | Символ для разделения строк в свойстве DelimitedText |
| property Strings[Index: Integer] : String; | Открывает доступ к строке с индексом Index |
| property StringsAdapter: TStringsAdapter; | Это свойство используется только при разработке компонентов, отвечающих стандарту Act iv |
| property Text: String; | Интерпретирует набор строк в виде одной длинной строки с разделителями eoln между отдельными строками набо |
| property Values[const Name: String]: String; | По части Name отыскивает в наборе и возвращает часть Value для строк вида
Name=Valu |
Свойство commaText интерпретирует содержимое набора строк в виде одной длинной строки с элементами вида "первая строка", "вторая строка", "третья строка" и т. д. (каждая строка набора заключается в двойные кавычки и отделяется от соседней строки запятой; если в строке встречается символ “"”, он удваивается). Свойство Text интерпретирует содержимое набора в виде одной длинной строки с элементами, разделенными стандартным признаком eoln (#13#10).
Свойства Names И Values обрабатывают строки вида Name=Value.
Такие строки широко используются в различных файлах инициации, например, в файле win. ini. Методы класса:
| function Add(const S: String) : Integer;
function AddObject(const S:String; aObject: TObject):Integer; |
Добавляет строку в набор данных и возвращает ее индекс добавляет строку и объект в набор данных |
| procedure AddStrings( Strings: TStrings); | Добавляет к текущему набору новый набор строк |
| procedure Append(const S:String) ; | То же, что Add, но не возвращает индекс вставленной строки |
| procedure Assign(Source: TPersistent) ; | Уничтожает прежний набор строк и загружает из Source новый набор. В случае не удачи возникает исключение EсоnvertError |
| procedure BeginUpdate; | Устанавливает флаг начала обновления.
До вызова EndUpdate блокируется сортировка строк, что ускоряет процесс много кратного изменения данных |
| procedure Clear; | Очищает набор данных и освобождает связанную с ним память |
| procedure Delete(Index: Integer) ; | Уничтожает элемент набора с индексом Index и освобождает связанную с ним память |
| procedure EndUpdate; | Сбрасывает флаг изменения и при необходимости сортирует строки |
| function Equals(Strings:TStrings): Boolean; | Сравнивает построчно текущий набор данных с набором Strings и возвращает True, если наборы идентичны |
| procedure Exchange(Indexl,
Index3: Integers; |
Меняет местами строки с индексами Index1 и Index2. Если объект сортируется, вызывает исключение EstringListError |
| function GetObject(Index:Integer): TObject; virtual; | Возвращает объект, связанный со строкой Index |
| function GetText: PChar; | Загружает строки из единого массива, в котором они отделяются друг от друга признаком EOLN |
| function IndexOf(const S:
String): Integer; |
Для строки S возвращает ее индекс или -1, если такой строки в наборе нет |
| function IndexOfName(const Name: String): Integer; | Возвращает индекс первой строки вида Name=Value, в которой часть Name совпадает с параметром обращения |
| function IndexOfObject (aObject: TObject): Integer; | Для объекта aObj ect возвращает индекс строки или -1, если такого объекта в наборе нет |
| procedure Insert(Index: In
teger; const S: Strings; |
Вставляет строку в набор и присваивает ей индекс Index |
| procedure InsertObject (Index: Integer; const S: String; aObject: TObject) | Вставляет строку и объект в набор и присваивает им индекс Index |
| procedure LoadFromFile (const FileName: Strings; | Загружает набор из файла |
| procedure LoadFromStream (Stream: TStream) ; | Загружает набор из потока |
| procedure Move(Curlndex, Nwlndex: Integers; | Перемещает строку из положения Curlndex в положение Newlndex |
| procedure SaveToFile(const FileName: Strings; | Сохраняет набор в файле |
| procedure SaveToStream (Stream: TStream) ; | Сохраняет набор в потоке |
| procedure SetText(Text:
PChar); |
Выгружает строки в единый массив, в ко
тором они отделяются друг от друга при знаком EOLN |
образом делает доступными во всех потомках, но он при этом не накладывает никаких ограничений на то, как располагаются в памяти строки и объекты. Каждый потомок решает эту задачу наиболее удобным для него способом. Например, потомок TStringList располагает строки и объекты в общей динамической памяти, для чего перекрывает все абстрактные методы своего родителя. Замечу, что? если вы создадите экземпляр класса TStrings с помощью его конструктора Create, компилятор предупредит вас о том, что этот экземпляр содержит абстрактные методы, так что пользоваться им нужно лишь в исключительных случаях.
ГРАФИЧЕСКИЙ ИНСТРУМЕНТАРИЙ
16.4. ГРАФИЧЕСКИЙ ИНСТРУМЕНТАРИЙБогатство изобразительных возможностей Windows связано с так называемым дескриптором контекста графического устройства DC (Device Context) и тремя входящими в него инструментами - шрифтом, пером и кистью. В Delphi созданы специализированные классы-надстройки, существенно упрощающие использование графических инструментов Windows: для контекста - класс TCanvas, для шрифта - TFont, для пера - ТРеп и для кисти - TBrush.
Связанные с этими классами объекты автоматически создаются для всех видимых элементов и становятся доступны программе через свойства Canvas, Font, Pen и Brush.
TActionList механизм действий
18.1.16. TActionList - механизм действийЭтот компонент впервые введен в Delphi 4. Он не имеет видимого изображения и служит для поддержки механизма действий (см. п. 17.7).
Основная схема его использования такова. Вначале с помощью его редактора создается действие - объект класса TAction (редактор вызывается двойным щелчком на компоненте либо с помощью опции ActionList Editor его вспомогательного меню, которое раскрывается после щелчка на нем правой кнопкой мыши - Рисунок 18.8).
Этот объект (на рисунке он имеет умалчиваемое имя Action1) имеет ряд свойств и событий, с помощью которых уточняется характер действия. Доступ к этим свойствам и событиям можно получить с помощью окна Инспектора объектов. С действием можно связать группу свойств (Caption, Checked, Enabled, Shortcut И Т. Д.), которыне будут помещаться в одноименные свойства компонентов, реализующих общее действие. Если с компонентом связан контейнер пиктограмм типа TImageList (свойство images - не действия, а самого компонента TActionList), при реализации действия можно использовать одну из хранящихся в нем пиктограмм (ImageIndex). Чтобы действие подкреплялось программным кодом, для него обязательно следует определить обработчик события OnExecute.
В свойства Action тех компонентов, активизация которых должна сопровождаться одним и тем же действием (например, в свойства Action опции меню и кнопки инструментальной панели), помещается имя только что определенного действия (Actioni). В результате выбор опции или нажатие кнопки вызовут один и тот же метод (OnExecute), в меню появится пиктограмма (imageindex), такая же пиктограмма будет у кнопки, у них будет одинаковые названия (caption), оперативные подсказки (Hint) И Т. Д.
Свойства компонента:
| property ActionCount: Integer; | Содержит количество определенных в компоненте действии (только для чтения) |
| property Actions[Index: Integer]: TContainedAction; | Позволяет программе обратиться к нужному действию (объекту класса TContainedAction) по его индексу index |
| property Images: TCustomImageList; | Содержит имя компонента класса TimageList |
| type TActionListState = (asNormal, asSuspended, asSus-pendedEnabled) ; property State: TActionListState; | Состояние действий: asNormal - нормальное; asSuspended - механизм действий отключен, их свойства Enabled не изменены; asSuspendedEnabled - механизм действий отключен, но их свойства Enabled имеют значения True |
Свойства TAction:
| property Caption: String; | Содержит строку, которая будет устанавливаться в свойствах caption всех компонентов, связанных данным действием |
| property Checked: Boolean; | Содержит значение, которое будет устанавливаться в свойствах Checked |
| property DisableIfNoHandler: Boolean; | Указывает, будут ли запрещены для выбора связанные компоненты, если для действия не определен обработчик OnExecute |
| property Enabled: Boolean; | Содержит значение, которое будет устанавливаться в свойствах Enabled |
| property HelpContext: THelpContext; | Содержит значение, которое будет устанавливаться в свойствах HelpContext |
| property Hint: String; | Содержит строку, которая будет устанавливаться в свойствах Hint |
| property Imagelndex: Integer; | Содержит индекс изображения в хранилище, указанном в свойстве images компонента. Это изображение будет связано с компонентами данного действия |
| property Shortcut: TShortCut; | Содержит значение, которое будет устанавливаться в свойствах shortcut |
| property Visible: Boolean; | Содержит значение, которое будет устанавливаться в свойствах visible |
TToolBar и ToolButton инструментальная
18.3.16. TToolBar и ToolButton - инструментальная панель и кнопки для нееКомпонент TToolBar представляет собой специальный контейнер для создания инструментальных панелей. Главная отличительная черта TToolBar - его способность гибкого управления дочерними элементами, которые он может группировать, выравнивать по размерам, располагать в несколько рядов. Компонент может манипулировать любыми вставленными в него дочерними элементами, но все его возможности в полной мере проявляются только со специально для него разработанным компонентом TToolButton (инструментальная кнопка). Этот компонент похож на кнопку TSpeedButton, но не ищите его в палитре компонентов - его там нет. Поскольку он разработан специально для TToolBar, вставить его в инструментальную панель можно только после щелчка правой кнопкой на компоненте TToolBar и выборе NewButton или NewSeparator (сепараторы предназначены для функционального выделения на инструментальной панели групп элементов и представляют собой разновидности кнопок TTooiButton). Компонент TTooiButton не имеет свойства, предназначенного для хранения картинки, однако TToolBar умеет использовать контейнер TimageList, чтобы извлечь из него нужную картинку и поместить ее на инструментальную кнопку.
Методику использования TToolBar совместно с TToolButton рассмотрим на примере программы, окно которой показано на Рисунок 18.32.
ИЕРАРХИЯ КОМПОНЕНТОВ
17.1. ИЕРАРХИЯ КОМПОНЕНТОВВсе компоненты Delphi порождены от класса TComponent, в котором инкапсулированы самые общие свойства и методы компонентов. Предком TComponent является класс TPersistent, который произошел непосредственно от базового класса TObject.
Класс TPersistent передает своим потомкам важный виртуальный метод
procedure Assign(Source: TPersistent);
с помощью которого поля и свойства объекта source копируются в объект, вызвавший метод Assign.
Замечу, что обмениваться данными могут все наследники TPersistent независимо от того, находятся ли они в непосредственном родстве по отношению друг к другу или имеют единственного общего Предка - TPersistent.
Класс TComponent служит базой для создания как видимых, так и невидимых компонентов.
Большинство видимых компонентов происходит от класса ТСоntrol. Два наследника этого класса - TWinControl И TGraphicControопределяют две группы компонентов: имеющие оконный ресурс rwincontroi и его потомки) и не имеющие этого ресурса TGraphicControl и его потомкам и).
Оконный ресурс - это специальный ресурс Windows, предназначенный для создания и обслуживания окон. Только оконные компоненты способны получать и обрабатывать сообщения Windows.
Оконный компонент в момент своего создания обращается к Windows с требованием выделения оконного ресурса и, если требование удовлетворено, получает так называемый дескриптор окна. TWinControl и его потомки хранят дескриптор окна в свойстве Handle.
Программист может использовать этот дескриптор для непосредственного обращения к API-функциям Windows. 1 Потомки TGraphicControl не требуют от Windows дефицитного оконного ресурса, но они и не могут получать и обрабатывать Win-jows-сообщения - управляет такими элементами оконный компонент-владелец (например, форма), который является посредником между Windows и не оконными компонентами.
ПОДДЕРЖКА СПРАВОЧНОЙ СЛУЖБЫ
17.10. ПОДДЕРЖКА СПРАВОЧНОЙ СЛУЖБЫВсе видимые элементы имеют свойства
property Hint: String;
property ShowHint: Boolean;
регулирующие появление и содержание ярлычка - небольшого справочного окна возле элемента, на котором остановился курсор. Ярлычки существенно облегчают начинающему пользователю знакомство с программным продуктом. Введение механизма ярлычков во все видимые компоненты легко решает проблему создания дружественного программного интерфейса в современном стиле.
Чтобы компонент смог показать ярлычок, нужно поместить текстовую строку в его свойство Hint и присвоить свойству showHint значение True. Обычно ярлычок содержит максимально лаконичный текст, чтобы не отнимать слишком большую площадь экрана. Вы можете дополнить этот текст развернутым сообщением в любом компоненте, который способен отображать текст. Как правило, это панель статуса, занимающая нижнюю часть формы. Чтобы отобразить <<длинное” сообщение, его нужно прежде всего поместить в строку Hint сразу после “короткого” и отделить обе части символом “[”.
Например:
MyControl.Hint := 'Подсказка!Развернутое сообщение';
Далее, необходимо в самом начале программы (обычно в обработчике события Oncreate главной формы) указать программе метод, который будет обрабатывать событие onHint. Это событие возникает в момент появления ярлычка и предназначено для отображения длинного сообщения, которое метод-обработчик может получить в свойстве Hint глобального объекта Application.
Например:
type
TFor.gif" >
ПОДДЕРЖКА СОМ
17.11. ПОДДЕРЖКА СОММодель компонентных объектов СОМ (Component Object Model) представляет собой технологию обмена объектами между разными приложениями и даже между разными сетевыми машинами. Эта технология усиленно развивается Microsoft и в перспективе может привести к тому, что ваша программа сможет использовать объект (напомню, что объект - это фрагмент исполняемого кода), установленный на машине, находящейся в другой части света и не относящейся к тому же классу, что и ваша машина, т. е. написанный на другом языке программирования и реализованный другим набором машинных инструкций!
В основе СОМ лежат те же идеи, что и в OLE, с той разницей, что СОМ-сервер может выполнять обработку СОМ-клиента на машине сервера.
Разумеется, и сервер, и клиент в технологииСОМ могут быть установлены на одной и той же машине, однако в OLE это фактически является обязательным требованием. Если клиент и сервер выполняются на разных машинах, реализуется распределенный вариант СОМ - DCOM (Distributed Component Object Model).
В Delphi включены средства поддержки СОМ как в виде готовых компонентов (например, DCOMConnection), так и на уровне класса TComponent, т. е. относящиеся ко всем компонентам Delphi.
Свойство этого класса
property ComObject:IUnknown;
возвращает интерфейс СОМ-объекта, если данный компонент поддерживает технологию СОМ. Если это не так, обращение к свойству возбудит исключительную ситуацию EComponentError.
Свойство
property VCLComObject: Pointer;
предназначено для внешнего использования (т. е. для экспорта СОМ-объекта) и поставляет ссылку на СОМ-объект Delphi.
СВОЙСТВА РАЗНОГО НАЗНАЧЕНИЯ
17.12. СВОЙСТВА РАЗНОГО НАЗНАЧЕНИЯУзнать текущее состояние любого управляющего элемента на этапе прогона программы можно с помощью свойства
type TControlState = set of (csLButtonDown, csClicked, csPalette, csReadingState, csAlignmentNeeded, csFocusing, csCreat-ing, csCustomPaint, ceDestroyingHandle);
property ControlState: TControlState;
класса TControl.
Элементы множества TControlState имеют следующий смысл:
| csLButtonDow | Над элементом была нажата и еще не отпущена левая кнопка мыши |
| n csClicked | То же, что csLButtonDown, но устанавливается, если стиль компонента (см. ниже) содержит флаг csClickEvents и означает, что нажатие кнопки интерпретируется как щелчок |
| csPalette | Элемент или его родитель получил сообщение
WMPALETTCHANGED |
| csReadingState | Элемент читает данные из потока |
| csAlignmentNeeded | Элемент нуждается в перерисовке, т. к. изменилось его свойство Alignment |
| csFocusing | Программа пытается передать элементу фокус ввода |
| csCreating | Элемент и/или его родительские и дочерние элементы находятся в стадии создания. Флаг очищается после завершения процесса |
| csCustomPaint | Элемент перерисовывается |
| csDestroyingHandle | Разрушается Windows-дескриптор элемента |
type TControlStyle = set of (csAcceptsControls, csCaptureMouse, csDesignInteractive, csFramed, csClickEvents, csSetCaption, csOpaque, csDoubleClicks, csFixedWidth, csFixedHeight, csNoDesignVisible, csReplicatable, csNoStdEvents, csDisplayDraglmage, csReflector, csActionClient, csMenu.gif" >
ИМЕНА И СОБСТВЕННИКИ КОМПОНЕНТОВ
17.2. ИМЕНА И СОБСТВЕННИКИ КОМПОНЕНТОВКласс TComponent включает в себя свойства и методы, общие для всех компонентов.
Свойство
property Name: TComponentName;
type TComponentName = String; // Delphi 32
type TComponentName = String[63]; // Delphi 1
определяет имя компонента. Имя компонента строится по тем же правилам, что и имена любых других объектов программирования - констант, переменных, подпрограмм и т. д.: оно представляет собой правильный идентификатор и должно быть уникальным в области своей видимости в программе. Так как компоненты помещаются на форму средой Delphi, каждый компонент автоматически получает создаваемое средой имя, совпадающее с именем своего класса (без начальной буквы Т) и дополненное числовым суффиксом: For.gif" >
РОДИТЕЛЬСКИЕ И ДОЧЕРНИЕ КОМПОНЕНТЫ
17.3. РОДИТЕЛЬСКИЕ И ДОЧЕРНИЕ КОМПОНЕНТЫКласс TControl со своими наследниками образуют всю палитру видимых компонентов Delphi. Терминологически они называются элементами управления, так как на их основе прежде всего реализуются управляющие элементы Windows - кнопки, переключатели, списки и т. п. В тексте книги я часто буду употреблять слова компонент и элемент как синонимы.
Как уже отмечалось, некоторые из наследников TControl обладают дескрипторами окон и способны получать и обрабатывать Wwdows-сообщения, другие окон не имеют, но обязательно включаются в состав оконных компонентов, которые управляют ими, согласуясь с требованиями (сообщениями) Windows. Оконные элементы управления обладают специальной оконной функцией, в которую Windows посылает управляющие сообщения (например, извещения о манипуляции пользователя с мышью или о нажатии клавиш клавиатуры). В терминологии Windows такие элементы называются родительскими, а связанные с ними неоконные элементы - дочерними. Замечу, что оконный компонент может выступать как родительский не только по отношению к неоконным компонентам, но и к оконным. В этом случае он просто транслирует управляющие сообщения Windows в оконные функции дочерних компонентов. Обязательным требованием Windows является визуальная синхронизация дочерних элементов: они не могут выходить из границ своего родителя и появляются и исчезают вместе с ним. Иными словами, родитель с дочерними элементами рассматривается Windows как единое целое.
Класс TControl определяет свойство parent, которое содержит ссылку на родительский компонент:
property Parent: TWinControl;
Это свойство не следует путать с собственником owner: owner создал компонент (не обязательно - видимый), a parent управляет видимым компонентом. поскольку конструктор TComponent. Create не изменяет свойства parent (в родительском классе TComponent такого свойства нет), при создании видимых компонентов на этапе прогона программы это свойство необходимо изменять программно. Например, Следующий обработчик События OnCreate формы For.gif" >
ПОЛОЖЕНИЕ РАЗМЕРЫ И ОФОРМЛЕНИЕ КОМПОНЕНТОВ
17.4. ПОЛОЖЕНИЕ, РАЗМЕРЫ И ОФОРМЛЕНИЕ КОМПОНЕНТОВПоложение и размеры компонента определяются четырьмя его свойствами (в пикселях):
property Height: Integer; // Высота
property Left: Integer;// Положение левой кромки
property Top: Integer;// Положение верхней кромки
property Width: Integer;// Ширина
Для всех компонентов, кроме форм, эти свойства задаются в координатах клиентской части родительского компонента. Для формы - в координатах экрана. Клиентская часть компонента - это внутренняя его область за исключением заголовка, рамки и меню. Свойства обычно определяются на стадии конструирования формы, но они доступны также и на этапе прогона программы. Изменение любого из них приводит к немедленному изменению положения или размера компонента как на этапе конструирования, так и при прогоне программы. Все четыре числовые величины содержатся также в единственном свойстве
property BoundsRect: TRect;
type
TPoint = record X: Longint;
Y: Longint;
end;
TRect = record case Integer of
0: (Left, Top, Right, Bottom: Integer);
1: (TopLeft, BottomRight: TPoint);
end;
Это свойство удобно использовать при прорисовке компонента методом TCanvas . FrameRect.
В некоторых случаях бывает необходимо пересчитать относительные координаты точки внутри клиентской части в абсолютные координаты экрана и наоборот. Эта задача решается двумя методами Control:
function ClientToScreen(const Point: TPoint): TPoint;
function ScreenToClient(const Point: TPoint): TPoint;
Важную роль играет свойство Align, определяющее выравнивание положения компонента относительно границ своего родителя:
type TAlign = (aINone, alTop, alBottom, alLeft, alRight, alClient) ;
property Align: TAlign;
Если это свойство не равно aiNone, компонент прижимается к верхней (alTop), нижней (alBottom), левой (alLeft) или правой (alRight) границе своего родителя. При этом размеры компонента по соседним с границей измерениям игнорируются, и компонент “растекается” по границе. Например, если Align=alTop, значения свойств компонента Left и width игнорируются и его прямоугольник будет занимать всю верхнюю часть клиентской области родителя высотой Height пикселей; если Align=alLeft, свойства тор и Height игнорируются и прямоугольник занимает левую часть родителя шириной width пикселей и т. д. Если несколько компонентов имеют одинаковое выравнивание, они последовательно прижимаются друг к другу в порядке их перечисления в свойстве controls: первый прижимается к границе родителя, второй - к границе первого и т. д. Вся не заполненная другими компонентами клиентская область родителя заполняется компонентами со свойствами Align=alClient, которые в этом случае накладываются друг на друга. Замечательной особенностью свойства является его постоянство при изменении размеров клиентской части родителя. Если, например, компонент прижат к верхней границе формы, он будет неизменно занимать верхнюю часть клиентской области при любых изменениях размеров окна. Таким способом можно легко реализовать панели с инструментальными кнопками, панели статуса и т. п. Временное отключение и затем включение эффекта от свойства Align обеспечивается методами
procedure DisableAlign;
procedure EnableAlign;
Любой видимый компонент можно спрятать или показать с помощью свойства visible или методами Hide и show:
property Visible: Boolean; // True - показывает
procedure Hide; // Прячет компонент
procedure Show; // Показывает компонент
Спрятанный компонент не реагирует на события от мыши или клавиатуры, он не участвует в дележе клиентской области родителя, ему нельзя передать фокус ввода клавишей Tab.
Если компонент частично или полностью перекрывается другими компонентами, его можно расположить над всеми компонентами и убрать обратно с помощью методов
procedure BringToFront; // Сделать верхним
procedure SendToBack.gif" >
УКАЗАТЕЛИ МЫШИ
17.5. УКАЗАТЕЛИ МЫШИПри перемещении указателя мыши по экрану он может менять свою форму в зависимости от свойства Cursor компонента, над которым он расположен в данный момент:
property Cursor: TCursor;
type TCursor = -32768..+32767;
В Delphi предопределены стандартные указатели, показанные на рисунке 17.2.
РЕАКЦИЯ НА СОБЫТИЯ ОТ МЫШИ И КЛАВИАТУРЫ
17.6. РЕАКЦИЯ НА СОБЫТИЯ ОТ МЫШИ И КЛАВИАТУРЫ17.6.1. События от мыши
Для большинства видимых компонентов определен набор обработчиков событий, связанных с мышью:
type
TMouseButton = (mbLeft, mbRight, mbMiddle) ;
TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft,
ssRight, ssMiddle, ssDouble);
TMouseEvent = procedure (Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer) of object;
TMouseMoveEvent = procedure(Sender: TObject;
Shift: TShiftState; X, Y: Integer) of object;
TNotifyEvent = procedure (Sender: TObject) of object-property OnMouseDown: TMouseEvent;
property OnMouseUp: TMouseEvent;
property OnMouseMove: TMouseMoveEvent;
property OnClick: TNotifyEvent;
property OnDblClick: TNotifyEvent;
Тип TMouseButton определяет одну из трех кнопок мыши: левую (mbLeft), правую (mbRigth) и среднюю (mbMiddle).
Тип TShiftState содержит признаки, уточняющие обстоятельства возникновения события: ssShift - нажата клавиша Shift; ssAit -нажата клавиша Alt; ssctri - нажата клавиша Ctrl; ssLeft - нажата левая кнопка мыши; ssRight - нажата правая кнопка; ssMiddie -нажата средняя кнопка; ssDoubie - нажаты одновременно левая и правая кнопки.
Обработчики OnMouseDown и OnMouseUp определяют реакцию программы на соответственно нажатие и отпускание кнопки мыши, оп-MouseMove - на перемещение указателя мыши над компонентом, оп-click и OnDblClick - соответственно на щелчок и двойной щелчок левой кнопки. Во всех обработчиках параметр sender содержит ссылку на компонент, над которым произошло событие, а х и y определяют координаты точки чувствительности указателя мыши в момент возникновения события в системе координат клиентской области родительского компонента. Замечу, что событие OnClick возникает после OnMouseDown, но перед OnMouseUp, а событие
OnDblClick Возникает после OnMouseUp.
МЕХАНИЗМ ДЕЙСТВИЙ ACTION
17.7. МЕХАНИЗМ ДЕЙСТВИЙ ACTIONВ Delphi 4...6 введен специальный механизм действий, дающий удобное средство централизованной реакции программы на те или иные действия пользователя. Для реализации действий в страницу Standard палитры компонентов включен специальный компонент
TActionList (CM. П. 18.1.15),
а в объект TComponent - свойство Action:
property Action: TBasicAction;
Централизация необходима потому, что подавляющее большинство промышленных программ для Windows содержат два или более интерфейсных элемента, реализующих одно и то же действие. Например, в среде Delphi некоторые команды главного меню дублируются соответствующими пиктографическими кнопками (в принципе любая команда меню Delphi может иметь кнопочный эквивалент).
Компонент TActionList содержит список названий действий и связанных с ними имен подпрограмм, которые эти действия реализуют. Чтобы связать компонент с нужным действием, достаточно раскрыть список его опции Action (этот список содержит имена всех действий во всех компонентах TActionList) и выбрать нужное название. При этом обычно меняется пиктографическое изображение и/или надпись на компоненте, а также связанная с ним оперативная подсказка (Hint). Свойство Action используется только после создания и наполнения списка (списков) TActionList.
ИНТЕРФЕЙС DRAG&DROP
17.8. ИНТЕРФЕЙС DRAG&DROPОперационная система Windows широко использует специальный прием связывания программ с данными, который называется Drag&Drop (перетащи и отпусти). Такой прием в Проводнике windows используется для копирования или перемещения файлов, а также для запуска обрабатывающей программы. Если, например, файл с расширением doc “перетащить” на пиктограмму WinWord, автоматически запустится текстовый редактор word for windows и в его окне появится текст из этого файла.
В Delphi реализован собственный интерфейс Drag&Drop, позволяющий компонентам обмениваться данными путем “перетаскивания” их мышью. Этот интерфейс определяется двумя свойствами и тремя событиями, доступными каждому видимому компоненту.[ В Delphi б события могут дублировать сложные свойства и наоборот. Сложными в данном случае называются свойства, ссылающиеся на внутренние объекты. ]
Свойство
TDragMode = (dmManual, dmAutomatic);
property DragMode: TDragMode;
определяет, как будет выполняться весь комплекс действий, связанных С Drag&Drop: dmManual - Вручную (программой); dmAutomatic -автоматически (свойствами и методами компонентов). Значение dmManual означает, что все необходимые для обслуживания интерфейса события генерируются программой, dmAutomatic - события инициируются свойствами и методами компонентов. Во всех случаях программист должен написать обработчики этих событий (см. ниже).
Свойство property DragCursor: TCursor;
определяет вид указателя мыши в момент, когда над компонентом “протаскиваются данные”. Если компонент готов принять данные, он устанавливает в это свойство значение crDrag l3, в противном случае - crNoDrag 0. Установка этих свойств осуществляется автоматически, если DragMode = dmAutomatic. Событие TDragState = (dsDragEnter, dsDragLeave, dsDragMove) ;
TDragOverEvent = procedure(Sender, Source: TObject;
X, Y: Integer; State: TDragState; var Accept: Boolean)
of object; property OnDragOver: TDragOverEvent;
возникает в момент перемещения указателя мыши “с грузом” над компонентом. Здесь sender - компонент, который возбудил событие (обычно это Self - сам компонент-получатель; при ручном управлении механизмом Drag&Drop это может быть не так); source - компонент-отправитель “груза”; х, y - текущие координаты указателя мыши в пикселях клиентской области компонента; State - состояние указателя (dsDragEnter - только что появился на компонентом; dsDragLeave -только что покинул компонент или бьша отпущена кнопка мыши;
dsDragMove - перемещается над компонентом). В параметре Accept обработчик сообщает, готов ли компонент принять данные (т rue - готов).
Событие
TDragDropEvent = procedure(Sender, Source: TObject;
X, Y: Integer) of object;
property OnDragDrop: TDragDropEvent;
означает, что пользователь “бросил” данные на компонент. Параметры обработчика совпадают по назначению с одноименными параметрами OnDragOver.
Наконец, при завершении перетаскивания (вне зависимости от того, приняты данные или нет) возникает событие TEndDragEveht = procedure(Sender, Target: TObject;X, Y: Integer) of objects; property OnEndDrag: TEndDragEvent;
где sender - отправитель данных; Target - получатель данных или nil, если никто не принял “посылку”; X, Y - координаты мыши в момент отпускания левой кнопки.
Чтобы проиллюстрировать использование механизма Drag&Drop, загрузите описанную в гл. 5 учебную программу, установите во всех ее компонентах в свойство DragMode значение dmAutomatic и создайте такой обработчик события OnDragOver для метки:
procedure TfmExample.IbOutputDragOver(Sender, Source: TObject;
X, Y: Integer; State: TDragState;
var Accept: Boolean);
begin
Accept := True;
lbOutput.Caption := (Source as TComponent).Name
end;
Теперь перетаскивание любого компонента на метку IbOutput заставит ее показать имя перетаскиваемого компонента (Рисунок 17.5).
ИНТЕРФЕЙС DRAG&DOCK
17.9. ИНТЕРФЕЙС DRAG&DOCKВ Delphi введена поддержка специального интерфейса Drag&Dock (перетащи и причаль), с помощью которого можно перетаскивать мышью компоненты на новое место. В среде Delphi этот интерфейс используется для настройки кнопок инструментальных панелей (см. гл. 2).
В интерфейсе Drag&Dock участвуют два компонента: принимающий компонент (всегда - потомок TWinControl) и перетаскиваемый компонент (потомок TControl).
Принимающий компонент должен иметь значение True в своем свойстве Docksite. Поскольку Drag&Dock является разновидностью более общего интерфейса Drag&Drop, в TControi введено дополнительное свойство
property DragKind: TDragKind;
type TDragKind = (dkDrag, dkDock) ;
с помощью которого различаются способы использования мыши: для Drag&Drop (dkDrag) или для Drag&Dock (dkDock). И у перетаскиваемого компонента, и у компонента-приемника эти свойства должны иметь значения dkDock.
Количество установленных на форме перетаскиваемых компонентов (Т. С. компонентов, у которых DragKind=dkDock И DockSite=False) Определяется свойством DockClientCount, а их список хранится в индексированном свойстве DockClients.
Для реализации Drag&Dock в класс TControl введены такие дополнительные свойства и события.
property AutoSize: Boolean;
Разрешает (True) или запрещает (False) оконному компоненту менять свои размеры автоматически в зависимости от количества и размеров содержащихся в нем дочерних компонентов. Свойство
property FloatingDockSiteClass: TWinControlClass;
определяет класс окна, в которое будет погружен дочерний элемент вне границ оконного элемента. Неоконные компоненты могут не только перетаскиваться в оконные компоненты-приемники, но и покидать их. После “отчаливания” от компонента-приемника неоконные элементы автоматически окружаются окном, тип которого содержит свойство FloatingDockSiteClass. По умолчанию это окно содержит уменьшенный по высоте заголовок и системную кнопку закрытия. В свойстве
property DockOrientation: TDockOrientation;
type TDockOrientation = (doNoOrient,doHorizontal,doVertical);
можно установить (или получить) ориентацию, которую будет иметь “причаливаемый” компонент в окне родителя: doNoOrient -сохраняется исходная ориентация перемещаемого компонента; do-Horizontal (dovertical) - компонент будет иметь горизонтальную (вертикальную) ориентацию. С помощью свойства
property LRDockWidth: Integer;
можно получить ширину последнего перемещенного компонента, который расположился горизонтально, а с помощью
property TBDockHeight: Integer;
- высоту последнего вертикально расположенного компонента.
Свойства
property UndockHeight: Integer; property UndockWidth: Integer;
определяют соответственно высоту и ширину последнего “отчалившего” компонента. Свойство
property Constraints: TSizeConstraints;
с помощью объекта класса TSizeConstraints накладывает ограничения на возможные размеры “причаливаемого” компонента (задает максимальные и минимальные величины для высоты и ширины).
События
property OnDockDrop: TDockDropEvent;
property OnDockOver: TDockOverEvent;
type TDockOverEvent = procedure(Sender: TObject; Source:
TDragDockObject; X, Y: Integer; State: TDragState;
var Accept:
Boolean) of object;
аналогичны событиямиOnDragDrop и OnDragOver (CM. П.17.7). Co6ытие
property OnGetSiteInfo: TGetSiteInfoEvent;
возникают перед событием OnDragDrop. Его обработчик должен сообщить объекту TDragDockObject, который автоматически связывается с перемещаемым объектом, некоторую дополнительную информацию (размеры, которые будет иметь принимаемый объект, будет ли он погружен в “плавающее” окно и т. п.). Наконец, событие
property OnUnDock: TUnDockEvent;
type TUnDockEvent = procedure (Sender: TObject; Client: TControl;
var Allow: Boolean) of object;
возникает при “отчаливании” неоконного компонента от своего родителя. Обработчик этого события должен поместить в Allow значение True, если компонент client может покинуть границы своего владельца sender.
Все указанные события обрабатываются автоматически, если оба компонента (клиент и сервер) содержат значение dmAutomatic в своем свойстве DragMode.
Чтобы познакомиться в действии с технологией Drag&Dock, поместите на пустую форму панель трапе! и кнопку TButton, установите для панели значение True в свойство Docksite, установите для обоих компонентов Значение dkDock в свойстваа DragKind И dmAutomatic в свойства DragMode. После запуска программы перетащите кнопку на панель, а затем стащите ее обратно.
TColorBox список выбора цвета
18.2.17. TColorBox - список выбора цветаКомпонент введен в версии 6. Он представляет собой комбинированный список, опциями которого являются цвета, т. е. предназначен для отображения и выбора цвета. В отличие от компонентов
TColorGrid (страница Samples) и TColorDialog (страница Dialogs) состав отображаемых им цветов может меняться.
Многие свойства, методы и события компонента совпадают с одноименными свойствами, методами и событиями его ближайшего родственника - компонента TCоmbоВох (см. п. 18.1.10).
Специфичные свойства компонента:
| property ColorNames[Index: Inte
ger]: Strings; |
Возвращает имя цвета по его индексу в списке выбора |
| property Colors[Index: Integer]:
TColor; |
Содержит список цветов |
| property DefaultColorColor:
TColor; |
Указывает умалчиваемый цвет. Свойство Style должно включать флаги cbSystem Colors И cbIncludeDefault |
| property NoneColorColor: TColor; | Указывает цвет “нет цвета”. Свойство Style должно включать флаги cbSystem Colors и cbIncludeNone |
| property Selected: TColor; | Указывает текущий выбранный цвет |
| type TColorBoxStyles =
(cbStandardColors, cbExtendedColors, cbSystemColors, cblnclude None, cbIncludeDefault, cbCustomColor, cbPrettyNames); TColorBoxStyle = set of TColor BoxStyles; property Style: TColorBoxStyle |
Определяет отображаемые компонентом цвета: cbStandardColors - список содержит 16 основных цветов; cbExtendedColors -список содержит дополнительные цвета, определенные в модуле Graghics; cbSystemColors - в списке отображаются цвета cIMoneyGreen,cISkyBlue,cICream и cIMedGray; cbIncludeNone -список содержит опцию cINone;cbIncludeDefault -список содержит опцию cIDefault; cbCus tomcolor - первая опция списка открывает стандартный диалог TColorDialog; cbPrettyNames - имена цветов отображаются без префикса cl |
TCoolBar и TCoolBand инструментальная
18.3.17. TCoolBar и TCoolBand - инструментальная панель и полосы для нееКомпонент TCoolBar предназначен для создания настраиваемых инструментальных панелей. Для каждого размещаемого на нем элемента TCoolBar создает объект класса TCoolBand (полоса), который может изменять свои размеры и положение в пределах границ компонента.
Следует сразу же заметить, что в отличие от TcontrolBar (страница Additional палитры компонентов) компонент TCoolBar предназначен для примерно таких же задач, но и в версии 2, где он появился впервые, и в версии б он все еще кажется “сырым”, плохо отлаженным.
Центральным свойством компонента является Bands - массив созданных в компоненте полос TCoolBand. Каждая полоса может иметь текст, пиктограмму и произвольный управляющий элемент. В отличие от ттоо1ваг или TControiBar полоса в TCoolBar всегда содержит только один интерфейсный элемент, но ничто не мешает этому элементу быть элементом-контейнером для размещения нескольких компонентов. Размещенный на полосе компонент окружен специальным окном TCoolBar и всегда стремится занять левый верхний угол полосы, при этом остальные размеры полосы изменяются так, чтобы полностью охватить элемент.
Поясним сказанное несложным примером.
КОМПОНЕНТЫ СТРАНИЦЫ STANDARD
18.1. КОМПОНЕНТЫ СТРАНИЦЫ STANDARD18.1.1. TFrame - рама и шаблоны компонентов
Этот компонент впервые введен в Delphi 5. Он определяет раму -контейнер для размещения других компонентов. В функциональном отношении компонент почти повторяет свойства формы и отличается от нее в основном лишь тем, что его можно помещать на формы или в другие рамы. Фактически рама представляет собой удобное средство создания шаблонов - произвольных наборов компонентов, максимально приспособленных для нужд конкретного пользователя. Раз созданный шаблон может подобно любому другому компоненту размещаться на форме или другой раме (допускается неограниченная вложенность рам). Замечу, что любые изменения в базовой раме (т. е. в раме, сохраненной в палитре) тут же отображаются во всех проектах, использующих данную раму.
Примечание
Примечание
Создание шаблонов - отнюдь не исключительная особенность Delphi 5 и б - соответствующие механизмы были включены и в две предыдущие версии 3 и 4. Рамы лишь упрощают процесс создания шаблонов. В конце параграфа приводится простая методика создания и использования шаблонов без рам, т. е. так, как это возможно сделать в версиях 3 и 4.
Первоначально проекту ничего не известно о, возможно, ранее созданных рамах, поэтому попытка поместить на пустую форму компонент-раму вызовет сообщение:
No frames in project.
To create a frame select File New Frame.
(В проекте нет рам. Чтобы создать раму выберите File | New Frame.)
Это сообщение и описываемая ниже методика подключения шаблонов - единственное, что отличает механизм использования шаблонов от использования стандартных компонентов.
Создадим простую раму, содержащую две кнопки - mbOk и mbCancel. Такой шаблон может пригодится при конструировании различных диалоговых окон.
КОМПОНЕНТЫ СТРАНИЦЫ ADDITIONAL
18.2. КОМПОНЕНТЫ СТРАНИЦЫ ADDITIONAL18.2.1. TBitBtn - кнопка с изображением
Пиктографическая кнопка TBitBtn представляет собой популярную разновидность стандартной кнопки TButton. Ее отличительная особенность - свойство Glyph, с помощью которого определяется растровое изображение, рисуемое на поверхности кнопки. В состав поставки Delphi входит множество рисунков, разработанных специально для размещения в этих кнопках (по умолчанию для старших версий Delphi эти рисунки размещаются в папке program Files |
Common Files | Borland Shared | Images | Buttons, для остальных версий - в папке images l Buttons каталога размещения Delphi).
Свойство Kind определяет одну из 11 стандартных разновидностей кнопки, показанных на Рисунок 18.9.
TPageControl набор страниц с закладками
18.3.2. TPageControl - набор страниц с закладкамиКомпонент TPageControl в отличие от TTabControl может содержать несколько перекрывающих друг друга панелей класса ттаь-Sheet. Каждая панель выбирается связанной с ней закладкой и может содержать свой набор помещенных на нее компонентов.
Чтобы на этапе конструирования добавить новую панель или выбрать ранее вставленную, щелкните по компоненту правой кнопкой мыши и выберите New page (новая панель), Next page (следующая панель) или previous page (предыдущая панель). Смена панелей идет циклически, т. е. после показа последней показывается первая и наоборот.
Помимо свойств HotTrack, MultiLine, ScrollOpposite, TabHeight, TabPosition и TabWidth, которые аналогичны одноименным свойствам TTabcontrol, компонент имеет следующие специфичные свойства:
| property ActivePage: TTab-Sheet; | Содержит ссылку на активную панель. Установка нового значения ActivePage размещает соответствующую панель поверх остальных. Для выбора новой панели следует использовать методы SelectNextPage и FindNextPage |
| property ActivePageIndex: Integer; | Содержит индекс активной панели |
| property PageCount: Integers; | Содержит количество панелей (только для чтения) |
| property Pages[Index: Integer] : TTabSheet; | Возвращает ссылку на панель по ее индексу (только для чтения) |
| function FindNextPage (CurPage: TTabSheet; GoFor.gif" > |
Компонент TTabControl представляет собой контейнер
18.3. КОМПОНЕНТЫ СТРАНИЦЫ WIN3218.3.1. TTabControl - набор закладок
Компонент TTabControl представляет собой контейнер с закладками. Свойство Tabs определяет названия и количество закладок. Событие onchange. возникает при выборе новой закладки и позволяет управлять содержимым окна компонента. Для примера на Рисунок 18.22 показано использование компонента для управления календарем (с помощью TTabControl созданы закладки с названиями месяцев).
Свойства компонента:
| property DisplayRect: TRect; | Определяет рабочую зону компонента, предназначенную для размещения других компонентов. Клиентская часть компонента содержит зону закладок и рабочую зону |
| property HotTrack: Boolean; | Если содержит True, название закладки автоматически выделяется цветом при перемещении над ней указателя мыши |
| property Images: TCustomImageList; | Определяет объект - хранилище изображений, которые будут прорисовываться слева от текста |
| property Multi-Line: Boolean; | Разрешает расположение закладок в несколько рядов. Если содержит False и закладки не умещаются в границах компонента, в зону закладок автоматически вставляются кнопки прокрутки |
| property OwnerDraw: Boolean; | Разрешает программную прорисовку закладок |
| property ScrollOpposite:
Boolean; |
Разрешает/запрещает перемещение неактивных рядов закладок на противоположную сторону компонента. Учитывается, если количество рядов больше 2 |
| type TTabStyle = (tsTabs,
tsButtons, tsFlatButtons) ; property Style: TTabStyle; |
Определяет стиль закладок: tsTabs - обычные
надписи; tsButtons -трехмерные кнопки; tsFlat Buttons - плоские кнопки |
| property TabHeight: Smallint; | Определяет высоту каждой закладки в пикселях.
Если содержит 0, высота закладок выбирается автоматически в зависимости от выбранного шрифта |
| property Tablndex: Integer; | Определяет индекс выбранной закладки или содержит -1, если ни одна закладка не выбрана. Индексация начинается с 0 |
| TTabPosition = (tpTop,
tpBottom) ; property TabPosition: TTab Position; |
Определяет положение зоны закладок относительно рабочей зоны компонента (tpTop - вверху, tpBottom - ВНИЗУ) |
| property Tabs: TStrings; | Определяет надписи на закладках и их количество.
Чтобы добавить или удалить закладку, нужно добавить ее надпись к списку Tabs или удалить надпись из списка |
| property TabWidth: Smallint; | Определяет ширину каждой закладки в пикселях.
Если содержит 0, ширина каждой закладки выбирается индивидуально в зависимости от длины ее надписи |
КОМПОНЕНТЫ СТРАНИЦЫ SYSTEM
18.4. КОМПОНЕНТЫ СТРАНИЦЫ SYSTEMВ этом разделе не описаны расположенные на этой странице компоненты TDDEClient, TDDEClientItem, TDDEServer И TDDEServerItem.
Они рассчитаны на поддержку устаревшей технологии межпрограммного обмена данными DDE - Dynamic Data Exchange (динамический обмен данными), которая в современных программах полностью вытеснена технологией OLE.
КОМПОНЕНТЫ СТРАНИЦЫ DIALOGS
18.5. КОМПОНЕНТЫ СТРАНИЦЫ DIALOGSВ состав Windows входит ряд типовых диалоговых окон, таких как окно выбора загружаемого файла, окно выбора шрифта, окно для настройки принтера и т. д. В Delphi реализованы классы, объекты которых дают программисту удобные способы создания и использования таких окон.
Работа со стандартными диалоговыми окнами осуществляется в три этапа.
Вначале на форму помещается соответствующий компонент и осуществляется настройка его свойств (следует заметить, что собственно компонент-диалог не виден в момент работы программы, видно лишь создаваемое им стандартное окно). Настройка свойств может проходить как на этапе конструирования, так и в ходе прогона программы. Как и для любых других компонентов, программист не должен заботиться о вызове конструктора и деструктора диалога - эти вызовы реализуются автоматически в момент старта и завершения программы.
На втором этапе осуществляется вызов стандартного для диалогов метода Execute, который создает и показывает на экране диалоговое окно. Вызов этого метода обычно располагается внутри обработчика какого-либо события. Например, обработчик выбора опции меню
Открыть файл может вызвать метод Execute Диалога TOpenDialog, обработчик нажатия инструментальной кнопки сохранить может вызвать такой же метод у компонента TSaveDialog и т. д. Только после обращения к Execute на экране появляется соответствующее диалоговое окно. Окно диалога является модальным окном, поэтому сразу после обращения к Execute дальнейшее выполнение программы приостанавливается до тех пор, пока пользователь не закроет окно. Поскольку Execute - логическая функция, она возвращает в программу True, если результат диалога с пользователем был успешным.
Проанализировав результат Execute, программа может выполнить третий этап - использование введенных с помощью диалогового окна данных - имени файла, настроек принтера, выбранного шрифта и т. д.
Проиллюстрируем сказанное следующим примером. Создадим простую программу для просмотра содержимого текстового файла. Для этого на пустую форму поместите компонент TOpenDialog, a также кнопку TButton и редактор TMето. При работе программы щелчок по кнопке будет сигналом о необходимости загрузить в редактор новый файл. Создайте такой обработчик события OnClick этой кнопки:
procedure TFor.gif" >
имеют более совершенные аналоги
18.6. КОМПОНЕНТЫ СТРАНИЦЫ WIN3.1Многие компоненты страницы win3. 1 имеют более совершенные аналоги в виде компонентов страницы Win32. Если вы работаете с windows 32, рекомендуется использовать вместо компонентов Win 3.1 компоненты Win32.
КОМПОНЕНТЫ СТРАНИЦЫ SAMPLES
18.7. КОМПОНЕНТЫ СТРАНИЦЫ SAMPLESКомпоненты этой страницы включены в Delphi как образцы (samples) разработки нестандартных компонентов, однако многие из них имеют вполне самостоятельное значение.
TChart построитель графиков
18.2.18. TChart - построитель графиковЭтот компонент предназначен для графического представления числовых данных. На Рисунок 18.18 показан пример использования компонента.
Компонент содержит большое количество специфичных свойств, событий и методов - их детальное рассмотрение потребовало бы значительного объема книги и здесь не приводится.
Общая схема его использования такова.
Вначале компонент помещается на форму. После щелчка по нему правой кнопкой мыши вызывается его вспомогательное меню, которое в числе прочих содержит опцию Edit chart - с помощью этой опции вызывается многолистное окно редактора компонента. Закладка Series этого окна открывает доступ к так называемым сериям - объектам класса TChartSeries, которые, собственно, и будут отображать наборы чисел в графическом виде. Чтобы отобразить данные, нужно создать как минимум одну серию - для этого следует в окне редактора нажать кнопку Add и выбрать подходящий тип графика (Рисунок 18.19).
После закрытия редактора компонент будет содержать примерный вид графика. Однако его реальный вид зависит от фактических данных, которые создаются в работающей программе и добавляются к серии с помощью методов AddX, AddY или AddXY объекта TChartSeries (получить доступ к нужной серии можно с помощью индексированного свойстваSeriesList - первая созданная серия имеет индекс 0, вторая 1 и т. д.). Например, такой обработчик события OnActivate формы создал график, показанный на Рисунок 18.18:
procedure TFor.gif" >
TPageScroller панель с прокруткой
18.3.18. TPageScroller - панель с прокруткойКомпонент служит контейнером для размещения длинных узких компонентов наподобие TToolBar. Его отличительная черта - наличие небольших стрелок прокрутки по сторонам контейнера в случае, если ширина (высота) дочернего окна превышает соответствующий размер компонента. Чтобы увидеть компонент в действии, щелкните по странице Win32 галереи компонентов Delphi (сам компонент TPageScroller на этой странице обычно не виден[ Для разрешения экрана 800х600. ]), и, чтобы получить к нему доступ, следует щелкнуть по кнопке с небольшой стрелкой в правой части страницы.
По назначению компонент весьма напоминает уже рассмотренный в п. 18.2.9 компонент TScrollBox и отличается от него двумя обстоятельствами: компонент не содержит полос прокрутки, а прокрутка осуществляется так, чтобы полностью показать ранее невидимый дочерний компонент.
Свойства компонента:
| property AutoScroll: Boolean; | Разрешает/запрещает автоматическую
прокрутку при перемещении указателя мыши над кнопкой прокрутки |
| property ButtonSize: Integer; | Определяет размер в пикселях кнопок про
крутки: для горизонтальной ориентации - ширину, для вертикальной - высоту |
| property Control: TWinControl; | Содержит ссылку на прокручиваемое окно |
| property DragScroll: Boolean; | Указывает, будет ли компонент приемни ком в операциях Drag&Drop. Если содержит True, компонент будет прокручивать дочернее окно при перемещении над ним указателя мыши с “грузом” |
| property Margin: Integer; | Указывает расстояние в пикселях от границы компонента до соответствующей стороны дочернего окна |
| type TPageScrollerOs-xentation =
(soHorizontal, soVertical) ; property Orientation: TPageS crollerOrientation; |
Определяет ориентацию компонента: soHorizontal -по горизонтали; soVertical -по вертикали |
| property Position: Integer; | Определяет текущее положение прокручиваемого окна относительно границ компонента |
РАЗНОВИДНОСТИ ФОРМ
19.1. РАЗНОВИДНОСТИ ФОРМРазновидности форм определяются значениями их свойств For.gif" >
СОЗДАНИЕ И ИСПОЛЬЗОВАНИЕ ФОРМ
19.3. СОЗДАНИЕ И ИСПОЛЬЗОВАНИЕ ФОРМДля подключения новой формы к проекту достаточно обратиться к репозиторию и выбрать нужную разновидность формы. Менеджер проекта автоматически подключает новую форму к списку используемых форм и обеспечивает все необходимые действия по ее инициации. Самая первая подключенная к проекту форма (стандартное имя формы - For.gif" >
Pис 19.1. Окно управления проектом
Каждое следующее окно становится видно только после обращения к его методу show или showModal. Чтобы обратиться к этим методам, нужно сослаться на объект-окно, который автоматически объявляется в интерфейсном разделе связанного с окном модуля. Для этого, в свою очередь, главное окно должно знать о существовании другого окна, что достигается ссылкой на модуль окна в предложении uses. Если, например, в ходе выполнения одного из методов главного окна программист захочет вызвать окно с именем fmFor.gif" >
ПРОГРАММЫ С МНОГИМИ ФОРМАМИ
19.4. ПРОГРАММЫ С МНОГИМИ ФОРМАМИСложные программы подчас требуют создания множества форм, каждая из которых решает ту или иную конкретную задачу. Например, при создании систем управления базами данных типичным для проекта будет разработка от 50 до 100 и более форм. Процесс создания такого проекта обычно растягивается на несколько месяцев, а над его реализацией трудятся одновременно несколько программистов. Все это затрудняет ориентацию программиста, его способность быстро вспомнить назначение той или иной формы. В этом случае существенную помощь может оказать файл проекта. Как уже говорилось, рядом с описанием включенного в проекта модуля содержится строка комментария, в которой Delphi указывает имя файла формы. Этот комментарий появляется в диалоговом окне после щелчка по инструментальной кнопке выбора формы Я или выбора опции view | For.gif" >
TActionManager менеджер действий
18.2.19. TActionManager - менеджер действийВместе с тремя другими компонентами страницы Additional -
TActionMainMenu.gif" >
TComboBoxEx список выбора с расширенными возможностями
18.3.19. TComboBoxEx - список выбора с расширенными возможностямиЭтот компонент впервые введен в версии 6. По сравнению с TCоmboBох (см. п. 18.1.11) он способен рисовать слева от элемента списка небольшое изображение и выводить элемент с заданным отступом от левого края списка (Рисунок 18.34). Кроме того, с каждым элементом можно связать указатель на произвольные данные, размещенные в динамической памяти.
ГЛАВНОЕ ОКНО
2.1. ГЛАВНОЕ ОКНОГлавное окно осуществляет основные функции управления проектом создаваемой программы. Это окно всегда присутствует на экране и упрямо занимает его самую верхнюю часть. Не пытайтесь его распахнуть на весь экран: даже в максимизированном состоянии его размеры и положение практически не отличаются от обычных.
Связано это с функциональностью главного окна: с одной стороны, оно несет в себе элементы, которые всегда должны быть под рукой у программиста, с другой - окно не должно отнимать у остальных окон Delphi значительного пространства экрана. Минимизация главного окна приводит к исчезновению с экрана других окон Delphi[ Эти окна появятся, как только будут восстановлены размеры главного окна. ], а его закрытие означает окончание работы программиста с системой программирования.
В главном окне располагается главное меню Delphi, набор пиктографических командных кнопок и палитра компонентов.
Главное меню [ Помимо главного меню в Delphi широко используется система вспомогательных меню, доступ к которым осуществляется правой кнопкой мыши. ] содержит все необходимые средства для управления проектом. Все опции главного меню представляют собой опции-заголовки, открывающие доступ к выпадающим меню второго уровня. Для начального знакомства с Delphi мы вполне обойдемся пиктографическими кнопками, и нам не понадобится обращаться к главному меню, вот почему подробное описание его опций вы найдете не здесь, а в прил. 1.
Все элементы главного окна располагаются на специальных панельках, в левой части которых имеются кнопки управления
ОКНО ФОРМЫ
2.2. ОКНО ФОРМЫОкно формы представляет собой проект Windows-окна будущей программы. Вначале это окно пусто. Точнее, оно содержит стандартные для Windows интерфейсные элементы - кнопки вызова системного меню, максимизации, минимизации и закрытия окна, полосу заголовка и очерчивающую рамку. Вся рабочая область окна обычно заполнена точками координатной сетки, служащей для упорядочения размещаемых на форме компонентов (вы можете убрать эти точки, вызвав с помощью меню Tools | Environment options соответствующее окно настроек и убрав флажок в переключателе Display Grid на окне, связанном с закладкой Preferences).
Значительную часть времени программист занят увлекательным занятием, напоминающим работу с набором деталей конструктора Lego: он “достает” из палитры компонентов, как из коробки с деталями, нужный компонент и размещает его на “наборном поле” окна формы, постепенно заполняя форму интерфейсными элементами. Собственно, именно в этом процессе наполнения формы и заключается главная изюминка визуального программирования. Программист в любой момент времени контролирует содержание окна создаваемой программы и может внести в него необходимые изменения.
ОКНО ДЕРЕВА ОБЪЕКТОВ
2.3. ОКНО ДЕРЕВА ОБЪЕКТОВЭто окно появилось в версии 6 и предназначено для наглядного отображения связей между отдельными компонентами, размещенными на активной форме или в активном модуле данных. Щелчок по любому компоненту в этом окне активизирует соответствующий компонент в окне формы и отображает свойства этого компонента в окне Инспектора объектов. Двойной щелчок приводит к срабатыванию механизма Code Insight, который вставляет в окно кода заготовку для обработчика события OnClick. Наконец, компонент можно “перетащить” в окне и таким образом поменять его владельца (свойство parent). В предыдущих версиях такую замену можно было сделать только с помощью межпрограммного буфера обмена Clipboard.
ОКНО ИНСПЕКТОРА ОБЪЕКТОВ
2.4. ОКНО ИНСПЕКТОРА ОБЪЕКТОВЛюбой размещаемый на форме компонент характеризуется некоторым набором параметров: положением, размером, цветом и т. д. Часть этих параметров, например, положение и размеры компонента, программист может изменять, манипулируя с компонентом в окне формы. Для изменения других параметров предназначено окно Инспектора объектов. Это окно содержит две страницы - Properties (Свойства) и Events (События). Страница properties служит для установки нужных свойств компонента, страница Events позволяет определить реакцию компонента на то или иное событие. Совокупность cвойств отображает видимую сторону компонента: положение относительно левого верхнего угла рабочей области формы, его размеры и цвет, шрифт и текст надписи на нем и т. п.; совокупность событий - его поведенческую сторону: будет ли компонент реагировать на щелчок мыши или на нажатие клавиш, как он будет вести себя в момент появления на экране или в момент изменения размеров окна и т. п.
Каждая страница окна Инспектора объектов представляет собой двухколончатую таблицу, левая колонка которой содержит название свойства или события, а правая - конкретное значение свойства или имя подпрограммы [ Если вам еще не знаком этот термин, считайте, что подпрограмма - это просто относительно небольшой фрагмент программы. Подробнее о подпрограммах см. п. 5.6. ], обрабатывающей соответствующее событие.
Строки таблицы выбираются щелчком мыши и могут отображать простые или сложные свойства. К простым относятся свойства, определяемые единственным значением - числом, строкой символов, значением True (Истина) или False (Ложь) и т. п. Например, свойство caption (Заголовок) представляется строкой символов, свойства Height (Высота) и width (Ширина) - числами, свойство Enabled (Доступность) - значениями True или False. Сложные свойства определяются совокупностью значений. Слева от имени таких свойств указывается значок “+”, а щелчок мышью по этому символу приводит к раскрытию списка составляющих сложного свойства. Чтобы закрыть раскрытый список, нужно щелкнуть по значку “-” сложного свойства [ Для версий Delphi 1...4 раскрыть или закрыть список составляющих сложного свойства можно только двойным щелчком. ].
В верхней части окна Инспектора объектов располагается раскрывающийся список всех помещенных на форму компонентов. Поскольку форма сама по себе является компонентом, ее имя также присутствует в этом списке. В отличие от предыдущих версий раскрывающийся список содержит не только имена компонентов, но и их классы.
В локальном меню окна, которое появляется после щелчка по нему правой кнопкой, имеется ряд опций, позволяющих настроить окно. В частности, после выбора stay on Top, окно Инспектора объектов будет “всплывать” над всеми другими окнами независимо от его активности. Такое состояние окна удобно при частом его использовании, например, при конструировании сложной формы, содержащей множество компонентов. Если выбрать в локальном меню опцию Arrange и затем by Category, все строки окна Инспектора объектов будут представлять собой раскрывающиеся списки свойств, упорядоченные по категориям (Рисунок 2.6).
ОКНО КОДА ПРОГРАММЫ
2.5. ОКНО КОДА ПРОГРАММЫОкно кода предназначено для создания и редактирования текста программы. Этот текст составляется по специальным правилам и описывает алгоритм работы программы. Совокупность правил записи текста называется языком программирования. В системе Delphi используется язык программирования Object Pascal, который представляет собой расширенную и усовершенствованную версию широко распространенного языка Паскаль, впервые предложенного швейцарским ученым Н. Виртом еще в 1970 г. и усовершенствованного сотрудниками корпорации Borland (созданные ими языки назывались Turbo Pascal, Borland Pascal и Object Pascal). Несмотря на то, что визуальная среда Delphi берет на себя многие рутинные аспекты программирования, знание языка Object Pascal является непременным условием для любого программиста, работающего в этой среде.
Первоначально окно кода содержит минимальный исходный текст, обеспечивающий нормальное функционирование пустой формы в качестве полноценного Windows-окна. В ходе работы над проектом программист вносит в него необходимые дополнения, чтобы придать программе нужную функциональность. Поскольку для создания даже простых программ вам понадобится создавать и изменять (редактировать) код программы, ниже описываются основные приемы работы с окном кода.
Сразу после открытия нового проекта в нем будут такие строки:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Frms, Dialogs;
type
TFor.gif" >
Динамическая загрузка
13.4.2. Динамическая загрузкаОписанный выше способ определения функций и процедур DLL (с помощью директивы External) заставит компилятор поместить в заголовок программы список всех DLL, и загрузчик загрузит библиотеки в память одновременно с загрузкой самой программы. Программа может загружать DLL и без External с помощью трех
Стандартных функций : LoadLibrary, GetProcAddress И FreeLibrary.
Следующий пример иллюстрирует технику такой загрузки DLL Cmplx:
type
TComplex = record Re, Im: Real;
end;
TComplexFunc = function (x, y: TComplex): TComplex;
stdcall;
procedure TfmExample.bbRunClick(Sender: TObject);
var
x,y,z: TComplex;
AddC,SubC,MulC,DivC: TComplexFunc;
Handle: LongWord;
procedure Output(Operation: Char);
....//Тело процедуры Output остается без изменений
end; //Output
begin //bbRunClick
// Загружаем библиотеку CMPLX.DLL Handle := LoadLibrary('Cmplx.dll');
if Handle = 0 then
begin
ShowMessage('He найдена библиотека CMPLX.DLL') ;
Halt
end;
{Определяем адреса функций. Три первые вызываем по индексу, четвертую - по имени. При вызове по индексу младшее слово PChar должно содержать индекс, поэтому делаем приведение типов:} @AddC := GetProcAddress(Handle,PChar(Longint (1)));
PSubC := GetProcAddress(Handle,PChar(Longint(2)));
@MulC := GetProcAddress(Handle,PChar(Longint(3)));
@DivC := GetProcAddress(Handle,'DivC');
x.re := Random;
x.im := Random;
y.re := Random;
y.im := Random; Output('+');
Output('-');
Output ('*');
Output ('/');
mmOutput.Lines.Add('');
// Освобождаем библиотеку FreeLibrary(Handle)
end;
Имена в Delphi
3.1.2. Имена в DelphiПоскольку речь зашла об именах, я должен объяснить свою странную приверженность к сокращенным англоязычным именам. Дело в том, что Delphi принципиально не признает ни русских, ни французских, ни китайских, ни вообще каких бы то ни было имен, в которых используются символы, отличные от латинских букв. цифр и знака подчеркивания, причем имя не должно начинаться цифрой, но может начинаться знаком подчеркивания. Так как в этом перечне нет пробела, имена не могут также состоять из нескольких слов. Далее, сокращения до не более чем 8 символов - это дань ограничениям Delphi версии 1. Эта версия рассчитана на работу под управлением Windows З.х, которая не признает длинных имен файлов. Если вы работаете с Delphi 32 (т. е. с любой из версий от 2-й до 6-й), можете не сокращать имена и написать my_first_unit или даже moy_pervij_modul, потому что эти версии рассчитаны на современные 32-разрядные операционные системы, разрешающие использовать длинные имена файлов.
Если вы тем или иным способом решили проблемы с именами модуля и программы, на экране появится окно вашей формы, как и следовало ожидать - пустое, но обладающее всеми атрибутами нормального Windows-окна: оно может изменять свое положение и размеры и, закрываясь, выгружает программу из оперативной памяти ПК.
Класс Exception
16.1.2. Класс ExceptionКласс Exception является родительским классом для всех классов-исключений. Этот класс объявляется в модуле sysUtils следующим образом:
type
Exception = class(TObject)
private
FMessage: String;
FHelpContext: Integer;
public
constructor Create(const Msg: Strings);
constructor CreateFmt(const Msg: String;
const Args: array of const);
constructor CreateRes(Ident: Integers);
constructor CreateResFmt(Ident: Integer;
const Args: array of const) ;
constructor CreateHelp(const Msg: String; aHelpContext:
Integer) ;
constructor CreateFmtHelp(const Msg: String;
const Args: array of const; aHelpContext: Integers);
constructor CreateResHelp(Ident: Integer; aHelpContext:
Integer) ;
constructor CreateResFmtHelp(Ident: Integer;
const Args: array of const;
aHelpContext: Integers);
property HelpCoatext: Integer read FHelpContext write FHeipContext;
property Message: String read FMessage write FMessage;
end;
В классе определены целых 8 конструкторов для создания объекта. С их помощью можно прочитать текстовое сообщение из ресурса, отформатировать его, связать исключение с контекстной справочной службой. Свойство Message делает доступным частное поле FMessage, в котором содержится текстовое сообщение.
Класс ТРеn
16.4.2. Класс ТРеnС помощью класса треп создается объект-перо, служащий для вычерчивания линий.
Свойства класса:
| property Color: TColor; | Цвет вычерчиваемых пером линий |
| property Handle: Inte ger; | Дескриптор пера. Используется при непосредственном обращении к API-функциям Windows |
| property Mode: TPenMode; | Определяет способ взаимодействия линий с фоном (см.ниже) |
| property Style: TPenStyle; | Определяет стиль линий (см. Рисунок 16.2). Учитывается только для толщины линий 1 пиксель. Для толстых линий стиль всегда ps Solid (сплошная) |
| property Width: Integer; | Толщина линий в пикселях экрана |
| Свойство Mode может принимать одно из следующих значений: | |
| pmBlack | Линии всегда черные. Свойства Color и Style игнорируются |
| pmWhite | Линии всегда белые. Свойства Color и Style игнорируются |
| pmNop | Цвет фона не меняется (линии не видны) |
| pmNot | Инверсия цвета фона. Свойства Color и Style игнорируются |
| pmCopy | Цвет линий определяется свойством Color пера |
| pmNotCopy | Инверсия цвета пера. Свойство Style игнорируется |
| pmMergePenNot | Комбинация цвета пера и инверсионного цвета фона |
| pmMaskPenNot | Комбинация общих цветов для пера и инверсионного цвета фона. Свойство Style игнорируется |
| pmMergeNotPen | Комбинация инверсионного цвета пера и фона |
| pmMaskNotPen | Комбинация общих цветов для инверсионного цвета пера и фона. Свойство Style игнорируется |
| pmMerge | Комбинация цветов пера и фона |
| pmNotMerge | Инверсия цветов пера и фона. Свойство Style игнорируется |
| pmMask | Общие цвета пера и фона |
| pmNotMask | Инверсия общих цветов пера и фона |
| pmXor | Объединение цветов пера и фона операцией XOR |
| pinNotXor | Инверсия объединения цветов пера и фона операцией XOR |
Конструктор массива
8.3.2. Конструктор массиваПри обращении к подпрограмме на месте формального параметра в виде открытого массива можно указывать так называемый конструктор массива. Конструктор массива представляет собой список разделенных запятыми значений элементов массива, обрамленный квадратными скобками. Например, в предыдущем примере вместо
const
A: array [-1..2] of Integer = (0,1,2,3);
В: array [5..7] of Integer = (4,5,6);
begin
ArrayPrint(A);
ArrayPrint(B);
end;
мы могли бы написать так:
begin
ArrayPrint ( [0,1,2,3]);
ArrayPrint([4,5,6]);
end;
Методы
9.2.2. МетодыИнкапсулированные в классе процедуры и функции называются методами. Они объявляются так же, как и обычные подпрограммы:
type
TMyClass = class
Function MyFunc(aPar: Integer): Integer;
Procedure MyProc;
end;
Доступ к методам класса, как и к его полям, возможен с помощью составных имен:
var
aObject: TMyClass;
begin
aObject.MyProc;
end;
Как уже говорилось, методы класса могут перекрываться в потомках. Например:
type
TParentClass = class Procedure DoWork;
end;
TChildClass = class(TParentClass) Procedure DoWork;
end;
Потомки обоих классов могут выполнять сходную по названию процедуру DoWork, но, в общем случае, будут это делать по-разному. Такое замещение методов называется статическим, т. к. реализуется компилятором.
В Object Pascal гораздо чаще используется динамическое замещение методов на этапе прогона программы. Для реализации этого метод, замещаемый в родительском классе, должен объявляться как динамический (с директивой dynamic) или виртуальный (virtual). Встретив такое объявление, компилятор создаст две таблицы -DMT (Dynamic Method Table) и VMT (Virtual Method Table) и поместит в них адреса точек входа соответственно динамических и виртуальных методов. При каждом обращении к замещаемому методу компилятор вставляет код, позволяющий извлечь адрес точки входа в подпрограмму из той или иной таблицы. В классе-потомке замещающий метод объявляется с директивой override (перекрыть). Получив это указание, компилятор создаст код, который на этапе прогона программы поместит в родительскую таблицу точку входа метода класса-потомка, что позволит родителю выполнить нужное действие с помощью нового метода.
Пусть, например, родительский класс с помощью методов show и Hide соответственно показывает что-то на экране или прячет изображение. Для создания изображения он использует метод Draw с логическим параметром:
type
TVisualObject = class(TWinControl)
Procedure Hide;
Procedure Show;
Procedure Draw(IsShow: Boolean); virtual;
end;
TVisualChildObject = class(TVisualObject)
Procedure Draw(IsShow: Boolean); override;
end;
Реализация методов show и Hide очень проста:
Procedure TVisualObject.Show;
begin
Draw(True) ;
end;
Procedure TVisualObject.Hide;
begin
Draw(False) ;
end;
Методы Draw у родителя и потомка имеют разную реализацию и создают разные изображения. В результате родительские методы show и Hide - прятать или показывать те или иные изображения будут в зависимости от конкретной реализации метода Draw у-любого из своих потомков. Динамическое связывание в полной мере реализует полиморфизм классов.
Разница между динамическими и виртуальными методами состоит в том, что таблица динамических методов DMT содержит адреса только -тех методов, которые объявлены как dynamic в данном классе, в то время как таблица VMT содержит адреса виртуальных методов не только данного класса, но и всех его родителей. Значительно большая по размеру таблица VMT обеспечивает более быстрый поиск, в то время как при обращении к динамическому методу программа сначала просматривает таблицу DMT у объекта, затем -у его родительского класса и так далее, пока не будет найдена нужная точка входа.
Динамически перекрываемые методы часто могут вообще ничего не делать. Такие методы называются абстрактными, они обязаны перекрываться в потомках. Программист может запретить вызов абстрактного метода, объявив его с директивой abstract. Например:
type
TVisualObject = class(TWinControl)
Procedure Draw(IsShow: Boolean); virtual; abstract;
end;
TVisualChildObject = class(TWinControl)
Procedure Draw(IsShow: Boolean); override; end;
var
aVisualObject: TVisualObject;
aVisualChild: TVisualChildObject ;
begin
aVisualObject.Show; {Ошибка/ Обращение к абстрактному методу}
aVisualChild.Show;
{Нормальное обращение. Метод Draw у класса TVisualChildObject перекрыт.)
end;
Обращение к неперекрытому абстрактному методу вызывает ошибку периода исполнения. Разумеется, в грамотно составленной программе абстрактные методы никогда не вызываются. Классы, содержащие абстрактные методы, называются абстрактными. Такие классы инкапсулируют общие свойства своих неабстрактных потомков, но объекты абстрактных классов никогда не создаются и не используются. Для эксплуатации абстрактных классов в библиотеку классов Delphi включаются классы-потомки, в которых перекрываются абстрактные методы родителя.
В состав любого класса входят два специальных метода -конструктор и деструктор. У класса TObject эти методы называются create и Destroy, так же они называются в подавляющем большинстве его потомков. Конструктор распределяет объект в динамической памяти и помещает адрес этой памяти в переменную self, которая автоматически объявляется в классе. Деструктор удаляет объект из кучи. Обращение к конструктору должно предварять любое обращение к полям и некоторым методам объекта. По своей форме конструкторы и деструкторы являются процедурами, но объявляются с помощью зарезервированных слов constructor и Destructor:
type
TMyClass = class IntField: Integer; Constructor Create(Value: Integer);
Destructor Destroy;
end;
Любые поля объекта, а также методы класса, оперирующие с его полями, могут вызываться только после создания объекта с помощью вызова конструктора, т. к. конструкторы распределяют объект в динамической памяти и делают действительным содержащийся в объекте указатель.
var
MyObject: TMyClass;
begin
MyObject.IntField := 0;
{ Ошибка! Объект не созданконструктором!}
MyObject := TMyClass.Create;
// Надо так: создаем объект
MyObject.IntField := 0;
// и обращаемся к его полю
MyObect.Free;
// Уничтожаем ненужный объект
end;
В базовом классе TObject определен метод Free, который сначала проверяет действительность адреса объекта и лишь затем вызывает деструктор Destroy. Обращение к деструктору объекта будет ошибочным, если объект не создан конструктором, поэтому для уничтожения ненужного объекта следует вызывать метод Free, как это сделано в предыдущем примере.
Большинство конструкторов реализуют некоторые действия, необходимые для правильной работы объекта. Поэтому в конструкторе класса-потомка следует сначала вызвать конструктор своего родителя, а уже затем осуществлять дополнительные действия. Вызов любого метода родительского класса достигается с помощью зарезервированного слова inherited (унаследованный):
Constructor TMyClass.Create(Value: Integer);
// Возможная реализация конструктора
begin
Inherited Create; // Вызываем унаследованный конструктор IntField := Value; // Реализуем дополнительные действия
end;
Некоторые методы могут вызываться без создания и инициации объекта. Такие методы называются методами класса, они объявляются с помощью зарезервированного слова class:
type
TMyClass = class(TObject)
class Function GetClassName: String;
end;
var
S: String;
begin
S := TMyClass.GetClassName;
end;
Методы класса не должны обращаться к полям, т. к. в общем случае вызываются без создания объекта, а следовательно, в момент вызова полей просто не существует. Обычно они возвращают служебную информацию о классе - имя класса, имя его родительского класса, адрес метода и т. п.
Наследование
9.1.2. НаследованиеЛюбой класс может быть порожден от другого класса. Для этого при его объявлении указывается имя класса-родителя:
TChildClass = class (TParentClass)
Порожденный класс автоматически наследует поля, методы и свойства своего родителя и может дополнять их новыми. Таким образом, принцип наследования обеспечивает поэтапное создание сложных классов и разработку собственных библиотек классов.
Все классы Object Pascal порождены от единственного родителя класса TObject. Этот класс не имеет полей и свойств, но включает в себя методы самого общего назначения, обеспечивающие весь жизненный цикл любых объектов - от их создания до уничтожения. Программист не может создать класс, который не был бы дочерним классом TObject. Следующие два объявления идентичны:
TaClass = class(TObject) TaClass = class
Принцип наследования приводит к созданию ветвящегося дерева классов, постепенно разрастающегося при перемещении от TObject к его потомкам. Каждый потомок дополняет возможности своего родителя новыми и передает их своим потомкам.
Для примера на Рисунок 9.1 показан небольшой фрагмент дерева классов Delphi. Класс Tpersistent обогащает возможности своего родителя TObject: он “умеет” сохранять данные в файле и получать их из него, в результате это умеют делать и все его потомки. Класс TComponent, в свою очередь, умеет взаимодействовать со средой разработчика и передает это умение своим потомкам. Tcontrol не только способен работать с файлами и средой разработчика, но он еще умеет создавать и обслуживать видимые на экране изображения, а его потомок TWinControi может создавать Windows-окна и т. д.
Нультерминальные строки
7.3.2. Нуль-терминальные строкиНуль-терминальные строки широко используются при обращениях к так называемым API-функциям Windows (API - Application Program Interface - интерфейс прикладных программ). Поскольку компоненты Delphi берут на себя все проблемы связи с API-функциями Windows, программисту редко приходится прибегать к нуль-терминальным строкам. Тем не менее в этом разделе описываются особенности обработки таких строк.
Прежде всего напомню, что базовый тип string хранит в памяти терминальный нуль, поэтому Object Pascal допускает смешение обоих типов в одном строковом выражении, а также реализует взаимное приведение типов с помощью автофункций преобразования String и PChar. Например:
procedure TfmExample.For.gif" >
Объекты Автоматизации и интерфейс IDispatch
9.4.2. Объекты Автоматизации и интерфейс IDispatchВ технологии OLE активно используются так называемые объекты Автоматизации (Automation objects). Эти объекты представляют собой экземпляры интерфейсных классов, родительским интерфейсом которых является специальный интерфейс IDispatch. Отличительной особенностью IDispatch является то обстоятельство, что методы объекта Автоматизации никогда не вызываются напрямую, но всегда - с помощью метода invoke интерфейса IDispatch. Управление объектами СОМ с помощью выполнения методов IDispatch называется маршализацией (marshaling).
Для объявления класса Автоматизации используется специальное зарезервированное слово dispinterface, а перечисляемые в нем методы и свойства должны снабжаться целочисленными идентификаторами, которые вставляются в конце описания методов (свойств) после зарезервированных слов dispid:
type
IStringsDisp = dispinterface [ ' {EE05DFE2-5549-11DO-9EA9-0020AF3D82DA} ' ]
property ControlDefault[Index: Integer]: OleVariant
dispid 0; default-function Count: Integer;
dispid 1;
property I tern[Index: Integer]: OleVariant dispid 2;
procedure Remove(Index: Integer); dispid 3;
procedure Clear; dispid 4;
function Add(Item: OleVariant): Integer; dispid 5;
function _NewEnum: lUnknown; dispid -4;
end;
В отличие от обычного интерфейсного класса класс Автоматизации не может иметь родительского класса, и поэтому за словом dispinterface нельзя указать список родителей. Идентификаторы методов (свойств) должны быть уникальными в пределах объявления класса. Все возвращаемые функциями и свойствами результаты, а также все параметры обращения к методам должны иметь один из
Следующих типов: Byte, Currency, Real, Double, Longint, Integer, Single, Smallint, AnsiString, WideString, TDateTime, Variant, OleVariant, WordBool или любой интерфейсный тип. За исключением директивы default, которую можно указать для свойства-массива, никакие другие директивы доступа в объявлении методов и свойств не допускаются.
Для доступа к объектам Автоматизации используются переменные типа вариант (см. следующую главу). Инициация такой переменной осуществляется вызовом функции CreateOleObject, определенной в модуле comobj. Эта функция возвращает ссылку на интерфейс IDispatch, с помощью которой можно обращаться к методам и свойствам класса Автоматизации так, как если бы они были методами и свойствами варианта. Например, следующая программа вызывает текстовый процессор MS Word, вставляет в пустую страницу две строки и сохраняет полученный документ на диске:
Uses ComObj ;
var
Word: Variant;
begin
Word := CreateoieObject('Word.Basic');
Word.FileNew('Normal');
Word.Insert('Первая строка'#13);
Word.Insert('Вторая строка'#13);
Word.FileSaveAs('с:\temp\test.txf, 3) ;
end;
Параметром обращения к CreateoieObject является имя сервера Автоматизации, которое должно быть предварительно зарегистрировано в реестре Windows 32. Характерно, что методы сервера не известны на этапе компиляции программы, поэтому компилятор никак не контролирует правильность их вызовов. Названия методов не подчиняются правилам построения идентификаторов Delphi, и в них могут использоваться символы национальных алфавитов.
Обработчик события OnClick
3.3.2. Обработчик события OnClickПри щелчке по кнопке мышью в работающей программе возникает событие OnClick. (По щелчку). Пока это событие никак не обрабатывается программой, и поэтому “нажатие” кнопки не приведет ни к каким последствиям. Чтобы заставить программу реагировать на нажатие кнопки, необходимо написать на языке object pascal фрагмент программы, который называется обработчиком события.
Перенос формы в архив
5.1.2. Перенос формы в архивПосле указанных выше изменений сохраните форму в файле с именем Example в каталоге архива Delphi. Этот каталог имеет имя Objrepos и размещается в каталоге размещения Delphi (по умолчанию - c:\Program Files\Borland\Delphi6). Архив (репозиторий)
Delphi служит для накопления типовых форм и проектов. Использование типовых заготовок стандартизует вид окон и способствует формированию собственного для программиста стиля оформления своих программных проектов.
Перенос формы в каталог Objrepos еще не обеспечивает включение этой формы в архив. Чтобы вызвать диалоговое окно регистрации формы в архиве, щелкните по форме правой кнопкой мыши и в появившемся вспомогательном меню выберите продолжение Add то Repository (см. Рисунок 5.2).
Секция FILES
21.4.2. Секция FILESС помощью этой секции определяются RTF-файлы, содержащие текст, справочной системы. Для нормальной работы компилятора необходимо определить хотя бы один файл в этой секции. Замечу, что содержимое этой секции автоматически изменяется при изменении списка RTF-files на странице Files окна options (см. п. 21.4.1).
Справочная служба может состоять из множества RTF-файлов. В этом случае все они должны быть перечислены в секции [Files]. Компилятор разрешает задать в этом списке один или несколько ссылочных ASCII-текстовых файлов, каждая строка которых указывает нужный RTF-файл .(т. е. содержит маршрут доступа и имя файла).
Системный реестр Windows
20.5.2. Системный реестр WindowsСистемный реестр Windows - это общедоступная база данных, хранящая индивидуальную для каждого компьютера настроечную информацию, используемую программным обеспечением. Данные в реестре упорядочены в древовидные структуры, состоящие из узлов, которые в терминологии Windows называются ключами. Каждый ключ имеет один родительский ключ, один или несколько дочерних ключей и ноль или несколько параметров типа <имя_парамет-ра>=<значение>, Исключение представляют, корневые ключи (они не имеют родителей) и дочерние ключи низшего уровня (они не имеют дочерних ключей). По умолчанию несистемное программное обеспечение регистрирует свою информацию в корневом ключе с именем hkey_current_user. Для просмотра/коррекции системного реестра используется системная утилита regedit.exe. Системному реестру Windows соответствует объект класса TRegistry.
Методы класса TRegistry:
| procedure CioseKey; | Записывает информацию в ключ и закрывает его |
| constructor Create; | Создает объект класса TRegistry. Устанавливает в RootKey значение hkeycurrent - user и в LazyWrite значение True |
| function CreateKey(const Key:
String): Boolean; |
Создает ключ с именем Key. Если имя начинается символом “\”, ключ является подключом корневого ключа, в противном случае - подключом текущего ключа |
| function DeleteKey(const Key:
String): Boolean; |
Удаляет ключ Key и возвращает True, если операция прошла успешно |
| function DeleteValue(const Name:
String): Boolean; |
В текущем узле удаляет значение параметра с именем Name |
| destructor Destroy; | Уничтожает объект TRegistry |
| TRegDataType == (rdUnknown,
rdString, rdExpandString, rdlnteger, rdBinary) ; TRegDataInfo = record RegData: TRegDataType; DataSize: Integers- end; |
Возвращает в параметре value значение, определяющее тип данных для параметра сименем valueName текущего ключа: rdunknown - неизвестный тип; rdString - стро
ковый тип;rdExpandString - значением является строка, описывающая переменную окружения Windows, например “%РАТН%”; |
| function GetDataInfo(const ValueName: String; var Value: TRegDataInfo) : Boolean; | rdlnteger - целочисленный тип; rdBinary - двоичный тип (набор битов) |
| function GetDataSize(const Valu-
eName: String): Integer; |
Возвращает длину значения параметра с
именем valueName в текущем узле |
| TRegDataType = (rdUnknown, rdString, rdExpandString, rdlnteger, rdBinary) ;
function GetDataType(const ValueName: String): TRegDataType; |
Возвращает значение, определяющее тип данных для параметра с именем ValueMame текущего ключа (см. метод GetDataInfo) |
| TRegKeyInfo = record
NumSubKeys: Integer; MaxSubKeyLen: Integer; NumValues: Integer; MaxValueLen: Integer; MaxDataLen: Integer; FileTime: TFileTime; end; function GetKeyInfo(var Value: TRegKeyInfo): Boolean; |
Возвращает в параметре Value информацию о текущем узле: - NumSubKeys количество дочерних узлов;MaxSubKeyLen - максимальная длина имени дочернего узла; NumValues - количество параметров; Мах-valueben - максимальная длина имени параметра; MaxDataLen - максимальна длина параметра; FileTime - время последнего обновления ключа |
| procedure GetKeyNames(Strings:TStrings) ; | Возвращает в параметре strings имена
всех дочерних ключей |
| procedure GetValueNames(Strings:TStrings) ; | Возвращает в параметре Strings имена
всех параметров |
| function HasSubKeys: Boolean; | Возвращает True, если ключ имеет дочерние ключи |
| function KeyExists(const Key:
String): Boolean; |
Возвращает True, если существует ключ с именем Key |
| function LoadKey(const Key, File-
Name: String): Boolean; |
Создает ключ с именем Key как дочерний ключ корневого ключа и загружает из файла FileName его содержимое (параметры и все подключи) |
| procedure MoveKey(const OldName,
NewName: String; Delete: Boolean) ; |
Копирует или перемещает ключ OldName в ключ NewName: Delete -содержит True для перемещения |
| function OpenKey(const Key:
String; CanCreate: Boolean): Boolean; |
Открывает существующий или создает и открывает новый ключ с именем Key и воз вращает True, если операция прошла успешно. CanCreate разрешает/запрещает создание ключа, если он не существует |
| function ReadBinaryData(const
Name: String; var Buffer; BufSize: Integer): Integer; |
Копирует не более Bufsize байт в переменную Buffer из параметра с именем Name.
Возвращает количество действительно скопированных байтов |
| function ReadXXXX(const Name:
String): YYYY; |
Возвращает значение параметра типа yyyy с именем Name |
| function RegistryConnect(const
UNCName: String): Boolean- |
Разрешает удаленному компьютеру ONCName доступ к системному реестру вашего компьютера |
| procedure RenameValue(const Old Name, NewName: Strings; | Переименовывает параметр OldName |
| function ReplaceKey(const Key
FileName, Back.gif" > |
События от клавиатуры
17.6.2. События от клавиатурыСобытия от мыши получают любые потомки TControl. В отличие от этого события от клавиатуры получают только некоторые оконные компоненты (потомки TWinControi). Обработка событий связана со следующими свойствами этих компонентов:
type
TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft,
ssRight, ssMiddie, ssDoubie) ;
TKeyEvent = procedure (Sender: TObject; var Key: Word;
Shift: TShiftState) of object;
TKeyPressEvent = procedure (Sender: TObject;
var Key: Char) of object-property OnKeyDown: TKeyEvent;
property OnKeyUp: TKeyEvent;
property OnKeyPress: TKeyPressEvent;
Параметр Shift, как и в обработчиках событий от мыши, содержит уточняющие признаки. Параметр Key в обработчиках TKeyEvent содержит виртуальный код клавиши, а в обработчике TKeypressEv-ent - ASCII-символ. Обработчики OnKeyDown и опкеуор перехваты-вают нажатие большинства клавиш клавиатуры, в то время как обработчик QnKeypress - только нажатие алфавитно-цифровых клавиш. Получаемый им символ Key учитывает выбранный язык и нажатую клавишу Shift.
Виртуальные коды клавиш определены константами vk_xxx в файле source | rtl | win windows . pas каталога размещения Delphi. Фактически виртуальный код - это просто уникальный числовой идентификатор клавиши. Для буквенно-цифровых клавиш О...9 и A...Z виртуальный код совпадает с кодом, возвращаемым функцией ord(X), где х - соответствующий заглавный символ: ord('o'), ord( 'w') и т. д. К сожалению, уникальность кода не обеспечивается для клавиши Enter в зоне дополнительных числовых клавиш, которой присвоен код 13, - как и аналогичной клавише в основной зоне, а также для правых и левых сдвиговых клавиш Shift, Alt и Ctrl. Кроме того, клавиши О...9 и Del в зоне дополнительной клавиатуры сопровождаются уникальным кодом только при активном переключателе NumLock, в противном случае они повторяют коды соответствующих управляющих клавиш. Все остальные клавиши стандартной клавиатуры (за исключением Print Screen, клавиш смещения курсора и Tab, нажатие на которые не передается в обработчики TKeyEvent) имеют постоянно закрепленные за ними числовые коды, позволяющие легко установить факт нажатия или отпускания любой из них.
Поскольку параметр кеу в каждом обработчике определен как параметр-переменная, программист может изменить фактический код клавиши на нужный. Такая возможность может оказаться полезной для фильтрации нажатия каких-либо клавиш. При этом изменение кода происходит в обработчике формы, а в оконный элемент с фокусом ввода будет поступать уже измененный код. Чтобы форма получила событие до передачи его в элемент с фокусом ввода, следует поместить в свойство property KeyPreview: Boolean; формы значение True.
Создание наследника TCustomVariantType
10.5.2. Создание наследника TCustomVariantTypeТип TCustomVariantType или его ближайшие Наследники TPublishableVariantType и TInvokeableVariantType Содержат методы и свойства, которые в нужный момент вызывают методы и свойства объекта VComplex для осуществления тех или иных преобразований. В модуле varcmpix объявляется такой класс:
type
TComplexVariantType =
class(TPublishableVariantType, IVarStreamable) protected
function LeftPromotion(const V: TVarData;
const Operator: TVarOp;
out RequiredVarType: TVarType): Boolean; override;
function RightPromotion(const V: TVarData;
const Operator: TVarOp;
out RequiredVarType: TVarType): Boolean; override;
function Getlnstance(const V: TVarData): TObject; override;
public
procedure Clear(var V: TVarData);
override;
function IsClear(const V: TVarData): Boolean; override;
procedure Copy(var Dest: TVarData;
const Source: TVarData;
const Indirect: Boolean);
override;
procedure Cast(var Dest:
TVarData;
const Source: TVarData);
override;
procedure CastTo(var Dest: TVarData;
const Source: TVarData;
const AVarType: TVarType);
override;
procedure BinaryOp(var Left: TVarData;
const Right: TVarData;
const Operator: TVarOp); override;
procedure UnaryOp(var Right: TVarData;
const Operator: TVarOp);
override;
function CompareOp(const Left: TVarData;
const Right: TVarData;
const Operator: Integer): Boolean;
override;
procedure Streamin(var Dest: TVarData;
const Stream: TStream) ;
procedure StreamOut(const Source: TVarData;
const Stream: TStream) ;
end;
Обратите внимание: класс TComplexVariantType - интерфейсный (см. п. 9.4.1). Помимо общих для варианта методов он реализует также два метода, специфичных для интерфейса Ivarstreamabie -Streamin и StreamOut, с помощью которых значения нового интерфейса сохраняются в потоке и считываются из него.
Задача этого класса - дать единообразные команды, способные интерпретироваться объектом vcomplex как команды преобразования типа хранящихся данных, их сравнения, реализации над ними тех или иных операций, наконец, записи их в поток и чтения из него. Например, метод cast этого класса вызывается для преобразования других типов значений к комплексному типу, метод castTo - для обратного преобразования, метод BinaryOp реализует бинарную операцию, a Unarydp - унарную и т. д.
Еще раз подчеркну, что основная работа (например, по выполнению бинарных операций) реализуется методами класса TComplex-Data. Класс TCompiexVariantType перекрывает абстрактные методы своего родителя, подключая TComplexData к решению той или иной проблемы.
Поскольку для создания экземпляра нового варианта необходим уже готовый экземпляр (объект) класса TCompiexVariantType, он создается в секции инициализации модуля varcmpix и уничтожается в завершающей секции:
initialization
ComplexVariantType := TCompiexVariantType.Create;
finalization
FreeAndNil(ComplexVariantType);
Создание объекта отображения
11.7.2. Создание объекта отображенияНа втором этапе создается объект отображения в память. Для этого используется такая функция:
function CreateFileMapping(hFile: THandle; IpFileMapping-Attributes: PSecurityAttributes; flProtect, dwMaximumSize-High, dwMaximumSizeLow: DWord; IpName: PChar): THandle;
Здесь hFile - дескриптор файла; ipFileMappingAttributes - указа-тель на структуру, в которой определяется, может ли создаваемый объект порождать дочерние объекты (обычно не может - nil); flProtect -определяет тип защиты, применяемый к окну отображения файла (см.ниже); dwMaximumSizeHigh, dwMaximumSizeLow - соответственно Старшие и младшие 32 разряда размера файла; если вы будете отображать файлы длинной до 4 ГбаЙТ, поместите В dwMaximumSizeHigh 0, а В dwMaximumSizeLow - длину файла; если оба параметра равны 0, размер окна отображения равен размеру файла; ipName - имя объекта отображения или nil.
Параметр flProtect задает тип защиты, применяемый к окну просмотра файла, и может иметь одно из следующих значений: page_readonly - файл можно только читать (файл должен быть создан или открыт В режиме fmOpenRead); PAGE_READWRITE - файл можно читать и записывать в него новые данные (файл открывается в режиме fmOpenReadWrite); PAGE_WRITECOPY - файл открыт для записи и чтения, однако обновленные данные сохраняются в отдельной защищенной области памяти (отображенные файлы могут разделяться программами, в этом режиме каждая программа сохраняет изменения в отдельной области памяти или участке файла подкачки); файл открывается В режиме fmOpenReadWrite или fmOpenWrite; этот тип защиты нельзя использовать в Windows 95/98. С помощью операции or к параметру fiprotect можно присоединить такие атрибуты:
sec_commit - выделяет для отображения физическую память или участок файла подкачки; sec_image - информация об атрибутах отображения берется из образа файла; sec_nocashe - отображаемые данные не кэшируются и записываются непосредственно на диск;
sec_reserve - резервируются страницы раздела без выделения физической памяти. Функция возвращает дескриптор объекта отображения или 0, если обращение было неудачным.
Страница Data Controls
4.8.2. Страница Data Controls15 компонентов этой страницы предназначены для визуализации данных, их ввода и редактирования. Многие компоненты этой страницы введены еще в версии 1.
Страница FastNet
4.9.2. Страница FastNetКомпоненты этой страницы предоставляют программисту возможность использования различных протоколов для передачи деловых сообщений и данных по локальным и/или глобальным сетям, в том числе и по Интернет. В версиях 2, 3 и 4 они размещались на странице internet. В версии 1 таких компонентов нет. Для меж-ллатформенных программ вместо этих компонентов следует использовать компоненты страниц Indy (см. ниже).
Структура модуля
5.2.2. Структура модуляМодули - это программные единицы, предназначенные для размещений фрагментов программ. С помощью содержащегося в них программного кода реализуется вся поведенческая сторона программы. Любой модуль имеет следующую структуру [ Более точное описание структуры модуля приводится в п. 12.1. ]: заголовок секция интерфейсных объявлений секция реализации терминатор Заголовок открывается зарезервированным словом Unit за которым следует имя модуля и точка с запятой. Секция интерфейсных объявлений открывается зарезервированным словом Interface, a секция реализации - словом implementation. Терминатором модуля, как и терминатором программы, является end с точкой. Следующий фрагмент программы является синтаксически правильным вариантом модуля:
unit Unit1;
interface
// Секция интерфейсных объявлений
implementation
// Секция реализации
end.
В секции интерфейсных объявлений описываются программные элементы (типы, классы, процедуры и функции), которые будут “видны” другим программным модулям, а в секции реализации раскрывается механизм работы этих элементов. Разделение модуля на две секции обеспечивает удобный механизм обмена алгоритмами между отдельными частями одной программы. Он также реализует средство обмена программными разработками между отдельными программистами. Получив откомпилированный “посторонний” модуль, программист получает доступ только к его интерфейсной части, в которой, как уже говорилось, содержатся объявления элементов. Детали реализации объявленных процедур, функций, классов скрыты в секции реализации и недоступны другим модулям.
Щелкните по закладке Unit1 окна кода, и вы увидите такой текст:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
For.gif" >
TColorGrid выбор или отображение цвета
18.7.2. TColorGrid - выбор или отображение цветаКомпонент предназначен для выбора и/или отображения цветов из 16-цветной палитры. Выбирать/отображать можно два цвета: основной и фоновый. Основной выбирается щелчком левой кнопки мыши и отображается символами fg, фоновый выбирается правой кнопкой и отображается символами bg (если оба цвета совпадают, соответствующая клетка таблицы помечается символами fb).
Свойства компонента:
| property Back.gif" > | Содержание | Вперед |
TMainMenu gif" >
18.1.2. TMainMenu.gif" >TNotebook набор страниц
18.6.2. TNotebook - набор страницМногостраничный контейнер TNotebook обычно работает в паре с TTabSet и предназначен для размещения других компонентов на нескольких перекрывающих друг друга страницах (панелях).
Свойства компонента:
| property ActivePage: Strings; | Определяет имя верхней страницы блокнота |
| property Pagelndex: Integers; | Содержит индекс верхней страницы блокнота |
| property Pages: TStrings; | Содержит набор строк с именами страниц |
Для компонента определено событие
property OnChange: TNotifyEvent;
которое возникает при смене страницы.
TOpenPictureDialog и TSavePictureDialog
18.5.2. TOpenPictureDialog и TSavePictureDialog - диалоги открытия и сохранения изображенийСпециализированные диалоги для открытия и сохранения графических файлов TOpenPictureDialog И TSavePictureDialog отличаются от
TOpenDialog и TSaveDialog двумя обстоятельствами. Во-первых, в них предусмотрены стандартные фильтры для выбора графических файлов (с расширениями bmp, ico, wmf и emf) . Во-вторых, в окна диалога включены панели для предварительного просмотра выбираемого файла.
На Рисунок 18.39 показано стандартное окно компонента TOpenPictureDialog.
TPaintBox окно для рисования
18.4.2. TPaintBox - окно для рисованияНазначение компонента TPaintBox - дать вам простое окно с канвой для рисования произвольных изображений. Канва содержится в свойстве Canvas компонента, графические инструменты - в свойствах Font, pen и Brush, а собственно рисование осуществляется в обработчике события OnPaint. Особенности использования этих инструментов см. в п. 16.4. Например, следующий обработчик создаст окно, показанное на Рисунок 18.35:
TSpeedButton кнопка для инструментальных панелей
18.2.2. TSpeedButton - кнопка для инструментальных панелей
Кнопки TSpeedButton отличаются от TBitBtn Тремя обстоятельствами: во-первых, они могут фиксироваться в утопленном состоянии, во-вторых, они не могут закрыть модальное окно в третьих, они не могут быть умалчиваемыми. Во всем остальном они повторяют свойства и методы TBitBtn.
Для фиксации кнопка должна быть отнесена к какой-либо группе кнопок (эта группа может состоять из нее одной - вариант одиночной фиксируемой кнопки). Для этого используется свойство GroupIndex: Integer, которое не должно быть равно 0. Поведение кнопки определяется логическим свойством AllowAllup: если это свойство имеет значение True, утопленная кнопка отпускается только при нажатии любой другой кнопки, входящей в ту же группу; если AllowAllup=False, кнопку можно освободить повторным щелчком. Индикатором состояния кнопки служит логическое свойство Down, которое имеет значение True, если кнопка утоплена. Свойство доступно для записи, что позволяет изменять состояние кнопки программно.
Для кнопки TSpeedButton предусмотрено событие onDbiciick, которое возникает при двойном щелчке на утопленной кнопке.
Указатели
7.4.2. УказателиОперативная память ПК представляет собой совокупность ячеек для хранения информации - байтов, каждый из которых имеет собственный номер. Эти номера называются адресами, они позволяют обращаться, к любому байту памяти. Object Pascal предоставляет в распоряжение программиста гибкое средство управления динамической памятью - так называемые указатели. Указатель - это переменная, которая в качестве своего значения содержит адрес байта памяти. С помощью указателей можно размещать в динамической памяти любой из известных в Object Pascal типов данных. Лишь некоторые из них (Byte, Char, ShortInt, Boolean) занимают во внутреннем представлении один байт, остальные - несколько смежных. Поэтому на самом деле указатель адресует лишь первый байт данных.
Как правило, указатель связывается с некоторым типом данных. Такие указатели будем называть типизированными. Для объявления типизированного указателя используется значок ^, который помещается перед соответствующим типом, например:
var
p1 : ^Integer;
р2 : ^Real;
type
PerconPointer = "PerconRecord;
PerconRecord = record Name : String;
Job : String;
Next : PerconPointer ,
end;
Обратите внимание: при объявлении типа PerconPointer мы сослались на тип PerconRecord, который предварительно в программе объявлен не был. Как уже отмечалось, в Object Pascal последовательно проводится в жизнь принцип, в соответствии с которым перед использованием какого-либо идентификатора он должен быть описан. Исключение сделано только для указателей, которые могут ссылаться на еще не объявленный тип данных.
В Object Pascal можно объявлять указатель и не связывать его при этом с каким-либо конкретным типом данных. Для этого служит стандартный тип pointer, например:
var
р: Pointer;
Указатели такого рода будем называть нетипизированньти. Поскольку нетипизированные указатели не связаны с конкретным типом, с их помощью удобно динамически размещать данные, структура и тип которых меняются в ходе работы программы.
Как уже говорилось, значениями указателей являются адреса переменных в памяти, поэтому следовало бы ожидать, что значение одного указателя можно передавать другому. На самом деле это не совсем так. В Object Pascal можно передавать значения только между указателями, связанными с одним и тем же типом данных.
Если, например,
var
pI1,pI2: ^integer;
pR: ^Real;
p: Pointer;
то присваивание
pI1 := pI2;
вполне допустимо, в то время как
pl1 :=pR;
запрещено, поскольку pI1 и pR указывают на разные типы данных. Это ограничение, однако, не распространяется на нетипизированные указатели, поэтому мы могли бы записать
p := pR;
pI1 := p;
и тем самым достичь нужного результата.
Условный оператор
5.4.2. Условный операторУсловный оператор позволяет проверить некоторое условие и в зависимости от результатов проверки выполнить то или иное действие. Таким образом, условный оператор - это средство ветвления вычислительного процесса.
Структура условного оператора имеет следующий вид:
if <условие> then <оператор1> else <оператор2>;
где if/ then/ else - зарезервированные слова (если, то, иначе);
<условие> - произвольное выражение логического типа;
<оператор1>, <оператор2> - любые операторы языка Object Pascal.
Условный оператор работает по следующему алгоритму. Вначале вычисляется условное выражение <условие>. Если результат есть True (истина), то выполняется <оператор1>, а <оператор2> пропускается; если результат есть False (ложь), наоборот, <оператор1> пропускается, а выполняется <оператор2>. Например:
var
X, Y, Max: Integer;
begin .
if X > Max then
Y := Max else
Y := X;
….
end;
При выполнении этого фрагмента переменная y получит значение переменной х, если только это значение не превышает мах, в противном случае y станет равно мах.
Условными называются выражения, имеющие одно из двух возможных значений: истина или ложь. Такие выражения чаще всего получаются при сравнении переменных с помощью операций отношения =, <>, >, >=, <, <=. Сложные логические выражения составляются с использованием логических операций and (логическое И), or (логическое ИЛИ) и not (логическое НЕ). Например:
if (а > b) and (b <> 0) then ...
Примечание
Примечание
В отличие от других языков программирования в Object Pascal приоритет операций отношения меньше, чем у логинеёкйх" операции, по этому отдельные составные части сложного логического вьфажёния 5 заключаются в скобки. Например, такая запись предыдущего оператора будет неверной:
if a>b and b <> 0 then ...// Ошибка так как фактически (с учетом приоритета операции) компилятор будет транслировать такую строку:
if a>(b and b)<>0 then...
Часть else <оператор2> условного оператора может быть опущена. Тогда при значении True условного выражения выполняется <оператор1>, в противном случае этот оператор пропускается:
var
X, Y, Max: Integer;
begin
if X > Мах then Мах := X;
Y := X;
end;
В этом примере переменная y всегда будет иметь значение переменной х, а в мах запоминается максимальное значение X.
Поскольку любой из операторов <оператор1> и <оператор2> может быть любого типа, в том числе и условным, а в то же время не каждый из “вложенных” условных операторов может иметь часть else <оператор2>, то возникает неоднозначность трактовки условий. Эта неоднозначность в Object Pascal решается следующим образом:
любая встретившаяся часть else соответствует ближайшей к ней сверху по тексту программы части then условного оператора. Например:
var
a,b,c,d : Integer;
begin a := 1;
b := 2;
с := 3;
d := 4;
if a < b then // Да
if с < d then // Да
if с < 0 then // Нет
с := 0 // Этот оператор не выполняется
else
а : = b; // а равно 2
if а < b then // Да
if с < d then // Да
if с < 0 then // Нет
с := 0 // с равно 0
else // if с < О
else //if с < d
else // If a < b
а := b; // Этот оператор не выполняется
end;
Учебная программа INTTEST
Игра “Угадай число”: программа случайным образом выбирает целое число в диапазоне О... 1000 и запоминает его. Пользователь пытается угадать его и вводит свое число. Сравнив ввод с запомненным числом, программа сообщает - больше, меньше или равно введенное число запомненному. Ввод продолжается до угадывания, после чего программа предлагает сыграть еще раз.
Поскольку пользователь вводит только числа, изменим форму fmExample: как и в предыдущей программе intmult вместо компонента edinput типа TEdit поместим на форму одноименный компонент типа TMaskEdit. Выберите опцию File | New | Application, щелкните по компоненту edinput и удалите его с помощью клавиши Delete, затем поместите на его место компонент MaskEdit (страница Additional), назовите его edInput (свойство Name) и в его свойство
EditMask поместите строку
0999;1;
В секцию private описания класса fmExampie поместите объявление целочисленного поля х:
private
{ Private declarations }
X: Integer;
Для обработчика события OnActivate формы fmExampie Напишите такой код:
procedure TfmExample.For.gif" >
Задание названия раздела
21.3.2. Задание названия разделаНазвание раздела используется в Help-службе следующим образом:
• оно появляется после активизации опции закладка в главном меню Help-службы;
• оно указывается в списке разделов диалоговых окон, связанных с кнопками поиск и хронология инструментальной панели справочного окна.
На Рисунок 21.3 показано окно поиск справочной службы Delphi.
Записи
7.2.2. ЗаписиЗапись - это структура данных, состоящая из фиксированного количества компонентов, называемых полями записи. В отличие от массива компоненты (поля) записи могут быть различного типа. Чтобы можно было ссылаться на тот или иной компонент записи, поля именуются.
Структура объявления типа записи такова:
<имя типа> = record <сп.полей> end;
Здесь <имя типа> - правильный идентификатор; record/ end - зарезервированные слова {запись, конец); <сп.полей> - список полей; представляет собой последовательность разделов записи, между которыми ставится точка с запятой.
Каждый раздел записи состоит из одного или нескольких идентификаторов полей, отделяемых друг от друга запятыми. За идентификатором (идентификаторами) ставится двоеточие и описание типа поля (полей), например:
type
BirthDay = record Day, Month: Byte;
Year : Word end;
var
a,b : Birthday;
В этом примере тип BirthDay (день рождения) есть запись с полями Day, Month и Year (день, месяц и год); переменные а и в содержат записи типа BirthDay.
Как и в массиве, значения переменных типа записи можно присваивать другим переменным того же типа, например
а := b;
К каждому из компонентов записи можно получить доступ, если использовать составное имя, т. е. указать имя переменной, затем точку и имя поля:
a.day := 27;
b.year := 1939;
Для вложенных полей приходится продолжать уточнения:
type
BirthDay = record Day,Month: Byte;
Year : Word end;
var
с : record
Name : String;
Bd : BirthDay end;
begin
if c.Bd.Year = 1989 then ... end.
Чтобы упростить доступ к полям записи, используется оператор присоединения with:
with <переменная> do <оператор>;
Здесь with, do - зарезервированные слова (с, делать);
<переменная> - имя переменной типа запись, за которой, возможно,
следует список вложенных полей; <оператор> - любой оператор Object Pascal.
Например:
с.Bd.Month := 9;
Это эквивалентно
with c.Bd do Month := 9;
или with с do with Bd do Month := 9;
или with с, Bd do Month := 9;
Object Pascal разрешает использовать записи с так называемыми вариантными полями, например:
type
For.gif" >
APPLICATION
20.1. APPLICATIONОбъект Application относится к классу TAppiication и инкапсулирует важнейшие свойства и методы программы как таковой. Он создается автоматически и доступен любой программе. Объект не помещен в палитру компонентов, поэтому его свойства недоступны на этапе конструирования, но становятся доступны при прогоне программы[ Некоторые свойства программы (в том числе ее пиктограмма, сведения о версии и используемом языке) могут устанавливаться с помощью менеджера проекта (опция project | Options и страница Application). ].
Application является посредником между программой и операционной системой. В частности, с его помощью осуществляется диспетчеризация сообщений Windows, реализуется контекстно-чувствительная справочная служба, он обрабатывает клавиши-акселераторы, исключительные ситуации и т. д.
Ниже описываются некоторые свойства Application для приложения Windows (для приложения Linux объект Application несколько отличается). Опущенные свойства предназначены в основном для прямого обращения к API-функциям Windows.
| property Active: Boolean; | Содержит True, если любое окно программы имеет фокус ввода |
| property BiDiMode: TBiDiMode; | Определяет свойство bidiMode (см. п. 17.12) для программы в целом |
| property CurrentHelpFile: Strings; | Определяет имя текущего справочного файла |
| property ExeName: Strings; | Содержит полное имя (с маршрутом доступа) исполняемого файла программы |
| property HelpFile: String; | Определяет имя файла справочной службы |
| property Hint: String; | Содержит длинную часть оперативной подсказки |
| property HintColor: TColor; | Определяет цвет фона ярлычка оперативной подсказки |
| property HintHidePause: Integers; | Определяет паузу (в миллисекундах) от момента появления ярлычка до его исчезновения |
| property HintPause: Integer; | Определяет паузу (в миллисекундах) от момента остановки указателя мыши до появления ярлычка |
| property HintShortPause: Integers; | Определяет паузу (в миллисекундах) появления ярлычка при переходе с одного компонента на другой |
| property Icon: TIcon; | Определяет пиктограмму программы |
| property MainFor.gif" > |
SCREEN
20.2. SCREENОбъект screen класса TScrеen инкапсулирует свойства и методы, упрощающие работу с дисплеем ПК, в том числе с его помощью оперативно изменяется вид используемого программой указателя мыши. Как правило, программа устанавливает указатель в виде песочных часов перед началом длинной по времени работы и восстанавливает умалчиваемую форму после ее завершения. Для этого используется свойство Cursor объекта Screen:
Screen.Cursor := crHourGlass;
// Выполняем длительную работу:
….
// Восстанавливаем умалчиваемую срорму:
Screen.Cursor :== crDefault;
Свойства объекта Screen:
| property ActiveControl: TWinCon-
trol; |
Содержит ссылку на элемент с фокусом ввода |
| property ActiveFor.gif" > |
PRINTER
20.3. PRINTERОбъект Printer автоматически создается, если в программе указана ссылка на модуль printers. Этот объект предоставляет программисту все необходимое для того, чтобы научить программу выводить данные на один из подключенных к ПК принтеров.
Вывод на принтер в Windows ничем не отличается от вывода на экран: в распоряжение программиста предоставляется свойство сап-vas объекта printer, содержащее набор чертежных инструментов и методы, свойственные классу TCanvas. Размер листа бумаги в пикселях принтера определяют свойства Height и Width, а набор принтерных шрифтов - свойство Fonts.
Свойства объекта printer:
| property Aborted: Boolean; | Содержит True, если выполнение предыдущего задания на печать было досрочно прекращено |
| property Canvas: TCanvas; | Канва принтера - основной инструмент создания изображения на листе бумаги |
| type TPrinterCapability =
(pcCopies, pcOrientation, pcCollation) ; TPrinterCapabilities = set of TPrinterCapability; property Capabilities: TPrinter Capabilities; |
Содержит возможности текущей настройки драйвера принтера: pcCopies - может печататься несколько копий документа; pcOrien tation -драйвер поддерживает разную ориентацию листа бумаги; pcCollation -документ печатается в подбор по экземплярам |
| property Copies: Integer; | Указывает требуемое количество копий документа |
| property Fonts: TStrings; | Содержит список всех доступных принтеру шрифтов |
| TPrinterOrientation =
(poPortrait, poLandscape) ; property Orientation: TPrinterOrientation; |
Определяет ориентацию листа бумаги:
poPortrait вертикальная; poLandscape - горизонтальная |
| property PageHeight: Integer; | Содержит высоту листа бумаги в пикселях принтера |
| property PageNumber: Integers; | Содержит номер печатаемой страницы документа (начинается с 1) |
| property PageWidth: Integer; | Содержит ширину листа бумаги в пикселях принтера |
| property Printerlndex: Integer; | Содержит индекс умалчиваемого принтера в списке Printers |
| property Printers: TStrings; | Содержит список всех доступных принтеров |
| property Printing: Boolean; | Содержит True, если принтер занят печатью документа |
| property Title: String; | Содержит имя задания на печать |
| Методы объекта printer: | |
| procedure Abort; | Досрочно прекращает печать документа |
| procedure BeginDoc; | Начинает печать документа |
| procedure EndDoc; | Завершает печать документа |
| procedure NewPage; | Начинает печать новой страницы документа |
procedure TFor.gif" >
CLIPBOARD
20.4. CLIPBOARDВ Windows широко используется буфер межпрограммного обмена данными Clipboard. Если программа Delphi сослалась на модуль Сlipbrd, для нее становится доступным автоматически созданный объект clipboard, инкапсулирующий методы и свойства для работы с буфером.
Свойства объекта clipboard:
| property AsTex-t: Strings; | Рассматривает содержимое буфера как текстовую строку длиной до 255 символов. Для обмена с буфером более длинными строками следует использовать его методы SetTextBuf и GetTextBuf |
| property For.gif" > |
НАСТРОЙКА ПРОГРАММ
20.5. НАСТРОЙКА ПРОГРАММУдобным средством хранения индивидуальных параметров настройки программы являются широко используемые в Windows З.х файлы инициации (файлы с расширением ini). Для Windows 32 индивидуальная настройка программ реализуется с помощью системного реестра. В этом разделе рассматриваются оба способа, т. к. даже если вы работаете с Windows 32, перенос программ на другие ПК проще реализовать с помощью ini-файлов.
TActionMainMenu gif" >
18.2.20. TActionMainMenu.gif" >ЭТАПЫ РАЗРАБОТКИ
21.1. ЭТАПЫ РАЗРАБОТКИРазработка Help-службы требует решения следующих основных задач.
ПЛАНИРОВАНИЕ СИСТЕМЫ СПРАВОК
21.2. ПЛАНИРОВАНИЕ СИСТЕМЫ СПРАВОКНа этапе планирования необходимо составить перечень разделов справочной службы и нужных перекрестных ссылок. Структура разделов и количество перекрестных ссылок зависит от сложности программы, для которой создается Help-служба, и опыта (и вкуса) разработчика. Полезно учесть следующие рекомендации.
СОЗДАНИЕ ТЕКСТОВЫХ ФАЙЛОВ
21.3. СОЗДАНИЕ ТЕКСТОВЫХ ФАЙЛОВВся справочная информация помещается в один или несколько текстовых файлов в формате RTF. Для их создания может использоваться любой текстовый редактор, поддерживающий этот формат.
При создании текстовых файлов учтите следующие особенности их подготовки:
| Сноска “#” Перечеркнутый или дважды подчеркнутый текст Подчеркнутый текст | Указывает идентификатор раздела Определяет отображение связанного с текстом раздела (перекрестной ссылки) в стандартном справочном окне
Определяет отображение раздела перекрестной ссылки в окне пояснений (“всплывающем” окне) |
| Скрытый текст | Определяет идентификатор раздела, связанного с перекрестной ссылкой |
| Сноска “$” | Задает название раздела |
| Сноска “К” | Указывает список ключевых слов для поиска раздела |
| Сноска “+” | Задает порядковый номер раздела в списке просмотра связанных разделов |
| Сноска “ /\ ” | Определяет условие компиляции раздела |
| Сноска “>” | Определяет тип дополнительного окна, в котором будет отображаться раздел |
| Сноска “!” | Указывает макрокоманду, которая будет выполняться при открытии окна с разделом |
РАЗРАБОТКА ПРОЕКТНОГО ФАЙЛА
21.4. РАЗРАБОТКА ПРОЕКТНОГО ФАЙЛАПроектный файл служит основным управляющим документом для Help-компилятора. В Windows 32 он создается с помощью утилиты Microsoft Help Workshop (MS HW) и представляет собой AS-CII-текстовый файл, содержащий несколько секций. Секция - это фрагмент текста, состоящий из заголовка и одной или нескольких следующих за ним строк (опций) вида
ИМЯ_ПАРАМЕТРА = ЗНАЧЕНИЕ,
подобно тому как организованы файлы инициации ini.
Для запуска MS HW следует загрузить файл help | tools | hcw.exe из папки размещения Delphi. Если файл проекта уже был ранее создан, для работы с ним используется опция File | open или соответствующая кнопка инструментальной панели MS HW. Для создания нового проектного файла выберите File | New и в дополнительном диалоговом окне - Help project; после указания имени создаваемого Help-файла в стандартном диалоговом окне save File окно MS HW приобретет вид, показанный на Рисунок 21.6.
Всю центральную часть окна занимает текст проектного файла, который первоначально состоит из единственной секции [options]. В отличие от обычных текстовых редакторов это окно недоступно для клавиатурного ввода: чтобы вставить в него текст или изменить уже введенные секции, используются расположенные справа кнопки.
ФАЙЛ СОДЕРЖАНИЯ СПРАВОЧНОЙ СЛУЖБЫ
21.5. ФАЙЛ СОДЕРЖАНИЯ СПРАВОЧНОЙ СЛУЖБЫСодержание справочной службы оформляется в файле с расширением сыт и становится доступным после нажатия кнопки содержание в справочном окне. Для создания/редактирования содержания используется утилита MS HW.
В строках Default filename (and window) И Default title В верхней части окна нужно указать соответственно имя ньр-файла, для которого создается содержание, и тип окна для отображения оглавлений, а также заголовок основного окна справочной службы. Замечу, что заголовок Default title, если он задан, переопределяет заголовок, указанный в секции [Options] файла проекта (см. п. 21.4.1).
Эти параметры можно установить вручную, но удобнее для ввода использовать вспомогательное диалоговое окно, которое раскрывается кнопкой Edit справа от строки Default title. При ручном вводе в строке Default filename (and window) имя файла отделяется от имени окна символом “>”.
Например:
HelpTest.hlp>WIND
Элементы содержания могут быть темами и разделами. Темы служат узлами в иерархической структуре содержания. В окне справочной службы слева от названия темы указывается пиктограмма в виде раскрытой или захлопнутой книги. Раздел - конечный элемент содержания. Слева от него указывается пиктограмма.
Для вставки в файл элемента содержания нужно щелкнуть по кнопке Add Above или Add Below. В первом случае элемент вставляется перед текущим элементом, во втором - после него.
Переключатели в верхней части окна определяют тип вставляемого элемента:
Heading - вставляется тема; при выборе этого переключателя все расположенные ниже строки, кроме Title, становятся недоступными;
Topic - вставляется раздел;
Macro - вставляется макрокоманда; эта макрокоманда будет выполняться при выборе элемента в окне содержания;
include - вставляется ASCII-текстовый файл с элементами содержания.
Четыре строки ниже переключателей используются только при вставке раздела. При вставке темы или включаемого файла доступна только первая строка, при вставке макрокоманды - первая и вторая, которая в этом случае снабжается надписью Macro.
В строке Title вводится произвольный текст длиной до 127 символов, который будет представлять элемент в окне содержания. В этой строке также указывается имя включаемого файла, если выбран переключатель Include. Во второй строке указывается идентификатор раздела или имя макрокоманды. В строке Help file нужно указать ньр-файл, если справочная система использует несколько файлов, а в строке window type - тип окна для отображения раздела.
Для смещения элемента оглавления на один уровень иерархии вниз используется клавиша Move Right, а на один уровень вверх -Move Left. Элемент сдвигается вместе со всеми другими элементами, расположенными ниже него. Максимальное количество уровней иерархии - 9.
Следует заметить, что файл содержания представляет собой AS-СН-текстовый файл, каждая строка которого соответствует элементу содержания. В начале строки указывается цифра, определяющая уровень иерархии, на котором располагается элемент. На Рисунок 21.8 для примера показано содержание справочной службы What's New in Delphi и соответствующий ей сnт-файл.
КОМПИЛЯЦИЯ ТЕСТИРОВАНИЕ И СВЯЗЬ С ПРОГРАММОЙ
21.6. КОМПИЛЯЦИЯ, ТЕСТИРОВАНИЕ И СВЯЗЬ С ПРОГРАММОЙКомпиляция и тестирование справочной службы не составляют проблемы: с помощью MS HW создайте (или загрузите) проектный файл и щелкните по кнопке save and compile или по инструментальной кнопке . После этого появляется окно, показанное на Рисунок 21.9.
При компиляции MS HW сворачивает свое окно и вновь раскрывает его после завершения работы компилятора, если отмечен переключатель Minimize window while compiling. После окончания компиляции в нем будут показаны сообщения компилятора. Если компилятор обнаружил ошибки, он сообщает о них, причем некритические ошибки сопровождаются предупреждениями (warnings) и замечаниями (notes), а критические - прерывают компиляцию.
МАКРОКОМАНДЫ WINHELP
21.7. МАКРОКОМАНДЫ WINHELPСправочная служба Windows 32 - WinHelp имеет встроенные макрокоманды, которые доступны из справочной службы программы. Макрокоманды могут выполняться в следующих случаях:
| Макрокоманда | Назначение |
| Управление инструментальными кнопками | |
| Back.gif" > |
TActionTollBar полоса кнопок для действий
18.2.21. TActionTollBar - полоса кнопок для действийКомпонент служит настраиваемым контейнером для связанных с действиями инструментальных кнопок. Кнопки реализуются техникой “перетаскивания” действий из окна менеджера действий (Рисунок 18.20).
Большое количество свойств компонента связано с динамически создаваемыми внутренними объектами, имеющими, в свою очередь, множество свойств (методов и событий). За подробной информацией о свойствах компонента и связанных с ними классами обратитесь к справочной службе.
TCustomizeDIg диалог настройки интерфейса
18.2.22. TCustomizeDIg - диалог настройки интерфейсаЭтот компонент служит для активизации окна менеджера действий (Рисунок 18.20). Для этого у него имеется единственный метод
procedure Show;
Свойство
property ActionManager: TCustomActionManager;
определяет экземпляр менеджера действий, окно которого нужно активизировать. Поскольку это окно не модальное, оно может перекрываться другими окнами. Если в свойство компонента
property StayOnTop: Boolean;
установить True, окно менеджера действий всегда будет располагаться поверх других окон.
Для вызова метода show проще всего использовать дополнительное меню контейнера опций или кнопок. Например:
procedure TFor.gif" >
ПУСТАЯ ФОРМА И ЕЕ МОДИФИКАЦИЯ
3.1. ПУСТАЯ ФОРМА И ЕЕ МОДИФИКАЦИЯКак уже говорилось, окно формы содержит проект Windows-окна программы. Важно помнить, что с самого начала работы над новой программой Delphi создает минимально необходимый код, обеспечивающий ее нормальное функционирование в Windows. Таким образом, простейшая программа готова сразу после выбора опции File | New | Application, и нам остается просто запустить програм-му. Однако до этого советую выполнить две важные вещи: создать собственный рабочий каталог (папку) и нужным образом настроить Delphi.
РАЗМЕЩЕНИЕ НОВОГО КОМПОНЕНТА
3.2. РАЗМЕЩЕНИЕ НОВОГО КОМПОНЕНТАРазместить на форме новый компонент не представляет труда. Для этого сначала нужно его выбрать (щелкнуть по нему мышью) в палитре компонентов, а затем щелкнуть мышью по точке рабочего пространства формы, где должен располагаться левый верхний угол компонента.
Попробуем таким способом включить в окно программы компонент Label (Метка), предназначенный для размещения различного рода надписей. Убедитесь в том, что в палитре компонентов выбрана страница Standard, и щелкните мышью по кнопке (эта кнопка отображает компонент Label в палитре компонентов). Теперь щелкните мышью по форме так, чтобы компонент появился на форме и располагался левее и выше ее центра (Рисунок 3.1). Первоначальные размеры и положение компонента на форме легко изменяются мышью, поэтому добиваться полного сходства с рисунком необязательно.
Новый компонент имеет стандартное имя Label1, и надпись на нем повторяет это имя. Изменим эту надпись: с помощью строки Caption окна Инспектора объектов введите надпись: я программирую на Delphi. Как только вы начнете вводить новую надпись, вид ком-понента на форме начнет меняться, динамически отражая все изменения, производимые вами в окне Инспектора объектов.
Выделим надпись цветом и сделаем ее шрифт более крупным. Для этого щелкните мышью по свойству Font окна Инспектора объектов и с помощью кнопки в правой части строки раскройте диалоговое окно настройки шрифта. В списке size (Размер) этого окна выберите высоту шрифта 24 пункта [ Пункт - 1/72 дюйма, т. е. приблизительно 0,04 мм. Таким образом, 24 пункта означает высоту шрифта чуть более 9 мм. ], а с помощью списка Color (Цвет) выберите нужный цвет (например, красный), после чего закройте окно кнопкой ок.
РЕАКЦИЯ НА СОБЫТИЯ
3.3. РЕАКЦИЯ НА СОБЫТИЯНастало время познакомиться с языком программирования Object Pascal, т. к. только с его помощью мы можем придать программе нужную функциональность и заставить ее выполнять полезную работу. Как уже говорилось, функциональность программы определяется совокупностью ее реакций на те или иные события. В связи с этим каждый компонент помимо свойств характеризуется также набором событий, на которые он может реагировать.
НЕКОТОРЫЕ ИТОГИ
3.4. НЕКОТОРЫЕ ИТОГИПеред тем как навсегда расстаться с нашей первой программой, сформулируем главные выводы, полученные в ходе работы с ней.
Динамическое изменение свойств компонента
3.3.3. Динамическое изменение свойств компонентаПоскольку кнопка Button1 в нашей программе способна “звучать”, полезно изменить ее надпись: вместо умалчиваемой надписи Button1, которую автоматически формирует Delphi по имени компонента, назовем кнопку, например, “Звук”. Проще всего это сделать с помощью окна формы и Инспектора объектов, т. е. на этапе конструирования формы (для этого нужно просто изменить свойство caption компонента Button1 в окне Инспектора объектов), но для более полного знакомства с Delphi мы рассмотрим другой способ - динамического[ К сожалению, эта процедура работает не всегда: если ваш ПК не оснащен звуковой картой, динамик будет молчать. В этом случае вместо MessageBeep (MB_OK) напишите просто Веер. Изменения на этапе конструирования называются статическими, а в ходе прогона программы - динамическими. ] изменения надписи на этапе прогона программы. Для этого создадим обработчик события OnCreate (По созданию) для формы и изменим в нем это свойство.
Событие OnCreate возникает после создания windows-окна, но до появления этого окна на экране. Чтобы создать обработчик этого события, раскройте список компонентов в верхней части окна Инспектора объектов, выберите компонент For.gif" >
Интерфейсный модуль
13.4.3. Интерфейсный модульПри вызове DLL-подпрограмм в большинстве случаев бывает необходимо передавать структурированные параметры типа записей, как тип TComplex в предыдущем примере. Поскольку DLL не могут экспортировать типы, приходится объявлять эти типы в вызывающей программе. Если вы часто обращаетесь в своих программах к той или иной DLL, удобно создать интерфейсный модуль, содержащий объявления как подпрограмм, так и связанных с ними типов. Например:
Unit Complx;
Interface
type
TComplex = record Re, Im: Real;
end;
function AddC(x, y: TComplex): TComplex; stdcall;
External 'Cmplx' index 1;
function SubC(x, y: TComplex): TComplex; stdcall;
External 'Cmplx' index 2;
function MulC(x, y: TComplex): TComplex; stdcall;
External 'Cmplx' index 3;
function DivC(x, y: TComplex): TComplex; stdcall;
External 'Cmplx' index 4;
Implementation end.
Такой интерфейсный модуль существенно упрощает разработку основной программы: в нашем примере он обеспечивает такой же интерфейс к библиотеке cmpix, как описанный выше модуль cmpix к своим объектам.
При обращении к подпрограммам DLL, написанным на других языках программирования, может оказаться, что внешнее имя подпрограммы содержит символы, которые не могут содержаться в правильном идентификаторе Delphi. Например, язык C++ разрешает использовать в идентификаторах символ “@”. В этом случае (а также если вы хотите переименовать экспортируемую из DLL подпрограмму) именуйте подпрограмму любым правильным с точки зрения Delphi идентификатором и укажите истинное имя подпрограммы после слова name. Например:
function MyFunction: WordBool; stdcall;
external 'MyDLL' name '_MyFunction@12'
Изменение свойств формы
3.1.3. Изменение свойств формыИтак, первый и самый простой шаг в Delphi-программировании вами уже сделан: вами создана нормальная Windows-программа. Разумеется, эта программа не реализует придуманного вами алгоритма, онавообще ничего путного не умеет делать, но это не беда! Впереди много времени и эта толстая книга, в которой как раз и рассказывается о том, как заставить вашу программу делать что-нибудь стоящее.
Теперь попробуем разобраться с тем, что такое модуль. В первом приближении мы можем считать модулем самостоятельный раздел программы, в чем-то подобный главе в книге. Модуль создается каждый раз, когда вы создаете новую форму (в программе может быть и, чаще, бывает не одна, а несколько - иногда несколько десятков форм и связанных с ними модулей). При компиляции программы Delphi создает файлы с расширениями pas, dfm и оси для каждого модуля: pas-файл содержит копию текста из окна кода программы, в файле с расширением dfm хранится описание содержимого окна формы, а в оси-файле - результат преобразования в машинные инструкции текста из обоих файлов. Файлы dcu создаются компилятором и дают необходимую базу для работы компоновщика, который преобразует их в единый загружаемый файл с расширением ехе.
Попробуем модифицировать программу, например, изменим заголовок ее окна. По умолчанию (т. е. без каких-либо усилий с нашей стороны) заголовок окна совпадает с заголовком формы: For.gif" >
Элементы программы
5.2.3. Элементы программыЭлементы программы - это минимальные неделимые ее части, еще несущие в себе определенную значимость для компилятора. К элементам относятся:
Идентификаторы - это слова, которыми программист обозначает любой другой элемент программы, кроме зарезервированного слова, идентификатора или комментария. Идентификаторы в Object Pascal могут состоять из латинских букв, арабских цифр и знака подчеркивания. Никакие другие символы или специальные знаки не могут входить в идентификатор. Из этого простого правила следует, что идентификаторы не могут состоять из нескольких слов (нельзя использовать пробел) или включать в себя символы кириллицы (русского алфавита).
Типы - это специальные конструкции языка, которые рассматриваются компилятором как образцы для создания других элементов программы, таких как переменные, константы и функции. Любой тип определяет две важные для компилятора вещи: объем памяти, выделяемый для размещения элемента (константы, переменной или результата, возвращаемого функцией), и набор допустимых действий, которые программист может совершать над элементами данного типа. Замечу, что любой определяемый программистом идентификатор должен быть описан в разделе описаний (перед началом исполняемых операторов). Это означает, что компилятор должен знать тот тип (образец), по которому создается определяемый идентификатором элемент.
Константы определяют области памяти, которые не могут изменять своего значения в ходе работы программы. Как и любые другие элементы программы, константы могут иметь свои собственные имена. Объявлению имен констант должно предшествовать зарезервированное слово const (от англ. constants - константы). Например, мы можем определить константы const
Kbyte = 1024;
Mbyte = Kbyte*Kbyte;
Gbyte = 1024*Mbyte;
чтобы вместо длинных чисел
1048576 (1024*1024) и 1073741824
(1024*1024*1024) писать, соответственно, Mbyte и Gbyte. Тип константы определяется способом ее записи и легко распознается компилятором в тексте программы, поэтому программист может не использовать именованные константы (т. е. не объявлять их в программе явно).
Переменные связаны с изменяемыми областями памяти, т. е. с такими ее участками, содержимое которых будет меняться в ходе работы программы. В отличие от констант переменные всегда объявляются в программе. Для этого после идентификатора переменной ставится двоеточие и имя типа, по образу которого должна строиться переменная. Разделу объявления переменной (переменных) должно предшествовать слово var. Например:
var
inValue: Integer;
byValue: Byte;
Здесь идентификатор inValue объявляется как переменная типа integer, а идентификатор byValue - как переменная типа Byte. Стандартный (т. е. заранее определенный в Object Pascal) тип integer определяет четырехбайтный участок памяти, содержимое которого рассматривается как целое число в диапазоне от -2 147 483 648 до+2 147 483 647, а стандартный тип Byte - участок памяти длиной 1 байт, в котором размещается беззнаковое целое число в диапазоне от 0 до 255 4 .[ Все приводимые в книге сведения относительно диапазона возможных значений и объема памяти стандартных типов относятся к Delphi 32. Для 16-разрядной версии 1 эти величины имеют другие значения, например, тип Integer в версии 1 занимает 2 банта и имеет диапазон значении от -32 768 до+32 767. ]
Метки - это имена операторов программы. Метки используются очень редко и только для того, чтобы программист смог указать компилятору, какой оператор программы должен выполнятся следующим. Метки, как и переменные, всегда объявляются в программе. Разделу объявлений меток предшествует зарезервированное сло-во label (метка). Например:
label
Loop;
begin
Goto Loop;
// Программист требует передать управление
// оператору, помеченному меткой Loop. .....
// Эти операторы будут пропущены
Loор:
// Оператору, идущему за этой меткой,
.....
// будет передано управление
end;
Подпрограммы - это специальным образом оформленные фрагменты программы. Замечательной особенностью подпрограмм является их значительная независимость от остального текста программы. Говорят, что свойства подпрограммы локализуются в ее теле. Это означает, что, если программист что-либо изменит в подпрограмме, ему, как правило, не понадобится в связи с этим изменять что-либо вне подпрограммы. Таким образом, подпрограммы являются средством структурирования программ, т. е. расчленения программ на ряд во многом независимых фрагментов. Структурирование неизбежно для крупных программных проектов, поэтому подпрограммы используются в Delphi-программах очень часто.
В Object Pascal есть два сорта подпрограмм: процедуры и функции. Функция отличается от процедуры только тем, что ее идентификатор можно наряду с константами и переменными использовать в выражениях, т. к. функция имеет выходной результат определенного типа. Если, например, определена функция
Function MyFunction: Integer;
и переменная var
X: Integer;
то возможен такой оператор присваивания:
Х := 2*MyFunction-l;
Имя процедуры нельзя использовать в выражении, т. к. процедура не имеет связанного с нею результата:
Procedure MyProcedure;
…
X := 2*MyProcedure-l; // Ошибка!
Класс TBrush
16.4.3. Класс TBrushОбъекты класса TBrush (кисти) служат для заполнения внутреннего пространства замкнутых фигур.
Свойства класса:
| property Bitmap: TBitmap; | Содержит растровое изображение, которое будет использоваться кистью для заполнения. Если это свойство определено, свойства Color и Style игнорируются |
| property Color: TColor; | Цвет кисти |
| property Handle: Integer; | Дескриптор кисти. Используется при не посредственном обращении к API- функциям Windows |
| property Style: TBrushStyle; | Стиль кисти (см. Рисунок 16.3) |
Клавиатура в MSDOS и Windows
17.6.3. Клавиатура в MS-DOS и WindowsСледует заметить, что Windows значительно “строже” относится к использованию клавиатуры, чем MS-DOS. Это может вызывать проблемы при переносе игровых приложений, а также приложений, созданных с помощью FoxPro или Clipper, в среду Delphi.
Если вы захотите сохранить устоявшиеся приемы использования клавиатуры в новой разработке (а я настоятельно рекомендую сделать это), вам, возможно, придется перехватывать сообщения Windows, так как только таким способом программа сможет опознать факт нажатия на системные клавиши Alt, Tab, Shift и т. п. Нажатие на остальные клавиши можно анализировать с помощью перехвата сообщений от клавиатуры в обработчиках Опкеуххх формы при установленном значении True в ее свойство Keypreview. Например, пусть акселератор Alt+X используется в существующей программе для закрытия модального диалогового окна. Чтобы сконструированное вами окно закрывалось по этой команде, напишите для него такой Обработчик события OnKeyDown:
procedure TFor.gif" >
Множества
7.2.3. МножестваМножества - это наборы однотипных логически связанных друг с другом объектов. Характер связей между объектами лишь подразумевается программистом и никак не контролируется Object Pascal. Количество элементов, входящих в множество, может меняться в пределах от 0 до 256 (множество, не содержащее элементов, называется пустым). Именно непостоянством количества своих элементов множества отличаются от массивов и записей.
Два множества считаются эквивалентными тогда и только тогда, когда все их элементы одинаковы, причем порядок следования элементов в множестве безразличен. Если все элементы одного множества входят также и в другое, говорят о включении первого множества во второе. Пустое множество включается в любое другое.
Пример определения и задания множеств:
type
digitChar = set of '0'..'9';
digit = set of 0. .9;
var
sl,s2,s3 : digitChar;
s4,s5,s6 : digit;
begin
si = ['1', '2', '3'];
s2 = ['3', '2', '1'];
s3 = ['2', '3'];
s4 = [0..3, 6];
s5 = [4, 5];
s6 = [3..9];
end.
В этом примере множества si и s2 эквивалентны, а множество S3 включено в s 2 , но не эквивалентно ему.
Описание типа множества имеет вид:
<имя типа> = set of <базовый тип>;
Здесь <имя типа> - правильный идентификатор; set, of - зарезервированные слова (множество, из); <базовый тип> - базовый тип элементов множества, в качестве которого может использоваться любой порядковый тип, кроме Word, Integer, Longint, Int64.
Для задания множества используется так называемый конструктор множества: список спецификаций элементов множества, отделенных друг от друга запятыми; список обрамляется квадратными скобками. Спецификациями элементов могут быть константы или выражения базового типа, а также тип-диапазон того же базового типа.
Над множествами определены следующие операции:
* пересечение множеств; результат содержит элементы, общие для обоих множеств; например, s4*s6 содержит [3], s4*s5 -пустое множество (см. выше);
+ объединение множеств; результат содержит элементы первого множества, дополненные недостающими элементами из второго множества:
S4+S5 содержит [0,1,2,3,4,5,6];
S5+S6 содержит [3, 4, 5, 6, 7, 8, 9] ;
разность множеств; результат содержит элементы из первого множества, которые не принадлежат второму:
S6-S5 содержит [3,6,7,8,9];
S4-S5 содержит [0,1, 2, 3, 6] ;
= проверка эквивалентности; возвращает True, если оба множества эквивалентны;
<> проверка неэквивалентности; возвращает True, если оба множества неэквивалентны;
<= проверка вхождения; возвращает True, если первое множество включено во второе;
>= проверка вхождения; возвращает True, если второе множество включено в первое;
in проверка принадлежности; в этой бинарной операции первый элемент - выражение, а второй - множество одного и того же типа; возвращает True, если выражение имеет значение, принадлежащее множеству:
3 in s 6 возвращает True;
2*2 in si возвращает False.
Дополнительно к этим операциям можно использовать две процедуры.
include - включает новый элемент во множество. Обращение к процедуре:
Include(S,I)
Здесь s - множество, состоящее из элементов базового типа TSet Base; I - элемент типа TSetBase, который необходимо включить во множество.
exclude - исключает элемент из множества. Обращение:
Exclude(S,I)
Параметры обращения - такие же, как у процедуры include. В отличие от операций + и -, реализующих аналогичные действия над двумя множествами, процедуры оптимизированы для работы с одиночными элементами множества и поэтому отличаются высокой скоростью выполнения.
Учебная программа PRIMSET
В следующем примере, иллюстрирующем приемы работы с множествами, реализуется алгоритм выделения из первой сотни натуральных чисел всех простых чисел[ Простыми называются целые числа, которые не делятся без остатка на любые другие целые числа, кроме 1 и самого себя. К простым относятся 1, 2, 3, 5, 7, 11, 13 и т. д.. ]. В его основе лежит прием, известный под названием “решето Эратосфена”. В соответствии с этим алгоритмом вначале формируется множество BeginSet, состоящее из всех целых чисел в диапазоне от 2 до N. В множество primerset (оно будет содержать искомые простые числа) помещается 1. Затем циклически повторяются следующие действия:
Эту программу нельзя использовать для произвольного N, так как в любом множестве не может быть больше 256 элементов.
procedure TfmExample.bbRunClick(Sender: TObject);
// Выделение всех простых чисел из первых N целых
const
N = 255; // Количество элементов исходного множества
type
SetOfNumber = set of 1..N;
var
n1,Next,i: Word; // Вспомогательные переменные
BeginSet, // Исходное множество
PrimerSet: SetOfNumber; // Множество простых чисел
S : String;
begin
BeginSet := [2..N];
// Создаем исходное множество
PrimerSet:= [1]; // Первое простое число
Next := 2; // Следующее простое число
while BeginSet о [ ] do // Начало основного цикла
begin
nl := Next; //nl-число, кратное очередному простому (Next)
// Цикл удаления из исходного множества непростых чисел:
while nl <= N do
begin
Exclude(BeginSet, nl);
n1 := nl + Next // Следующее кратное
end; // Конец цикла удаления
Include(PrimerSet, next);
// Получаем следующее простое, которое есть первое
// число, не вычеркнутое из исходного множества
repeat
inc(Next)
until (Next in BeginSet) or (Next > N)
end;
// Конец основного цикла
// Выводим результат:
S := '1';
for i := 2 to N do
if i in PrimerSet then
S := S+', '+IntToStr(i);
mmOutput.Lines.Add(S)
end;
Перед тем как закончить рассмотрение множеств, полезно провести небольшой эксперимент. Измените описание типа SetOfNumber следующим образом:
type
SetOfNumber = set of 1..1;
и еще раз запустите программу из предыдущего примера. На экран будет выведено 1, 3, 5, 7
Множества BeginSet и PrimerSet состоят теперь из одного элемента, а программа сумела поместить в них не менее семи!
Секрет этого прост: внутреннее устройство множества таково, что каждому его элементу ставится в соответствие один двоичный разряд (один бит); если элемент включен во множество, соответствующий разряд имеет значение 1, в противном случае - 0. В то же время минимальной единицей памяти является один байт, содержащий 8 бит, поэтому компилятор выделил множествам по одному байту, и в результате мощность каждого из них стала равна 8 элементам. Максимальная мощность множества - 256 элементов. Для таких множеств компилятор выделяет по 16 смежных байт.
И еще один эксперимент: измените диапазон базового типа на 1..256. Хотя мощность этого типа составляет 256 элементов, при попытке компиляции программы компилятор сообщит об ошибке: Sets may have at most 256 elements (Множества могут иметь не более 256 элементов) т. к. нумерация элементов множества начинается с нуля независимо от объявленной в программе нижней границы. Компилятор разрешает использовать в качестве базового типа целочисленный тип-диапазон с минимальной границей 0 и максимальной 255 или любой перечисляемый тип не более чем с 256 элементами (максимальная мощность перечисляемого типа - 65536 элементов).
Одноименные методы
9.2.3. Одноименные методыВ отличие от остальных версий Delphi в версиях 4...6 появилась возможность в рамках одного класса иметь несколько одноименных методов. Описанный выше механизм перекрытия родительского метода одноименным методом потомка приводит к тому, что потомок “не видит” перекрытый родительский метод и может обращаться к нему лишь с помощью зарезервированного слова inherited. В Delphi 4 введено зарезервированное слово overload (перезагрузить), с помощью которого становятся видны одноименные методы как родителя, так и потомка.
При обнаружении одноименного метода компилятор Delphi предупреждает о том, что у класса уже есть аналогичный метод с дру гими параметрами. Для подавления сообщений объявление одноименного метода можно сопровождать зарезервированным словом reintrpduce (вновь ввести).
Примечание
Примечание
Чтобы одноименные методы можно было отличить друг от друга,каждый из них должен иметь уникальный набор, параметров. В ходе шлпоянения программы при: обращении к одному, из одноименнх методов программа проверяет; тип и количество фактических параметров обращения и выбирает нужный метод
В следующем примере в классе TFor.gif" >
Операторы повторений
5.4.3. Операторы повторенийВ языке Object Pascal имеются три различных оператора, с помощью которых можно запрограммировать повторяющиеся фрагменты программ.
Счетный оператор цикла FOR имеет такую структуру:
for <параметр цикла> := <нач_знач> to <кон знач> do <оператор>;
Здесь for, to, do - зарезервированные слова (для, до, выполнить);
<параметр_цикла> - переменная типа Integer (точнее, любого по-, рядкового типа, см. гл. 7); <нач_знач> - начальное значение - выражение того же типа; <кон_знач> - конечное значение - выражение того же типа; <оператор> - произвольный оператор Object Pascal.
При выполнении оператора for вначале вычисляется выражение <нач_знач> и осуществляется присваивание <параметр_цикла> := <нач_знач>. После этого циклически повторяется:
В качестве иллюстрации применения оператора for рассмотрим программу, осуществляющую ввод произвольного целого числа n и вычисление суммы всех целых чисел от 1 до N.
Для нового приложения (опция File | New | Application) соз дайте такой обработчик bbRunСlick:
procedure TfmExample.bbRunClick(Sender: TObject);
var
i,N,Sum : Integer;
begin
try // Преобразуем ввод с контролем правильности:
N := StrToInt(edInput.Text);
except // Следующие операторы выполняются, если есть ошибка ShowMessage('Ошибка ввода целого числа');
dinput.SelectAll; // Выделяем неверный ввод
Exit // Завершаем работу обработчика
end;
edInput.Text :=' ';
edinput.SetFocus;
Sum := 0; // Начальное значение Sum
for i := 1 to N
do // Цикл формирования суммы
Sum := Sum+i;
mmOutput.Lines.Add('Сумма всех целых чисел '+'в диапазоне 1...'+IntToStr(N)+' равна '+IntToStr(Sum));
end ;
Комментарий к программе
Прежде всего обратите внимание на операторы
try // Преобразуем ввод с контролем правильности:
N := StrToInt(edinput.Text);
except // Следующие операторы выполняются, если есть ошибка ShowMessage("Ошибка ввода целого числа');
edinput.SelectAll; // Выделяем неверный ввод
Exit // Завершаем работу обработчика
end;
С помощью зарезервированных слов try (попробовать), except (исключение) и end реализуется так называемый защищенный блок. Такими блоками программист может защитить программу от краха при выполнении потенциально опасного участка (подробнее см. п. 14.1). В отличие от предыдущих программ мы не изменили компонент edinput, поэтому пользователь может ввести в нем произвольный текст. Если этот текст не содержит правильное представление целого числа, попытка выполнить оператор
N := StrToInt(edInput.Text);
в обычной программе привела бы к аварийному завершению программы. Чтобы этого не произошло, мы защитили этот оператор, расположив его за try и перед except. Если ошибки нет, все операторы, стоящие за except и до end, пропускаются и обработчик нормально срабатывает. Если обнаружена ошибка, возникает так называемая исключительная ситуация (исключение) и управление автоматически передается оператору, стоящему за except, - начинается обработка исключения. Вначале с помощью стандартной процедуры ShowMessage мы сообщаем пользователю об ошибке[ Если вы запустите программу из среды Delphi, исключение будет сначала перехвачено средой и на экране появится сообщение на английском языке о характере и месте возникновения ошибки. В этом случае закройте окошко с сообщением и нажмите F9 - программа продолжит свою работу, и вы увидите окно процедуры ShowMessage. ], затем с помощью edInput. SeiectAll выделяем ошибочный текст в компоненте edinput и, наконец, с помощью вызова стандартной процедуры Exit аварийно завершаем работу обработчика (но не программы!).
Отметим также два обстоятельства. Во-первых, условие, управляющее работой оператора for, проверяется перед выполнением оператора <оператор>: если условие не выполняется в самом начале работы оператора for, исполняемый оператор не будет выполнен ни разу. Другое обстоятельство - шаг наращивания параметра цикла строго постоянен и равен (+1). Существует другая форма оператора:
for <пар_цик>: = <нач_знач> downto <кон_знач> do <оператор>;
Замена зарезервированного слова to на downto означает, что шаг наращивания параметра цикла равен (-1), а управляющее условие Приобретает вид <параметр__цикла> = <кон_знач>.
Предыдущий пример можно модифицировать так, чтобы сделать его пригодным для подсчета любых сумм - положительных и отрицательных:
Sum := 0;
if N >= 0 then
for i := 1 to N do
Sum := Sum + i
else
for i := -1 downto N do
Sum := Sum + i ;
Два других оператора повторений лишь проверяют условие выполнения или повторения цикла, но не связаны с изменением счетчика цикла.
Оператор цикла WHILE с предпроверкой условия:
while <условие> do <оператор>;
Здесь while, do - зарезервированные слова {пока [выполняется условие], делать), <условие> - выражение логического типа; <оператор> - произвольный оператор Object Pascal.
Если выражение <условие> имеет значение True, то выполняется <оператор>, после чего вычисление выражения <условие> и его проверка повторяются. Если <условие> имеет значение False, оператор while прекращает свою работу.
Учебная программа EPSILON
Программа отыскивает так называемое “машинное эпсилон” -такое минимальное, не равное нулю вещественное число, которое после прибавления его к 1,0 еще дает результат, отличный от 1,0. Замечу, что для хранения и преобразования дробных чисел в Object Pascal предназначены так называемые вещественные типы (см. гл. 7). В учебной программе используется один из этих типов - Real, занимающий 8 смежных байт и представляющий дробные (вещественные) числа в диапазоне от 10- 324 до 10+ 308 с точностью 15... 16 значащих цифр 10 .
У читателя, привыкшего к непрерывной вещественной арифметике, может вызвать недоумение утверждение о том, что в дискретной машинной арифметике всегда существуют такие числа o
procedure TfmExample.bbRunClick(Sender: TObject) ;
var
Epsilon: Real;
begin
Epsilon := 1;
while l+Epsilon/2>l do
Epsilon := Epsilon/2;
IbOutput.Caption := 'Машинное эпсилон = ' +FloatToStr(Epsilon)
end;
Комментарий к программе
Для вещественных чисел можно использовать операцию деления без отбрасывания дробной части ( символ “/”). После применения этой операции результат всегда имеет вещественный тип, поэтому такой фрагмент программы ошибочен:
var
X : Integer; begin
X := 4/2; // Ошибка!Вещественный результат нельзя
// присвоить целой переменной
end;
Стандартная функция FloatToStr преобразует вещественное число в строку символов.
Оператор цикла REPEAT... UNTIL с постпроверкой условия:
repeat <тело цикла> Until <условие>;
Здесь repeat, until - зарезервированные слова (повторять [до тех пор}, пока [не будет выполнено условие]); <тело_цикла> - произвольная последовательность операторов Object Pascal; <условие> - выражение логического типа.
Операторы <тело_цикла> выполняются хотя бы один раз, после чего вычисляется выражение <условие>: если его значение есть False, операторы <тело_цикла> повторяются, в противном случае оператор repeat... until завершает свою работу.
Обратите внимание: пара repeat... unti1 подобна операторным скобкам begin ... end, поэтому перед until ставить точку с запятой необязательно.
Замечу, что для правильного выхода из цикла условие выхода должно меняться внутри операторов, составляющих тело цикла while или repeat... until. Следующие циклы никогда не завершатся “естественным” способом:
while True do begin
end;
и
repeat
until False;
Для гибкого управления циклическими операторами for, while и repeat в состав Object Pascal включены две процедуры без параметров:
break - реализует немедленный выход из цикла; действие процедуры заключается в передаче управления оператору, стоящему сразу за концом циклического оператора;
continue - обеспечивает досрочное завершение очередного прохода цикла; эквивалент передачи управления в самый конец циклического оператора.
Введение в язык этих процедур практически исключает необходимость использования операторов безусловного перехода goto (см. ниже п. 5.4.5).
Определение ключевых слов
21.3.3. Определение ключевых словHelp-служба позволяет искать разделы по связанным с ними ключевым словам. В диалоговом окне Поиск (см. выше Рисунок 21.3) предусмотрены строка (1) для ввода ключевых слов и возможность выбора их из списка (2). Для любого раздела можно назначить сколько угодно ключевых слов и наоборот - с любым ключевым словом можно связать сколько угодно разделов.
Для определения ключевого слова в начале раздела (до первого символа текста раздела) ставится сноска, помеченная латинской буквой “К” или “k”. Например: к открыть;текст файл;ASCII;текст
Все связанные с разделом ключевые слова помещаются в текст сноски и отделяются от “К” одним пробелом, а друг от друга символом “;”. Группы связанных по смыслу ключевых слов объединяются во фразы, которые отделяются друг от друга пробелами. Help-служба ищет и отображает в списке выбора названия всех разделов, ключевые слова которых перечислены в одной фразе. Например, если для приведенной выше сноски пользователь ввел слово файл, будут представлены названия разделов, связанных со словами файл, ASCII и текст.
Помимо основной таблицы ключевых слов в Help-службе может быть определена дополнительная таблица. Слова из дополнительной таблицы не показываются в окне Поиск. Их использование возможно только вмакрокомандах ALink и TestALink (СМ. П. 21.7). Для вставки ключевых слов в дополнительную таблицу используется сноска, помеченная латинской буквой “А”: А таблица/слово
Палитра компонентов
2.1.3. Палитра компонентовПалитра компонентов - это главное богатство Delphi. Она занимает правую часть главного окна и имеет закладки, обеспечивающие быстрый поиск нужного компонента. Под компонентом понимается некий функциональный элемент, содержащий определенные свойства и размещаемый программистом в окне формы. С помощью компонентов создается каркас программы, во всяком случае - ее видимые на экране внешние проявления: окна, кнопки, списки выбора и т. д.
Как и панель кнопок, палитра компонентов может настраиваться. Для этого используется специальный редактор, окно которого появляется на экране после щелчка правой кнопкой мыши на любой пиктограмме в палитре компонентов и выбора опции properties (Свойства) (Рисунок 2.5).
Нет смысла удалять какой-то из компонентов, а создавать новые мы с вами пока еще не умеем, поэтому я не рекомендую вам экспериментировать с редактором палитры. Тем не менее один совет все-таки дам. В стандартном наборе страниц палитры компонентов есть страница Samples, содержащая довольно часто используемые компоненты. В то же время ее закладка в палитре закрыта двумя небольшими кнопками “прокрутки” закладок палитры. Имеет смысл поменять ее местами с менее используемой страницей, например, со страницей ADO. Вы можете “перетащить” строку Samples в окне Pages редактора палитры вверх и “положить” ее на строку ADO. После такой перестановки закладка Samples станет доступна в любой момент. Если, к тому же, вы не планируете использовать в своих проектах технологию ADO для доступа к базам данных, перетащите строку ado в самый конец списка.
Полиморфизм
9.1.3. ПолиморфизмПолиморфизм - это свойство классов решать схожие по смыслу проблемы разными способами. В рамках Object Pascal поведенческие свойства класса определяются набором входящих в него методов. Изменяя алгоритм того или иного метода в потомках класса, программист может придавать этим потомкам отсутствующие у родителя специфические свойства. Для изменения метода необходимо перекрыть его в потомке, т. е. объявить в потомке одноименный метод и реализовать в нем нужные действия. В результате в объекте-родителе и объекте-потомке будут действовать два одноименных метода, имеющих разную алгоритмическую основу и, следовательно, придающих объектам разные свойства. Это и называется полиморфизмом объектов.
В Object Pascal полиморфизм достигается не только описанным выше механизмом наследования и перекрытия методов родителя, но и их виртуализацией (см. ниже), позволяющей родительским методам обращаться к методам своих потомков.
Секция WINDOWS
21.4.3. Секция WINDOWSСекция [windows] определяет используемый в справочной службе набор дополнительных окон. Каждое указанное в секции окно характеризуется своим типом, цветом, размерами, заголовком. Только имена перечисленных в секции окон могут указываться в ссылках и сносках “>” RTF-файлов.
В строке create a window named следует задать имя окна. Замечу, что, если указать имя main, установки, производимые далее, будут относиться к основному окну справочной службы (именно таким способом мне, например, удалось получить нужный заголовок основного окна). С помощью списка Based on this standard window можно выбрать один из трех возможных стандартных типов окна:
procedure - окно предназначено для вывода текстов процедур; оно позиционируется в правом верхнем углу экрана и при значительной ширине может своим правым краем выйти за пределы экрана;
Reference - обычное справочное окно; позиционируется в левом верхнем углу, занимает приблизительно 2/3 экрана по высоте и ширине;
Error message - окно предназначено для вывода сообщений об ошибках, позиционируется по центру экрана, занимает почти всю высоту экрана и 3/4 его ширины.
Замечу, что все три типа создают стандартные Windows-окна с “толстой” рамкой и заголовком, т. е. их положение и размеры пользователь может изменять по своему усмотрению, так что выбор типа не носит решающего характера. Кроме того, с помощью кнопки Auto sizer на странице position (см. ниже) можно визуально настроить положение и размеры окна.
Страница General
window type - позволяет выбрать одно из ранее определенных окон; все дальнейшие установки на странице General будут осуществляться для указанного в этой строке окна; подобные строки есть на всех других страницах окна window Properties;
Add - вызывает окно Рисунок 21.8 для добавления нового окна к списку окон;
Remove - удаляет окно из списка;
include - включает ASCII-текстовьгй файл со списком окон;
Title bar text - определяет заголовок окна;
comment - содержит произвольный комментарий; здесь, например, можно указать функциональность окна; текст комментария не включается в результирующий файл;
Auto-size height - если переключатель выбран, окно автоматически изменяет высоту в зависимости от разрешения экрана;
Maximize window - окно максимизируется по размеру экрана;
Keep Help window on top - окно всегда появляется поверх остальных окон.
Страница Position определяет положение и размеры окна в момент его появления на экране. тор - отступ левого верхнего угла от верхнего края экрана;
Left - отступ левого верхнего угла от левого края экрана;
Height - высота окна;
width - ширина окна;
Adjust for user screen resolution - если переключатель выбран, координаты задаются относительно виртуального экрана с разрешением 1024х1024; если не выбран, координаты указываются в пикселях;
Auto-sizer - после щелчка по этой кнопке появляется окно с кнопками ОК и Cancel для визуальной настройки его размеров и положения;
Default position - после щелчка по этой кнопке окну задаются умалчиваемые размеры.
Страница Buttons
Определяет состав включаемых в окно инструментальных кнопок. Если выбран указанный ниже переключатель, в окно вставляется соответствующая кнопка.
Contents - кнопка Содержание;
Index - кнопка Индекс;
Find - кнопка Поиск;
Help Topics - кнопка Разделы;
Print - кнопка Печать;
Back.gif" >
Создание окна просмотра
11.7.3. Создание окна просмотраНаконец, на третьем этапе создается окно просмотра, т. е. собственно отображение данных в адресное пространство программы:
function MapViewOfFile(hFileMappingObject: THandle; dwDesiresAccess: DWord; dwFileOffsetHigh, dwFileIffsetLow, dwNumberOfBytesToMap: DWord): Pointer;
Здесь hFileMappingObject -дескриптор объекта отображения; dwDesiresAccess - определяет способ доступа к данным и может иметь одно из следующих значений: file_map_write - разрешает чтение и запись, При ЭТОМ В функции CreateFileMapping должен использоваться атрибут page_readwrite; file_map_read - разрешает только чтение, в функции CreateFileMapping должен использоваться атрибут
PAGE_READONLY или PAGE_READWRITE; FILE_MAP_ALL_ACCESS - тоь же, что и file_map_write; file_map_copy - данные доступны для записи и чтения, однако обновленные данные сохраняются в отдельной защищенной области памяти; в функции CreateFileMapping должен использоваться атрибут page_writecopy; dwFileOffsetHigh, dwFileIffsetLow -определяют соответственно старшие и младшие разряды смещения от начала файла, начиная с которого осуществляется отображение;
dwNumberOfBytesToMap - определяет длину окна отображения (0 - длина равна длине файла). Функция возвращает указатель на первый байт отображенных данных или nil, если обращение к функции оказалось неуспешным.
Создание вспомогательных методов
10.5.3. Создание вспомогательных методовНесмотря на интенсивное использование классов TCompiexData и TCompiexVariantType, эти классы в конечном счете остаются скрытыми от пользователя нового варианта за счет набора вспомогательных методов, таких как VarComplexCreate, VarIsComplex, VarAsComplex и т. п., которые преобразуют обычные процедурные вызовы в вызовы методов и обращения к свойствам соответствующих классов.
Стандартные классы исключений
16.1.3. Стандартные классы исключенийВ Delphi определены стандартные классы исключений, перечисленные в табл. 16.1. Именно эти имена, а также имена пользовательских классов (см. п. 16.1.5) могут использоваться в обработчиках исключении.
Таблица 16.1
| Класс | Родитель | Обрабатываемое исключение |
| EAbort | Exception | Реализует “тихую” (без какого-либо сообщения) обработку любого исключения |
| EAbstractErrpr | Exception | Программа пытается вызвать абстрактный метод |
| EAccessViolation | Exception | Программа пыталась обратиться к не принадлежащей ей области памяти или использует недействительный указатель |
| EAppletException | Exception | Ошибка связана с созданием управляющих панелей в апплет-приложениях |
| EArrayError | Exception | Возникает из-за различного рода ошибок при работе с массивами (неверный индекс, попытка вставить элемент в массив фиксированной длины или в отсортированный массив и т. п.) |
| EAssertionFaild | Exception | Возбуждается отладочной процедурой Assert, когда тстируемое ею логическое выражение имеет значение False. |
| EBitsError | Exception | Программа пыталась обратиться к свойству Bits объекта TBits с индексом меньше нуля или больше максимально допустимого значения |
| EBrokerException | Exception | Объект-брокер не может найти сервер |
| ECacheError | Exception | Ошибка в наборе данных для компонента Tde-cisionCube |
| EClassNotFound | EFilerError | Для компонента, читаемого из потока данных, не найден соответствующий класс. Обычно возникает"в случае, когда в форму вставлен нестандартный компонент, а в библиотеке компонентов Delphi нет связанного с ним класса |
| ECommonCalendar-Error | Exception | Возникает в объектах класса TCommonCalendar и его потомках, когда вводится неверная дата |
| EComponentError | Exception | Возникает при различных манипуляциях программы с компонентом (программа не может зарегистрировать компонент, переименовать его или когда для его работы требуется интерфейс СОМ, который компонентом не поддерживается) |
| EControlC | Exception | Возникает при нажатии Ctrl-C при работе приложения в режиме консолиЛ |
| EConvertError | Exception | Ошибка преобразования в функциях StrToint или StrToFloat |
| ECorbaDispatch | Exception | Возникает в программах, использующих технологию corba, при ошибках, связанных с несовпадением интерфейсов сервера и брокера данных |
| ECorbaException | Exception | Возникает в программах, использующих технологию CORBA |
| ECorbaUser-Exception | ECorbaException | Возникает как определяемая пользователем реакция на ошибки интерфейса |
| EDatabaseError | Exception | Возникает, когда компонент обнаруживает ошибку в базе данных |
| EDateTimeError | Exception | Возбуждается компонентом TDateTimePicker при попытке ввода неверной даты или времени |
| EDBClient | EDatabaseError | Ошибка связана с неправильной работой Tcli-entDataSet |
| EDBEditError | Exception | Возникает, когда компонент пытается использовать данные, несовместимые с заданной маской |
| EDBEngineError | EDatabaseError | Связана с ошибками BDE |
| EDimensionMar-Error | Exception | Возникает, когда используемый в кубе решений набор данных не имеет агрегатных полей |
| EDimIndexError | Exception | Связана с нарушением размерности массива данных для куба решений |
| EDivByZero | EIntError | Ошибка целочисленного деления на ноль |
| EDSWriter | Exception | Ошибка при подготовке провайдером пакета данных для набора данных |
| EExternal-Exception | EStream-Error | Возникла ошибка, код которой не является предопределенным в Delphi |
| EFCreateError | EStream-Error | Ошибка при создании файла. Например, попытка создать файл на устройстве, предназначенном только для чтения, или в несуществующем каталоге |
| EFilerError | EStream-Error | Программа пытается повторно зарегистрировать в потоке один и тот же класс |
| EFOpenError | EStream-Error | Ошибка открытия потока данных. Например, попытка открыть несуществующий файл |
| EHeapException | Exception | Ошибка связана с неправильными операциями над динамической памятью |
| ElBClientError | ElBError | Ошибка связана с функционированием IBX-клиента |
| ElBError | EDatabaseError | Общая ошибка технологии IBX |
| ElBInterbase-Error | ElBError | Ошибка связана с функционированием сервера в технологии IBX |
| EInOutError | Exception | Любая ошибка в файловых операциях. Поле ErrorCode объекта этого класса содержит код ошибки |
| EInterpreterError | Exception | Возникает, когда компонент класса TDataBlockinterpeter не может интерпретировать данные блока данных |
| EIntError | Exception | Любая ошибка в целочисленных вычислениях |
| EIntfCastError | Exception | Попытка недопустимого приведения типов в OLE-объектах |
| EIntOverflow | EIntError | Ошибка целочисленного переполнения: программа пытается присвоить целочисленной переменной значение, выходящее из 32-двоичных разрядов |
| EInva1i dArgument | EMatchError | Возбуждается математическими функциями при выходе аргумента из допустимого диапазона |
| EInvalidCast | Exception | Программа пытается осуществить недопустимое преобразование типов с помощью оператора as |
| EInvalidGraphic | Exception | Программа пытается загрузить в контейнер изображение из файла, который имеет недопустимый формат (допустимыми форматами являются растр, метафайл, курсор, пиктограмма) |
| EInvalidGraphic-Operation | Exception | Программа пытается выполнить недопустимую графическую операцию |
| EInvalidGrid-Operation | Exception | Программа пытается выполнить недопустимую операцию над таблицей (например, обратиться к несуществующему столбцу или РЯДУ) |
| EInvalidImage | EFilerError | Программа пытается прочитать ресурс изображения из файла, в котором этого ресурса нет |
| EInvalidOp | EMatchError | Ошибка в операциях с плавающей точкой (недопустимая инструкция, переполнение стека сопроцессора и т. п.) |
| EInvalidOpera-tion | Exception | Не имеющий окна компонент пытается выполнить операцию, требующую дескриптора окна |
| EInvalidPointer | EHeap-Exception | Попытка использовать недействительный указатель |
| EListError | Exception | Эта ошибка связана с неверными действиями программы по отношению к разного рода спискам. Например обращение к элементу списка с индексом меньше нуля или больше максимально допустимого |
| ELowCapacity-Error | Exception | Ошибка возникает при попытке выделения памяти на устройстве, у которого нет нужной свободной памяти. |
| EMatchError | Exception | Любая ошибка при выполнении вычислений с плавающей точкой. |
| EMenu.gif" > |
Страница dbExpress
4.8.3. Страница dbExpress7 компонентов, представленных на этой странице, поддерживают технологию dbExpress прямого доступа к некоторым промышленным серверам баз данных. Все компоненты страницы впервые введены в версии 6.
Страница WebServices
4.9.3. Страница WebServicesКомпоненты этой страницы поддерживают технологию SOAP Simple Object Access Protocol) для создания служб Web. Служба Web - это программа, запускаемая сервером Web в ответ на клиентское требование. Служба должна подготовить отклик, который она возвращает серверу, а тот - клиенту.
TFontDialog диалог выбора шрифта
18.5.3. TFontDialog - диалог выбора шрифтаКомпонент TFontDialog создает и обслуживает стандартное окно выбора шрифта (Рисунок 18.41). Свойство
TFontDialogDevice = (fdScreen, fdPrinter, fdBoth) ;
property Device: TFontDialogDevice;
определяет тип устройства, для которого выбирается шрифт:
fdScreen - экран; fdPrinter - принтер; fdBoth - шрифты, поддерживаемые и экраном, и принтером.
TImageList хранилище изображений
18.3.3. TImageList - хранилище изображенийКомпонент класса TImageList представляет собой контейнер для хранения множества рисунков одинакового размера. Он может быть полезен при программном создании набора инструментальных кнопок, секций управляющего заголовка, при разработке программ, использующих анимационные эффекты, и вообще там, где требуется индексированный доступ к изображениям.
Компонент не имеет собственной канвы и поэтому не может самостоятельно отображать хранимые в нем картинки, которые могут быть растрами (bmp) или пиктограммами (ico). Его метод Draw получает канву от другого компонента и рисует изображение в клиентской области этого компонента. В компоненте есть множество специальных свойств и методов, упрощающих обслуживание набора картинок. Для получения дополнительной информации обратитесь к встроенной справочной службе. Пример использования компонента см. в п. 18.2.13.
Тип датавремя
7.1.3. Тип дата-времяТип дата-время определяется стандартным идентификатором TDateTime и предназначен для одновременного хранения и даты, и времени. Во внутреннем представлении он занимает 8 байт и подобно currency представляет собой вещественное число с фиксированной дробной частью: в целой части числа хранится дата, в дробной - время. Дата определяется как количество суток, прошедших с 30 декабря 1899 года, а время - как часть суток, прошедших с 0 часов, так что значение 36444,837 соответствует дате 11.10.1999 и времени 20:05. Количество суток может быть и отрицательным, однако значения меньшие -693594 (соответствует дате 00.00.0000 от Рождества Христова) игнорируются функциями преобразования даты к строковому типу.
Над данными типа TDateTime определены те же операции, что и над вещественными числами, а в выражениях этого типа могут участвовать константы и переменные целого и вещественного типов.
Для работы с датой и временем используются подпрограммы, перечисленные в табл. 7.6.
Таблица 7.6. Подпрограммы для работы с датой и временем
| Function Date: TDateTime;
Function DateToStr(D: TDateTime): String; Function DateTimeToStr(D: TDateTime): String ; Function For.gif" > |
TMaskEdit специальный редактор
18.2.3. TMaskEdit - специальный редактор
Специализированный редактор TMaskEdit предназначен для ввода текста, соответствующего некоторому шаблону, задаваемому свойством EditMask: String. Если это свойство не задано, TMaskEdit работает как обычный редактор TEdit. Свойство IsMasked: Boolean доступно только для чтения и содержит True, если строка шаблона задана. Свойство EditText: string содержит текст до наложения на него маски шаблона (т. е. то, что ввел пользователь), а свойство Text: String может (в зависимости от шаблона см. ниже) содержать либо исходный текст, либо результат наложения на него маски шаблона.
Шаблон состоит из трех частей, отделенных друг от друга символами “;”. Первая часть задает маску ввода, вторая - это символ “О” или “I”, определяющий, записывается ли в Text результат наложения маски или исходный текст (“О” - исходный текст). В третьей части указывается символ, который в окне редактора будет стоять в полях, предназначенных для ввода символов (текст в редакторе может содержать символы маски; например, для ввода семизначного номера телефона текст в начале ввода может выглядеть так: (095)ХХХ-ХХ-ХХ где доступные для ввода пользователя поля указаны символом “X” -последним символом в шаблоне).
Маска состоит из описателей полей ввода, специальных символов и литералов. Описатель указывает, какой именно символ может ввести пользователь в данное поле (описатель всегда описывает поле единичной длины, т. е. рассчитанное на ввод одного символа). Литерал вставляется в текст, показываемый в окне редактора, но при вводе курсор перескакивает через литерал и не дает пользователю возможности изменить его. Литералами считаются любые символы, кроме описателей полей и специальных символов, а также любой символ, которому предшествует символ “\”. Специальные символы формируют дополнительные указания редактору.
Описатели полей ввода представлены в следующей таблице:
| Символ Поле... |
| L должно содержать букву
с может содержать любой символ 1 может содержать букву 0 должно содержать цифру А должно содержать букву или цифру 9 может содержать цифру а может содержать букву или цифру # может содержать цифру, “+”, “-” С должно содержать любой символ |
| Специальные символы: | |
| \ | Следующий символ - литерал. Позволяет вставить в маску литералы из символов описателей полей ввода и специальных символов |
| : | На это место вставляется символ-разделитель Windows для часов, минут, секунд |
| / | На это место вставляется символ-разделитель Windows для полей даты |
| ; | Разделитель частей шаблона |
| ! | Подавляет все ведущие пробелы |
| > | Все следующие за ним поля ввода преобразуют буквы к заглавным |
| < | Все следующие за ним поля ввода преобразуют буквы к строчным |
| <> | Отменяет преобразование букв |
| Маска | Вид в редакторе | Свойство EditText | Свойство Text |
| (095)000-0000;0;х | (095)ххх-хххх | 123456 | 1234567 |
| (095)0000000;1;х | (095)ххх-хххх | 7 12345 | (095)1234567 |
| (095)\0\00-0000;1; . | (095)00.-.... | 1234567 | (095)0012345 |
Остальные свойства компонента повторяют соответствующие свойства TEdit. В частности, установка в свойство passwordchar любого символа, кроме #0, обеспечивает секретность ввода: в этом случае все вводимые в компоненте символы заменяются символом PasswordChar.
TMediaPlayer медиаплейер
18.4.3. TMediaPlayer - медиаплейерКомпонент TMediaPlayer представляет собой набор кнопок (Рисунок 18.36), предназначенных для управления различными мультимедийными устройствами (компакт-дисками, звуковыми картами и т. п.).
TPopupMenu gif" >
18.1.3. TPopupMenu.gif" >TSpinButton спаренная кнопка
18.7.3. TSpinButton - спаренная кнопкаВ отличие от компонента TUpDown (см. п. 18.3.7) компонент TSpinButton не связан с регулированием числовой величины и может использоваться просто как пара кнопок: верхняя (up) и нижняя (Down). Для компонента следует написать обработчики его событий onup-click и onDownclick, в которых реализуется реакция программы на щелчок по той или иной кнопке.
Рисунки на кнопках определяются свойствами upGlyph и DownGiyph. Каждый рисунок может содержать 1, 2 или 3 изображения: 1-е - для нормальной кнопки, 2-е - для запрещенной, 3-е - для нажатой.
TTabbedNotebook набор страниц с закладками
18.6.3. TTabbedNotebook - набор страниц с закладкамиКомпонент TTabbedNotebook представляет собой объединение TTabSet и TNotebook в готовый многостраничный блокнот с заклад-ками. В отличие от TTabSet закладки в TabbedNotebook могут располагаться в несколько рядов.
Свойства ActivePage, Pagelndex И Pages компонента совпадают c одноименными свойствами компонента TNotebook. Свойство property TabsPerRow: Integer; определяет количество закладок в одном ряду.
С помощью метода function GetIndexFor.gif" >
Умалчиваемые параметры
8.2.3. Умалчиваемые параметрыВ Delphi 4, 5 и 6 можно использовать так называемые умалчиваемые параметры, т. е. параметры, которые могут опускаться при обращении к подпрограмме. Умалчиваемые параметры замыкают список формальных параметров и имеют вид
<имя>:<тип> = <значение>
Например,
Procedure P(a: array of Integer; S: String = '');
В этом случае два следующих обращения идентичны:
Р([1,2,3], ' ');
Р([1,2,3]);
Если в подпрограмме используются два и более умалчиваемых параметра, то в случае переопределения одного из них при обращении к подпрограмме следует указывать все параметры вплоть до последнего переопределяемого (т. е. нельзя заменять непереопределяемые умалчиваемые параметры запятыми). Например:
Procedure P(a: array of Integer; S: String = '';
В: Integer = 0) ;
Допустимые обращения:
Р([1,2,3]);
Р([1,2,3], 'Строка');
Р(1,2,3],",1)
Вариантные массивыпараметры
8.3.3. Вариантные массивы-параметрыВ Delphi 32 при передаче подпрограмме массивов переменной длины и размерности удобно использовать вариантные массивы (см. п. 7.4.3). В следующем примере с помощью функции GetAr-rayAverage определяется среднее арифметическое значение всех элементов вариантного массива произвольной длины и размерности не выше 5:
function GetArrayAverage (const V: Variant): Double;
{Возвращает среднее арифметическое значение массива произвольной длины и размерности или очень маленькую отрицательную величину, если V - не вариант или если его размерность больше 5} var
i,j,k,l,m: Integer;
Sum: Double;
NItem: Integer;
begin
Result := -1E-309;
if ((VarType(V) and VarArray) <> VarArray) or
(VarArrayDimCount(V) > 5) then Exit;
Sum := 0;
NItem := 0;
// Подсчитываем количество элементов массива
for k := 1 to VarArrayDimCount(V) do
NItem := NItem+VarArrayH'ighBound(V, k)-VarArrayLowBound(V,k) ;
// Подсчитываем сумму элементов case VarArrayDimCount(V) of
1: for i "VarArrayLowBound(V,1) to VarArrayHighBound(V,1) do
Sum := Sum+V[i] ;
2: for i =VarArrayLowBound(V,1) to VarArrayHighBound(V,1) do
for j :=VarArrayLowBound(V,2) to VarArrayHighBound(V,2) do
Sum := Sum+V[i,j] ;
3: for i: =VarArrayLowBound(V,1) to VarArrayHighBound(V,1) do
for j: =VarArrayLowBound(V,2) to VarArrayHighBound(V,2) do
for k: =VarArrayLowBound(V,3) to VarArrayHighBound(V,3) do
Sum := Sum+V[i,j,k] ;
4: for i: =VarArrayLowBound(V,1) to VarArrayHighBound(V,1) do
for j: =VarArrayLowBound(V,2) to VarArrayHighBound(V,2) do
for k :=VarArrayLowBound(V,3) to VarArrayHighBound(V,3) do
for l: =VarArrayLowBound(V,4) to VarArrayHighBound(V,4) do
Sum := Sum+V[i,j,k,1];
5: for i:=VarArrayLowBound(V,1) to VarArrayHighBound(V,1) do
for j :=VarArrayLowBound(V,2) to VarArrayHighBound(V,2) do
for k: =VarArrayLowBound(V,3) to VarArrayHighBound(V,3) do
for 1 :=VarArrayLowBound(V,4) to VarArrayHighBound(V,4) do
for m:= VarArrayLowBound(V,5) to VarArrayHighBound(V,5) do
Sum := Sum+V[i,j,k,1,m];
end;
Result := Sum/NItem
end;
В подобного рода подпрограммах ограничение на размерность вариантного массива определяется, как правило, количеством вариантов в предложении case.
Выделение и освобождение динамической памяти
7.4.3. Выделение и освобождение динамической памятиВся динамическая память в Object Pascal рассматривается как сплошной массив байтов, который называется кучей.
Память под любую динамически размещаемую переменную выделяется процедурой New. Параметром обращения к этой процедуре является типизированный указатель. В результате обращения указатель приобретает значение, соответствующее адресу, начиная с которого можно разместить данные, например:
var pI,pJ: ^Integer;
pR: ^Real;
begin
New (pI) ;
New (pR) ;
end;
После того как указатель приобрел некоторое значение, т. е. стал указывать на конкретный физический байт памяти, по этому адресу можно разместить любое значение соответствующего типа. Для этого в операторе присваивания сразу за указателем без каких-либо пробелов ставится значок ^ , например:
pJ^ := 2; // В область памяти pJ помещено значение 2
pl^ := 2*pi; // В область памяти pR помещено значение 6.28
Таким образом, значение, на которое указывает указатель, т. е. собственно данные, размещенные в куче, обозначаются значком ^, который ставится сразу за указателем. Если за указателем нет значка ^ , то имеется в виду адрес, по которому размещены данные. Имеет смысл еще раз задуматься над только что сказанным: значением любого указателя является адрес, а чтобы указать, что речь идет не об адресе, а о тех данных, которые размещены по этому адресу, за указателем ставится ^ (иногда об этом говорят как о разыменовании указателя).
Динамически размещенные данные можно использовать в любом месте программы, где это допустимо для констант и переменных соответствующего типа, например:
рR^ := Sqr(pR") + I^ - 17;
Разумеется, совершенно недопустим оператор
pR := Sqr(pR") + I^ - 17;
так как указателю pR нельзя присвоить значение вещественного выражения. Точно так же недопустим оператор
pR ^ := Sqr(pR) ;
поскольку значением указателя pR является адрес и его (в отличие от того значения, которое размещено по этому адресу) нельзя возводить в квадрат. Ошибочным будет и такое присваивание:
pR^' := pJ;
так как вещественным данным, на которые указывает pR, нельзя присвоить значение указателя (адрес).
Динамическую память можно не только забирать из кучи, но и возвращать обратно. Для этого используется процедура Dispose. Например, операторы
Dispose(pJ);
Dispose(pR);
вернут в кучу память, которая ранее была закреплена за указателями pJ и pR (см. выше).
Замечу, что процедура Dispose (pPtr) не изменяет значения указателя pPtr, а лишь возвращает в кучу память, ранее связанную с этим указателем. Однако повторное применение процедуры к свободному указателю приведет к возникновению ошибки периода исполнения. Освободившийся указатель программист может пометить зарезервированным словом nil. Помечен ли какой-либо указатель или нет, можно проверить следующим образом:
const
pR: ^Real = NIL;
begin
if pR = NIL then
New (pR) ;
Dispose(pR) ;
pR := NIL;
end;
Никакие другие операции сравнения над указателями не разрешены.
Приведенный выше фрагмент иллюстрирует предпочтительный способ объявления указателя в виде типизированной константы с одновременным присвоением ему значения nil. Следует учесть, что начальное значение указателя (при его объявлении в разделе переменных) может быть произвольным. Использование указателей, которым не присвоено значение процедурой New или другим способом, не контролируется Delphi и вызовет исключение.
Как уже отмечалось, параметром процедуры New может быть только типизированный указатель. Для работы с нетипизированными указателями используются Процедуры GetMem И FreeMem:
GetMem(P, Size); // резервирование памяти;
FreeMem(P, Size); // освобождение памяти.
Здесь р - нетипизированный указатель; size - размер в байтах требуемой или освобождаемой части кучи.
Примечание
Примечание
Испoльзoвaние прцeдyp GetMem/FreeMemMem, как и вообще вся работа диамияесжой памятью, требует особой осторожности и тщателвного солюдения простого правила: освобождать нужно ровно столько пайти, сколько её было зарезервировано, и именно с того адреса, с которого она была зарезёрвирована.
Дополнительные возможности APIфункций
16.4.4.1. Дополнительные возможности API-функцийЗамечу, что все богатство изобразительных возможностей Windows далеко не исчерпывается набором свойств и методов класса TCanvas: этот класс инкапсулирует лишь наиболее популярные приемы работы с чертежными инструментами. В этом разделе перечисляются некоторые функции Windows, которые не инкапсулирует класс TCanvas и которые способны значительно разнообразить текстовый вывод (именно он наиболее обеднен узкими рамками TCanvas).
Некоторые текстовые функции API
| type TLogFont = record
If Height: Integer; IfWidth: Integer; IfEs- capment: Integer; IfOri- entation: Integer; IfWeight: Integer; If Italic: Byte; IfUnder- line: Byte; IfStrikeOut: Byte; IfCharSet: Byte; IfOutPrecision: Byte; IfClipPrecision: Byte; IfQuality: Byte; IfPitchAndFamily: Byte; 1fFaceName: PChar ; end; function CreateFont(Font: TLogFont): hFont; |
Создает новый шрифт на основе данных в параметре Font. Назначение полей структуры TLogFont см. после таблицы |
| function DrawText(DC:hDC; pText: PChar; varRect:'TRect; For.gif" > |
СТРАНИЦА STANDARD
4.1. СТРАНИЦА STANDARDНа странице Standard палитры компонентов сосредоточены стандартные для Windows интерфейсные элементы, без которых не обходится практически ни одна программа.
Frame - рама. Наравне с формой служит контейнером для размещения других компонентов. В отличие от формы может размещаться в палитре компонентов, создавая заготовки компонентов. Впервые введен в версию Delphi 5.
MainMenu.gif" >
ДОСТУП К СЕРВЕРАМ АВТОМАТИЗАЦИИ
4.10. ДОСТУП К СЕРВЕРАМ АВТОМАТИЗАЦИИМногочисленные компоненты страницы servers обеспечивают удобный программный доступ к популярным СОМ-серверам, входящим в Microsoft Office'97 и доступным на любом компьютере, на котором полностью или частично установлен комплект этих программ.
Примечание
Примечание
Поскольку в базовом языке MS Qffice'97 - Visual Basic for Application - произошли значительные изменения по сравнению с версией, использовавшейся в MS Office'95 компоненты этой страницы будут нормально работать только с MS Office'97
Использование этих компонентов осложняется двумя обстоятельствами. Во-первых, на вашей машине или в доступном вам сетевом окружении должны быть установлены соответствующие серверы (Word, Excel, PowerPoint и т. д.). Во-вторых, все эти компоненты представляют собой так называемые контроллеры Автоматизации, т. е. существеннейшим образом используют многочисленные свойства, методы и события своих серверов. Поскольку взаимодействие с такого рода серверами требует знания интерфейса сервера (см. гл. 15), каждый компонент, с одной стороны, непривычно одинаков, показывая в окне Инспектора объектов лишь минимум свойств, общих для всех серверов Автоматизации, а с другой - разительно отличается от остальных своим уникальным набором свойств, методов и событий. Рассмотрение этих наборов далеко выходит за рамки любой книги по Delphi, кроме того, работа с СОМ и Объектами Автоматизации также не является целью этого диска.
Эти компоненты не могут использоваться в межплатформенных приложениях (Linux не поддерживает СОМ).
Области
16.4.4.2. ОбластиК сожалению, в класс TCanvas не включена еще одна изобразительная возможность Windows - области (Regions). Области - такие же графические объекты, как перо, кисть, шрифт. Они образуются с помощью комбинации простейших геометрических фигур - прямоугольников, многоугольников, эллипсов. Замечательной особенностью областей является возможность создания с их помощью непрямоугольных кнопок, цветовых областей, окон. А вот как оно было создано:
uses
For.gif" >
СТРАНИЦА ADDITIONAL
4.2. СТРАНИЦА ADDITIONALВ страницу Additonal помещены 18 дополнительных компонентов, с помощью которых можно разнообразить вид диалоговых окон.
BitBtn - командная кнопка с надписью и пиктограммой.
SpeedButton - пиктографическая кнопка. Обычно используется для быстрого доступа к тем или иным опциям главного меню.
MaskEdit - специальный текстовый редактор. Способен фильтровать вводимый текст, например, для правильного ввода даты.
StringGrid - таблица строк. Этот компонент обладает мощными возможностями для представления текстовой информации в табличном виде.
DrawGrid - произвольная таблица. В отличие от StringGrid ячейки этого компонента могут содержать произвольную информацию, в том числе и рисунки.
Image - рисунок. Этот компонент предназначен для отображения рисунков, в том числе пиктограмм и метафайлов.
Shape - фигура. С помощью этого компонента вы можете вставить в окно правильную геометрическую фигуру - прямоугольник, эллипс, окружность и т. п.
Bevel - кромка. Служит для выделения отдельных частей окна трехмерными рамками или полосами.
ScrollBox - панель с полосами прокрутки. В отличие от компонента Panel автоматически вставляет полосы прокрутки, если размещенные в нем компоненты отсекаются его границами.
CheckListBox - список множественного выбора. Отличается от стандартного компонента ListBox наличием рядом с каждой опцией независимого переключателя типа CheckBox, облегчающего выбор сразу нескольких опций. Впервые введен в версии 3.
Splitter - граница. Этот компонент размещается на форме между двумя другими видимыми компонентами и дает возможность пользователю во время прогона программы перемещать границу, отделяющую компоненты друг от друга. Впервые введен в версии 3.
StaticText - статический текст. Отличается от стандартного компонента Label наличием собственного windows-окна, что позволяет обводить текст рамкой или выделять его в виде “вдавленной” части формы. Впервые введен в версии 3.
ControiBar - полоса управления. Служит контейнером для “причаливаемых” компонентов в технологии Drag&Dock. Впервые введен в версии 4.
ApplicationEvents - получатель события. Если этот компонент помещен на форму, он будет получать все предназначенные для программы сообщения Windows (без этого компонента сообщения принимает глобальный объект-программа Application). Впервые введен в версии 5.
ValueListEditor - редактор строк, содержащих пары имя = значение. Пары такого типа широко используются в Windows, например, в файлах инициации, в системном реестре и т. п. Впервые введен в версии 6.
LabeledEdit - комбинация однострочного редактора и метки. Впервые введен в версии 6.
ColorBox - специальный вариант ComboBox для выбора одного из системных цветов. Впервые введен в версии 6.
Chart - диаграмма. Этот компонент облегчает создание специальных панелей для графического представления данных. Впервые введен в версии 3.
ActionManager - менеджер действий. Совместно с тремя следующими компонентами обеспечивает создание приложений, интерфейс которых (главное меню и инструментальные кнопки) может настраиваться пользователем. Впервые введен в версии 6.
ActionMainMenu.gif" >
Страница Win32 содержит интерфейсные элементы
4.3. СТРАНИЦА WIN32Страница Win32 содержит интерфейсные элементы для 32-разрядных операционных систем Windows 95/98/NT/2000 (в версии 2 эта страница называется win 9 5). Этой страницы нет в версии 1.
TabControl - набор закладок. Каждая закладка представляет собой прямоугольное поле с надписью и/или рисунком. Выбор той или иной закладки распознается программой и используется для управления содержимым окна компонента.
PageControl - набор панелей с закладками. Каждая панель может содержать свой набор интерфейсных элементов и выбирается щелчком по связанной с ней закладке.
ImageList - набор рисунков. Представляет собой хранилище для нескольких рисунков одинакового размера.
RichEdit - многострочный редактор форматированного текста. В отличие от компонента Memo страницы Standard текст в компоненте RichEdit подчиняется правилам Расширенного Текстового Формата (RTF - Rich Text For.gif" >
СТРАНИЦА SYSTEM
4.4. СТРАНИЦА SYSTEMНа этой странице представлены компоненты, которые имеют различное функциональное назначение, в том числе компоненты, поддерживающие стандартные для Windows технологии межпрограммного обмена данными OLE (Object Linking and Embedding -связывание и внедрение объектов) и DDE (Dynamic Data Exchange -динамический обмен данными). Технология DDE в современных программах полностью вытеснена гораздо более мощной технологией СОМ, и поэтому соответствующие им компоненты в книге не рассматриваются.
Timer - таймер. Этот компонент служит для отсчета интервалов реального времени.
PaintBox - окно для рисования. Создает прямоугольную область, предназначенную для прорисовки графических изображений.
MediaPlayer - мультимедийный проигрыватель. С помощью этого компонента можно управлять различными мультимедийными устройствами.
OleContainer - OLE-контейнер. Служит приемником связываемых или внедряемых объектов.
Компоненты этой страницы имеются во всех предыдущих версиях Delphi.
СТРАНИЦА DIALOGS
4.5. СТРАНИЦА DIALOGSКомпоненты страницы Dialogs реализуют стандартные для Windows диалоговые окна.
OpenDialog - открыть. Реализует стандартное диалоговое окно “Открыть файл”.
SaveDialog - сохранить. Реализует стандартное диалоговое окно “Сохранить файл”.
OpenPictureDialog - открыть рисунок. Реализует специальное окно выбора графических файлов с возможностью предварительного просмотра рисунков.
SavePictureDialog - сохранить рисунок. Реализует специальное окно сохранения графических файлов с возможностью предварительного просмотра рисунков.
FontDialog - шрифт. Реализует стандартное диалоговое окно выбора шрифта.
ColorDialog - цвет. Реализует стандартное диалоговое окно выбора цвета.
PrintDialog - печать. Реализует стандартное диалоговое окно выбора параметров для печати документа.
PrinterSetupDialog - настройка принтера. Реализует стандартное диалоговое окно для настройки печатающего устройства.
FindDialog - поиск. Реализует стандартное диалоговое окно поиска текстового фрагмента.
ReplaceDialog - замена. Реализует стандартное диалоговое окно поиска и замены текстового фрагмента.
Компоненты OpenPictureDialog И SavePictureDialog введены в версии 3, остальные имеются в предыдущих версиях. Разумеется, интерфейс окон для Windows 16 (версия 1) отличается от интерфейса Windows 32.
Большинство компонентов этой страницы введены
4.6. СТРАНИЦА WIN31Большинство компонентов этой страницы введены для совместимости с версией 1. В современных программах вместо них рекомендуется использовать соответствующие компоненты страницы Win32.
TabSet - набор закладок. В приложениях для Windows 32 вместо него рекомендуется использовать компонент TabControl.
OutLine - дерево выбора. В приложениях для Windows 32 вместо него рекомендуется использовать компонент Treeview.
TabbedNotebook - набор панелей с закладками. В приложениях для Windows 32 вместо него рекомендуется использовать компонент PageControl.
Notebook - набор панелей без закладок. В приложениях для Windows 32 вместо него рекомендуется использовать компонент Page-Control.
Header - управляющий заголовок. В приложениях для Windows 32 вместо него рекомендуется использовать компонент Header-Control.
FileListBox - панель выбора файлов.
DirectorybistBox - панель выбора каталогов.
DiriveComboBox - панель выбора дисков.
FilterComboBox - панель фильтрации файлов.
Компоненты FileListBox, DirectoryListBox, DriveComboBox и FilterComboBox впервые появились в версии 3. Их функции реализованы элементами стандартных окон OpenDialog и SaveDialog, которые и рекомендуется использовать в Windows 32.
| Назад |
СТРАНИЦА SAMPLES
4.7. СТРАНИЦА SAMPLESЭта страница содержит компоненты разного назначения.
Gauge - индикатор состояния. Подобен компоненту ProgressBar (страница Win32), но отличается большим разнообразием форм.
СolorGrid - таблица цветов. Этот компонент предназначен для выбора основного и фонового цветов из 16-цветной палитры.
SpinButton - двойная кнопка. Дает удобное средство управления некоторой числовой величиной.
SpinEdit - редактор числа. Обеспечивает отображение и редактирование целого числа с возможностью его изменения с помощью двойной кнопки.
DirectoryOutLine - список каталогов. Отображает в иерархическом виде структуру каталогов дискового накопителя.
Calendar - календарь. Предназначен для показа и выбора дня в месяце.
КОМПОНЕНТЫ ДЛЯ РАБОТЫ С БАЗАМИ ДАННЫХ
4.8. КОМПОНЕНТЫ ДЛЯ РАБОТЫ С БАЗАМИ ДАННЫХВ Delphi развиты средства построения приложений, рассчитанных на работу с электронными архивами (базами данных). Причем Delphi 6 предоставляет программисту возможность выбора способа доступа к данным: это может быть стандартный для ранних версий Delphi доступ с помощью машины баз данных BDE (Borland Data
base Engine), усиленно развиваемая Microsoft технология ADO ActiveX Data Objects), прямое управление сервером InterBase с помощью технологии IBExpress, наконец, технология dbExpress для непосредственного обращения к промышленным серверам MySQL, DB2, Oracle и некоторым другим.
КОМПОНЕНТЫ ДЛЯ ДОСТУПА К ИНТЕРНЕТ
4.9. КОМПОНЕНТЫ ДЛЯ ДОСТУПА К ИНТЕРНЕТ4.9.1. Страница Internet
Компоненты этой страницы обеспечивают средства связи программы с глобальной компьютерной сетью Интернет. Эта сеть позволяет установить соединение между двумя удаленными компьютерами, один из которых (клиент) получает информацию, а другой (сервер) передает ее. Оба компьютера должны следовать протоколу TCP/IP (Transport Control Protocol/Internet Protocol - транспортный управляющий протокол/Интернет протокол), обеспечивающему логическую независимость связи от аппаратных средств компьютеров. Частью Интернет является всемирная паутина World Wide Web
(WWW), использующая межкомпьютерный обмен так называемыми HTML-страницами (HyperText Markup Language - язык разметки гипертекста) на основе HTTP-протокола (HyperText Transfer Protocol - протокол передачи гипертекста). WWW реализует удобные средства для неформального общения мирового сообщества на са-мые разные темы. В то же время возможности Интернет не ограниваются только WWW, т. к. по глобальной сети можно передавать гктронную почту, разнообразные файлы, устраивать телеконференции и даже осуществлять телефонные переговоры. В последнее время усиленно развиваются так называемые интранет-сети, в ко-торых технология Интернет используется для передачи служебной и ювой информации в рамках одного или нескольких предприятий. для создания именно таких сетей и предназначены в основном компоненты этой страницы.
Фокус ввода
17.6.4. Фокус вводаПоскольку клавиатура - одна, а элементов, могущих ее использовать, может быть много, необходимо каким-то способом выделять элемент, которому в данный момент передается клавиатурный ввод. Это выделение достигается передачей элементу фокуса ввода с помощью его метода procedure SetFocus;
Компонент с фокусом ввода имеет значение True в своем свойстве property Focused: Boolean;
Если элемент запрещен к выбору или невидим, его свойство
property CanFocus: Boolean;
имеет значение False.
Фокус ввода передается элементу после щелчка на нем мышью или в порядке выбора его клавишей Tab. Чтобы элемент можно было выбирать этой клавишей, следует установить в его свойство
property TabStop: Boolean;
значение True. Порядок выбора элемента определяется свойством
property TabOrder: Integer;
Delphi следит за уникальностью и непрерывностью значений этого свойства у всех помещенных на форму не запрещенных и видимых в данный момент компонентов. С помощью метода procedure GetTabOrderList(List: TList) ; можно получить список всех дочерних элементов, выбираемых клавишей Tab.
Класс TCanvas
16.4.4. Класс TCanvasЭтот класс создает “канву”, на которой можно рисовать чертежными инструментами - пером, кистью и шрифтом. Объекты класса ЕСаnvas автоматически создаются для всех видимых компонентов, которые должны уметь нарисовать себя. Они инкапсулируют объекты Font, pen, Brush, а также многочисленные методы, использующие эти объекты.
Свойства класса:
| property Brush: TBrush; property ClipRect: TRect; | Объект-кисть Определяет текущие размеры области, нуждающейся в прорисовке |
| property CopyMode: TCopyMode; | Устанавливает способ взаимодействия растрового изображения с цветом фона |
| property Font: TFont; | Объект-шрифт |
| property Handle: Integer; | Дескриптор канвы. Используется при непосредственном обращении к API-функциям Windows |
| property LockCount: In
tegers; |
Счетчик блокировок канвы. Увеличивается на единицу при каждом обращении к методу Lock и уменьшается на единицу при обращении к Unlock |
| property Pen: TPen; | Объект-перо |
| property PenPos:TPoint; | Определяет текущее положение пера в пикселях относительно левого верхнего угла канвы |
| property Pixels[X,Y:Integer]: TColor; | Массив пикселей канвы |
| cmBlackness | Заполняет область рисования черным цветом |
| cmDestInvert | Заполняет область рисования инверсным цветом фона |
| cmMergeCopy | Объединяет изображение на канве и копируемое изображение операцией and |
| cmMergePaint | Объединяет изображение на канве и копируемое изображение операцией OR |
| cmNotSrcCopy | Копирует на канву инверсное изображение источника |
| cmNotSrcErase | Объединяет изображение на канве и копируемое изображение операцией OR и инвертирует полученное |
| cmPatCopy | Копирует образец источника |
| cmPatInvert | Комбинирует образец источника с изображением на канве с
помощью операции XOR |
| cmPatPaint | Комбинирует изображение источника с его образцом с помощью операции OR, затем полученное объединяется с изображением на канве также с помощью OR |
| cmSrcAnd | Объединяет изображение источника и канвы с помощью операции AND |
| cmSrcCopy | Копирует изображение источника на канву |
| cmSrcErase | Инвертирует изображение на канве и объединяет результат с изображением источника операцией AND |
| cmSrcInvert | Объединяет изображение на канве и источник операцией XOR |
| cmSrcPaint | Объединяет изображение на канве и источник операцией OR |
| cmWhitness | Заполняет область рисования белым цветом |
Методы класса:
| procedure Arc(X1, Y1, X2, Y2, ХЗ, Y3, Х4, Y4: Integer); | Чертит дугу эллипса в охватывающем прямоугольнике (Xl,Yl)-(X2,Y2). Начало дуги лежит на пересечении эллипса и луча, проведенного из его центра в точку (ХЗ, Y3), а конец - на пересечении с лучом из центра в точку (Х4, Y4). Дуга чертится против часовой стрелки (см. Рисунок 16.4, а) |
| procedure BrushCopy
(const Dest: TRect; Bitmap: TBitmap; const Source: TRect; Color: TColor); |
Копирует часть изображения Source на участок канвы Dest. Color указывает цвет в Dest, который должен заменяться на цвет кисти канвы. Метод введен для совместимости с ранними версиями Delphi. Вместо него следует пользоваться классом Т Image List |
| procedure Chord(XI,
Yl, X2, Y2, X3, Y3, |
Чертит сегмент эллипса в охватывающем прямоуголь нике (XI, У1) - (X2, Y2). Начало дуги сегмента лежит на пересечении эллипса и луча, проведенного из его центра в точку (X3, Y3), а конец - на пересечении с лучом из центра в точку (X4, Y4). Дуга сегмента чертится против часовой стрелки, а начальная и конечная точки дуги соединяются прямой (см. Рисунок 16.4, б) |
| procedure CopyRect (Dest: TRect; Canvas: TCanvas;Source: TRect) ; | Копирует изображение Source канвы Canvas в участок Dest текущей канвы. При этом разнообразные специальные эффекты достигаются с помощью свойства CopyMode |
| procedure Draw(X, Y:Integer; Graphic:TGraphic) ; | Осуществляет прорисовку графического объекта Graphic так, чтобы левый верхний угол объекта расположился в точке (X, Y) |
| procedure DrawFocusRect (const Rect:TRect) ; | Прорисовывает прямоугольник с помощью операции XOR, поэтому повторная прорисовка уничтожает ранее вычерченный прямоугольник. Используется в основном для прорисовки нестандартных интерфейсных элементов при получении ими фокуса ввода и при потере его |
| procedure Ellipse(XI, Yl, X2,
Y2: Integers; |
Чертит эллипс в охватывающем прямоугольнике (XI, Yl) - (X2, Y2). Заполняет внутреннее пространство эллипса текущей кистью |
| procedure FillRect(const Rect: TRect); | Заполняет текущей кистью прямоугольную область Rect, включая ее левую и верхнюю границы, но не затрагивая правую и нижнюю границы |
| procedure Flood-
Fill(X, Y: Integer; Color: TColor; Fill Style: TFillStyle); |
Производит заливку канвы текущей кистью. Залив
ка начинается с точки (X, Y) и распространяется вовсе стороны от нее. Если FillStyle=fsSurface, заливка распространяется на все соседние точки с цветом Color. Если FillStyle=fsBorder, наоборот, заливка прекращается на точках с этим цветом |
| procedure FrameRect(const Rect: TRect); | Очерчивает границы прямоугольника Rect текущей кистью толщиной в 1 пиксель без заполнения внутренней части прямоугольника |
| procedure LineTo(X,
Y: Integer); |
Чертит линию от текущего положения пера до точки
(X,Y) |
| procedure Lock; | Блокирует канву в многопоточных приложениях для предотвращения использования канвы в других по токах команд |
| procedure MoveTo(X,Y: Integer); | Перемещает перо в положение (X, Y) без вычерчивания линий |
| procedure Pie(XI,
Yl, X2, Y2, X3, Y3, X4, Y4: Longint); |
Рисует сектор эллипса в охватывающем прямоугольнике (XI, Yl) - (X2, Y2). Начало дуги лежит на пересечении эллипса и луча, проведенного из его центра в точку (X3, Y3), а конец - на пересечении случом из центра в точку (X4, Y4). Дуга чертится против часовой стрелки. Начало и конец дуги соединяются прямыми с ее центром (см. Рисунок 16.4, в) |
| procedure Polygon.
(Points: array of TPoint) ; |
Вычерчивает пером многоугольник по точкам, заданным в массиве Points. Конечная точка соединяется с начальной и многоугольник заполняется кистью. Без заполнения используйте - Polyline |
| procedure Polyline
(Points: array of TPoint); |
Вычерчивает пером ломаную прямую по точкам, заданным в массиве Points |
| procedure Rectan
gle(XI, Yl, X2, Y2: Integer); |
Вычерчивает и заполняет прямоугольник (XI, Yl) -S(X2, Y2). Для вычерчивания без заполнения используйте FrameRect или Polyline |
| procedure Refresh; | Устанавливает в канве умалчиваемые шрифт и кисть |
| procedure RoundRect(Xl, Yl, X2,Y2, X3, Y3: Inte ger) ; | Вычерчивает и заполняет прямоугольник (XI,Yl)- (X2, Y2) со скругленными углами. Прямоугольник (XI, Yl) - (X3, Y3) определяет дугу эллипса для округления углов (см. Рисунок 16.4, г) |
| procedure Stretch Draw (const Rect:TRect; Graphic:
TGraphic ); |
Вычерчивает и при необходимости масштабирует графический объект Graphic так, чтобы он полностью занял прямоугольник Rect |
| function TextExtent
(const Text:String): TSize; |
Возвращает ширину и высоту прямоугольника, охватывающего текстовую строку Text |
| function TextHeight
(const Text: String): Integer; |
Возвращает высоту прямоугольника, охватывающего текстовую строку Text |
| procedure TextOut(X,
Y: Integer; const Text: String) ; |
Выводит текстовую строку Text так, чтобы левый
верхний угол прямоугольника, охватывающего текст, располагался в точке (X, Y) |
| procedure TextRect(Rect: TRect; X, Y:
Integer; const Text: String) ; |
Выводит текстовую строку Text так, чтобы левый верхний угол прямоугольника, охватывающего текст, располагался в точке (х, Y). Если при этом какая-либо часть надписи выходит из границ прямоугольника Rect, она отсекается и не будет видна |
| function TextWidth
(const Text:String): Integer; |
Возвращает ширину прямоугольника, охватывающего текстовую строку Text |
| function TryLock:
Boolean; |
Пытается заблокировать канву. Если она не заблокирована другим потоком команд, - True, в противном случае ничего не делает и возвращает False |
| procedure Unlock; | Уменьшает на 1 счетчик блокировок канвы |
Определение условий компиляции
21.3.4. Определение условий компиляцииПодобно директивам условной компиляции Delphi в RTF-файл можно вставлять указания Help-компилятору помещать или не помещать в результирующий файл тот или иной раздел. Такие указания могут понадобиться на этапе отладки справочной службы, а также при создании нескольких версий приложения (например, справочная служба демонстрационной версии может не содержать некоторые разделы, определенные для основной версии). Они вставляются в текст с помощью сноски, помеченной символом “*”. Чтобы включить условный раздел в Help-файл или исключить его из файла, ключевое слово, определяемое сноской “*”, должно указываться в секции соответственно include или Exclude файла проекта справочной службы (см. п. 21.4.1).
В тексте сноски “*” можно указать одно или несколько управляющих слов (следующие друг за другом слова в тексте сноски разделяются символом “;”). Раздел будет включен в Help-файл, если хотя бы одно из связанных с ним управляющих слов указано в секции include файла проекта (если раздел не имеет сноски “*”, он всегда включается в результирующий файл). Управляющие слова могут содержать любые символы, кроме “;” и пробелов. Например:
Test_Build; AppVersionI; DebuggVer
Освобождение ресурсов отображения
11.7.4. Освобождение ресурсов отображенияПосле использования отображенных данных ресурсы окна отображения нужно освободить функцией function UnMapViewOfFile(IpBaseAddress: Pointer): BOOL; единственный параметр обращения к которой должен содержать адрес первого отображенного байта, т. е. адрес, возвращаемый функцией MapViewOfFile. Закрытие объекта отображения и самого файла осуществляется обращением к функции
function CloseHandle(hObject: THandle).
Процедуры и функции для работы с динамической памятью
7.4.4. Процедуры и функции для работы с динамической памятьюВ табл. 7.14 приводится описание как уже рассмотренных процедур и функций Object Pascal, так и некоторых других, которые могут оказаться полезными при обращении к динамической памяти.
Таблица 7.14. Средства Object Pascal для работы с памятью
| Function Addr(X):
Pointer; |
Возвращает адрес аргумента X. Аналогичный результат возвращает операция @ |
| Procedure Dispose (var P: Pointer) ; | Возвращает в кучу фрагмент динамической памяти, который ранее был зарезервирован за типизированным указателем P |
| Procedure Free-Mem(var P: Pointer; Size: Integer) ; | Возвращает в кучу фрагмент динамической памяти, который ранее был зарезервирован за нетипизированным указателем Р |
| Procedure Get-Mem(var P: Pointer; Size: Integer) ; | Резервирует за нетипизированным указателем Р фрагментдинамической памяти требуемого размера Size |
| Procedure New(var P: Pointer) ; | Резервирует фрагмент кучи для размещения переменной и помещает в типизированный указатель Р адрес первого байта |
| Function SizeOf(X): Integer; | Возвращает длину в байтах внутреннего представления указанного объекта Х |
Таблица 7.15. Средства Windows для работы с памятью
| CopyMemory | Копирует содержимое одного блока памяти в другой блок.
Блоки не должны перекрываться хотя бы частично |
| FillMemory | Заполняет блок памяти указанным значением |
| GetProcessHeap | Возвращает дескриптор кучи для текущей программы |
| GetProcessHeaps | Возвращает дескрипторы куч для всех работающих программ |
| GlobalAlloc | Резервирует в куче блок памяти требуемого размера |
| GlobalDiscard | Выгружает блок памяти |
| GlobalFlags | Возвращает информацию об указанном блоке памяти |
| GlobalFree | Освобождает блок памяти и возвращает его в общий пул памяти |
| GlobalHandle | Возвращает дескриптор блока памяти, связанного с заданным указателем |
| GlobalLock | Фиксирует блок памяти и возвращает указатель на его первый байт |
| GlobalMemoryStatus | Возвращает информацию о доступной памяти (как физической, так и виртуальной) |
| GlobalReAlloc | Изменяет размер и атрибуты ранее зарезервированного блока памяти |
| GlobalSize | Возвращает размер в байтах блока памяти |
| GlobalUnlock | Снимает фиксацию блока памяти и делает его перемещаемым |
| HeapAlloc | Резервирует в куче неперемещаемый блок памяти |
| HeapCompact | Удаляет фрагментацию кучи |
| HeapCreate | Создает для программы новую кучу |
| HeapDestroy | Возвращает кучу в общий пул памяти |
| HeapFree | Освобождает блок памяти, зарезервированный функциями
HeapAlloc или HeapReAlloc |
| HeapLock | Делает указанную кучу доступной только для текущего потока |
| HeapReAlloc | Изменяет размер и/или свойства кучи |
| HeapSize | Возвращает размер кучи в байтах |
| HeapUnlock | Делает указанную кучу доступной для любых потоков текущего процесса |
| HeapValidate | Проверяет состояние кучи или размещенного в ней блока памяти |
| IsBadCodePtr | Сообщает, может ли вызывающая программа читать данные из указанного адреса памяти (но не из блока памяти) |
| IsBadHugeReadPtr | Сообщает, может ли вызывающая программа читать данные из указанного блока памяти |
| IsBadHugeWritePtr | Сообщает, может ли вызывающая программа изменять содержимое указанного блока памяти |
| IsBadReadPtr | Сообщает, может ли вызывающая программа читать данные из указанного блока памяти |
| IsBadStringPtr | Сообщает, может ли программа читать содержимое строки, распределенной в куче |
| IsBadWritePtr | Сообщает, может ли вызывающая программа изменять содержимое указанного блока памяти |
| LocalAlloc | Аналогична GlobalAlloc |
| :: LocalDiscard | Аналогична GloalDiscard |
| 'LocalFlags | Аналогична GlobalFlags |
| LocalFree | Аналогична Global Free |
| LocalHandle | Аналогична GlobalHandle |
| LocalLock | Аналогична GlobalLock |
| LocalReAlloc | Аналогична GlobalReAlloc |
| LocalSize | Аналогична GlobalSize |
| LocalUnlock | Аналогична GlobalUnlock |
| MoveMemory | Копирует один блок памяти в другой. Блоки могут перекрываться |
| VirtualAlloc | Резервирует блок виртуальной памяти |
| VirtualFree | Освобождает блок виртуальной памяти |
| VirtualLock | Фиксирует блок виртуальной памяти |
| VirtualProtect | Изменяет права доступа текущей программы к виртуальному блоку памяти |
| VirtualProtectEx | Изменяет права доступа указанной программы к виртуальному блоку памяти |
| VirtualQuery | Возвращает свойства виртуального блока памяти по отношению к вызывающей программе |
| VirtualQueryEx | Возвращает свойства виртуального блока памяти по отношению к указанной программе |
| VirtualUnloc'k | Снимает фиксацию блока виртуальной памяти |
| ZeroMemory | Заполняет блок памяти нулями |
Секция BITMAPS
21.4.4. Секция BITMAPSЭта секция определяет список папок, в которых компилятор будет искать графические файлы, встроенные в текст справки директивами bmc, bmi, bmr (см. п. 21.3.6). Если ни одна папка не определена, компилятор сможет подключить только те файлы, которые располагаются в том же каталоге, где создается нlр-файл.
Страница DataSnap
4.8.4. Страница DataSnapНа этой странице сосредоточены компоненты, реализующие взаимодействие машин в локальной сети или Интернет в типичном для БД случае, когда клиент работает с удаленными данными. Часть компонентов известны по другим версиям Delphi, часть появилась в версии 6.
Страница WebSnap
4.9.4. Страница WebSnapНа этой странице сосредоточены компоненты, развивающую известную из предыдущих версий технологию Web Server. В настоящей версии эти компоненты не поддерживают межплатформенные программы.
Свойства
9.2.4. СвойстваСвойства - это специальный механизм классов, регулирующий доступ к полям. Свойства объявляются с помощью зарезервированных СЛОВ property, read И write (слова read И write считаются зарезервированньши только в контексте объявления свойства). Обычно свойство связано с некоторым полем и указывает те методы класса, которые должны использоваться при записи в это поле или при чтении из него. Например:
type
TaClass = class
IntField: Integer; Function GetField: Integer;
Procedure SetField (Value: Integers);
Property IntegerValue: Integer read GetField
write SetField;
end ;
В контексте программы свойство ведет себя как обычное поле. Например, мы могли бы написать такие операторы:
var
aClass: TaClass;
Value: Integer;
begin
aClass := TaClass.Create; { Обязательное обращение к
конструктору перед обращением к полю или свойству!} aClass.IntegerValue := 0;
Value := aClass.IntegerValue;
aClass.Destroy; // Удаление ненужного объекта
end;
Более того, возможен и такой оператор присваивания:
aClass.IntField := NewValue;
Разница между этим оператором и оператором
aClass.IntegerValue := NewValue;
заключается в том, что при обращении к свойству автоматически подключается метод setFieid, в котором могут реализовываться специфичные действия. Вспомним использовавшийся нами в учебной программе оператор
IbOutput.Caption := 'Строка';
Свойство Caption компонента Label вызывает метод setText, который не только запоминает строку символов во внутренней переменной, но и осуществляет прорисовку метки с новым текстом.
Если нет необходимости в специальных действиях при чтении или записи свойства, вместо имени соответствующего метода можно указывать имя поля:
type
TaClass = class IntFiled: Integer;
Procedure SetFieid (Value: Integers;
Property IntegerValue:
Integer read IntFiled write SetFieid;
end;
Если необходимо, чтобы свойство было доступно только для чтения или только для записи, следует опустить соответственно часть write или read. Вообще говоря, свойство может и не связываться с
полем. Фактически оно описывает один или два метода, которые осуществляют некоторые действия над данными того же типа, что и свойство.
TColorDialog диалог выбора цвета
18.5.4. TColorDialog - диалог выбора цветаКомпонент создает и обслуживает стандартное диалоговое окно выбора цвета, показанное на Рисунок 18.42.
Свойства компонента:
| property Color: TColor; | Содержит выбранный цвет |
| property CustomColors: TStrings; | Содержит до 16 цветов, определенных пользователем. Каждая строка имеет такой формат: Со1огх=нннннн, где х - буква от а до р, определяющая номер цвета, нннннн ~ шестнадцатеричное представление цвета в формате rgb |
| TColorDialogOption = (cdFullOpen, cdPreventFullOpen, cdShowHelp, cdSolidColor, cdAnyColor) ; TColorDialogOptions = set of TColorDialogOption; property Options: TColorDialogOptions; | Определяет настройку окна: cdFullOpen -показывать с развернутым окном выбора цвета пользователя; cdPreventFullOpen -запретить показ окна выбора цвета пользователя; cdShowHelp - включить в окно кнопку Help; cdSolidColor - выбирать ближайший сплошной цвет; cdAnyColor -разрешить выбор не сплошных цветов |
TLabel метка для отображения текста
18.1.4. TLabel - метка для отображения текстаПримечание
Примечание

Метка Label может отображать длинную текстовую строку своего свойства Caption в виде нескольких строк: для этого установите в AutoSize значение False, задайте достаточно большие размеры метки и поместите в Wordwrap значение True. Для отображения действительно многострочного текста используйте компоненты TMemo (см.п. 18.1.7)HTRichEdit(cM.n. 18.3.4).
TOutLine просмотр иерархических структур
18.6.4. TOutLine - просмотр иерархических структурПодобно компоненту TTreeview страницы Win32 компонент Tout-Line предназначен для отображения иерархических структур данных (каталогов, например). Элементом отображения является узел. Каждый узел имеет родительский узел и дочерние узлы. Исключение составляет узел самого верхнего уровня (он не имеет родительского узла) и узлы самых нижних уровней (они не имеют дочерних узлов),
Для каждого узла компонент создает объект класса TOutLineNode. Его свойства:
| property Data: Pointers; | Указатель на связанные с узлом данные |
| property Expanded: Boolean; | Если содержит True, с узлом связан раскрытый список дочерних узлов |
| property FullPath: String; | Содержит полное имя узла со списком имен всех родительских узлов, разделенных символом ItemSeparator объекта ToutLine |
| property Hasltems: Boolean; | Содержит True, если с узлом связаны дочерние узлы |
| property Index: Longint; | Содержит уникальный идентификатор узла в компоненте ToutLine |
| property IsVisible: Boolean; | Содержит True, если узел виден в окне компонента ToutLine |
| property Level: Integer; | Определяет уровень иерархии узла. Узел самого верхнего уровня имеет уровень 0, его дочерние узлы - уровень 1, их дочерние узлы - уровень 2 и т. д. |
| property Text: String; | Определяет имя узла |
| property Topltem: Longint; | Содержит индекс своего родительского узла первого уровня (родительский узел нулевого уровня не виден в компоненте TOutLine) |
| procedure ChangeLevelBy(Value: TChangeRange) ; | Перемещает уровень узла на один вверх (Value=-1) или вниз(Value=+l) Закрывает список дочерних узлов |
| procedure Collapse; procedure FullExpand; | Раскрывает список всех своих дочерних узлов на всех уровнях |
| function GetFirstChild: TTreeNode; | Возвращает ссылку на первый дочерний узел или nil, если нет дочерних узлов |
| function GetPrevChild(Value: Longint): Longint; | Возвращает индекс узла, предшествующего узлу Value |
| TAttachMode = (oaAdd, oaAddChild, oalnsert) ; procedure MoveTo(Destination: Longint; AttachMode: TAttachMode) ; | Перемещает узел со всеми потомками в положение, определяемое индексом Destination и режимом AttachMode: oaAdd -добавить последним на том же уровне, что и Destination; oaAddChild -добавить последним к потомкам узла Destination; oalnsert - вставить на место Destination, который смещается ниже него на том же уровне |
| property Canvas: TCanvas; | Определяет канву для прорисовки компонента |
| property itemHeight: Integer; | Определяет высоту узлов |
| property Items[Index: Longint]: TOutlineNode; | Открывает доступ к узлу по его индексу |
| property ItemCount: Longing; | Содержит общее количество узлов |
| property Lines: TStrings; | Содержит список всех узлов |
| TOutlineOption = (ooDrawTreeRoot,
ooDrawFocusRect, ooStretchBitmaps) ; TOutlineOptions = set of Tout lineOption; property Options: TOutlineOptions; |
Определяет атрибуты прорисовки: ooDraw TreeRoot - соединять линии узлов верхнего уровня; ooDrawFocusRect - выделять пунктиром сфокусированный узел; oostretch Bitmaps - масштабировать пиктограммы |
| TOutlineStyle = (osText, osPlus-
MinusText, osPictureText, osPlus- MinusPictureText, osTreeText, osTreePictureText) ; property OutlineStyle: TOutlineStyle; |
Задает стиль прорисовки: osText - выводится только текст(без линий); osPlusMinusText - текст и пиктограммы PicturePlus/PictureMinus;osPictureText -текст и пиктограммы PictureOpen/PictureClosed/PictureLeaf;osPlusMinus-PictureText - объединяет два предыдущих стиля; osTreeText - текст и линии связи между узлами; osTreePictureText - объединяет osTreeText и osPictureText |
| property PictureClosed: TBitmap; | Содержит пиктограмму узла с закрытым списком дочерних узлов. По умолчанию -закрытая папка |
| property PictureMinus: TBitmap; | Содержит пиктограмму узла с закрытым списком дочерних узлов. По умолчанию - пиктограмма со знаком минус |
| property PictureOpen: TBitmap; | Содержит пиктограмму узла с открытым списком дочерних узлов. По умолчанию - открытая папка |
| property PictureLeaf: TBitmap; | Содержит пиктограмму узла, не имеющего дочерних узлов. По умолчанию - пиктограмма документа |
| property PicturePlus: TBitmap; | Содержит пиктограмму узла с открытым списком дочерних узлов. По умолчанию - пиктограмма со знаком плюс |
| property Row: Longint; | Содержит индекс сфокусированного узла |
| property ScrollBars: TScroll-Style; | Определяет наличие полос прокрутки: ssNone - нет полос; ssHorizontal - горизонтальная полоса; ssVertical - вертикальная полоса; ssBoth - и горизонтальная, и вертикальная полоса |
| function Add(Index: Longint; const Text: String): Longint; | Добавляет узел с именем Text как последний на тот же уровень иерархии, что и узел index, и возвращает его индекс (режим oaAdd) |
| function AddChild(Index: Longint;
const Text: String): Longing; |
Добавляет дочерний узел с именем Text к узлу index и возвращает его индекс (режим oaAddChild) |
| function AddChildObject(Index:
Longint; const Text: String; const Data: Pointer): Longint; |
Добавляет дочерний узел с именем Text и данными Data к узлу index и возвращает его индекс |
| function AddObject(Index: Long
int; const Text: String; const Data: Pointer): Longint; |
Добавляет узел с именем Text и с данными Data как последний на тот же уровень иерархии, что и узел index, и возвращает его индекс |
| procedure BeginUpdate ; | Блокирует перерисовку компонента перед вставкой/удалением нескольких узлов |
| procedure Clear; | Удаляет все узлы компонента |
| procedure EndUpdate; | Разрешает перерисовку компонента после вставки/удаления нескольких узлов |
| procedure FullCollapse; | Закрывает списки всех дочерних узлов на всех уровнях |
| procedure FullExpand; | Раскрывает списки всех дочерних узлов на всех уровнях |
| function GetDataItem(Value: Pointer): Longint; | Возвращает индекс узла по его данным |
| function GetItem(X, Y: Integer): Longint; | Возвращает индекс узла по его координатам |
| function GetTextItem(Value: String) : Longing; | Возвращает индекс узла по его имени |
| function Insert(Index: Longint;
const Text: String): Longing; |
Вставляет узел с именем Text на место узла Index(режим oalnsert) |
| function InsertObj ect(Index:
Longint; const Text: String; const Data: Pointer): Longint; |
Вставляет узел с именем Text и данными Data на место узла index (режим oalnsert) |
| procedure LoadFromFile(const
FileName: String); |
Загружает содержимое компонента из файла с именем FileName |
| procedure LoadFromFile(const FileName: Strings; | Сохраняет содержимое компонента в файле |
| procedure SetUpdateState(Value: Boolean); | С именем FileName если Value=True, соответствует BeginUp date, в противном случае - EndUpdate |
| EOutlineChange = procedure
(Sender: TObject; Index: Longint) of object; property OnCollapse: EOut lineChange;Возникает при закрытии списка дочерних узлов узда Index |
|
| TOwnerDrawState = set of
(odSelected, odGrayed, odDisabled, odChecked, odFocused) ; TListBox; Index: Integer; Rect:TRect; State: TOwnerDrawState) of Object; property OnDrawItem: TDrawItemEvent; |
Возникает при необходимости прорисовки узла index: Rect - прямоугольник прори совки; State - состояние узла (odSelected - узел выделен; odDisabled - узел запрещен для выбора; odFocused - узел сфокусирован) |
| EOutlineChange = procedure (Sender: TObject; Index: Longint) of object; property OnExpand: EOut lineChange; | Возникает при открытии списка дочерних узлов узла Index |
TRichEdit ввод и отображение RTFтекста
18.3.4. TRichEdit - ввод и отображение RTF-текстаКомпонент TRichEdit представляет собой многострочный редактор, работающий с расширенным текстовым форматом RTF. Текст формата RTF хранит дополнительную служебную информацию, управляющую свойствами каждого абзаца и сменой шрифта по ходу текста.
TSpinEdit редактор для ввода целого числа
18.7.4. TSpinEdit - редактор для ввода целого числаКомпонент TSpinEdit предназначен для ввода/отображения числа. Он представляет собой комбинацию специализированного потомка однострочного редактора rcustomEdit и кнопок TSpinButton. Редактор способен вводить только числа (в этом и заключается его специализация), а кнопки используются для изменения числа на некоторую фиксированную величину.
Свойства компонента:
| property Button: TSpinButton; | Содержит ссылку на встроенный объект TSpinButton |
| property EditorEnabled: Boolean; | Разрешает/запрещает использовать редактор для ручного ввода числа |
| property Increment: Longint; | Содержит число, на которое будет изменяться свойство value при нажатии кнопок TSpinButton |
| property MaxValue: Longint; | Содержит верхнюю границу диапазона возможных значений value |
| property MinValue: Longint; | Содержит нижнюю границу диапазона возможных значений value |
| property Value: Longint; | Содержит текущее значение числовой величины |
Вызов исключения
16.1.4. Вызов исключенияВ некоторых ситуациях программисту бывает необходимо инициировать собственное исключение. Для этого он использует зарезервированное слово raise (возбудить). Если это слово встретилось в секции try.. .exception или try.. .finally, немедленно начинают свою работу секции соответственно except... end и finally... end. Если оно встретилось в except.. .end или finally.. .end, считается, что данный защищенный блок на текущем уровне вложенности (блоки могут быть вложенными) завершил свою работу и управление передается вышестоящему уровню.
Слово raise возбуждает исключение самого общего класса Exception. Если программист желает возбудить исключение конкретного типа (не важно - стандартного или собственного), он должен явно указать класс создаваемого в этот момент объекта путем вызова его конструктора. Например, следующий оператор возбудит ошибку ввода/вывода:
raise EInOutError.Create('Ощибка!') ;
Такой прем - единственная возможность возбудить нестандартное исключение, обрабатываемое пользовательским классом.
УЧЕБНАЯ ПРОГРАММА
5.1. УЧЕБНАЯ ПРОГРАММАПри описании свойств языка мне понадобится иллюстрировать их небольшими примерами. В таких примерах чаще всего реализуются простые действия по вводу некоторых данных, их преобразованию и выводу результатов на экран. Для реализации этих действий создадим форму, которая будет содержать все необходимые для учебных примеров интерфейсные элементы. Чтобы эта форма была доступна в любой учебной программе, мы поместим ее в так называемый репозиторий Delphi - архив, в котором сохраняются заготовки для новых программ. Замечу, что в версии 1 нет репозитория. Тем не менее полезно и в этом случае создать учебную форму: чтобы избавить себя от повторения одних и тех же действий при реализации разных примеров. Сохраните ее в файле с именем Example, например, а при создании новой программы свяжите ее с проектом (опция File | Add) и сразу же сохраните под другим именем (File | Save As).
Вид формы для учебной программы показан на Рисунок 5.1. На форме размещена панель (трапе!), две кнопки (TBitBtn), строка ввода (TEdit), метка (TLabel) и многострочный редактор (тмето). Панель понадобилась для того, чтобы размещенные на ней кнопки, строка ввода и метка всегда располагались в нижней части окна, даже если окно распахнуто на весь экран. Левая кнопка ок служит для сообщения программе о том, что в строке ввода подготовлен текст. Обработчик события onciick этой кнопки будет тем самым местом программы, куда мы будем помещать учебные фрагменты. Правая кнопка close служит для завершения работы программы. Ее функции аналогичны функциям системной кнопки закрытия окна, и поэтому ее можно было бы и не размещать на форме. Однако я предпочитаю использовать крупную, бросающуюся в глаза кнопку, чтобы даже неопытный пользователь сразу увидел интерфейсный элемент, с помощью которого он сможет прекратить работу с программой. Метка располагается над строкой ввода и пока не видна на экране. Она предназначена для размещения коротких сообщений, которые будет формировать программа. Для вывода многострочных сообщений служит редактор TMеmо, занимающий все остальное место окна.
СТРУКТУРА ПРОГРАММ DELPHI
5.2. СТРУКТУРА ПРОГРАММ DELPHIЛюбая программа в Delphi состоит из файла проекта (файл с расширением dpr) и одного или нескольких модулей (файлы с расширениями pas). Каждый из таких файлов описывает программную единицу Object Pascal.
ТИПЫ
5.3. ТИПЫТипы в Object Pascal играют огромную роль. Связано это с тем, что лежащий в его основе язык Pascal был специально придуман как средство обучения студентов программированию. Поскольку начинающий программист легко может допустить ошибку или неточно описать свои действия, компилятор Pascal должен был иметь средства контроля за действиями программиста, чтобы вовремя предостеречь его от последствий неверных действий. Первоначально типы как раз и предназначались для того, чтобы программист явно указывал компилятору, какого размера память нужна ему в программе и что он собирается делать с этой памятью. Практика применения типов показала их высокую эффективность для защиты программы от случайных ошибок, так что практически все современные языки программирования в той или иной степени реализуют механизм типов. В Object Pascal значение типов возросло в еще большей степени, т. к. с их помощью определяются классы - основной инструмент программиста.
ОПЕРАТОРЫ ЯЗЫКА
5.4. ОПЕРАТОРЫ ЯЗЫКАС одним из наиболее часто используемых операторов языка Object Pascal - оператором присваивания мы уже познакомились (см. п. 3.3.3). Ниже рассматриваются остальные операторы.
МАССИВЫ
5.5. МАССИВЫРассмотренные выше простые типы данных позволяют использовать в программе одиночные объекты - числа, символы, строки и т. п. В Object Pascal могут использоваться также объекты, содержащие множество однотипных элементов. Это массивы - формальное объединение нескольких однотипных объектов (чисел, символов, строк и т. п.), рассматриваемое как единое целое. К необходимости применения массивов мы приходим всякий раз, когда требуется связать и использовать целый ряд родственных величин. Например, результаты многократных замеров температуры воздуха в течение года удобно рассматривать как совокупность вещественных чисел, объединенных в один сложный объект - массив измерений.
При описании массива необходимо указать общее количество входящих в массив элементов и тип этих элементов. Например:
var
а : array [1..10] of Real;
b : array [0..50] of Char;
с : array [-3..4] of String;
Как видим, при описании массива используются зарезервированные слова array и of (массив, из). За словом array в квадратных скобках указывается тип-диапазон, с помощью которого компилятор определяет общее количество элементов массива. Тип-диапазон (подробнее см. в гл. 7) задается левой и правой границами изменения индекса массива, так что массив А состоит из 10 элементов, массив В - из 51, а массив С - из 8 элементов. За словом of указывается тип элементов, образующих массив.
Доступ к каждому элементу массива в программе осуществляется с помощью индекса - целого числа (точнее, выражения порядкового типа, см. гл. 7), служащего своеобразным именем элемента в массиве (если левая граница типа-диапазона равна 1, индекс элемента совпадает с его порядковым номером). При упоминании в программе любого элемента массива сразу за именем массива должен следовать индекс элемента в квадратных скобках, например:
var
a: array [1..10] of Integer;
b: array [0..40] of Char;
c: array [-2..2] of Boolean;
k: Integer;
begin
b[17] := 'F';
c[-2] := a[1] > 2;
for k := 1 to 10 do a[k] := 0;
end;
В правильно составленной программе индекс не должен выходить за пределы, определенные типом-диапазоном. Например, можно использовать элементы а [ 1 ], в[38], с[0], но нельзя а [0 ] илис[38] (определение массивов см. выше). Компилятор Object Pascal может[ Буквальный перевод array - боевой порядок, упорядоченная масса (войск). В компьютерной терминологии array переводится словом массив. ] контролировать использование индексов в программе как на этапе компиляции, так и на этапе прогона программы.
Учебная программа AVERAGE
Для иллюстрации приемов работы с массивами составим программу, которая создает массив случайных целых чисел, подсчитывает их среднее арифметическое, а также определяет и выводит на экран минимальное и максимальное из этих чисел.
procedure TfmExample.bbRunClick(Sender: TObject);
{Программа создает массив из N случайных целых чисел, равномерно распределенных в диапазоне от 0 до MAX_VALUE-1, подсчитывает среднее арифметическое этих чисел, а также минимальное и максимальное из них.} const
N = 1000; // Количество элементов массива
MAX_VALUE = 100+1;// Диапазон значений случайных чисел var
m: array [1..N] of Integer; // Массив чисел
i: Integer;// Индекс массива
max,min: Integer; // Максимальное и минимальное число
sum: Real;// Сумма чисел
begin
// Наполняем массив случайными числами:
for i := 1 to N do
m[i] := Random(MAX_VALUE);
// Задаем начальные значения переменных:
sum : = m [ 1 ] ;
max : = m [ 1 ] ;
min := m[1] ;
// Цикл вычисления суммы всех случайных чисел и поиска
// минимального и максимального:
for i := 2 to N do
begin
sum := sum + m[i];
if m[i] < min then
min := m[i]
else if m[i] > max then
max := m[i] end;
// Вычисляем среднее значение и выводим результат:
IbOutput.Caption := 'Мин = '+IntToStr(min)+' Макс = '+ IntToStr(max)+' Среднее = '+FloatToStr(sum/N) ;
end;
Для создания массива используется встроенная функция Ran-dom(Max), которая возвращает случайное целое число, равномерно распределенное в диапазоне от 0 до мах-1 (мах - параметр обращения).
ПРОЦЕДУРЫ И ФУНКЦИИ
5.6. ПРОЦЕДУРЫ И ФУНКЦИИПроцедуры и функции (я часто буду использовать их общее название - подпрограммы} представляют собой важный инструмент Object Pascal, позволяющий писать хорошо структурированные программы. В структурированных программах обычно легко прослеживается основной алгоритм, их проще понять любому читате лю, они удобнее в отладке и менее чувствительны к ошибкам программирования. Все эти свойства являются следствием важной особенности подпрограмм, каждая из которых представляет собой во многом самостоятельный фрагмент программы, связанный с основной программой лишь с помощью нескольких параметров. Самостоятельность подпрограмм позволяет локализовать в них все детали программной реализации того или иного алгоритмического действия, и поэтому изменение этих деталей, например, в процессе отладки обычно не приводит к изменениям основной программы.
Многие примеры в этой книге невелики по размерам (не более 30-40 строк), поэтому в таких программах можно обойтись и без подпрограмм. Иное дело - создание крупных программ в сотни, тысячи и десятки тысяч строк. Писать такие программы как нечто единое целое, без расчленения на относительно самостоятельные фрагменты, т. е. без структурирования, просто невозможно. Практически во всех языках программирования имеются средства структурирования. Языки, в которых предусмотрены такие механизмы, называются процедурно-ориентированными. К их числу принадлежит и Object Pascal.
Процедурой в Object Pascal называется особым образом оформленный фрагмент программы, имеющий собственное имя. Упоминание этого имени в тексте программы приводит к активизации процедуры и называется ее вызовом. Сразу после активизации процедуры начинают выполняться входящие в нее операторы, после выполнения последнего из них управление возвращается обратно в . основную программу и выполняются операторы, стоящие непосредственно за оператором вызова процедуры (Рисунок 5.8).
Для обмена информацией между основной программой и процедурой используется один или несколько параметров вызова. Как мы увидим дальше (см. гл.11), процедуры могут иметь и другой механизм обмена данными с вызывающей программой, так что параметры вызова могут и не использоваться. Если они есть, то они перечисляются в круглых скобках за именем процедуры и вместе с ним образуют оператор вызова процедуры.
Функция отличается от процедуры тем, что результат ее работы возвращается в виде значения этой функции, и, следовательно, вызов функции может использоваться наряду с другими операндами в выражениях.
Классы TGraphic и TPicture
16.4.5. Классы TGraphic и TPictureВажное место в графическом инструментарии Delphi занимают классы TGraphic и TPicture.
TGraphic - это абстрактный класс, инкапсулирующий общие свойства и методы трех своих потомков: пиктограммы (TIcon), метафайла (TMetafile) и растрового изображения (TBitmap). Общей особенностью потомков TGraphic является то, что обычно они сохраняются в файлах определенного формата. Пиктограммы представляют собой небольшие растровые изображения, снабженные специальными средствами, регулирующими их прозрачность. Для файлов пиктограмм обычно используется расширение ico. Метафайл - это изображение, построенное на графическом устройстве с помощью специальных команд, которые сохраняются в файле с расширением wmf или emf. Растровые изображения - это произвольные графические изображения в файлах со стандартным расширением bmp.
Свойства класса TGraphic:
| property Empty: Boolean; | Содержит True, если с объектом не связано графическое изображение |
| property Height: Integer; | Содержит высоту изображения в пикселях |
| property Modified: Boolean; | Содержит True, если графический объект изменялся |
| property Palette: HPALETTE; | Содержит цветовую палитру графического объекта |
| property PaletteModified: Boolean; | Содержит True, если менялась цветовая палитра графического объекта |
| property Transparent: Boolean; | Содержит True, если объект прозрачен для фона, на котором он изображен |
| property Width: Integer; | Содержит ширину изображения в пикселях |
| Методы Класса TGraphic: | |
| procedure LoadFromClipooardFor.gif" > |
Метки и операторы перехода
5.4.5. Метки и операторы переходаМожно теоретически показать, что рассмотренных операторов вполне достаточно для написания программ любой сложности. В этом отношении наличие в языке операторов перехода кажется излишним. Более того, современная технология структурного программирования основана на принципе “программировать без GOTO”: считается, что злоупотребление операторами перехода затрудняет понимание программы, делает ее запутанной и сложной в отладке. Тем не менее в некоторых случаях использование операторов перехода может упростить программу.
Оператор перехода имеет вид:
goto <метка>;
Здесь goto - зарезервированное слово (перейти [на метку]); <метка> - метка.
Метка в Object Pascal - это произвольный идентификатор, позволяющий именовать некоторый оператор программы и таким образом ссылаться на него. В целях совместимости со стандартным языком Паскаль в Object Pascal допускается в качестве меток использование также целых чисел без знака.
Метка располагается непосредственно перед помечаемым оператором и отделяется от него двоеточием. Оператор можно помечать несколькими метками, которые в этом случае отделяются друг от друга двоеточием. Перед тем как появиться в программе, метка должна быть описана. Описание меток состоит из зарезервированного слова label (метка), за которым следует список меток:
Label
loop, Ibl, lb2;
begin
goto Ibl;
loop: .........
Ibl:lb2: ......
......
goto lb2;
end;
Действие оператора goto состоит в передаче управления соответствующему меченному оператору.
При использовании меток необходимо руководствоваться следующими правилами:
Пример использования
11.7.5. Пример использованияВ следующем листинге приводится текст модуля, который создает окно, показанное на Рисунок 11.1.
Программа создает дисковый файл, состоящий из 100000 случайных вещественных чисел (длину файла можно выбрать другой, если изменить значение редактора длина массива). Файл с именем test.dat создается путем отображения файла в память (кнопка память) и традиционным способом (кнопка Файл). В обоих случаях показывается время счета (процессор 400 МГц, память 64 Мбайт). Чем больше частота и память, тем больше будет разница во времени.
Секция MAP
21.4.5. Секция MAPВ этой секции следует определить числовые идентификаторы разделов, которые будут автоматически вызываться кнопками Help и клавишей F1 в работающей программе. Напомню, что все видимые компоненты Delphi имеют специальное свойство HeipContext, в которое можно поместить числовой идентификатор раздела справочной службы. Если соответствующий компонент имеет фокус ввода и пользователь нажимает кнопку F1, автоматически включается справочная система Windows, которая отыскивает в ньр-файле и показывает в справочном окне соответствующий раздел. Только разделы, указанные в секции [map] , могут быть контекстно-доступными из работающей программы. Остальные разделы можно просмотреть после вызова справки с помощью выбора ключевых слов, кнопками просмотра связанных разделов или по содержанию справочной службы.
В списке Map topics IDs to numeric values указываются уже определенные разделы в формате
идентификатор_темы=Неlр Сontext
Здесь идентификатор_темы - идентификатор, определенный сноской # в RTF-файле; HelpContext -присвоенный разделу числовой идентификатор, который можно помещать в свойство HelpContext визуального компонента.
Для задания идентификатора нового раздела или удаления раздела из списка Map используются соответственно кнопки Add и Remove. С помощью кнопки include можно указать ASCII-файл с перечнем идентификаторов разделов и присвоенными им числовыми идентификаторами. Кнопка Edit позволяет отредактировать элемент списка.
При разработке файлов справочной службы, включающих множество разделов, приходится запоминать (или распечатывать) многочисленные идентификаторы разделов, чтобы поставить им в соответствие числовые идентификаторы. Эту проблему можно упростить, если вы назначили идентификаторы такими же, как и названия разделов, заменив в них пробелы символами подчеркивания. В этом случае можно вызвать опцию File | Report, в появившемся диалоговом окне указать имя нlр-файла и имя файла для отчета, установить режим вывода названий (отметить переключатель Titles) и щелкнуть по кнопке Report - MS HW создаст текстовый файл с перечнем названий всех тем. Если этот файл не слишком велик, он будет тут же показан в окне MS HW, и вы сможете без труда вспомнить идентификаторы.
Создание собственного класса
16.1.5. Создание собственного классаПрограммист может создать собственный класс обработки исключений, объявив его потомком Exception или любого другого стандартного класса (этим другим чаще всего бывает класс EAbort). Объявление нестандартного класса имеет смысл только тогда, когда вам необходимо научить программу распознавать некорректные наборы данных и соответствующим образом на них реагировать.
Пусть, например, в программе используется цикл ввода целочисленных значений из текстового файла, их проверки и преобразования. Проверка заключается в простом контроле неотрицательности очередного числа после ввода и его положительности после преобразования. Перед проверкой необходимо получить строку из файла (здесь может возникнуть ошибка EinOutError) и преобразовать ее в целую величину (здесь возможна ошибка EConvertError); после проверки осуществляется обработка величины, в процессе которой может возникнуть ошибка EIntError.
Создадим новый класс EIntCheckError и будем возбуждать исключение этого класса при обнаружении ошибки в данных:
type
EIntCheckError = class(EAbort)
end;
var
F: TextFile;
S: String;
k: Integer;
begin
try
// Готовимся к работе: открываем файл AssignFile(F, FileName);
Reset(F); // Здесь возможна ошибка EinOutError // Цикл ввода-контроля-преобразования while not EOF(F) do begin
// Вводим символы очередного числа
ReadLn(F,S);// Здесь возможна ошибка EinOutError
// Преобразуем символы в число
k := StrToInt(S); // Здесь возможна ошибка EConvertError
// Проверяем число
if k < 0 then
raise EIntCheckError.Create("Отрицательное число');
// Преобразуем число
..... // Здесь возможна ошибка EIntError
// Вновь проверяем число
if k <= 0 then
raise EIntCheckError.Create('He положительное число');
end;
except
on E: EIntCheckError do
ShowMessage(E.Message) ;
on EInOutError do
ShowMessage('Некорректная файловая операция');
on EConvertError do
ShowMessage('Ошибка в записи числа');
on EIntError do
ShowMessage('Ошибка преобразования');
end;
end;
В этом примере создается класс EIntCheckError, который ничем, кроме названия, не отличается от своего родителя EAbort. В реальной программе потомок обычно расширяет набор полей (свойств) своего родителя или перекрывает его методы; приведенный пример лишь иллюстрирует, что делать это необязательно. При неудачной проверке операторами
raise EIntCheckError.Create('Отрицательное число') ;
и
raise EIntCheckError.Create('Ошибка преобразования');
возбуждается исключение нового класса. При этом с помощью унаследованного конструктора create создается новый безымянный объект, а строковый параметр обращения к конструктору запоминается в поле FMessage и становится доступен с помощью свойства Message объекта. Обработчик исключения EIntCheckError именует объект идентификатором e и с помощью стандартной процедуры ShowMessage показывает его в небольшом окне на экране.
Пример наглядно показывает выгоды использования исключений. В принципе весь этот фрагмент можно было бы написать с многочисленными проверками if... then, но в этом случае логика программы стала бы запутанной, а сама программа - сложной в отладке.
Страница BDE
4.8.5. Страница BDEЗдесь представлены компоненты, поддерживающие доступ к данным с помощью BDE - Table, Query, StoredProc И Т. П. Механизм BDЕ в равной степени успешно работает как с файл-серверными, кис клиент-серверными БД. Компоненты этой страницы есть во всех версиях Delphi.
Страницы Indy Clients Indy Servers Indy Misc
4.9.5. Страницы Indy Clients, Indy Servers, Indy MiscРасположенные на этих страницах компоненты в функциональном плане дублируют компоненты страницы FastNet, но позволяют их использовать в межплатформенных приложениях.
TDirectoryOutLine отображение структуры каталогов
18.7.5. TDirectoryOutLine - отображение структуры каталоговКомпонент предназначен для отображения древовидной структуры каталогов (см. Рисунок 18.46). В отличие от TDirectoryListBox (см. п. 18.6.7) компонент отображает полную структуру каталогов, а не маршрут доступа к одному из них.
TDrawGrid произвольная таблица
18.2.5. TDrawGrid - произвольная таблицаКомпонент TDrawGrid предоставляет программисту мощные возможности создания и обслуживания табличных структур данных. Он обеспечивает двухмерное представление данных, упорядоченных по столбцам и рядам, и избавляет программиста от многих рутинных аспектов, связанных с представлением и обслуживанием таблиц.
Чтобы таблица была работоспособной, в ней как минимум следует определить обработчик события OnDrawCell, которое возникает при необходимости прорисовать ту или иную ячейку. Для прорисовки используется табличное свойство Canvas.
Компонент TDrawGrid является непосредственным родителем строковой таблицы TStringGrid, поэтому передает ей все свои свойства, методы и события за исключением специфичных для строк свойств Cells, Cols, Objects И Rows. Поскольку порядок описания компонентов в этой главе соответствует умалчиваемому порядку их расположения на страницах палитры компонентов, TStringGrid описан раньше своего родителя TDrawGrid, и вы сможете найти информацию о свойствах, методах и событиях последнего в предыдущем параграфе.
В следующем примере компонент TDrawGrid используется для показа текста и картинок одновременно, причем текст можно редактировать. Картинки взяты из каталога images l splash | igcolor (Рисунок 18.11).
TEdit ввод и отображение строки
18.1.5. TEdit - ввод и отображение строки
Компонент класса TEdit представляет собой однострочный редактор текста. С его помощью можно вводить и/или отображать достаточно длинные текстовые строки.
Центральным свойством компонента является Text, которое представляет собой отображаемую компонентом строку. С помощью обработчика события onchange программа может контролировать вводимый пользователем текст и при необходимости фильтровать его, игнорируя недопустимые символы. В следующем примере компонент фильтрует все символы, которые не соответствуют правильному представлению вещественного числа:
var
OldText: String;
procedure TFor.gif" >
THeader управляющий заголовок
18.6.5. THeader - управляющий заголовокКомпонент THeader представляет собой многоколончатый заголовок с регулируемыми размерами колонок (секций). Каждая колонка (секция) заголовка может содержать текст и/или графику. Компонент способен обрабатывать событие onResize, которое возникает при каждом изменении размеров любой секции. В ходе обработки этого события программа обычно соответствующим образом изменяет линейные размеры столбцов таблицы или подобной структуры, с которой связан компонент.
Свойства Компонента THeader:
| property Sections: TStrings; | Содержит набор заголовков секций. Методами Add, Delete, Insert объекта Sections можно добавлять, вставлять и удалять секции заголовка |
| property SectionWidth[X: Integer] : Integer; | Содержит ширину секции с индексом index |
| TSectionEvent = procedure(Sender: TObject; ASection, AWidth: Integer) of object; | Возникает при завершении изменения размера секции с индексом ASection. AWidth -текущая ширина секции |
| property OnSized: TSectionEvent; TSectionEvent = procedure(Sender: TObject; ASection, AWidth: Integer) of object-property OnSizing: TSectionEvent; | Возникает в процессе изменения размера секции с индексом ASection. AWidth - текущая ширина секции |
TPrintDialog диалог настройки параметров печати
18.5.5. TPrintDialog - диалог настройки параметров печатиКомпонент TPrintDialog создает стандартное диалоговое окно для выбора параметров печати, показанное на Рисунок 18.42.
TTrackBarрегулятор величины
18.3.5. TTrackBar-регулятор величины
Компонент класса TTrackBar предназначен для визуального управления числовой величиной. Он во многом схож со стандартным элементом TScroll-Ваг и отличается от него в основном оформлением.
Свойства компонента:
| property Frequency: Integer; | Определяет частоту нанесения меток: 1 - каждое значение диапазона изменения имеет метку; 2 - каждое 2-е значение и т. д. |
| property LineSize: Integer; | Определяет смещение ползунка при нажатии клавиш курсора или при единичном перемещении мышью |
| property Max: Integer; | Определяет максимальное значение диапазона изменения |
| property Min: Integer; | Определяет минимальное значение диапазона измене ния |
| property Orientation:
TTrackBarOrientation; |
Определяет ориентацию компонента: trHorizontal -горизонтальная; trVertical -вертикальная |
| property PageSize: Integer; | Определяет смещение ползунка при нажатии клавиш Page Up, Page Down или при щелчке мышью на концах шкалы |
| property Position: Integer; | Определяет текущее положение ползунка |
| property SelEnd: Integer- | Задает конечную позицию выделения |
| property SelStart: Inte | Задает начальную позицию выделения |
| ger-property SliderVisible: Boolean-property ThumbLength: Integer; TTickMark = (tmBottomRight, tmTopLeft, tmBoth) ; property TickMarks: TTickMark; TTickStyle = (tsNone, tsAuto, tsManual) ; property TickStyle: TTickStyle; | Определяет, будет ли видимым указатель компонента Определяет длину указателя
Определяет способ нанесения меток: tmBottomRight -внизу или справа; tmTopLeft - вверху или слева; tmBottom - по обеим сторонам Определяет стиль нанесения меток: tsNone - нет меток; tsAuto - метки наносятся с частотой Frequence; tsManual - наносятся начальная и конечная метки, остальные наносит программа с помощью метода setTick |
procedure SetTick(Value: Integer);
устанавливается метка в позицию, определяемую значением value.
Указание порядка просмотра связанных разделов
21.3.5. Указание порядка просмотра связанных разделовСвязанные в некотором отношении разделы можно просматривать с помощью кнопок на инструментальной панели окна справочной службы. Связь разделов подразумевается создателем службы и может быть любая - по смысловой связанности, в алфавитном порядке, в порядке знакомства с программным продуктом и пр. Ниже представлен пример списка связанных разделов:
| Файл | гл меню:005 |
| Новый | меню файл:005 |
| Открыть | меню файл:010 |
| Сохранить | меню файл:015 |
| Сохранить как | меню файл:020 |
| Печатать | меню файл:025 |
| Выход | меню файл:030 |
| Редактировать | гл меню:010 |
| Очистить | меню редак:005 |
| Вырезать | меню редак:010 |
| Копировать | меню редак:015 |
| Вставить | меню редак:020 |
| Отменить | меню редак:025 |
| Окно | гл меню:015 |
| Каскад | меню окно:005 |
| Мозаика | меню окно:010 |
| Закрыть все | меню окно:015 |
Чтобы связать с разделом код для указания порядка просмотра раздела, необходимо вставить сноску “+”: *гл_меню:010
Обычно в качестве кодовой последовательности выбирают общее название связанных разделов и цифры порядкового номера. Номера полезно задавать с некоторым шагом (в нашем пример шаг равен 5), чтобы была возможность вставлять дополнения в списки разделов и при этом не изменять уже существующие сноски.
Замечу, что кнопки просмотра связанных разделов появляются в справочном окне автоматически, только от одного факта указания сноски “+” в текущем разделе. Чтобы вставить их независимо от этого, нужно выполнить макрокоманду BrowsButtons. Если макрокоманда выполнена, а текущий раздел не связан ссылкой “+” с другими разделами, кнопки появятся, но будут запрещены для выбора.
ИДЕНТИФИКАТОРЫ
6.2. ИДЕНТИФИКАТОРЫИдентификаторы в Object Pascal - это имена констант, переменных, меток, типов, объектов, классов, свойств, процедур, функций, модулей, программ и полей в записях. Идентификаторы могут иметь произвольную длину.
Идентификатор всегда начинается буквой, за которой могут следовать буквы и цифры. Напомню, что буквой считается также символ подчеркивания, поэтому идентификатор может начинаться этим символом и даже состоять только из одного или нескольких символов подчеркивания. Пробелы и специальные символы алфавита не могут входить в идентификатор.
Примеры правильных идентификаторов:
| a | MyProgramIsBestProgram | external |
| ALPHA | date_27_sep_39 | _beta |
1 Program // начинается цифрой
block#l // содержит специальный символ
My Prog // содержит пробел
mod // зарезервированное слово
КОНСТАНТЫ
6.3. КОНСТАНТЫВ качестве констант в Object Pascal могут использоваться целые, вещественные и шестнадцатеричные числа, логические константы, символы, строки символов, конструкторы множеств и признак непределенного указателя NIL.
Целые числа записываются со знаком или без него по обычным правилам и могут иметь значение в диапазоне от -2 63 до +2 63 -1 1 . Следует учесть, что, если целочисленная константа выходит за указанные границы, компилятор дает сообщение об ошибке. Такие константы должны записываться с десятичной точкой, т. е. определяться как вещественные числа.
Вещественные числа записываются со знаком или без него с использованием десятичной точки и/или экспоненциальной части.
Экспоненциальная часть начинается символом е или е, за которым могут следовать знаки “+” или “-” и десятичный порядок. Символ е (е) означает десятичный порядок и имеет смысл “умножить на 10 в степени”. Например,
3.14Е5 - 3,14 умножить на 10 в степени 5;
-17e-2 -минус 17 умножить на 10 в степени минус 2.
Если в записи вещественного числа присутствует десятичная точка, перед точкой и за ней должно быть хотя бы по одной цифре. Если используется символ экспоненциальной части е (в), за ним должна следовать хотя бы одна цифра десятичного порядка.[ Только для версий 4...6. Для версии 1 диапазон от -32536 до +32535. Для версии 2 и 3 от -2147483648 до +4294967294 ]
Шестнадцатеричное число состоит из шестнадцатеричных цифр, которым предшествует знак доллара $ (код символа 36). Диапазон шестнадцатеричных чисел - от $ffffffffffffffff до
$7FFFFFFFFFFFFFFF (для версии 4...6).
Логическая константа - это либо слово false (ложь), либо слово true (истина).
Символьная константа - это любой символ ПК, заключенный в апострофы:
'z' - символ “z”;
'Ф' - символ “Ф”.
Если необходимо записать собственно символ апострофа, он удваивается:
'''' - символ “'” (апостроф).
Допускается использование записи символа путем указания его внутреннего кода, которому предшествует символ # (код 35), например:
#97 - символ “а”;
#90 - символ “Z”;
#39 - символ “'”;
#13 - символ “CR”.
Строковая константа - любая последовательность символов (кроме символа CR - возврат каретки), заключенная в апострофы. Если в строке нужно указать сам символ апострофа, он удваивается, например:
'Это - строка символов';
'That''s string'.
Строка символов может быть пустой, т. е. не иметь никаких символов в обрамляющих ее апострофах. Строку можно составлять из кодов нужных символов с предшествующими каждому коду символами #, например, строка #83#i2i#i09#98#ii#i08 эквивалентна строке ' Symbol '.
Наконец, в строке можно чередовать части, записанные в обрамляющих апострофах, с частями, записанными кодами. Таким способом можно вставлять в строки любые управляющие символы, в том числе и символ cr (код 13), например:
#7'Ошибка !'#13'Нажмите любую клавишу ...'#7 .
Конструктор множества - список элементов множества, обрамленный-квадратными скобками,например:
[ 1,2,4..7,12]
[blue, red]
[ ]
[true]
В Object Pascal разрешается в объявлении констант использовать произвольные выражения, операндами которых могут быть ранее объявленные нетипизированные константы, имена типов и объектов, а также следующие функции от них:
| abs | lo | ptr | swap |
| chr | odd | round | trunc |
| hi | ord | sizeof | |
| length | pred | succ |
Например:
const
MaxReal = Maxint div SizeOf(real) ;
NumChars = ord('Z') - ord('a') + 1;
Ln10 = 2.302585092994;
Ln10R = 1 / Ln10;
ВЫРАЖЕНИЯ
6.4. ВЫРАЖЕНИЯОсновными элементами, из которых конструируется исполняемая часть программы, являются константы, переменные и обращения к функциям. Каждый из этих элементов характеризуется своим значением и принадлежит к какому-либо типу данных. С помощью знаков операций и скобок из них можно составлять выражения, которые фактически представляют собой правила получения новых значений.
Частным случаем выражения может быть просто одиночный элемент, т. е. константа, переменная или обращение к функции. Значение такого выражения имеет, естественно, тот же тип, что и сам элемент. В более общем случае выражение состоит из нескольких элементов (операндов) и знаков операций, а тип его значения определяется типом операндов и видом примененных к ним операций.
Примеры выражений:
у
21 (а + b) * с
sin(t)
а > 2
not Flag and (a = b)
NIL
[1, 3..7] * setl
ОПЕРАЦИИ
6.5. ОПЕРАЦИИВ Object Pascal определены следующие операции:
унарные not, @ ;
мультипликативные *, /, div, mod, and, shi, shr;
аддитивные +, -, or, xor;
отношения =, <>, <, >, <=, >=, in.
Приоритет операций убывает в указанном порядке, т. е. наивысшим приоритетом обладают унарные операции, низшим - операции отношения. Порядок выполнения нескольких операций равного приоритета устанавливается компилятором из условия оптимизации кода программы и не обязательно слева направо. При исчислении логических выражений операции равного приоритета всегда вычисляются слева направо, причем будут вычисляться все или только достаточные операции в зависимости от установленного в среде
Delphi переключателя Project | Options | Compiler | Complete
Boolean eval: при установленном переключателе вычисляются все операции отношения, при неустановленном - только те, что необходимы для однозначного определения результата исчисления.
Правила использования операций с операндами различного типа приводятся в табл. 6.1.
Таблица 6.1
| Операция | Действие | Тип операндов | Тип результата |
| not | Отрицание | Логический | Логический |
| not | To же | Любой целый | Тип операнда |
| @ | Адрес | Любой | Указатель |
| * | Умножение | Любой целый | Наименьший целый |
| * | Тоже | Любой вещественный | Extended |
| * | Пересечение множеств | Множественный | Множественный |
| / | Деление | Любой вещественный | Extended |
| div | Целочисленное деление | Любой целый | Наименьший целый |
| mod | Остаток от деления | Тоже | - Тоже |
| and | Логическое И | Логический | Логический |
| and | То же | Любой целый | Наименьший целый |
| shl | Левый сдвиг | Тоже | То же |
| shr | Правый сдвиг | То же | То же |
| + | Сложение | Тоже | Тоже |
| + | Тоже | Любой вещественный | Extended |
| + | Объединение множеств | Множественный | Множественный |
| + | Сцепление строк | Строковый | Строковый |
| - | Вычитание | Любой целый | Наименьший целый |
| - | Тоже | Любой вещественный | Extenden |
| or | Логическое или | Логический | Логический |
| or | Тоже | Любой целый | Наименьший целый |
| = | Равно | Любой простой или строковый | Логический |
| 0 | Не равно | Тоже | Тоже |
| < | Меньше | Логический | Логический |
| <= | Меньше или равно | Тоже | Тоже |
| > | Больше | То же | Тоже |
| >= | Больше или равно | Тоже | Тоже |
INLINE.
В Object Pascal определены следующие логические операции:
not - логическое НЕ;
and - логическое И;
or - логическое ИЛИ;
xor - исключительное ИЛИ.
Логические операции применимы к операндам целого и логического типов. Если операнды - целые числа, то результат логической операции есть тоже целое число, биты которого (двоичные разряды) формируются из битов операндов по правилам, указанным в табл. 6.2.
Таблица 6.2
| Логичеcкие операции над данными целого типа (поразрядно) 5 | |||||
| Операнд 1 | Операнд 2 | not | and | or | xor |
| 1 | - | 0 | - | - | - |
| 0 | - | 1 | - | - | - |
| 0 | 0 | - | 0 | 0 | 0 |
| 0 | 1 | - | 0 | 1 | 1 |
| 1 | 0 | - | 0 | 1 | 1 |
| 1 | 1 | - | 1 | 1 | 0 |
i shl j - сдвиг содержимого / на j разрядов влево; освободившиеся младшие разряды заполняются нулями;
i shr j - сдвиг содержимого i на j разрядов вправо; освободившиеся старшие разряды заполняются нулями.
В этих операциях i и у - выражения любого целого типа.
Логические операции над логическими данными дают результат логического типа по правилам, указанным в табл. 6.3.
Таблица 6.3
| Логические операции над данными логического типа | |||||
| Операнд 1 | Операнд 2 | not | and | or | xor |
| True | - | False | - | - | - |
| False | - | True | - | - | - |
| False | False | - | False | False | False |
| False | True | - | False | True | True |
| True | False | - | False | True | True |
| True | True | - | True | True | False |
Секция ALIASES
21.4.6. Секция ALIASESВ этой секции можно указать псевдонимы идентификаторов разделов, с помощью которых можно модифицировать секцию Map без изменения RTF-файлов. Назначение кнопок Add, Remove, include и Edit такое же, как и в секции мар. После назначения псевдонима он может использоваться в секции мар вместо идентификатора раздела. Эта возможность облегчает модификацию справочной службы.
Страница ADO
4.8.6. Страница ADOКомпоненты этой страницы в функциональном отношении во многом подобны компонентам страницы BDE, но поддерживают доступ к данным с помощью техологии ADO (ADOTable, ADOQuery,
ADostoredproc и т. д.). Все компоненты страницы впервые введены в версии 5.
TCalendar ввод и отображение даты
18.7.6. TCalendar - ввод и отображение датыКомпонент TCalendar отображает календарь на выбранный месяц и год. Его свойства Day, Month и Year могут содержать любую дату от 1 до 9999 года от Рождества Христова.
Свойства компонента:
| property CalendarDate: ~DateTime; property CellText[ACol, ARow: Integer]: String;
property Day: Integer; property GridLineWidth: Integer; |
Содержит выбранную дату Содержит текст в ячейке календаря на пересечении столбца ACol с рядом ARow (только для чтения) Определяет выбранный день месяца |
| property Month: Integer; property Readonly: Boolean; | Устанавливает толщину линий таблицы календаря Определяет выбранный месяц Если содержит True, пользователь не может выбрать другую дату |
| type TDayOfWeek = 0..6;property StartOfWeek: TSayOfWeek; | Определяет день недели, который будет отображаться в самом левом столбце таблицы |
| property UseCurrentDate: Boolean; | Если содержит True, компонент будет показывать текущую системную дату |
| property Year: Integer; | Определяет выбранный год |
| Методы компонента: | |
| procedure NextMonth; procedure NextYear; procedure PrevMonth; | Показывает календарь на следующий месяц Показывает календарь на следующий год Показывает календарь на предыдущий месяц |
| procedure PrevYear; | Показывает календарь на предыдущий год |
TFileListBox панель с именами файлов
18.6.6. TFileListBox - панель с именами файловКомпонент TFileListBox представляет собой панель с именами файлов. Совместно С компонентами TDriveComboBox, TFilterComboBox и TDirectoryListBox может использоваться для создания диалоговых окон доступа к файлам.
Свойства компонента:
| property Directory: String; | Определяет каталог размещения файлов |
| property Drive: Char; | Определяет диск размещения файлов |
| property FileEdit: TEdit; property FileName: String; | Объект-редактор для ввода имени файла вручную Введенное или выбранное имя файла |
| TFileAttr = (ftReadOnly, ftHidden, ftSystem, ftVolumeID, ftDirectory, ftArchive, ftNormal) ; TFileType = set of TFileAttr; property FileType: TFileType; | Определяет типы элементов, показываемых в окне компонента: ftReadOnly - файлы только для чтения; ftHidden - скрытые файлы; ftSystem -системные файлы; ftVolumeID - метки носителей; ftDirectory - каталоги; ftArchive - архивные файлы; ftNormal - обычные файлы |
| property Mask: String; | Определяет маску выбора файлов |
| property MultiSelect: Boolean; | Разрешает/запрещает множественный выбор файлов |
| property ShowGlyphs: Boolean; | Если содержит True, рядом с именами файлов показываются пиктограммы типа файла |
| procedure ApplyFilePath(const EditText: Strings; | Заменяет значения свойств Drive, Directory, FileName и Mask на те, что содержатся в строке EditText |
| procedure Update; | Обновляет содержимое окна |
property OnChange: TNotifyEvent;
возникающее при любом изменении выбора в окне компонента.
TImage отображение картинок
18.2.6. TImage - отображение картинокTMemo ввод и отображение текста
18.1.6. TMemo - ввод и отображение текста
Компоненты класса тмето предназначены для ввода, редактирования и/или отображения достаточно длинного текста. Текст хранится в свойстве Lines класса TStrings и, таким образом, представляет собой пронумерованный набор строк (нумерация начинается с нуля). С помощью свойств И методов этого класса (Count, Add, Delete, Clear и т. д. - см. п. 16.3.1) можно динамически формировать содержимое компонента.
Свойства BorderStyle, CanUndo, HideSelection, MaxLentgh, Modified, OEMConvert, OnChange, Readonly, SelLength, SelStart и SelText аналогичны соответствующим свойствам класса TEdit. Свойство WordWrap аналогично свойству TLabel. WordWrap. Другие специфичные свойства представлены ниже:
| property CaretPos: TPoint; | Содержит координаты мигающего текстового курсора относительно границ клиентской области компонента (только для Delphi 4...6) |
| property Lines: TStrings; TScrollStyle = (ssNone, ssHorizontal, ssVertical, ssBoth) ; property ScrollBars: Tscroll-Style; | Содержит строки текста Определяет наличие в окне редактора полос прокрутки: ssNone - нет полос;ssHorizontal -есть горизонтальная полоса; ssVertical - есть вертикальная полоса; ssBoth - есть обе полосы |
| property WantReturns: Boolean; | Если содержит True, нажатие Enter вызывает переход на новую строку, в противном случае обрабатывается системой. Для перехода на новую строку в этом случае следует нажать Ctrl+Enter |
| property WantTabs: Boolean; | Если содержит True, нажатие Tab вызывает ввод в текст символа табуляции, в противном случае - обрабатывается системой. Для ввода символа табуляции в этом случае следует нажать Ctrl+Tab |
Специфичные методы класса аналогичны методам класса TEdit.
Поскольку компонент является потомком TControl, он имеет также свойство Text, которое содержит отображаемый компонентом текст в виде одной длинной строки. В этой цепочке символов границы строк многострочного текста выделяются символами #13#10 (признак eoln - конец строки). В отличие от этого свойство Lines содержит пронумерованный список строк: первая строка в этом списке имеет индекс 0, вторая - 1, а общее количество строк можно узнать с помощью Lines .count.
Свойство Text удобно использовать для поиска в тексте нужного фрагмента. Чтобы, например, найти и выделить в тексте фрагмент, содержащийся В компоненте edSearch типа TEdit, можно использовать такой обработчик события onclick кнопки btSearch:
procedure TFor.gif" >
TPrinterSetupDialog диалог настройки параметров принтера
18.5.6. TPrinterSetupDialog - диалог настройки параметров принтераКомпонент создает окно настройки параметров принтера, вид которого зависит от типа принтера. Этот диалог взаимодействует с драйвером принтера и не возвращает в программу никакой информации, поэтому его метод Execute - процедура, а не функция.
Вставка графики
21.3.6. Вставка графикиЕсли вы создаете RTF-файл с помощью редактора Word, вы можете вставлять в текст графические врезки средствами редактора. Единственное ограничение: файлы с графикой должны соответствовать формату bmp. Однако Help-компилятор имеет и собственные средства вставки графических врезок с помощью внешних вмр-файлов. Ниже описывается, как это сделать.
Чтобы вставить в текст графический образ, необходимо поместить на предназначенное для размещения графики место специальную директиву в одном из следующих форматов:
(bmc filename.bmp}
{bml filename.bmp}
{bmr filename.bmp}
Здесь filename - имя вмр-файла; bmc, bml, bmr - команды, управляющие положением картинки относительно текста.
Команда bmc (от BitMap Char) предписывает рассматривать графический образ как символ. В этом случае он располагается точно на том месте в тексте справки, где указана директива вставки. Оставшаяся часть текста слева и справа от директивы разместится соответственно слева и справа от врезки, а высота строки с врезкой будет автоматически выбрана так, чтобы текст не накладывался на картинку. Команды bml (BitMap Left) и bmr (BitMapRight) заставят картинку прижаться соответственно к левому или правому краю окна справки. Все перечисленные в директивах ДМР-файлы должны располагаться в каталоге, указанном в опции bmroot секции [Options] проектного файла (см. п. 21.4.1).
Графический образ может служить ссылкой на пояснение или перекрестной ссылкой. Чтобы придать ему такие свойства, необходимо набрать текст директивы вместе с обрамляющими фигурными скобками перечеркнутым или дважды подчеркнутым шрифтом, если графическая врезка используется в качестве перекрестной ссылки, или подчеркнутым одной линией, если она служит ссылкой на пояснение. Сразу за выделенной таким образом директивой нужно указать скрытым текстом идентификатор связанного раздела. Например:
Этот графический образ [bmc flower.bmp]Bitmap Cross вставлен непосредственно в текст и служит перекрестной ссылкой. {bml hardware.bmp}Bitmap Comment Если щелкнуть мышью по расположенной слева картинке, появится дополнительное окно с пояснениями. Такие окна удобно использовать для пояснения второстепенных деталей справки.
{bmr legal.bmp} Правая картинка не является перекрестной ссылкой. Она просто иллюстрирует одно из многочисленных изображений, поставляемых для текстового редактора MS Word.
На Рисунок 21.5 показан экран Help-службы с графическими вставками. Для его создания использовался приведенный выше фрагмент RTF-файла.
ПРОСТЫЕ ТИПЫ
7.1. ПРОСТЫЕ ТИПЫК простым типам относятся порядковые, вещественные типы и тип дата-время.
Порядковые типы отличаются тем, что каждый из них имеет конечное количество возможных значений. Эти значения можно определенным образом упорядочить (отсюда - название типов) и, следовательно, с каждым из них можно сопоставить некоторое целое число - порядковый номер значения.
Вещественные типы , строго говоря, тоже имеют конечное число значений, которое определяется форматом внутреннего представления вещественного числа. Однако количество возможных значений вещественных типов настолько велико, что сопоставить с каждым из них целое число (его номер) не представляется возможным.
Тип дата-время предназначен для хранения даты и времени. Фактически для этих целей он использует вещественный формат.
СТРУКТУРИРОВАННЫЕ ТИПЫ
7.2. СТРУКТУРИРОВАННЫЕ ТИПЫЛюбой из структурированных типов (а в Object Pascal их четыре: массивы, записи, множества и файлы) характеризуется множественностью образующих этот тип элементов. Каждый элемент, в свою очередь, может принадлежать структурированному типу, что позволяет говорить о возможной вложенности типов. В Object Pascal допускается произвольная глубина вложенности типов, однако суммарная длина любого из них во внутреннем представлении не должна превышать 2 Гбайт [ 16-разрядные версии операционной системы Windows З.х используют так называемую “ сегментную” модель памяти, поэтому в Delphi 1 любой структурированный тип не может занимать более одного сегмента (65536 байт). ].
В целях совместимости со стандартным Паскалем в Object Pascal разрешается перед описанием структурированного типа ставить зарезервированное слово packed, предписывающее компилятору по возможности экономить память, отводимую под объекты структурированного типа; но компилятор фактически игнорирует это указание: “упаковка” данных в Object Pascal осуществляется автоматачески везде, где это возможно.
СТРОКИ
7.3. СТРОКИДля обработки текстов в Object Pascal используются следующие типы:
В стандартном Паскале используются только короткие строки String [n] . В памяти такой строке выделяется n+i байт, первый байт содержит текущую длину строки, а сами символы располагаются начиная со 2-го по счету байта. Поскольку для длины строки в этом случае отводится один байт, максимальная длина короткой строки не может превышать 255 символов. Для объявления короткой строки максимальной длины предназначен стандартный тип ShortString (эквивалент String[255]).
В Windows широко используются нуль-терминальные строки, представляющие собой цепочки символов, ограниченные символом #о. Максимальная длина такой строки лимитируется только доступной памятью и может быть очень большой.
В 32-разрядных версиях Delphi введен новый тип string, сочетающий в себе удобства обоих типов. При работе с этим типом память выделяется по мере надобности (динамически) и ограничена имеющейся в распоряжении программы доступной памятью. Замечу, что в Delphi 1 тип string эквивалентен String [2 55], т. е. определяет короткую строку максимально возможной длины.
Для совместимости с компонентами, основывающимися на OLE-технологии, в Delphi 32 введены также широкие строки, объявляемые стандартным типом wideString. По своим свойствам они идентичны длинным строкам string, но отличаются от них тем, что для представления каждого символа используются не один, а два байта.
Примеры объявлений строковых типов:
var
ssS: String[250];// Короткая строка длиной до 250 символов
ssMax: ShortString;// Короткая строка длиной до 255 символов
stS : String; // Длинная строка
swS: WideString;// Широкая строка
pcS: PChar; // Ссылка на нуль-терминальную строку
acS: array [0..1000] of Char; // Нуль-терминальная строка
// длиной до 1000 символов
При объявлении переменной sss компилятор выделит для ее размещения 250 + 1 = 251 байт и поместит в первый байт 0 - текущую длину строки. При выполнении такого фрагмента программы:
procedure TfmExample.bbRunClick(Sender: TObject);
var
ssS: String[250];
begin
ssS :='Строка символов';
ssS[6] := ' и'; // Символы в строке нумеруются, начиная с 1
IbOutput.Caption := ssS; // Выводится “Строки символов”
end;
сначала в переменную ssS будет помещена цепочка символов строка символов, причем 1-й байт получит значение 15 (количество символов в строке). После выполнения второго оператора символ с индексом б (индексация байтов начинается с 0, но, поскольку первый байт содержит текущую длину, первый символ в строке имеет индекс 1) будет заменен на “и”, и в переменной окажется цепочка строки символов.
Совершенно другим будет механизм работы с памятью при объявлении длинной строки sts: компилятор выделит для переменной 4 байта, достаточные для размещения номера той ячейки памяти, начиная с которой будет фактически располагаться символьная строка. Говорят, что sts ссылается на строку. Такого рода переменные-ссылки называются указателями и обсуждаются в гл. 9. При выполнении первого оператора такого обработчика:
procedure TfmExample.bbRunClick(Sender: TObject);
var
stS, stSS: String;
begin
stS :='Строка символов';
stSS := stS;
stS := 'Это - '+stS;
stS[7] := ' c' ; // Символы в строке нумеруются, начиная с 1
IbOutput.Caption := stS; //Выводится “Это - строка символов”
end;
программа (а не компилятор!) определит длину цепочки символов Строка символов, обратится к ядру перационной системы (ОС) с требованием выделить для нее участок памяти длиной 15+5=20 байт, поместит в переменную sts номер первого выделенного байта [ На самом деле в stS запоминается дескриптор выделенного участка памяти, см. гл. 9. ] и, начиная с него, разместит в этом участке цепочку символов, завершив ее терминальным нулем и 4-байтным счетчиком ссылок. Такое размещение на этапе прогона программы называется динамическим, в то время как размещение на этапе компиляции - статическим. Счетчик ссылок играет важную роль в механизме работы с памятью. С его помощью реализуется “кэширование” памяти: при выполнении оператора
stSS := stS;
память для размещения значения переменной stSS не выделяется, в переменную stSS помещается содержимое указателя sts, а счетчик ссылок в связанной с ним памяти увеличивается на единицу. Таким образом, оба указателя будут ссылаться на одну и ту же область памяти, счетчик ссылок которой будет содержать значение 2. При выполнении оператора
stS := 'Это - '+stS;
счетчик ссылок уменьшается на единицу, выделяется новая область памяти длиной 2 о + б = 2 б байт, указатель на эту область помещается в stS, а в саму память переписывается цепочка символов Это -строка символов, терминальный ноль и содержащий единицу счетчик ссылок. Теперь переменные stS и stss будут ссылаться на разные участки памяти, счетчики ссылок которых будут содержать по единице. Выделенная для размещения строки String область памяти освобождается, если ее счетчик ссылок стал равен нулю.
Похожим образом осуществляется работа с памятью при объявлении переменной pcs типа pchar: компилятор считает эту переменную указателем и выделит для нее 4 байта:
procedure TfmExample.bbRunClick(Sender: TObject);
var
pcS: PChar;
begin
pcS :='Строка символов';
pcS[5] := 'и'; {Символы в нуль-строке нумеруются,начиная с 0}
IbOutput.Caption := pcS; // Выводится “Строки символов”
end;
Программа потребует от ОС 15 + 1 = 16 байт, разместит в памяти цепочку символов и завершающий ее терминальный 0 и поместит адрес выделенного участка памяти в pcs.
Примечание
Примечание
В стандартном паскале, при обращении к области памяти, на которую ссылается указатель , требуется за именем указателя ставить специальный символ .“^”. В Object Раsса1 интенсивно используется динамическая, память, и поэтому, это жесткое требование смягчено: в большинстве случаев (и при обращении к типу pchar в том числе) символ "^" ставить не следует.
И, наконец, последнее объявление acs как массива символов. В Object Pascal считается совместимым с pchar одномерный массив символов с нулевой нижней границей. В отличие от pcs память для такой переменной выделяется статически (в нашем примере компилятор выделит в сегменте данных для переменной acs 1001 байт).
Для размещения в acs нуль-терминальной цепочки символов используется процедура strcopy:
procedure' TfmExample.bbRunClick(Sender: TObject) ;
var
acS: array [0..1000] of Char;
begin
StrCopy(acS,'Строка символов') ;
acS[5] := 'и'; { Символы в нуль-строке нумеруются,начиная с 0}
lbOutput.Caption := acS; // Выводится “Строки символов”
end;
Необходимость в нуль-терминальных строках возникает только при прямом обращении к API-функциям ОС. При работе с компонентами Delphi в основном используются более удобные длинные строки, которые рассматриваются в п. 7.3.1.
И несколько слов о широких строках, 32-разрядные версии Windows используют три сорта символов: однобайтный символ ANSI, двухбайтный символ и символ Unicode. Однобайтный символ связан с одним из 256 возможных значений, которые трактуются в зависимости от установленной в Windows национальной страницы (для размещения кириллицы используется страница 1251). 256 символов вполне достаточны для отображения национального алфавита любого европейского языка. Для отображения алфавитов некоторых азиатских языков этого недостаточно. В этом случае используется двухбайтный символ, в котором младший байт обычно кодируется семибитным ASCII-кодом, а старший указывает, как должен трактоваться этот код (каким символом он будет изображаться в документе или на экране). Символ Unicode в памяти занимает одно слово, которое имеет 65536 возможных значений. Специальная международная комиссия по Unicode выработала соглашение, позволяющее с помощью этого кода представить все символы всех языков мира. Двухбайтные символы и символы Unicode объявляются стандартным типом widecnar, а составленные из них строки - типом widestring. Все Windows-программы, использующие OLE-технологию обмена строками, должны кодировать символы в соответствии с Unicode.
УКАЗАТЕЛИ И ДИНАМИЧЕСКАЯ ПАМЯТЬ
7.4. УКАЗАТЕЛИ И ДИНАМИЧЕСКАЯ ПАМЯТЬ7.4.1. Динамическая память
Динамическая память - это оперативная память ПК, предоставляемая программе при ее работе. Динамическое размещение данных означает использование динамической памяти непосредственно при работе программы. В отличие от этого статическое размещение осуществляется компилятором Object Pascal в процессе компиляции программы. При динамическом размещении заранее не известны ни тип, ни количество размещаемых данных.
ПСЕВДОНИМЫ ТИПОВ
7.5. ПСЕВДОНИМЫ ТИПОВДля любого типа можно объявить сколько угодно псевдонимов. Например:
type
TMyInteger = Integer;
В дальнейшем псевдоним можно использовать так же, как и базовый тип:
var
Mylnt: TMyInteger;
begin
Mylnt := 2*Round(pi);
end;
Такого рода псевдонимы обычно используются для повышения наглядности кода программы. Однако в Object Pascal можно объявлять строго типизированные псевдонимы добавлением зарезервированного слова type перед именем базового типа:
type
TMyIntegerType = type Integer;
var
MylntVar: TMyIntegerType;
С точки зрения компилятора, типизированные псевдонимы совместимы с базовым типом в различного рода выражениях, но фактически они объявляют новый тип данных, поэтому их нельзя использовать в качестве формальных параметров обращения к подпрограммам вместо базового типа. Если, например, объявлена процедура
function MylntFunc(APar: integer): Integer;
begin
end;
то такое обращение к ней
MylntFunc(MylntVar)
будет расценено компилятором как ошибочное.
Строго типизированные псевдонимы заставляют компилятор вырабатывать информацию о типе для этапа прогона программы (RTTI - Run-Time Type Information). Эта информация обычно используется средой Delphi для обеспечения функционирования разного рода редакторов свойств и программ-экспертов.
Секция Config
21.4.7. Секция ConfigСекция [Config] предназначена для указания макрокоманд, которые будут выполняться в момент открытия справочной службы. С ее помощью можно также зарегистрировать подпрограммы из библиотеки) DLL, которые после этого могут использоваться наравне с макрокомандами.
Страница InterBase
4.8.7. Страница InterBase“Родной” для Delphi сервер баз данных InterBase (производитель - InterBase Software Corporation - является дочерним предприятием Borland) имеет непосредственную поддержку в виде компонентов этой страницы. В них используется технология IBExpress, позволяющая отказаться от BDE, ADO или иных подобных механизмов доступа к данным. Все компоненты страницы впервые введены в версии 5.
TButton кнопка
18.1.7. TButton - кнопка
Кнопки TButton широко используются для управления программами. Связанный с кнопкой алгоритм управления реализуется в обработчике события OnClick.
Свойства компонента:
| property Cancel: Boolean; | Если имеет значение True, событие OnClick кнопки возникает при нажатии клавиши Esc |
| property Default: Boolean; | Если имеет значение True, событие OnClick кнопки возникает при нажатии клавиши Enter |
| type TModaiResult = Low(Integer)..High(Integer) ; property ModalResult: TModaiResult; | Определяет результат, с которым было закрыто модальное окно (см. ниже пояснение) |
В терминологии Windows модальными окнами называются такие специальные окна, которые, раз появившись на экране, блокируют работу пользователя с другими окнами вплоть до своего закрытия. Обычно с их помощью реализуется диалог, требующий от пользователя принятия некоторого решения. Для этого в состав модального окна включается несколько кнопок. Если у кнопки определено свойство ModalResult, нажатие на нее приводит к закрытию модального окна и возвращает в программу значение ModalResult как результат диалога с пользователем. В Delphi определены следующие стандартные значения ModalResult:
mrNone Модальное окно не закрывается
mrlgnore Была нажата кнопка Ignore
mrOk Была нажата кнопка Oк
mrYes Была нажата кнопка Yes
mrCancel Была нажата кнопка Cancel
mrNo Была нажата кнопка No
mrAbort Была нажата кнопка Abort
mrAll Была нажата кнопка All
mrRetry Была нажата кнопка Retry
В отличие от большинства других видимых компонентов кнопка TButton является компонентом самой Windows и поэтому не может изменять свой цвет произвольным образом - она его меняет вместе с изменением палитры Windows. Кнопка всегда имеет системный цвет clBtnFace и не имеет свойства Color. Шрифт надписи на кнопке может менять свой стиль и размер, но компонент игнорирует изменение его цвета.
TDirectoryListBox панель с именами устройств
18.6.7. TDirectoryListBox - панель с именами устройствКомпонент TDirectoryListBox представляет собой панель с именами каталогов. Совместно с компонентами TDriveComboBox, tfuterComboBox И TFileListBox может использоваться для создания диалоговых окон доступа к файлам. Свойства компонента:
| property CaseSensitive: Boolean; | Содержит True, если файловая система чувствительна к высоте букв |
| property Directory: String; | Содержит имя каталога |
| property DirLabel: TLabel; | Указывает связанный с компонентом объект-метку, в котором отображается полный путь к текущему каталогу |
| property Drive: Char; | Содержит имя диска |
| property FileList: TFileListBox; | Указывает связанный с компонентом объект TFileListBox, в котором отображается содержимое каталога |
| property PreserveCase: Boolean; | Содержит True, если файловая система нечувствительна к высоте букв |
| function DisplayCase(const S: String): Strings; | Преобразует буквы строки S к строчным с учетом языкового драйвера, если ни свойство CaseSensitive, ни свойство PreserveCase не содержит True |
| function FileCompareText(const A, B: String): Integers; | Сравнивает строки а и в с учетом свойства CaseSensitive |
| function GetItemPath(Index : Integer) : Strings; | Возвращает путь к дочернему каталогу по его индексу |
| procedure OpenCurrent; | Открывает текущий каталог |
| procedure Update; | Обновляет текущий каталог |
property OnChange: TNotifyEvent;
возникающее при любом изменении выбора в окне компонента.
TFindDialog диалог поиска
18.5.7. TFindDialog - диалог поискаСтандартное диалоговое окно компонента TFindDialog используется для поиска фрагмента текста (Рисунок 18.43).
Свойства компонента:
| property FindText: String; | Указывает образец для поиска |
| property Left: Integer; | Содержит горизонтальную позицию левого верхнего угла места появления окна |
| property Options: TFindOptions; | Определяет настройку диалога (см. ниже) |
| property Position: TPoint; | Содержит горизонтальную и вертикальную позицию левого верхнего угла места появления окна |
| property Top: Integer; | Содержит вертикальную позицию левого верхнего угла места появления окна |
TFindOption = (frDown, frFindNext, frHideMatchCase, frHideWholeWord, frHideUpDown, frMatchCase, frDisableMatchCase, frDisableUpDown, frDisableWholeWord, frReplace, frReplaceAll, frWholeWord, frShowHelp) ;
TFindOptions = set of TFindOption;
TShape стандартная фигура
18.2.7. TShape - стандартная фигура
Компонент рисует одну из простейших геометрических фигур, определяемых следующим множеством:type TShapeType = (stRectangle, stSquare, stRoundRect, stRoundSquare, stEllipse, stCircle) ;
(прямоугольник, квадрат, скругленный прямоугольник, скругленный квадрат, эллипс, окружность). Фигура полностью занимает все пространство компонента. Если задан квадрат или круг, а размеры элемента по горизонтали и вертикали отличаются, фигура чертится с размером меньшего измерения.
Помимо стандартных чертежных инструментов Brush и pen (шрифт для компонента не нужен) в компоненте определено свойство shape.' TShapeType, которое и задает вид геометрической фигуры. Изменение этого свойства приводит к немедленной перерисовке изображения.
TUpDown спаренная кнопка
18.3.7. TUpDown - спаренная кнопка
Компонент TUpDown предназначен для регулирования числовой величины. Он имеет пару кнопок, с помощью которых величина наращивается или уменьшается. Обычно компонент TUpDown связан с другим компонентом класса TEdit, который отображает регулируемую величину и при необходимости может редактировать ее. Связанный компонент называется компаньоном.
Свойства компонента:
| TUDAlignButton = (udLeft, udRight) ; property AlignButton: TUDAlignButton; | Определяет положение компонента относительно компаньона: udLeft - TUpDown располагается слева от него; udRight - справа от него |
| property Associate: TWinuontrol; | Определяет связанный компонент. TupDown автоматически располагается с нужной стороны компаньона и выравнивает свою высоту с его высотой |
| property Increment: Smallint; | Определяет шаг наращивания/уменьшения регулируемой величины |
| property Max: Smallint; | Определяет максимальное значение диапазона
изменения регулируемой величины |
| property Min: Smallint; | Определяет минимальное значение диапазона изменения регулируемой величины |
| TUDOrientation = (udHorizontal,
udVertical) ; property Orientation: TUDOrientation; |
Определяет ориентацию компонента: udHorizontal - по горизонтали; udVertical - по вертикали |
| property Positior-.: Sallint; | Содержит текущее значение регулируемой величины |
| property Thousands: Boolean; | Если содержит True, в отображение числовой величины в компаньоне вставляются разделители тысяч |
| property Wrap: Boolean; | Запрещает/разрешает выход position из диапазона Max...Min (True - запрещает) |
type TUDChangingEvent = procedure (Sender: TObject;
var AllowChange: Boolean) of object;
property OnChar.ging: TUDChanginEvent;
И
type TUDBtnType = (btNext, btPrev) ;
type TUDClickEvent = procedure (Sender: TObject; Button:
TUDBtnType) ;
property OnClick: TUDClickEvent;
Первое возникает при любом изменении регулируемой величины. Обработчик события в параметре AllowChange сообщает, может ли величина измениться. Второе - при щелчке по кнопкам элемента. Параметр Button определяет нажатую кнопку: btprev - вниз или влево; btNext - вверх или вправо.
Выполнение макрокоманд
21.3.7. Выполнение макрокомандПри открытии того или иного раздела можно выполнить одну или несколько макрокоманд. С помощью макрокоманд можно гибко воздействовать на состояние окна справочной службы: его положение, размеры, цвет, содержимое меню и инструментальных кнопок, отображать другие Help-файлы, выполнять внешние программы и т. д. (см. п. 21.7). Для указания макрокоманды, исполняющейся в момент открытия раздела, ее имя задается в тексте сноски “!”. Сноска указывается вместе с другими сносками в самом начале раздела (до первого символа текста). Например, для вставки в инструментальную панель кнопок просмотра связанных разделов сноска имеет такой вид:
!BrowseButtons ( )
Если нужно указать несколько макрокоманд, они отделяются в тексте сноски символами “;”.
ЛОКАЛИЗАЦИЯ ИМЕН
8.1. ЛОКАЛИЗАЦИЯ ИМЕННапомню, что вызов подпрограммы осуществляется простым упоминанием имени процедуры в операторе вызова процедуры или имени функции в выражении. В Delphi 32 функцию можно вызывать точно так же, как и процедуру, т. е. без использования возвращаемого ею значения. Как уже говорилось, любое имя в программе должно быть обязательно описано перед тем, как оно появится среди исполняемых операторов. Не делается исключения и в отношении подпрограмм: каждую свою процедуру и функцию программисту необходимо описать в разделе описаний.
Описать подпрограмму - значит указать ее заголовок и тело. В заголовке объявляются имя подпрограммы и формальные параметры, если они есть. Для функции, кроме того, указывается тип возвращаемого ею результата. За заголовком следует тело подпрограммы, которое подобно программе состоит из раздела описаний и раздела исполняемых операторов. В разделе описаний подпрограммы могут встретиться описания подпрограмм низшего уровня, а в них - описания других подпрограмм и т. д.
Вот какую иерархию описаний получим, например, для программы, структура которой изображена на Рисунок 8.1 (для простоты считается, что все подпрограммы представляют собой процедуры без параметров):
Параметры
8.2.2. ПараметрыСписок формальных параметров необязателен и может отсутствовать. Если же он есть, то в нем должны быть перечислены имена формальных параметров и их типы, например:
Procedure SB(a: Real; b: Integer; с: Char);
Как видно из примера, параметры в списке отделяются друг от друга точками с запятой. Несколько следующих подряд однотипных параметров можно объединять в подсписки, например, вместо
Function F(a: Real; b: Real): Real;
можно написать проще:
Function F(a,b: Real): Real;
Операторы тела подпрограммы рассматривают список формальных параметров как своеобразное расширение раздела описаний:
все переменные из этого списка могут использоваться в любых выражениях внутри подпрограммы. Таким способом осуществляется настройка алгоритма подпрограммы на конкретную задачу.
Рассмотрим такой полезный пример. В Object Pascal не предусмотрена операция возведения вещественного числа в произвольную степень[ Начиная с версии 2 с Delphi поставляется модуль Match, в котором есть соответствующая функция. ]. Тем не менее эту задачу можно решить с использованием стандартных математических функций Ехр и Ln по следующему алгоритму:
X Y = e (Y*Ln(X))
Создадим функцию с именем power и двумя вещественными параметрами а и в, которая будет возвращать результат возведения а в степень в. Обработчик события bbRunСlick нашей учебной формы fmExampie читает из компонента edInput текст и пытается выделить из него два числа, разделенных хотя бы одним пробелом. Если это удалось сделать, он обращается к функции power дважды: сначала возводит первое число х в степень второго числа y, затем х возводится в степень -y.
procedure TfmExample.bbRunClick(Sender: TObject);
Function Power(A, B: Real): Real;
{Функция возводит число А в степень В. Поскольку логарифм отрицательного числа не существует, реализуется проверка значения А: отрицательное значение заменяется на положительное, для нулевого числа результат равен нулю. Кроме того, любое число в нулевой степени дает единицу.} begin
if А > 0 then
Result := Ехр(В * Ln(A)) else if A < 0 then
Result := Ехр(В * Ln(Abs(A))) else if В = 0 then
Result := 1 else
Result := 0;
end; // Power var
S: String;
X, Y: Real; begin
{Читаем строку из edinput и выделяем из нее два вещественных числа, разделенных хотя бы одним пробелом.} S := edinput.Text;
if (S = '') or (pos(' ' ,S) = 0) then
Exit; // Лет текста или в нем нет
// пробела - прекращаем дальнейшую работу try
// Выделяем первое число:
X := StrToFloat(copy(S, I, pos(' ', S) - 1));
// Если успешно, удаляем символы до пробела // и выделяем второе число:
Delete (S, 1, pos (' ', S) ) ;
Y := StrToFloat(Trim(S)) ;
except
Exit; // Завершаем работу при ошибке преобразования end;
mmOutput.Lines.Add(FloatToStr(Power(X, Y) ) ) ;
mmOutput.Lines.Add(FloatToStr(Power(X, -Y) ) ) ;
end;
Для вызова функции Power мы просто указали ее в качестве параметра при обращении к стандартной функции преобразования вещественного числа в строку FloatToStr. Параметры х и y в момент обращения к функции power - это фактические параметры. Они подставляются вместо формальных параметров а и в в заголовке функции, и затем над ними осуществляются нужные действия. Полученный результат присваивается специальной переменной с именем Re-suit, которая в теле любой функции интерпретируется как то значение, которое вернет функция после окончания своей работы. В программе функция power вызывается дважды - сначала с параметрами х и y, а затем х и -y, поэтому будут получены два разных результата.
Механизм замены формальных параметров на фактические позволяет нужным образом настроить алгоритм, реализованный в подпрограмме. Object Pascal следит за тем, чтобы количество и типы формальных параметров строго соответствовали количеству и типам фактических параметров в момент обращения к подпрограмме. Смысл используемых фактических параметров зависит от того, в каком порядке они перечислены при вызове подпрограммы. В нашем примере первый по порядку фактический параметр будет возводиться в степень, задаваемую вторым параметром, а не наоборот. Программист должен сам следить за правильным порядком перечисления фактических параметров при обращении к подпрограмме.
Любой из формальных параметров подпрограммы может быть либо параметром-значением, либо параметром-переменной, либо, наконец, параметром-константой.
В предыдущем примере параметры а и в определены как параметры-значения. Если параметры определяются как параметры-переменные, перед ними необходимо ставить зарезервированное слово var, а если это параметры-константы - слово const, например:
Procedure MyProcedure(var A: Real; В: Real; const C: String);
Здесь а - параметр-переменная, в - параметр-значение, а с - параметр-константа .
Определение формального параметра тем или иным способом существенно в основном только для вызывающей программы: если формальный параметр объявлен как параметр-переменная, то при вызове подпрограммы ему должен соответствовать фактический параметр в виде переменной нужного типа; если формальный параметр объявлен как параметр-значение или параметр-константа, то при вызове ему может соответствовать произвольное выражение. Контроль за неукоснительным соблюдением этого правила осуществляется компилятором Object Pascal. Если бы для предыдущего примера был использован такой заголовок функции:
Function Power (A: Real; var В : Real): Real;
то при втором обращении к функции компилятор указал бы на несоответствие типа фактических и формальных параметров (параметр обращения -Y есть выражение, в то время как соответствующий ему формальный параметр B описан как параметр-переменная).
Для того чтобы понять, в каких случаях использовать тот или иной тип параметров, рассмотрим, как осуществляется замена формальных параметров на фактические в момент обращения к подпрограмме.
Если параметр определен как параметр-значение, то перед вызовом подпрограммы это значение вычисляется, полученный результат копируется во временную память (стек) и передается подпрограмме. Важно учесть, что даже если в качестве фактического параметра указано простейшее выражение в виде переменной или константы, все равно подпрограмме будет передана лишь копия переменной (константы). Любые возможные изменения в подпрограмме параметра-значения никак не воспринимаются вызывающей программой, так как в этом случае изменяется копия фактического параметра.
Если параметр определен как параметр-переменная, то при вызове подпрограммы передается сама переменная, а не ее копия (фактически в этом случае подпрограмме передается адрес переменной). Изменение параметра-переменной приводит к изменению фактического параметра в вызывающей программе.
В случае параметра-константы в подпрограмму также передается адрес области памяти, в которой располагается переменная или вычисленное значение. Однако компилятор блокирует любые присваивания параметру-константе нового значения в теле подпрограммы.
Итак, параметры-переменные используются как средство связи алгоритма, реализованного в подпрограмме, с внешним миром: с помощью этих параметров подпрограмма может передавать результаты своей работы вызывающей программе. Разумеется, в распоряжении программиста всегда есть и другой способ передачи результатов - через глобальные переменные. Однако злоупотребление глобальными связями делает программу, как правило, запутанной, трудной в понимании и сложной в отладке. В соответствии с требованиями хорошего стиля программирования рекомендуется там, где это возможно, использовать передачу результатов через фактические параметры-переменные.
С другой стороны, описание всех формальных параметров как параметров-переменных нежелательно по двум причинам. Во-первых, это исключает возможность вызова подпрограммы с фактическими параметрами в виде выражений, что делает программу менее компактной. Во-вторых, и главных, в подпрограмме возможно случайное использование формального параметра, например, для временного хранения промежуточного результата, т. е. всегда существует опасность непреднамеренно испортить фактическую переменную. Вот почему параметрами-переменными следует объявлять только те, через которые подпрограмма в действительности передает результаты вызывающей программе. Чем меньше параметров объявлено параметрами-переменными и чем меньше в подпрограмме используется глобальных переменных, тем меньше опасность получения не предусмотренных программистом побочных эффектов, связанных с вызовом подпрограммы, тем проще программа в понимании и отладке. По той же причине не рекомендуется использовать параметры-переменные в заголовке функции: если результатом работы функции не может быть единственное значение, то логичнее использовать процедуру или нужным образом декомпозировать алгоритм на несколько подпрограмм. -
Существует еще одно обстоятельство, которое следует учитывать при выборе вида формальных параметров. Как уже говорилось, при объявлении параметра-значения осуществляется копирование фактического параметра во временную память. Если этим параметром будет массив большой размерности, то существенные затраты времени и памяти на копирование при многократных обращениях к подпрограмме можно минимизировать, объявив этот параметр параметром-константой. Параметр-константа не копируется во временную область памяти, что сокращает затраты времени на вызов подпрограммы, однако любые его изменения в теле подпрограммы невозможны - за этим строго следит компилятор.
Еще одно свойство Object Pascal - возможность использования нетипизированных параметров. Параметр считается нетипизированным, если тип формального параметра-переменной в заголовке подпрограммы не указан, при этом соответствующий ему фактический параметр может быть переменной любого типа. Заметим, что нетипизированными могут быть только параметры-переменные:
Procedure MyProc(var aParametr);
Нетипизированные параметры обычно используются в случае, когда тип данных несущественен. Такие ситуации чаще всего возникают при разного рода копированиях одной области памяти в другую, например, С помощью процедур BlockRead, BlockWrite, Move-Memory И Т. П.
ОПИСАНИЕ ПОДПРОГРАММЫ
8.2. ОПИСАНИЕ ПОДПРОГРАММЫОписание подпрограммы состоит из заголовка и тела подпрограммы.
ПАРАМЕТРЫМАССИВЫ И ПАРАМЕТРЫСТРОКИ
8.3. ПАРАМЕТРЫ-МАССИВЫ И ПАРАМЕТРЫ-СТРОКИМожет сложиться впечатление, что объявление переменных в списке формальных параметров подпрограммы ничем не отличается от объявления их в разделе описания переменных. Действительно, в обоих случаях много общего, но есть одно существенное различие:
типом любого параметра в списке формальных параметров может быть только стандартный или ранее объявленный тип. Поэтому нельзя, например, объявить следующую процедуру:
Procedure S (a: array [1..10] of real);
так как в списке формальных параметров фактически объявляется тип-диапазон, указывающий границы индексов массива.
Если мы хотим передать какой-то элемент массива, то проблем, как правило, не возникает, но если в подпрограмму передается весь массив, то следует первоначально описать его тип. Например:
type
аТуре = array [1..10] of Real;
Procedure S(var a: аТуре);
Поскольку короткая строка является фактически своеобразным массивом, ее передача в подпрограмму осуществляется аналогичным образом:
type
InputType = String [15];
OutputType = String [30];
Function St(S: InputType): OutputType;
Требование описать любой тип-массив или тип-строку перед объявлением подпрограммы, на первый взгляд, кажется несущественным. Действительно, в рамках простейших вычислительных задач обычно заранее известна структура всех используемых в программе данных, поэтому статическое описание массивов не вызывает проблем. Однако разработка программных средств универсального назначения связана со значительными трудностями.
ПРОЦЕДУРНЫЕ ТИПЫ
8.4. ПРОЦЕДУРНЫЕ ТИПЫОсновное назначение процедурных типов - дать программисту гибкие средства передачи функций и процедур в качестве фактических параметров обращения к другим процедурам и функциям.
Для объявления процедурного типа используется заголовок процедуры (функции), в котором опускается ее имя, например:
type
Proc1 = Procedure (a, b, с: Real; var d: Real); Proc2 = Procedure (var a, b);
РгосЗ = Procedure;
Func1 = Function: String;
Func2 = Function (var s: String): Real;
Как видно из приведенных примеров, существует два процедурных типа: тип-процедура и тип-функция.
В следующий программе иллюстрируется механизм передачи процедур в качестве фактических параметров вызова. Программа выводит на экран таблицу двух функций: sin1 (х) = (sin(x) + 1) * Ехр(-х) и cosi(x) = (Cos(x) + 1) * Ехр(-х) . Вычисление и печать значений этих функций реализуются в процедуре printFunc, которой в качестве параметров передается количество np вычислений функции в диапазоне х от 0 до 2*3.141592 и имя нужной функции.
Function Sinl(X: Real): Real;
begin
Result := (Sin(X) + 1) * Exp(-X) end; // Sin 1
Function Cosl(X: Real): Real;
begin
Result := (Cos(X) + 1) * Exp(-X) end; // Cosi
procedure TfmExample.bbRunClick(Sender: TObject);
type
Func = function (X: Real): Real; // Процедурный тип Procedure PrintFunc(NP: Integer; F; Func) ;
var
k: Integer;
X: Real;
begin
for k := 0 to NP do
begin
X:=k*2*pi/ NP;
mmOutput.Lines.Add(FloatToStrF(X, ffExponent, 10, 2) + #9#9 + FloatToStrF(F(X), ffExponent, 10, 2)) ;
end;
end; // PrintFunc
begin // bbRunClick
nmiOutput.Lines.Add(#9'Функция SINI:');
PrintFunc (10, Sini);
mmOutput.Lines.Add(#9'Функция COSI:');
PrintFunc (10, Cosi);
end;
Обратите внимание: передаваемые подпрограммы не могут быть локальными, т. е. процедурами или функциями, объявленными внутри другой подпрограммы. Вот почему описание подпрогра^.' sini и cosi размещаются вне обработчика bbRunciick, но выше не." по тексту модуля. Замечу, что символ #9 - это символ табуляции. который вставляется в формируемые строки для разделения колонок с цифрами.
В программе могут быть объявлены переменные процедурных типов, например,так:
var
p1 : Proc1;
fl, f2 : Func2;
ар : array [1..N] of Proc1;
Переменным процедурных типов допускается присваивать в качестве значений имена соответствующих подпрограмм. После такого присваивания имя переменной становится синонимом имени подпрограммы.
РЕКУРСИЯ И ОПЕРЕЖАЮЩЕЕ ОПИСАНИЕ
8.5. РЕКУРСИЯ И ОПЕРЕЖАЮЩЕЕ ОПИСАНИЕРекурсия - это такой способ организации вычислительного процесса, при котором подпрограмма в ходе выполнения составляющих ее операторов обращается сама к себе.
Рассмотрим классический пример - вычисление факториала. Программа получает от компонента edinput целое число n и выводит в компонент lboutput значение N!, которое вычисляется с помощью рекурсивной функции Factorial.
При выполнении правильно организованной рекурсивной подпрограммы осуществляется многократный переход от некоторого текущего уровня организации алгоритма к нижнему уровню последовательно до тех пор, пока, наконец, не будет получено тривиальное решение поставленной задачи. В нашем случае решение при n = 0 тривиально и используется для остановки рекурсии.
procedure TfmExample.bbRunClick(Sender: TObject);
Function Factorial(N: Word): Extended;
begin
if N = 0 then
Result : = 1 else
Result := N * Factorial(N-1)
end;
var
N: Integer;
begin
try
N := StrToInt(Trim(edinput.Text));
except
Exit; end;
IbOutput.Caption := FloatToStr(Factorial(N))
end;
Рекурсивная форма организации алгоритма обычно выглядит изящнее итерационной и дает более компактный текст программы, но при выполнении, как правило, медленнее и может вызвать переполнение стека (при каждом входе в подпрограмму ее локальные переменные размещаются в организованной особым образом области памяти, называемой программным стеком).
Рекурсивный вызов может быть косвенным. В этом случае подпрограмма обращается к себе опосредованно, путем вызова другой подпрограммы, в которой содержится обращение к первой, например:
Procedure A (i : Byte);
begin
В (i);
end;
Procedure В (j : Byte) ;
begin
а(j);
end;
Если строго следовать правилу, согласно которому каждый идентификатор перед употреблением должен быть описан, то такую программную конструкцию использовать нельзя. Чтобы такого рода вызовы стали возможны, вводится опережающее описание:
Procedure В (j : Byte) ; For.gif" >
Отображение текста раздела в дополнительном окне
21.3.8. Отображение текста раздела в дополнительном окнеПомимо основного окна в справочной службе можно определить множество дополнительных окон, каждое из которых в общем случае будет иметь свой цвет, заголовок, размеры и т. д. Дополнительные окна описываются в секции [windows] проектного файла (см. п. 21.4.). Чтобы указать, что раздел справки должен по умолчанию отображаться в дополнительном окне, используется ссылка “>” (с помощью модификации гиперссылки можно заменить умалчиваемый тип окна на другой, см. ниже). В тексте ссылки указывается тип окна так, как он определен в проектном файле, например:
> wind
В ссылке “>” может указываться только одно умалчиваемое окно. Другим способом указания дополнительного окна является модификация перекрестной ссылки (см. п. 21.3.1). Если, например, в
ссылке
ГИПЕРТЕКСТ НУРЕКТЕХТ
раздел hypertext должен отображаться в окне windi, ссылка оформляется следующим образом:
ГИПЕРТЕКСТ НУРЕКТЕХТ>WIND1
Окно, указанное в тексте ссылки, имеет приоритет перед умалчиваемым окном, если оно определено сноской">" для раздела. Для нашего примера это означает, что окно windi будет использоваться для отображения ссылки гипертекст даже в том случае, если раздел hypertext имеет сноску “>”, в которой указано другое окно.
Секция BAGGAGE
21.4.8. Секция BAGGAGEКнопкой Data Files окна MS HW открывается диалоговое окно определения файлов, которые будет использовать справочная служба. Список этих файлов содержит секция [Baggage] проектного файла. Помимо RTF-файлов, которые обычно вставляются в секции [Files] (см. п. 21.4.2), здесь можно также указать файлы библиотек DLL, подпрограммы которых после этого могут использоваться как макрокоманды.
Страница Decision Cube
4.8.8. Страница Decision CubeНа этой странице представлены компоненты для систем принятия решений на основании анализа многомерных наборов данных. Компоненты этой страницы впервые введены в версии 3.
TBevel кромка
18.2.8. TBevel - кромкаКомпонент класса TBevel носит оформительский характер и предназначен для выделения группы элементов или отделения их друг от друга. Свойство
type TBevelShape = (bsBox, bsFrame, bsTopLine, bsBottomLine, bsLeftLine, bsRightLine);
property Shape: TBevelShape;
определяет вид компонента (прямоугольник, рамка, верхняя линия, нижняя линия, левая линия, правая линия).
Свойство
type TBevelStyle = (bsLowered, bsRaised) ;
property Style: TBevelStyle;
задает стиль компонента (вдавленный или выпуклый).
TCheckBox независимый переключатель
18.1.8. TCheckBox - независимый переключатель
Независимый переключатель TCheckBox используется для того, чтобы пользователь мог указать свое решение типа Да/Нет или Да/Нет/Не совсем (в последнем случае в окошке компонента устанавливается флаг выбора, но само окошко закрашивается серым цветом). Это решение отражается в свойстве State компонента, доступном как для чтения, так и для записи. В составе диалогового окна может быть несколько компонентов TCheckBox. Состояние любого из них не зависит от состояния остальных, поэтому такие переключатели называются независимыми.
Типичное использование компонента:
if CheckBoxl.Checked then
else
Или:
case CheckBoxl.State of cbChecked :... ;
cbUnchecked:...;
cbGrayed :...;
end;
Свойства компонента:
| type TLeftRight = (taLeftJustify, taRightJustify) ; property Alignment: TLeftRight; | Определяет положение текста: taLeftJustify - с левой стороны компонента; taRightJustify - С Правой стороны |
| property AllowGrayed: Boolean; | Разрешает/запрещает использование состояния cbGrayed (Не совсем) |
| ptoperty Caption: Strings | Содержит связанный с компонентом текст |
| property Checked: Boolean; | Содержит выбор пользователя типа Да/Нет. Состояния cbUnchecked и cbGrayed отражаются как False |
| type TCheckBoxState = (cbUnchecked, cbChecked, cbGrayed) ; property State: TCheckBoxState | Содержит состояние компонента: cbUnchecked - нет; cbChecked - да; cbGrayed - не совсем |
TDriveComboBox список выбора устройства
18.6.8. TDriveComboBox - список выбора устройстваКомпонент TDriveComboBox представляет собой список выбора с именами доступных дисков. Совместно с компонентами TDirectoryListBox, TFilterComboBox И TFileListBox может использоваться для создания диалоговых окон доступа к файлам.
Свойства компонента:
| property DirList: TDirectoryList-Box; | Содержит ссылку на объект TDirectoryListBox, в котором отображается структура файлов на диске |
| property Drive: Char; TTextCase = (tcLowerCase, tcUp-perCase); property TextCase: TTextCase; | Содержит имя текущего диска Определяет отображение буквы диска: tcLowerCase - отображать строчной буквой; tcuppercase - отображать заглавной буквой |
property OnChange: TNotifyEvent;
возникающее при любом изменении выбора в окне компонента, а также событие
property OnDropDown: TNotifyEvent;
связанное с раскрытием списка.
THotKey ввод акселератора
18.3.8. THotKey - ввод акселератораКомпонент THotKey служит для ввода или отображения клавиш быстрого выбора (в терминологии Windows их называют горячими клавишами, или акселераторами). При вводе компонент работает
как специализированный однострочный редактор, который распознает нажатие сдвиговых клавиш Shift, Ctrl и Alt и преобразует их в текст <
Свойства компонента:
| property AutoSize: Boolean; | Разрешает/запрещает автоматическое изме
нение размеров компонента при изменении шрифта, которым отображается текст в нем |
| type TShortCut =
Low(Word)..High(Word) ; property HotKey: TShortCut; |
Содержит код клавиши быстрого выбора |
| type THKInvalidKey = (hcNone,
hcShift, hcCtrl, hcAlt, hcCtrlAlt, hcShiftCtrlAlt) ; THKInvalidKeys = set of THKIn validKey; property InvalidKeys: THKInvalid Keys; |
Указывает запрещенные комбинации сдвиговых клавиш: hcNone - запрещено отсутствие сдвиговых клавиш; hcShift - запрещена клавиша Shift; hcCtrlAlt -запрещена
комбинация Ctrl + Alt и т. д. По умолчанию содержит [hcNone, hcShift]. При вводе запрещенной комбинации она заменяется комбинацией, содержащейся в свойстве Modifier |
| type THKModifier = (hkShift,
hkCtrl, hkAlt, hkExt); THKModifiers = set of THKModi fier; property Modifiers: THKModifiers; |
Содержит комбинацию сдвиговых клавиш,
которая заменяет собой запрещенную комбинацию. По умолчанию содержит hkAlt, и поэтому нажатие, например, одиночной алфавитно-цифровой клавиши заменяется ее комбинацией с клавишей Alt |
TReplaceDialog диалог поиска и замены
18.5.8. TReplaceDialog - диалог поиска и заменыКомпонент TReplaceDialog создает и обслуживает окно поиска и замены текстового фрагмента (см. Рисунок 18.44).
ОСНОВНЫЕ ПОНЯТИЯ
9.1. ОСНОВНЫЕ ПОНЯТИЯКлассы - это особое “изобретение” программистов для упрощения разработки сложных программ и улучшения их качества. В основе классов лежат три фундаментальных принципа, которые называются инкапсуляция, наследование и полиморфизм.
СОСТАВЛЯЮЩИЕ КЛАССА
9.2. СОСТАВЛЯЮЩИЕ КЛАССА9.2.1. Поля
Полями называются инкапсулированные в классе данные. Поля могут быть любого типа, в том числе - классами, например:
type TMyClass = class
aIntField: Integer;
aStrField: String;
aObjField: TObject;
end;
Каждый объект получает уникальный набор полей, но общий для всех объектов данного класса набор методов и свойств. Фундаментальный принцип инкапсуляции требует обращаться к полям только с помощью методов и свойств класса. Однако в Object Pascal разрешается обращаться к полям и напрямую:
type
TMyClass = class
FIntField: Integer;
FStrField: String; end;
var
aObject: TMyClass;
begin
aObject.FIntField := 0;
aObject.FStrField := 'Строка символов';
end;
Класс-потомок получает все поля всех своих предков и может дополнять их своими, но он не может переопределять их или удалять.
Таким образом, чем ниже в дереве иерархии располагается класс, тем больше данных получают в свое распоряжение его объекты.
ОБЪЯВЛЕНИЕ КЛАССА
9.3. ОБЪЯВЛЕНИЕ КЛАССАЛюбой вновь создаваемый класс может содержать секции (разделы), определяемые зарезервированными словами published (опубликованные), private (закрытые), protected (защищенные), public (доступные) и automated (автоматизированные). Внутри каждой секции вначале определяются поля, а затем - методы и свойства.
Секции определяют области видимости элементов описания класса. Секция public не накладывает ограничений на область видимости перечисляемых в ней полей, методов и свойств - их можно вызывать в любом другом модуле программы. Секция published также не ограничивает область видимости, однако в ней перечисляются свойства, которые должны быть доступны не только на этапе исполнения, но и на этапе конструирования программы (т. е. в окне Инспектора объектов). Секция published используется только при разработке нестандартных компонентов. Замечу, что среда Delphi помещает описания компонентов, вставленных в форму, в специальную секцию без названия, которая располагается сразу за заголовком класса и продолжается до первой объявленной секции. Эта секция - published. Программисту не следует помещать в нее собственные элементы описания класса или удалять из нее элементы, вставленные средой. Секция private сужает область видимости до минимума: закрытые элементы описания доступны только внутри методов данного класса и подпрограммах, находящихся в том же модуле, где описан класс. Элемент, объявленный в секции private, становится недоступным даже ближайшим потомкам класса, если они размещаются в других модулях. Секция protected доступна только методам самого класса, а также любым его потомкам, независимо от того, находятся ли они в том же модуле или нет. Наконец, секция automated используется только для объявления свойств и методов, которые будут добавлены к так называемому интерфейсу OLE-объектов Автоматизации; область видимости членов этой секции не ограничена.
В Object Pascal разрешается сколько угодно раз объявлять любую секцию, причем порядок следования секций не имеет значения. Любая секция может быть пустой.
Следующий фрагмент кода поясняет области видимости.
Unit Unit1;
Interface
Uses Controls, For.gif" >
ИНТЕРФЕЙСЫ
9.4. ИНТЕРФЕЙСЫИнтерфейсы играют главную роль в технологиях СОМ (Component Object Model - компонентная модель объектов), CORBA (Common Object Request Broker Architecture - архитектура с брокером требуемых общих объектов) и связанных с ними технологиях удаленного доступа, т. е. технологиях доступа к объектам, расположенным (и выполняющимся) на другой машине. Их основная задача - описать свойства, методы и события удаленного объекта в терминах машины клиента, т. е. на используемом при разработке клиентского приложения языке программирования. С помощью интерфейсов программа клиента обращается к удаленному объекту так, как если бы он был ее собственным объектом.
Тема интерфейсов достаточно обширна и интересна. В этой главе даются лишь самые общие сведения об интерфейсах. Сведение этой темы в одну главу с классами не случайно, т. к. интерфейс представляет собой пустой класс, т. е. класс, в котором провозглашены, но никак не расшифрованы свойства и методы.
Страница QReport
4.8.9. Страница QReportОколо 30 компонентов страницы предназначены для упрощения создания отчетов по материалам, хранящимся в БД. Большинство компонентов страницы впервые введено в версии 2.
TAnimate отображение анимации
18.3.9. TAnimate - отображение анимацииКомпонент TAnimate представляет собой проигрыватель видеоклипов формата AVI (Audio Video Interleaved - чередование аудио и видео). Компонент воспроизводит видеочасть файла AVI и игнорирует его звуковое сопровождение. Он способен показывать лишь несжатое изображение или изображение, сжатое по методу RLE (Run-Length Encoding). Изображение воспроизводится в отдельном потоке команд, что освобождает ресурсы программы для выполнения необходимой работы на фоне демонстрации клипа.
Если вы захотите посмотреть компонент в действии (Рисунок 18.24), выполните следующее:
TFilterComboBox список выбора с расширениями файлов
18.6.9. TFilterComboBox - список выбора с расширениями файловКомпонент TFilterComboBox представляет собой список выбора с расширениями файлов. Совместно с компонентами TDirectoryListBox, TDriveComboBox и TFiieListBox может использоваться для создания диалоговых окон доступа к файлам.
Свойства компонента:
| property FileList: TFiieListBox; | Указывает связанный с компонентом объект для просмотра файлов. |
| property Filter: String; | Содержит фильтр в виде поясняющего текста и маски. |
| property Mask: String; property Text: TCaption; | Содержит текущую маску выбора файлов. Содержит поясняющий текст фильтра. |
property OnChange: TNotifyEvent;
возникающее при любом изменении выбора в окне компонента, а также событие
property OnDropDown: TNotifyEvent;
связанное с раскрытием списка.
TRadioButton зависимые переключатели
18.1.9. TRadioButton - зависимые переключатели
В отличие от TCheckBox компоненты TradioButton представляют собой зависимые переключатели, предназначенные для выбора одного из нескольких взаимоисключающих решений. На форму (точнее, в компонент-контейнер) помещается по меньшей мере два таких компонента. Они могут иметь только два состояния, определяемых свойством Сhecked. Если в одном компоненте это свойство принимает значение True, во всех других компонентах, расположенных в том же контейнере, свойства Сhecked принимают значения False.
Помимо свойства checked компонент TRadioButton имеет еще одно специфичное свойство - Alignment, аналогичное такому же свойству TCheckBox. Как и в TCheckBox, программист не может изменять размеры и цвет круглого окошка компонента.
TScrollBox панель с прокруткой
18.2.9. TScrollBox - панель с прокруткойА) вид рамы на этапе конструирования
Рисунок 18.1. а) вид рамы на этапе конструирования: 6) окно регистрации рамы в палитре компонентов
Установленные параметры создадут минимальную по размерам раму с двумя именованными кнопками. Так как свойство Anchors рамы содержит значения [akRight, akBottoms], рама будет все время отслеживать свое положение относительно правого нижнего угла контейнера, в который она будет помещена.
/B> а) окно выбора доступного
Рисунок 18.2 . а) окно выбора доступного шаблона; б) форма с размещенным на ней шаблоном
Свойства входящих в шаблон компонентов, а также свойства самого размещенного на форме шаблона можно менять, приспосабливая их к конкретным нуждам программы.
Компонент TFrame является потомкам TScrollingWinControl, от которого ему достались три описываемых ниже специфичных свойства (остальные свойства, события и методы унаследованы от rwin-controi и описаны в гл. 17):
| property AutoScroll: Boolean;property HorzScrollBar: TControlScrollBar; | Определяет свойства горизонтальной полосы прокрутки |
| property VertScrollBar: TControlScrollBar; | Определяет свойства вертикальной полосы прокрутки |
Свойства TControlScrollBar:
| property Margin: Word; | Определяет минимальное расстояние от полосы до края компонента, в котором она расположена |
| property ButtonSize: Integer; | Определяет размер кнопок полосы прокрутки |
| property Color: TColor; | Определяет цвет полосы |
| type=(sbHorizontal,sbVertical) ; property Kind: ScrollBarKind; | Указывает ориентацию полосы (это свойство - только для чтения) |
| type TScrollBarInc = 1..32767; property Increment: TScrollBarInc; | Указывает перемещение бегунка при щелчке мышью на концевой кнопке полосы |
| property ParentColor: Boolean; | Если содержит True, цвет полосы определяется системными установками Windows. Установка значения в свойство color при
водит к автоматической установке значения False в свойство ParentColor |
| property Position: Integer; | Определяет положение бегунка на полосе прокрутки |
| property Range: Integer; | Определяет размер скроллируемой области |
| property ScrollPos: Integers; | Определяет положение скроллируемой области |
| property Size: Integer; | Определяет ширину полосы в пикселях |
| property Smooth: Boolean; | Если содержит True, прокрутка осуществляется стандартным образом: щелчок по концевой кнопке вызывает смещение приблизительно на 1/10 части всей прокручиваемой области. Если содержит False, смещение определяется свойством Increment |
| TScrollBarStyle = (ssRegular,
ssFlat, ssHotTrack); |
Определяет стиль полосы: ssRegular обычная полоса; ssFlat - плоская полоса; |
| property Style: TScrollBarStyle; | ssHotTrack - плоская полоса, ее компоненты выделяются цветом при перемещении над ней указателя мыши |
| property ThumbSize: Integer; | Определяет ширину бегунка в пикселях |
| property Tracking: Boolean; | Разрешает/запрещает динамическую прокрутку при перемещении ползунка |
| property Visible: Boolean; | Определяетвидимость полосы |
/B> Диалоговое окно регистрации формы в архиве
Рисунок 5.2 . Диалоговое окно регистрации формы в архиве
Не советую пользоваться опцией меню Project | Add то Repositiry, т. к. в этом случае в репозиторий будет добавлен проект, а не форма. Проекты из репозитория копируются целиком вместе с многочисленными родительскими классами, что замедляет время создания нового проекта и приводит к неоправданным затратам дисковой памяти.
В строке Title напишите имя формы fmExample, В Строке Description — пояснение, например, прототип главной формы для учебной программы, раскройте список page и выберите в нем For.gif" >
/B> Файл проекта с многими формами
Рисунок 19.3 Файл проекта с многими формами
/B> Форма со вставленной кнопкой
Рисунок 3.2 Форма со вставленной кнопкой
Этот фрагмент должен представлять собой последовательность текстовых строк, в которых программист указывает, что именно должна делать программа в ответ на нажатие кнопки. Фрагмент оформляется в виде специальной подпрограммы языка Object Pascal - процедуры.
Чтобы заставить Delphi самостоятельно сделать заготовку для процедуры обработчика события OnClick, дважды подряд без заметной паузы щелкните мышью по вновь вставленному компоненту[ У начинающего пользователя Windows не всегда получается двойной щелчок. Этот нехитрый прием широко используется и в Windows, и в Delphi, так что вам придется потренироваться в его освоении: без него Delphi не вставит заготовку процедуры, и вам понадобится самостоятельно писать не только этот текст, но и производить дополнительные манипуляции с Инспектором объектов и окном кода. ]. В ответ Delphi активизирует окно кода, и вы увидите в нем такой текстовый фрагмент:
procedure TFor.gif" >
/B> Окно определения маски компонента MaskEdit
Рисунок 5.6 . Окно определения маски компонента MaskEdit
В строке Input Mask введите
#99999999;1;
В окошке Character for Blanks вместо умалчиваемого символа-заполнителя “_” укажите пробел и закройте окно кнопкой ок. Сформированная нами маска заставит компонент автоматически контролировать ввод пользователя и отвергать любые символы, кроме знаков + или - в первой позиции (элемент маски “#”) и цифр (элементы “9”).
Теперь все готово к кодированию программы.
Дважды щелкните по кнопке bbResuit и введите такой код для обработчика события OnClick этой кнопки:
procedure TfniExample.bbResultClick( Sender: TObject) ;
// Обработка ввода 2-го операнда
begin // Преобразуем текст из edinput в целое число:
Y := StrToInt(Trim(edinput.Text));
// Сообщаем в Memo о вводе 2-го операнда:
mmOutput.Lines.Add('2-й операнд:'+edInput.Text);
// Вычисляем и показываем результат:
mmOutput.Lines.Add('Результат: '+ IntToStr(X)+' * '+IntToStr(Y)+' = '+IntToStr(X*Y));
edinput.Text := ''; // Очищаем ввод
edinput. SetFocus;
// и возвращаем ему фокус
IbOutput.Caption := 'Введите 1-й операнд; bbResuit.Hide;
// Прячем кнопку
bbResuit bbRun.Show;
// и показываем bbRun
end;
Для ввода обработчика события onciick кнопки bbRun нужно сначала с помощью списка выбора в верхней части окна Инспектора объектов отыскать и выбрать компонент bbRun (напомню, он полностью закрыт кнопкой bbResuit), затем дважды щелкнуть в правом столбце строки onciick на странице Events и ввести такой код:
procedure TfmExample.bbRunClick(Sender: TObject);
// Обработка ввода 1-го операнда
begin
// Преобразуем текст из edinput в целое число
Х := StrToInt(Trim(edinput.Text));
// Сообщаем в Memo о вводе 1-го операнда
mmOutput.Lines.Add('1-й операнд: '+edInput.Text);
edinput.Text := ''; // Очищаем ввод
edInput.SetFocus;// и возвращаем ему фокус
IbOutput.Caption := 'Введите 2-й операнд:';
bbResult.Show; // Показываем кнопку bbResult
bbRun.Hide; // и прячем bbRun
end;
Осталось передать фокус ввода компоненту edinput в момент старта программы и определить переменные х и y для хранения операндов. Разыщите в самом начале окна кода программы описание класса TfmExample и отредактируйте его следующим образом:
private
{ Private declarations } X,Y: Integer;.
Затем с помощью списка выбора в окне Инспектора объектов выберите форму fmExampie и после двойного щелчка на строке опАс-tivate страницы Events введите такой обработчик события:
procedure TfmExample.For.gif" >
/B> Окно просмотра печатного документа
Рисунок 20.1 . Окно просмотра печатного документа/B> Окно редактора с готовым изображением указателя
Рисунок 17.4 . Окно редактора с готовым изображением указателя/B> Окно установки параметров секции Options
Рисунок 21.7 . Окно установки параметров секции Options
if users paste... - определяет текст, который будет добавляться в конце копируемой через Clipboard или печатаемой справочной информации.
Страница Compession
Эта страница управляет сжатием результирующего файла.
None - результирующий файл не сжимается;
Maximum - результирующий файл максимально сжимается;
Custom - выбирает алгоритм сжатия результирующего файла.
Страница Sorting
Задает язык и способ сортировки ключевых слов.
Language of Help file - определяет используемый для сортировки ключевых слов язык;
Other - определяет язык сортировки по его индексу;
Non-spacing marks - если переключатель выбран, при сортировке игнорируются кавычки и апострофы; Symbols - если переключатель выбран, при сортировке игнорируются пробелы и знаки препинания; separate index... - содержит перечень символов, которые используются для указания нижних уровней сортировки.
Страница Files
Определяет расположение используемых в проекте файлов и папок.
Help File - имя результирующего нlр-файла; это имя должно быть указано обязательно;
Log File - имя ASCII-текстового файла, в который компилятор будет помещать свою информацию (может не указываться);
RTF-files - определяет имена исходных файлов с текстами справок; замечу, что изменение имен файлов фактически приводит к изменению секции [Files] (см. ниже п. 21.4.2);
contents file - указывает имя файла содержания, если такой файл создан (см. п. 21.5);
тмр folder - определяет папку для хранения временных файлов компилятора;
substitute path prefix - указывает имя маршрута доступа к rtf и вмр-файлам; используется при перемещении этих файлов в другую папку, чтобы не исправлять множество ссылок во всей справочной информации.
Страница FTS
Управляет созданием индекса для быстрого поиска по отдельным словам или фразам справочного текста. Этот индекс создается при первом обращении к окну поиск.
Generate full text search index - Создавать индекс по всем словам справочных фалов;
Include untitled topics in index - включает в индекс разделы без названия;
Enable search for word only - разрешить поиск только по словам;
Enable search for phrase - разрешить поиск по фразам;
Enable display of matching phrase - разрешить поиск по списку выделенных фраз;
Enable search for similar topics - разрешить поиск по альтернативным словам.
Опции этой страницы имеют значение только для сжатых файлов. Переключатели Enable могут существенно влиять на объем результирующего файла и время поиска информации.
Страница Macros
Определяет макрокоманды, автоматически выполняемые при выборе того или иного ключевого слова.
Keywords - содержит список ключевых слов, для которых определены макрокоманды;
Title that appears... - указывает заголовок окна Найденные разделы при выборе соответствующего слова;
Macro (s) associated with... - связанная со словом макрокоманда;
Add - позволяет добавить слово к списку Keywords;
Remove - удаляет слово из списка Keywords;
Edit - изменяет определение макрокоманды или заголовка для указанного слова.
Страница Build Tags
Содержит список условий, включающих разделы в результирующий файл (верхний список) или исключающих их из него (нижний список). Условия касаются только тех разделов, которые помечены ссылкой “*” (см. п. 21.3.4).
Страница Fonts
Определяет шрифты, используемые в справочной системе.
character set - определяет используемый в результирующем файле набор символов (он может отличаться от набора символов на инструментальной машине);
Font in winHelp Dialog boxes - определяет шрифт, используемый в диалоговых окнах справочной службы;
substitute this fonts.. - содержит перечень подстановок, указывающих, какой шрифт в исходном RTF-файле будет заменен при отображении в окне справки и на какой шрифт он будет заменен.
/B> Окно запуска компилятора
Рисунок 21.9 . Окно запуска компилятора
Для тестирования скомпилированного справочного файла используется одна из опций меню Test:
contents File - тестирует файл содержания;
close All Help - закрывает все ранее открытые нlр-файлы;
send a macro - посылает в winHelp нужную макрокоманду;
WinHelp api - вызывает нужный раздел справочной службы по присвоенному ему в секции map числовому идентификатору.
Тестирование файла содержания заключается в автоматическом вызове всех указанных в содержании разделов. Если какой-либо раздел не вызывается, выдается сообщение (Рисунок 21.10), позволяющее найти и устранить ошибку.
Связь с программой реализуется с помощью свойств HelpContext видимых компонентов, в которые следует поместить числовые идентификаторы нужных разделов справочной службы так, как они определены. В секции MAP. Кроме того, в свойство Application. HelpFile нужно поместить имя нlр-файла. Обычно эта связь устанавливается в обработчике события ОnCreat главной формы программы. После такой настройки пользователь программы сможет с помощью клавиши F1 получить контекстно-чувствительную справку, т. к. при нажатии F1 автоматически вызывается раздел, числовой идентификатор которого помещен в свойство HeipContext компонента с фокусом ввода. Если Heipcontext компонента с фокусом ввода содержит 0, вызывается раздел, указанный в HelpContext его владельца, а если и у того это свойство не определено, используется HelpContext активной формы (если во всей цепочке владельцев, включая активную форму, свойство HelpContext не определено, нажатие F1 игнорируется).
/B> Списки свойств упорядоченные по категориям
Рисунок 2.6 . Списки свойств упорядоченные по категориям
Любые категории можно сделать невидимыми. Для этого нужно в локальном меню выбрать view и затем в дополнительном меню убрать флажок слева от категории.
В отличие от предыдущих версий Delphi в версии 6 сложные свойства, ссылающиеся на объекты, выделяются в окне Инспектора объектов цветом и показываются на странице Events. Если такое свойство определено, слева от него появляется кнопка “+”, позволяющая увидеть (и при необходимости изменить) свойства и обработчики событий связанного объекта. Для примера на Рисунок 2.7 показано, как с помощью окна Инспектора объектов, связанного с формой For.gif" >
Рисунок 2.7. Установка обработчика OnClick опции меню для формы For.gif" >
/B> Стили л иний
Рисунок 16.2 . Стили л иний
/B> Вставка ссылки на модуль
Рисунок 19.2 . Вставка ссылки на модульПри вызове метода show второе окно появляется на экране и работает одновременно с первым, поэтому управление сразу передается оператору, стоящему за обращением к этому методу. Такие окна называются немодальными, они всегда открываются в одном методе, а закрываются в другом. В отличие от этого обращение к show-Modal создает модальное окно, которое полностью берет на себя дальнейшее управление программой, поэтому оператор за обращением к showModal в вызывающей части программы получит управление только после закрытия модального окна.
Модальные окна всегда требуют от пользователя принятия какого-либо решения. С их помощью реализуется диалог с пользователем или создается информационное окно, которое пользователь должен закрыть после ознакомления с содержащейся в нем информацией. Если от пользователя требуется принятие решения, в модальное окно вставляются зависимые или независимые переключатели, кнопки и другие интерфейсные элементы, с помощью которых пользователь сможет сообщить программе о принятом решении. В момент закрытия диалога модальное окно должно поместить число, соответствующее решению пользователя, в свое свойство ModalResuit. Некоторые стандартные кнопки (ok, Yes, No, cancel и т. п.) автоматически выполняют эти действия: помещают нужное число в ModalResuit и закрывают окно. В других случаях об этом должен позаботиться программист. Вызывающая программа получает значение ModaiResuit как значение функции showModal и может тут же его проанализировать:
if For.gif" >
Демонстрация комплексных вариантов
Рисунок 10.1. Демонстрация комплексных вариантов
Создание пользовательского варианта проходит в три этапа.
Демонстрация компонента TAnimate
Рисунок 18.24. Демонстрация компонента TAnimate
Демонстрация компонента TValueListEditor
Рисунок 18.17. Демонстрация компонента TValueListEditor| property DropDownRows: Integer; | Указывает максимальное количество строк в списке возможных значении, показ которых не сопровождается появлением полосы прокрутки |
| property ItemProps[const KeyOrIndex: Variant]: TItemProp; | Сложное свойство, управляющее различными аспектами отображения значений (см. пояснения ниже) |
| type TKeyOption = (keyEdit, keyAdd, keyDelete, keyUnique) ;
TKeyOptions = set of TDisplayOption; property KeyOptions: TKeyOptions; |
Управляет возможным изменением списка: keyEdit - пользователь может изменять имя параметра (в первом столбце); keyAdd - пользователь может добавлять новую пару имя-значение нажатием клавиши Insert (требует включения keyEdit); keyDelete -пользователь может уничтожить выделен ную пару нажатием клавиши Delete; keyUnique - названия вводимых пользователем имен должны быть уникальными |
| property Keys[Index: Integer]:String; | Открывает доступ к названиям значений по их индексам |
| property RowCount: Integer; | Содержит количество строк |
| property Strings: TStrings; | Содержит строки списка |
| property TitleCaptions: TStrings; | Содержит заголовки столбцов |
| property Values[const Key:String]: String; | Открывает доступ к значениям по их индексам |
| property EditMask: String; | Содержит маску для формирования значения. Правила создания маски описаны в п. 18.2.3 |
| type TEditStyle = (esSimple,
esEllipsis, esPickList); property EditStyle: TEditStyle; |
Определяет правила редактирования значения: esSimple - значение редактируется в обычном однострочном редакторе; esEllipsis - в строку значения вставляется кнопка для вызова диалогового окна редактора значения (возбуждается событие OEditButtonclick); esPickList - в строку значения вставляется кнопка для раскрытия списка возможных значений (возбуждается событие OnGetPickList) |
| property MaxLength: Integer; | Определяет максимальную длину (в символах) значения. Если 0, нет ограничений на длину |
| property PickList: TStrings; | Содержит выпадающий список возможных значений |
| property Readonly: Boolean; | Разрешает/запрещает редактирование значения |
procedure TFor.gif" >
Диалоговое окно выбора формы
Рисунок 19.4. Диалоговое окно выбора формы
Форма для учебной программы
Рисунок 5.1. Форма для учебной программы
Фрагмент дерева классов Object Pascal
Рисунок 9.1. Фрагмент дерева классов Object Pascal
Главное окно с нестандартным расположением своих элементов
Рисунок 2.4. Главное окно с нестандартным расположением своих элементов
это последовательность произвольных операторов программы,
| 5.4.1. Составной оператор и пустой оператор Составной оператор - это последовательность произвольных операторов программы, заключенная в операторные скобки - зарезервированные слова begin ... end . Составные операторы - важный инструмент Object Pascal, дающий возможность писать программы по современной технологии структурного программирования (без операторов перехода goto). Object Pascal не накладывает никаких ограничений на характер операторов, входящих в составной оператор. Среди них могут быть и другие составные операторы - язык Object Pascal допускает произвольную глубину их вложенности: Функция Trim не определена в версии 1. Вместо указанной единственной строки в этом случае следует написать :[ while post' ', edinput.Text)>0 do system.delete(edinput.Text, post' ', edinput.Text), 1); StrToint(edinput.Text);] begin begin begin end; end; end; Фактически весь раздел операторов, обрамленный словами begin ... end, представляет собой один составной оператор. Поскольку зарезервированное слово end является закрывающей операторной скобкой, оно одновременно указывает и конец предыдущего оператора, поэтому ставить перед ним символ “;” необязательно. Наличие точки с запятой перед end в предыдущих примерах означало, что между последним оператором и операторной скобкой end располагается пустой оператор. Пустой оператор не содержит никаких действий, просто в программу добавляется лишняя точка с запятой. В основном пустой оператор используется для передачи управления в конец составного оператора: как и любой другой, пустой оператор может быть помечен, и ему можно передать управление. |
стереть символ справа от курсора
| П1.2.2. Команды удаления/вставки |
| INS | включить/отключить режим вставки | Delete | стереть символ справа от курсора |
| Enter | вставить строку | Ctrl+T | стереть слово справа от курсора |
| Qrl+Y | удалить строку | Ctrl+Q+Y | стереть остаток строки справа от курсора |
| Back.gif" > |
Представляет собой удобную комбинацию однострочного
| 18.2.16. TLabelEdit - однострочный редактор с меткой Представляет собой удобную комбинацию однострочного редактора с меткой. Надпись в метке определяет свойство EditLabei. Свойство type TLabelPosition = (IpAbove, ipBelow, IpLeft, IpRight); property LabelPosition: TLabelPosition; определяет положение метки относительно редактора, а property LabelSpacing: Integer; расстояние от метки до редактора (в пикселях). Впервые введен в версии 6. |
с версии 5, главное окно
| 2.1.2. Настройка окон Начиная с версии 5, главное окно обогатилось тремя новыми интерфейсными элементами, указанными в группе Desktops предыдущей таблицы. С помощью этих инструментов программист может подготовить несколько вариантов расположения остальных окон Delphi и сохранить их в настроечном файле. Обычно выбираются две или три основные конфигурации окон: для режима разработки форм, для кодирования и для отладки. При разработке формы на экране должна быть видна сама форма, Дерево объектов и Инспектор объектов. Настроив соответствующие размеры и положение этих окон, такую настройку можно сохранить под именем, например, Design Desk. Для режима кодирования обычно нужно только максимально распахнутое на экран окно кода с браузером Code Explorer и пристыкованное к нему окно Дерева объектов. Такую конфигурацию можно сохранить под именем code-Desk. Наконец, в отладочном режиме к окну кода желательно “прицепить” некоторые отладочные окна, такие как Watches (окно наблюдений за переменными/выражениями) и Breakpoints (окно создания/настройки точек контрольного останова). Такую конфигурацию можно сохранить под именем DebugDesk, например. Теперь при переходе к тому или иному режиму достаточно раскрыть список и выбрать из него нужную настройку. Если вы предварительно укажете с помощью кнопки настройку для отладочного режима, эта стройка появится автоматически, как только среда перейдет в режим отладки. |
Использование графических врезок
Рисунок 21.5. Использование графических врезок
Кнопки компонента TMediaPlayer
Рисунок 18.36 . Кнопки компонента TMediaPlayer
Если ваш компьютер оснащен звуковой картой, вставьте этот компонент в пустую форму, в его свойство FileName поместите название любого файла с расширением WAV (из каталога с: | winsows | media), установите в свойство Autoopen компонента значение True и запустите программу - после щелчка мышью по кнопке
вы услышите звучание выбранного музыкального фрагмента. Как видите, использование компонента предельно просто. Он автоматически распознает тип мультимедийного устройства по расширению файла и берет на себя управление этим устройством. Разумеется, в каждый момент времени компонент может управлять лишь одним устройством, однако с помощью изменения содержимого FileName или явно с помощью свойства DeviceType программа может менять устройство, связанное с компонентом.Каждая кнопка компонента имеет собственное имя, позволяющее программисту сделать какую-либо кнопку невидимой или недоступной. В следующей таблице приводится имя и назначение каждой кнопки (под носителем информации подразумеваются файлы и физические устройства, которые могут служить источником или приемником информации).
btStop |
Останавливает запись или воспроизведение |
btNext |
Позиционирует устройство на следующую дорожку или в конец носителя информации, если устройство не имеет дорожек |
btPrev |
Позиционирует устройство на предыдущую дорожку или в начало носителя информации, если устройство не имеет до |
btStep |
рожек Позиционирует устройство на один блок кадров ближе к концу носителя информации. Количество кадров в блоке |
btBack.gif" >
|
Компонент Tfmage воспроизводит изображение
Рисунок 18.12. Компонент Tfmage воспроизводит изображение
Метка IbOutput показывает имя перетаскиваемого компонента
Рисунок 17.5. Метка IbOutput показывает имя перетаскиваемого компонента
Для ручного (программного) управления механизмом Drag&Drop используются следующие методы, доступные любому потомку TControl:
| procedure BeginDrag (Immediate: Boolean); | Используется источником для инициализации процесса Drag&Drop. Если Immediate =True, процесс начинается немедленно, в противном случае - после смещения указателя мыши на 5 пикселей в любом направлении |
| procedure DragDrop (Source: TObject; X, Y: Integer); | Вызывает обработчик события OnDragDrop |
| procedure EndDrag(Drop: Boolean); | Вызывает обработчик события OnEndDrag и в параметре Drop сообщает о том, были ли приняты данные |
Наиболее важные окна Delphi
Рисунок 2.1. Наиболее важные окна Delphi:
Настройка инструментальных панелек
Рисунок 2.3. Настройка инструментальных панелек: а) вспомогательное меню; б) окно настройки с выбранной закладкой Command
Для примера на Рисунок 2.4 показано главное окно с нестандартным расположением панелек и набором отображаемых в них кнопок.
При его создании мне хотелось, с одной стороны, получить больше места для размещения страниц галереи компонентов, а с другой поместить в главное окно пиктограммы часто используемых мною команд меню: Project | Syntax check (проверка синтаксиса кода программы), View | Debug Windows | Watches) доступ к окну наблюдения отладочного режима) и View | Debug windows | Breakpoints (доступ к окну точек останова).
Окно демонстрационной программы
Рисунок 18.23. Окно демонстрационной программы DEMOS | RICHEDIT | RICHED1T.EXE
На Рисунок 18.23 показан пример использования возможностей компонента. Полный текст программы, с помощью которой создан рисунок, приводится в папке demos | RICHEDIT | RICHEDIT.DPR, котораянаходится в каталоге размещения Delphi.
Компонент использует вспомогательные объекты класса TTextAt-tributes для хранения атрибутов шрифта. Эти атрибуты распространяются на весь текст через свойство редактора DefAttributes или на выделенную часть текста - через его свойство SeiAttributes.
Помимо обычных шрифтовых свойств CharSet, Color, Height, Name, Pitch, Size И Style (см. класс TFont) объект TTextAttributes содержит также свойства consistentAttributes и protected. Первое доступно только для чтения и содержит набор текстовых характеристик, общих как для всего текста, так и для его выделенной части. Свойство protected защищает весь текст или его части от редактирования. Попытка изменить текст, имеющий атрибут protected, вызывает обработчик события OnProtectChange, который может разрешить или запретить изменения. По умолчанию изменения запрещены.
Для каждого текстового абзаца создается объект класса трага-Attributes, в котором сохраняются атрибуты абзаца. Эти атрибуты доступны через следующие свойства класса TparaAttributes:
| property Alignment: TAlignment; | Определяет горизонтальное выравнивание текста абзаца относительно границ компонента |
| property Firstlndent: Longint; | Указывает отступ текста абзаца в пикселях от предыдущего абзаца |
| property Leftlndent: Longint; | Указывает отступ текста абзаца в пикселях от левого края компонента |
| TNumberingStyle =
(nsNone, nsBullet) ; property Numbering: TNum beringStyle; |
Указывает, надо ли вставлять слева от абзаца символы списка. Если содержит nsBullet, символы списка вставляются |
| property Rightlndent:
Longint; |
Указывает отступ текста абзаца в пикселях от правого края компонента |
| property Tab[Index: Byte] : Longing; | Для табулостопа с индексом index содержит его позицию в пикселях от левого края компонента |
| property TabCount: Irteger; | Определяет количество табулостопов в строке абзаца |
| property DefAttributes:
TTextAttributes; |
Определяет шрифтовые атрибуты всего текста |
| TConversionClass = class of TConversion;
property DefaultConverter: TConversionClass; |
Свойство указывает класс конвертора, использующегося для преобразования текстовых форматов причтении или записи текста. По умолчанию нет преобразования |
| property HideScroliBars:
Boolean; |
Определяет, будет ли редактор автоматически вставлять полосы прокрутки, если текст отсекается границами компонента. Игнорируется, если scrollBars содержит ssNone |
| property HideSelection:
Boolean; |
Указывает, будет ли убираться выделение текста, если компонент потеряет фокус ввода |
| property Lines: TStrings; | Содержит набор строк текста. С помощью его методов LoadFromFile и SaveToFile компонент может читать текст из файла или записывать в него текст |
| property PageRect: TRect; | Указывает размеры страницы при печати на принтере |
| property Paragraph:
TParaAttributes; |
Содержит атрибуты текущего абзаца, т. е. абзаца с выделением или с текстовым курсором. Программа не может изменить свойство paragraph, но может изменить свойства связанного с ним абзаца |
| property PlainText: Boolean; | Запрещает/разрешает записывать в файл или читать из него служебную информацию формата RTF (True -запрещает) |
| property SelAttributes:
TTextAttributes; |
Определяет шрифтовые атрибуты выделенного текста |
| property SelLength: Integer; | Задает длину в символах выделенной части текста |
| property SelStart: Integer; | Определяет номер первого символа выделенной части текста от начала текста (нумерация символов начинается с 0). Если нет выделения, указывает символ, перед которым располагается текстовый курсор |
| property SelText: String; | Содержит выделенный текст. Установка нового значения SelText заменяет выделенный текст на новый, а если нет выделения - вставляет его в позицию курсора |
| procedure Clear;
TSearchType = (stWholeWord, stMatchCase) ; TSearchTypes = set of TSear chType ; function FindText(const SearchStr: String; StartPos, Length: Integer; Options: TSear chTypes) :Integer; |
Удаляет весь текст
Ищет в тексте строку SearchStr и возвращает индекс первого ее символа при удачном поиске: StartPos - начало поиска: Length-длина строки, options указывает, будет ли поиск идти по целым словам и надо ли учитывать высоту букв |
| function GetSelTextBuf(Buffer:
PChar; BufSize: Integer): Integer; |
Копирует не более BufSize символов выделенного текста в буфер Buffer и возвращает количество скопированных символов |
| procedure Print(const Caption:
String) ; |
Форматирует текст по границам листа бумаги и печатает его на умалчиваемом принтере, caption определяет заголовок печати |
| TConversionClass = class of TConversion; class procedure RegisterConver-
sionFor.gif" > |
Окно демонстрационнойпрограммы
Рисунок 11.1. Окно демонстрационнойпрограммы
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, For.gif" >
Окно кода с расположенным слева браузером Code Explorer
Рисунок 2.8. Окно кода с расположенным слева браузером Code ExplorerДвойной щелчок мышью на элементе в окне браузера приводит к позиционированию текстового указателя в окне кода на описание соответствующего объекта или его первое упоминание. При разработке несложных учебных программ можно закрыть окно браузера маленькой кнопкой
Окно компонента TDirectoryOutLine
Рисунок 18.46. Окно компонента TDirectoryOutLine
Компонент является наследником класса TCustomOutLine, и поэтому многие его свойства (itemHeight, Optins, PictureXXX, ShowBars и Style) совпадают с аналогичными свойствами другого наследника этого класса - компонента TOutLine. Свойство TTextCase = (tcLowerCase, tcUpperCase, tcAsIs) ;
property TextCase: TTextCase;
определяет высоту букв в именах каталогов: tcLowerCase - строчные буквы; tcUpperCase - заглавные буквы; tcAsis - строчные и заглавные буквы.
Следующие два свойства доступны только на этапе прогона программы:
property Drive: Char;
property Directory: TFileName;
Первое определяет выбранный диск, второе - выбранный каталог.
Окно конструктора меню
Рисунок 18.3. Окно конструктора менюСоздание опций не вызывает проблем. Перейдите в окно Инспектора объектов и введите текст опции в строке caption, после чего нажмите Enter - опция готова, и можно переходить к следующей. Каждая опция главного меню может раскрываться в список подопций или содержать конечную команду. Для создания подопций щелкните мышью по строке ниже опции и введите первую подопцию. Продолжайте ввод, пока не будет создан весь список подопций, после чего щелкните по пустому прямоугольнику справа от первой опции и введите вторую опцию. Процесс гораздо сложнее описать, чем выполнить.
В названиях опций можно указать символ “&” перед тем символом, который определит клавишу быстрого выбора опции (в терминологии Windows такие клавиши называются акселераторами). Например, на Рисунок 18.3 показана опция Файл, которую можно выбрать сочетанием клавиш Alt+Ф. При создании меню эта опция в строке caption Инспектора объектов содержала текст &Файл.
Если вы захотите вставить разделительную черту, отделяющую группы подопций, назовите очередной элемент меню именем “-”. Так, например, создана черта, отделяющая опции сохранить как и выход в примере меню на Рисунок 18.3: свойство caption, пятого по счету элемента списка опций Файл, содержит единственный символ “-”.
Для создания разветвленных меню, т. е. таких, у которых подопций вызывают новые списки подопций, щелкните по подопций и нажмите Ctrl+вправо, где вправо - клавиша смещения курсора вправо. Такого же эффекта можно добиться после щелчка правой кнопкой мыши на подопций и выборе продолжения create Submenu. На Рисунок 18.4 показан пример разветвленной структуры меню.
Свойства компонента:
| property AutoMerge: Boolean; | Разрешает/запрещает слияние главного меню вторичной формы с главным меню основной формы в не MDI-приложениях |
| type TMenu.gif" > |
Окно Поиск со списком названий
Рисунок 21.3. Окно Поиск со списком названий найденных разделов (“З. Выберите нужный раздел ...”)
Название раздела задается с помощью сноски “$”, которая должна предшествовать первому символу текста раздела. На Рисунок 21.4 показан пример окна Word с названием Режим|0тладка для раздела Отладочный режим. Название раздела записывается в тексте сноски и отделяется от символа “$” одним пробелом. В тексте названия можно указывать любые символы, в том числе и пробелы. Максимальная длина названия - 255 символов. Обычно название раздела совпадает с его заголовком.
Окно прогона программы сравнения
h2> Окно прогона программы сравнения сортировки строк для Windows 32 и Windows З.х
Как видим, строки в 32-разрядных Windows сортируются не с учетом внутреннего кода символа, а с учетом “смысла”: в начале располагаются все знаки препинания и разного рода “мусор”, затем идут цифры, буквы латинского алфавита и символы кириллицы. Буквы упорядочены парами - сначала заглавная, за ней строчная - и не идут сплошным массивом. “Виновником” такой сортировки является API-функция AnsiCompareText, К который обращается метод TStringList. Quicksort. Если вам понадобится отсортировать так, как это принято в MS-DOS или Windows З.х, т. е. по коду символа, проделайте следующее.
begin
if S1 < S2 then Result := -1
else if SI == S2 then Result := 0
else Result := 1
end;
3. С помощью опции Project | Add To Project добавьте измененный модуль classes к вашему проекту и сделайте новый прогон программы. Теперь оба столбца будут идентичны.
Окно програлшы для определения цветовых констант
Рисунок 17.1. Окно програлшы для определения цветовых константОкно программы CopyTxt
Рисунок 5.4. Окно программы CopyTxt
Комментарий к программе
Вводимый текст хранится в свойстве Text компонента edInput. После выполнения первого оператора присваивания он будет перенесен в свойство caption компонента IbOutput и тут же появится на экране над строкой ввода.
Многострочньш редактор mmOutput способен сохранять и отображать на экране множество строк. Все они содержатся в его свойстве Lines, относящемуся к классу TStringList (подробнее об этом классе см. п. 12.1). Метод Add класса TStringList добавляет новую строку к имеющемуся в Lines набору строк. Добавленная с помощью второго оператора строка тут же отображается на экране. С помощью оператора
edInput.Text := ' ' ;
строка ввода очищается и подготавливается к вводу нового текста. Двойной апостроф в правой части оператора указывает “пустую” строку или, что то же, строку нулевой длины. Завершает обработчик оператор
edinput.SetFocus ;
с помощью которого строка edinput получает фокус ввода. Термином “фокус ввода” в Delphi фактически обозначается клавиатура”* “Получить фокус ввода” означает связать указанный компонент с клавиатурой. В окне программы может быть несколько компонентов, способных принимать и обрабатывать клавиатурный ввод (в нашей программе таких компонентов четыре: редактор mmoutput, строка edinput и кнопки bbRun и bbciose). Каждый из таких компонентов имеет метод SetFocus, с помощью которого программа может передать компоненту контроль над клавиатурой. Чтобы оценить действия, реализуемые оператором edinput. SetFocus, поставьте в самом начале оператора признак комментария (символы “//”), сделайте новый прогон программы и введите с ее помощью хотя бы 2-3 строки.
Замечу, что в момент появления окна программы на экране строка edinput не имеет фокуса ввода, что затрудняет ввод первой строки. Попробуйте самостоятельно создать обработчик события опАс-tivate для формы fmExampie и в нем установить фокус ввода для строки edinput. (Подсказка: раскройте список выбора в верхней части окна Инспектора объектов, выберите в нем компонент fmExampie и дважды щелкните по правой колонке свойства OnActivate на странице Events этого окна.)
Окно программы IntMult
Рисунок 5.5. Окно программы IntMult
Прежде всего обсудим две проблемы, связанные с реализацией программы:
2*3
и после анализа строки выводит результат. Однако логика анализа существенно перегрузит программу и потребует использования в ней средств, с которыми мы пока не знакомы. Значительно проще вставить в форму еще одну кнопку. Тогда щелчок по первой кнопке будет сигналом о том, что в строке ввода подготовлен первый операнд, а щелчок по второй - что готов второй операнд и можно вычислять результат. В этом варианте следует предусмотреть случай, когда щелчок по второй кнопке будет предшествовать щелчку по первой и программа будет вычислять выражение с неопределенным первым операндом. Решение этой дополнительной проблемы состоит в том, чтобы сделать вторую кнопку недоступной или даже невидимой до тех пор, пока не будет введен первый операнд.
Подводя итог, я предлагаю поместить на форму fmExample новую кнопку BitBtn (страница Additional галереи компонентов) так, чтобы она полностью закрыла собой имеющуюся кнопку bbRun, назвать новую кнопку bbResuit (свойство Name), установить для нее сорт (свойство Kind) bkOK и сделать ее временно невидимой (поместить в свойство visible значение False). После такой подготовки в момент начала работы новая кнопка не будет видна и не помешает пользователю щелкнуть по кнопке bbRun. В обработчике события bbRun-click следует спрятать кнопку bbRun и показать кнопку bbResuit, чтобы пользователь смог подтвердить ввод второго операнда. Сделайте необходимые изменения формы для нового проекта, а я пока перейду к обсуждению второй проблемы.
Суть второй проблемы заключается в том, что пользователь может случайно или преднамеренно ввести строку, которая не содержит правильного представления целого числа. Преобразование такой строки к целому числу может привести к аварийному завершению работы программы. Существует множество способов решения этой проблемы, я предлагаю наиболее простой: заменить обычный однострочный редактор edinput на специализированный, способный контролировать ввод пользователя. Удалите из формы редактор edinput (щелкните по нему мышкой и нажмите клавишу Delete) и поместите на его место компонент MaskEdit (страница Additional). Дайте ему прежнее имя edinput (свойство Name) и раскройте диалоговое окно свойства EditMask (Рисунок 5.6). Это свойство указывает маску компонента, т. е. определяет, какие символы и в какой последовательности может набирать пользователь в окне ввода.
Окно редактора архива
Рисунок 5.3. Окно редактора архиваВ списке pages этого окна щелкните по строке For.gif" >
Окно редактора ImageList
Рисунок 18.16 . Окно редактора ImageList
| property AutoDrag: Boolean; | Разрешает/запрещает компонентам ToolBar покидать границы controlBar |
| property Picture: TPicture; | Содержит изображение, которое, периодически повторяясь, создает фон компонента |
| property RowSize: TRowSize; | Задает высоту одного ряда инструментальных панелей. Умалчиваемое значение 25 в точности соответствует высоте одной панели и в этом случае между рядами нет зазора |
| property RowSnap: Boolean; | Если содержит True, “причаливаемая” панель будет выравниваться по высоте ряда |
procedure StickControls; virtual;
устанавливает все дочерние компоненты на их окончательные позиции после “причаливания” или “отчаливания” очередной инструментальной панели. Его нужно перекрыть, если стандартное размещение панелей по каким-либо причинам вас не устраивает;
События компонента:
| TBandInfoEvent = procedure(Sender: TObject; Control: TControl; var Insets: TRect; var PreferredSize, RowCount: Integer) of object-property OnBandInfo: TBandInfoEvent; | Возникает при перемещении панели внутри компонента: Sender - компонент; control - панель; insets - зазор между сторонами компонента и панели; Рге-ferredsize - предпочтительная ширина панели; RowCount - количество рядов панелей |
| TBandMoveEvent = procedure (Sender: TObject; Control: TControl; ARect: TRect) of object/property OnBandMove: TBandMoveEvent; | Возникает при перемещении панели " внутри компонента: Sender - компонент; Control - панель; ARect - прямоугольник для размещения панели |
| TBandPaintEvent = procedure (Sender: TObject; Control: TCon-tro,l; Canvas: TCanvas; var ARect: TRect; var Options: TBandPaintOp-tions) of object;
property OnPaint: TNotifyEvent; |
Возникает при необходимости прорисовки панели: sender - компонент; Control - панель; Canvas - канва для прорисовки; ARect - прямоугольник прорисовки; Options - определяет, какая часть панели нуждается в прорисовке Возникает при необходимости прорисовки компонента |
Окно редактора изображений с заготовкой для указателя мыши
Рисунок 17.3. Окно редактора изображений с заготовкой для указателя мыши
Окно редактора палитры компонентов
Рисунок 2.5. Окно редактора палитры компонентов
Окно со списком стандартных действий
Рисунок 18.21. Окно со списком стандартных действийЕсли вы запустите программу, то увидите пустое окно с меню File и инструментальной кнопкой Exit, причем опции меню (кроме недоступной опции Run) и инструментальная кнопка выполняют ожидаемые от них действия. Щелчок по инструментальной панели активизирует уже знакомое нам (Рисунок 18.20) окно редактора Atcion-Manageri, и вы можете изменять состав меню и инструментальной панели.
Свойства компонента:
| property ActionBars: TAction
Bars; |
Содержит коллекцию всех инструменталь ных полос, определенных в приложении. Коллекция автоматически пополняется, когда на очередную полосу впервые кладется элемент меню (категория) или кнопка (действие) |
| property ActionCount: Integer; | Содержит общее количество определенных в программе действий |
| property Actions[Index: Integer]:
TContainedAction; |
Открывает индексированный доступ к конкретному действию |
| property FileName: TFileName; | Имя файла, в котором компонент сохраняет текущую конфигурацию действий |
| property LinkedActionLists: TActionListCollection; | Содержит коллекцию всех связанных с компонентом действий |
| property Images: TCustomImageList; | Ссылка на связанное с компонентом хранилище изображений |
| property PrioritySchedule:
TStringList; |
Содержит для каждого действия номера сессий (запусков программы), когда связанная с действием кнопка или опция меню меняла свою видимость. Если какой-то элемент интерфейса должен постоянно присутствовать на экране, его строка PrioritySchedule должна хранить (-1) |
| type TActionListState = (asNormal, asSuspended, asSuspendedEnabled) ; | Включает или отключает действия: asNormal - все действия включены; asSuspended - все действия выключены, их свойства |
| property State: TActionListState; | Enabled не изменяются; asSuspendedE nabled - все действия выключены, их свойства Enabled получают значения True |
Методы компонента:
| procedure LoadFromFile(const FileName: String); | Читает файл, указанный в параметре File-Name и загружает информацию, необходимую для восстановления полос действий |
| procedure LoadFromStream(Stream: TStream); | Загружает информацию, необходимую для восстановления полос действий, из потока Stream Восстанавливает вид полосы таким, как сохраняет ее свойство DefaultActionBar Уничтожает файл, указанный в свойстве FileName |
| procedure ResetActionBar(Index: Integer) ; procedure ResetUseageData; | Сохраняет текущие настройки интерфейса в файле FileName |
| procedure SaveToFile(const FileName: String) ; procedure SaveToStream(Stream: TStream); | Сохраняет текущие настройки интерфейса в потоке Stream |
| function ExecuteAction(Action: TBasicAction): Boolean; override; | Создает событие OnExecute для выполнения действия Action |
Окно связи с Inprise (Borland)
Рисунок 2.2. Окно связи с Inprise (Borland)
С помощью этого окна вы сможете получить доступ к Web-страницам корпорации Inprise для просмотра самой свежей информации о корпорации и ее программных продуктах, копирования дополни тельных файлов, чтения ответов на наиболее часто задаваемые вопросы и т. д. При повторных запусках Delphi это окно появляется автоматически с некоторой периодичностью, определяемой настройками на странице окна Tolls | Environment Options, связанной с закладкой Delphi Direct. Вы также сможете его вызвать в любой момент с помощью опции Help | Delphi Direct главного меню.
Окно утилиты Microsoft Help Workshop
Рисунок 21.6. Окно утилиты Microsoft Help Workshop
Страница General
Default topic - идентификатор умалчиваемого раздела;
Help title - заголовок основного окна справочной службы; замечу, что мне не удалось получить заметных результатов, связанных с изменением этой строки, так что для изменения заголовка основного окна пришлось использовать дополнительное окно main (см. ниже п. 21.4.3); заголовок можно также изменить при создании файла содержания (см. п. 21.5);
Notes - если переключатель выбран, компилятор сообщает о возникающих проблемах, если не выбран - только общее количество предупреждений и ошибок;
Progress - если переключатель выбран, компилятор сообщает о транслируемом -RTF-файле;
Errors - открывает окно для указания кодов ошибок, о которых компилятор не будет сообщать;
Display this text... - определяет текст, который будет помещен
В окно Справка | Версия справочной службы;
ОТ АВТОРА
ОТ АВТОРАЭтот диск предназначен для тех, кто самостоятельно или под руководством опытного преподавателя пытается научиться программировать, т.е. создавать программы, работающие под управлением современных 32-разрядных графических операционных систем (ОС) Windows 95/98/NT/2000 (в дальнейшем - Windows 32).
Эволюция технических средств персональных компьютеров привела к повсеместному вытеснению старой “доброй” ОС MS-DOS значительно более мощными системами Windows, программирование для которых существенно сложнее, чем программирование для MS-DOS. Разработчики систем программирования, и прежде всего такие корпорации, как Microsoft и Borland, не замедлили выпустить соответствующие средства: уже в 1991 году, т. е. сразу после появления Windows 3.1, Borland выпускает Turbo Pascal for Windows, а в 1992 - усовершенствованную версию этой системы программирования - Borland Pascal with Objects 7.0. Эти первые специализированные инструменты требовали основательного знания Windows и были сложны в освоении. Но вот в 1993 году Microsoft выпустила первую визуальную среду программирования Visual Basic, и программирование для Windows стало даже проще, чем программирование для MS-DOS. В ответ на это Borland в 1995 году выпустила первую версию Delphi, а затем, с интервалом в 1 год, - еще 4 версии: 2, 3, 4 и 5. Наконец, в середине 2001 г. выпускается версия б, которая и положена в основу этой книги. Замечу, что материал книги можно с некоторыми (часто несущественными) ограничениями использовать и для изучения более ранних версий.
Не секрет, что лучшим языком для изучения и освоения программирования является Паскаль, а лучшей в мире системой программирования для MS-DOS - Turbo Pascal. Delphi продолжила серию Паскаль-ориентированных средств программирования и, по моему глубокому убеждению, является наиболее удобным инструментом для Windows-программирования.
Этот диск во многом использует материал книги [27], который был дополнен и изменен с учетом изменений в версиях Delphi 6 и 5. В ней рассматривается менее трети возможностей этой мощной современной системы программирования, и это не случайно. Дело в том, что версии Delphi развивались по принципу наращивания своих возможностей. Если с 1-й по 4-ю версии Delphi могла работать с базами данных только с помощью механизма BDE, то в версии б таких механизмов уже 4 - BDE, ADO, IBExpress, dbExpress. Если 8 компонентов страницы internet версии 2 давали лишь возможность использовать некоторые технологии Интернет в локальных сетях, то более 100 компонентов версии 6 обеспечивают полноценную возможность Web-программирования, т. е. создания работающих под управлением Web-сервера программ, обеспечивающих интерактивное взаимодействие с клиентом и публикацию по его требованию необходимых данных. Как бы там ни было, перед вами всего лишь “Учебный курс”, т. е. Диск, в котором описываются лишь самые общие приемы программирования с помощью Delphi. Она, как уже говорилось, рассчитана, в основном, на начинающих программистов, во всяком случае ее освоение не требует специальных знаний ни в области программирования, ни в области Windows, хотя умение работать с Windows на уровне пользователя - обязательное условие (если, разумеется, вы захотите создать хотя бы одну из описываемых в книге программ).
Руководство на диске делится на 3 части.
В первой дается неформальное знакомство со средой Delphi и основными конструкциям лежащего в ее основе языка программирования Object Pascal. Изложенный в ней материал, как мне кажется, позволит вам в дальнейшем “видеть” систему целиком, не погрязая в неизбежных деталях, которым и посвящены остальные главы книги.
Вторая часть посвящена современному языку программирования Object Pascal, без детального знания которого эффективная работа с Delphi невозможна. Фактически все основные синтаксические конструкции и операторы этого языка описываются в довольно большой по объему и насыщенной короткими учебными примерами 5-й главе, а все остальные главы этой части посвящены типам данных. Особое значение имеет глава 9, в которой описывается основополагающий инструмент Object Pascal - классы и объекты. Практически все современные языки программирования (в том числе C++ и Visual Basic) поддерживают методику объектно-ориентированного программирования (ООП), позволяющую резко сократить сроки разработки программ и существенно повысить их качество. В гл. 9 описываются включенные в Object Pascal средства ООП, а в гл. 16 - классы самого общего назначения.
В третьей части книги рассматриваются компоненты, формы и программа в целом. Сразу оговорюсь, что рассматриваются далеко не все компоненты, но только общего употребления: за рамками книги остались компоненты для работы с базами данных, с Internet и ряд специальных компонентов.
Главы 17 и 18 посвящены стандартным компонентам - основным строительным элементам любой Delphi-программы. Являющиеся частным случаем классов, компоненты играют огромную роль в практике Delphi-программирования.
В заключительных главах книги рассмотрены так называемые глобальные объекты. Эти объекты автоматически создаются в момент старта программы и уничтожаются вместе с ней. К глобальным относится собственно объект-программа, а также экран, принтер, буфер межпрограммного обмена. Здесь же описывается методика создания справочной службы программы и проблемы ее распространения и настройки.
П 1 1 4 Опция View
П 1.1.4. Опция View| Project Manager | Показывает окно Менеджера проекта |
| Translation Manager | Открывает доступ к Менеджеру трансляций Показывает окно Инспектора объектов |
| Object Inspector | Показывает окно |
| Object TreeView | Дерева объектов |
| To_Do List | Открывает доступ к списку To-Do |
| Alignment Palette | Показывает окно палитры выравнивания компонентов |
| Browser | Показывает окно браузера объектов |
| Code Explorer | Показывает спрятанное ранее окно Навигатора кода |
| Component List | Показывает окно для выбора компонентов |
| Window List | Показывает окно открытых окон проекта |
| Debug Windows | Отладочные окна. Эта опция-заголовок открывает доступ к подменю со следующими опциями |
| Breakpoints | Показывает окно точек останова |
| Call Stack | Показывает окно стека |
| Watching expressions | Показывает окно наблюдения за переменными/выражениями |
| Local Variables | Позволяет наблюдать за изменениями локальных переменных в отладочном режиме |
| Threads | Показывает окно статуса потоков команд |
| Modules | Показывает окно модулей проекта |
| Event Log | Показывает журнал событии |
| CPU | Показывает состояние регистров центрального процессора |
| FPU | Показывает состояние регистров арифметического сопроцессора |
| Desktops | Управляет конфигурациями основных окон. Эта опция-заголовок открывает доступ к подменю со следующими опциями |
| Save Desktop | Сохраняет текущую конфигурацию |
| Delete | Удаляет ранее сохраненную конфигурацию |
| Save Debug Desktop | Определяет текущую конфигурацию как отладочную |
| Toggle For.gif" > |
П 1 2 РАБОТА С РЕДАКТОРОМ
П 1.2. РАБОТА С РЕДАКТОРОМВсе команды редактора можно разделить на команды перемещения курсора, команды удаления/вставки, команды работы с блоками, прочие.
При их описании используются следующие обозначения клавиш управления курсором:
| вл
вп |
курсор влево;
курсор вправо; |
вв
вн |
курсор вверх;
курсор вниз. |
П 1 3 2 Окно наблюдения
П 1.3.2. Окно наблюденияНаблюдать за состоянием переменной или выражения можно с помощью специального окна, вызываемого опцией View | Debug windows | Watches (cm. там же).
Окно наблюдения (Рисунок П 1.17) используется в отладочном режиме для наблюдения за изменением значений выражений, помещенных в это окно. Для добавления нового выражения щелкните по окну правой кнопкой мыши и выберите опцию New Watch. В строке Expression введите выражение. Окно Repeat count определяет количество показываемых элементов массивов данных; окно Digits указывает количество значащих цифр для отображения вещественных данных; переключатель Enabled разрешает или запрещает вычисление выражения. Остальные элементы определяют вид представления значения. Замечу, что в последних версиях Delphi вы можете просмотреть в отладочном режиме текущее значение любой переменной, если укажите на нее курсором: значение появится в ярлычке рядом с курсором.
П 1 3 8 Ведение протокола работы программы
П 1.3.8 Ведение протокола работы программыВ ряде случаев бывает неудобно или невозможно пользоваться пошаговой отладкой программ. Если вы, например, установите точку останова в подпрограмме прорисовки сетки TDBGrid, программа после останова не сможет нормально продолжить свою работу, т. к. в этом случае она будет пытаться восстановить экран и вновь будет остановлена и т. д. В таких ситуациях вам могут помочь контрольные точки, которые не прерывают работу программы, а лишь помещают некоторую информацию в специальный файл трассировки. Для реализации такой точки раскройте окно RunlAdd Breakpoint | Source Breakpoint (см. Рисунок П1.19), уберите флажок в переключателе Break и напишите сообщение в строке Log message. Вы можете также в строке Eval expression указать некоторое выражение, которое будет вычислено и вместе с сообщением помещено в протокол работы программы. Этот протокол можно просмотреть в любой момент (в том числе и после завершения прогона программы) с помощью опции View] Debug Windows! Event Log.
П1 1 2 Опция Edit
П1.1.2. Опция Edit| Undo | Отменяет последнее изменение проекта |
| Redo | Восстанавливает последнее изменение проекта |
| Cut | Вырезает выбранный компонент формы или фрагмент текста и
помещает его в буфер Clipboard |
| Copy | Копирует в Clipboard выделенные компоненты формы или
фрагмент текста модуля |
| Paste | Извлекает из буфера и переносит компоненты на форму или копирует текст в модуль (в позицию, указываемую текущим положением текстового курсора) |
| Delete | Удаляет выделенные компоненты или фрагмент текста |
| Select All | Выделяет все компоненты формы или весь текст модуля |
| Align To Grid | Привязывает выделенные компоненты к масштабной сетке так, чтобы их левые верхние углы располагались в ближайших точках сетки |
| Bring To Front | Перемещает выделенные компоненты на передний план |
| Send To Back.gif" > |
П1 1 3 Опция Search
П1.1.3. Опция Search| Find | Ищет фрагмент текста и подсвечивает его, если он найден |
| Find In Files | Ищет фрагмент текста во всех файлах проекта, или только в открытых файлах, или, наконец, |
| Replace | Ищет и заменяет фрагмент текста во всех файлах текущего каталога |
| Search Again | Повторяет поиск или поиск и замену |
| Incremental Search | Ищет текст по мере его ввода - сначала первую букву, затем две первые буквы и т. д. |
| Go to Line Number | Перемещает курсор на строку с указанным номером от начала файла |
| Browse Symbol | Показывает место возникновением определения символа программы (опция доступна только после успешного прогона программы). Символом считается любой глобальный идентификатор вашего проекта |
| Find Error | По адресу ошибки периода прогона программы отыскивает фрагмент кода, связанный с ее |
П1 1 5 Опция Project
П1.1.5. Опция Project| Lanages | Позволяет добавить новый, удалить или сделать главным один из существующих языков локализации |
| View Source | Показывает окно с кодом проекта Опция-заголовок. |
| Add To Repository | Помещает проект в репозиторий |
| Import Type Library | Импортирует в проект библиотеку типов элементов ActiveX |
| Remove From Project | Удаляет файл из проекта |
| Add To Project | Добавляет файл к проекту |
| Add Remove Set Active Update Resources DLL | Добавляет новый язык локализации Удаляет существующий язык локализации Делает активным язык локализации Создает заново ресурсные DLL, управляющие локализацией программы |
| Add New Project | Добавляет программу, DLL или пакет к текущей проектной группе |
| Add Exists Project | Открывает проект и добавляет его к текущей проектной группе |
| Compile Project! | Компилирует модули, которые изменились с момента предыдущей компиляции проекта |
| Build Projecti | Компилирует все модули проекта и создает исполняемую программу |
| Syntax Check Project1 | Проверяет синтаксическую правильность программы |
| Information | Показывает информацию о вашей программе |
| Compile All Projects | Компилирует все файлы данной проектной группы, которые изменились с момента предыдущей компиляции |
| Build All Projects | Компилирует все файлы данной проектной группы независимо от того, изменялись ли они или нет с момента последней компиляции |
| Web Deployment Options | Устанавливает ActiveX компонент или ActiveFor.gif" > |
П1 1 5 Опция Run
П1.1.5. Опция Run| Run | Компилирует программу и делает ее прогон |
| Attach to Process | Позволяет присоединиться в режиме отладки к одному из уже запущенных процессов на другой сетевой машине |
| Parameters | Указывает командную строку запуска вашей программы |
| Register ActiveX Servers | Регистрирует ваш проект в реестре Windows. Опция доступна для ActiveX-проектов |
| Unregister ActiveX Servers | Удаляет ваш проект из реестра Windows. Опция доступна для ActiveX-проектов |
| Install MTS Objects | Регистрирует в вашем проекте объект MTS |
| Step Over | В отладочном режиме выполняет текущую строку кода и не прослеживает работу вызываемых подпрограмм |
| Trace Into | В отладочном режиме выполняет текущую строку кода и
прослеживает работу вызываемых подпрограмм |
| Trace To Next Source Line | Программа выполняется до ближайшего от текущего
положения курсора исполняемого оператора |
| Run To Cursor | В отладочном режиме выполняет программу и останавливается перед выполнением кода в строке с текстовым курсором |
| Run Until Return | В отладочном режиме выполняет текущую подпрограмму и останавливается |
| Show Execution Point | Отображает в окне кода оператор, на котором было прервано выполнение программы |
| Program Pause | Приостанавливает прогон отлаживаемой программы |
| Program Reset | Прекращает прогон программы и восстанавливает ре жим конструирования программы |
| Inspect | Открывает окно проверки текущего значения |
| Evaluate/Modify | Открывает окно проверки/изменения переменных |
| Add Watch | Добавляет переменную или выражение в окно наблюдения |
| Add Breakpoint | Добавляет точку останова |
П1 1 6 Опция Component
П1.1.6. Опция Component| New Component | Открывает окно эксперта компонентов |
| Install Component | Помещает компонент в существующий или новый пакет |
| Import ActiveX Control | Добавляет к проекту библиотеку типов ActiveX-компонентов |
| Create Component Template | Помещает шаблон в палитру компонентов |
| Install Packages | Указывает пакеты, необходимые на этапе конструирования и прогона программы |
| Configure Palette | Вызывает диалоговое окно настройки палитры компонентов |
П1 1 7 Опция Database
П1.1.7. Опция Database| Explore | Вызывает инструмент исследования баз данных - Database Explorer или SQL Explorer (в зависимости от версии Delphi) |
| SQL Monitor | Вызывает инструмент запросов к БД - SQL Monitor |
| For.gif" > |
П1 1 8 Опция Tools
П1.1.8. Опция Tools| Environment Options | Вызывает окно настройки параметров среды Delphi и ее инструментов |
| Editor Options | Вызывает окно настройки параметров редактора Delphi |
| Debugger Options | Вызывает окно настройки параметров отладчика Delphi |
Диалоговое окно настройки параметров среды вызывается опцией Tools I Environment Options (Рисунок П1.11).
П1 1 9 Опция Help
П1.1.9. Опция Help| Delphi Help | Основная справочная служба Delphi |
| Delphi Tools | Справочная служба по инструментам Delphi |
| Windows SDK | Справочная служба по Windows API |
| Borland Home Page | Домашняя страничка Borland |
| Delphi Home Page | Домашняя страничка Delphi |
| Borland Developer Support | Страничка поддержки разработчиков |
| Delphi Direct | Окно Интернет-поддержки разработчика |
| Customize | Вызов службы OpenHelp |
| About | Окно с краткой информацией о Delphi |
П1 2 1 Команды перемещения курсора
П1.2.1. Команды перемещения курсора| вл | на символ влево | HOME | в начало строки |
| вп | на символ вправо | END | в конец строки |
| Ctrl-ВЛ | на слово влево | Ctrl+PgUp | в начало экрана |
| Ctrl-ВП | на слово вправо | Ctrl+PgDn | в конец экрана |
| вв | на строку вверх | Ctrl+HOME | в начало файла |
| вн | на строку вниз | Ctrl+END | в конец файла |
| PgUp | на страницу вверх | Ctrl+Q+B | в начало блока |
| PgDn | на страницу вниз | Ctrl+Q+K | в конец блока |
П1 2 3 Команды работы с блоками
П1.2.3. Команды работы с блокамиПри подготовке текстов программ часто возникает необходимость перенести фрагмент текста в другое место или удалить его. Для такого рода операций удобно использовать блоки - фрагменты текста, рассматриваемые как единое целое. Длина блока может быть достаточно большой, он может занимать несколько экранных страниц. В каждый момент в одном окне редактора может быть объявлен только один блок. Обмен блоками между окнами возможен только через буфер Clipboard.
| Ctrl+K+T | пометить в качестве блока слово слева от курсора |
| Ctrl+K+P | напечатать блок |
| Ctrl+K+H | убрать выделение блока цветом; повторное использование Ctrl+K+H вновь выделит блок |
| Ctrl+K+Y | удалить блок |
| Ctrl+K+R | читать блок из дискового файла в позицию, определяемую текстовым курсором |
| Ctrl+K+W | записать блок на диск |
| Ctrl+K+I | сместить блок вправо на два символа |
| Ctrl+K+U | сместить блок влево на два символа |
| Shift+Delete | вырезать блок и поместить его в Clipboard |
| Ctrl+Insert | копировать блок в буфер Clipboard |
| Shift+Insert | вставить содержимое Clipboard в позицию, указываемую текстовым курсором |
П1 2 4 Прочие команды
П1.2.4. Прочие команды| Ctrl+F F3 | искать по образцу продолжить поиск |
| Ctrl+R | искать по образцу и заменить |
| Ctrl+K+n | установить маркер; п = 0..9 (см. ниже) |
| Ctrl+Q+n | искать маркер |
| Ctrl+Q+] | искать парную скобку (см. ниже) |
| Ctrl+O+O | вставить настройку компилятора в начало файла (см. ниже) |
| Ctri+Shift+R | начинает и заканчивает определение макроса |
| Ctrl+Shift+P | выполняет ранее определенный макрос |
Ctrl+K+n. Устанавливает в текущую позицию курсора маркер с номером п = 0..9. Маркер на экране появляется в виде небольшого окошка с номером маркера в служебном поле слева от текста. Он никак не влияет на исполнение программы. Команда используется совместно с командой Ctrl+Q+n (искать маркер с номером и) для ускорения поиска нужных фрагментов текста при разработке крупных программ. Раз установленный маркер нельзя удалить, но можно его поместить в другое место файла. При записи на диск маркеры не запоминаются, т. е. после чтения файла с диска в нем нет маркеров.
Ctrl+Q+]. Эта команда используется для поиска ближайшей парной скобки. Она позволяет отыскивать пары скобок ( и ), { и }, [ и ]. Подведите курсор так, чтобы он расположился непосредственно перед одной из скобок, и дайте команду - редактор отыщет нужную парную скобку.
Ctrl+0+0. Эта команда заставит редактор поместить в самое начало файла строки, содержащие текущую настройку среды в виде директив компилятора, например:
($A+,B-,C+,D+,E-,F-,G+,H+,
I+,J+,K-,L+,M-,N+,0+,P+,
Q-,R-,S-,T-,U-,V+,W-,X+,
Y-}
($MIKSTACKSIZE $00004000)
($MAXSTACKSIZE $00100000)
{$IMAGEBASE $00400000}
{$APPTYPE GUI)
В окне кода можно запрограммировать часто повторяющиеся манипуляции с клавишами в виде макроса. Для начала указания макроса используется команда Ctri+Shift+R . После этого любые действия программиста с клавиатурой запоминаются вплоть до повторения команды Ctrl+Shift+R. Запомненный макрос исполняется командой Ctrl+Shift+P.
П1 2 5 Интеллектуальные возможности редактора
П1.2.5. Интеллектуальные возможности редактораТермин “интеллектуальные возможности” носит условный характер - он обозначает действия, которые редактор выполняет автоматически или по вашей команде и которые существенно упрощают анализ текстов программ, подготовку стандартных программных заготовок, отладку программ.
П1.2.5.1. Поиск объявлений
Если активизировать окно кода и перемещать в нем указатель мыши при нажатой и удерживаемой клавише Ctrl, текст программы приобретает свойства гипертекста: на идентификаторах стандартный указатель мыши заменяется на руку с пальцем, а соответствующий идентификатор выделяется цветом и подчеркиваеся. Если в этот момент нажать левую кнопку мыши, редактор попытается отыскать исходный текст модуля, в котором объявлен соответствующий тип, подпрограмма или глобальная переменная, и, если поиск окажется удачным, загрузит текст модуля в окно кода и установит в нем текстовый курсор в начале описания типа (подпрограммы, переменной). Такого же эффекта можно достичь, если щелкнуть по идентификатору правой кнопкой мыши и выбрать опцию Find Declaration.
Поиск идет в следующем порядке (ниже указаны опции меню и элементы соответствующих окон, содержащие нужные каталоги):
Если мышь перемещается над идентификатором без нажатой и удерживаемой клавиши Shift, рядом с указателем мыши появляется небольшое окно, в котором сообщается, к какому элементу языка относится идентификатор (к процедуре, функции, переменной и т. д.), а также имя модуля и номер строки в нем, где этот идентификатор впервые описан.
П1.2.5.2. Создание стандартных заготовок для новых свойств и методов
При объявлении новых свойств класса в интерфейсной секции вы можете написать лишь имя свойства и его тип.
После нажатия Ctrl+Shift+C или щелчка правой кнопкой мыши и выбора продолжения Complete Class at Cursor редактор добавит необходимые элементы Read и Write в описание свойства и внесет другие изменения в текст программы.
Пусть, например, вы написали
type TMyButton = class(TButton) property Size: Integer;
procedure DoSomething;
end;
и нажали Ctrl+Shift+C (текстовый курсор при этом должен находиться в любом месте внутри описания класса). Редактор изменит описание класса следующим образом:
type TMyButton = class(TButton)
property Size:
Integer read FSize write SetSize;
procedure DoSomething;
private
FSize: Integer;
procedure SetSize(const Value: Integers;
end;
и добавит в исполняемую секцию описание двух методов:
{ TMyButton }
procedure TMyButton.DoSomething;
begin
end;
procedure TMyButton.SetSize(const Value: Integer);
begin
FSize := Value;
end;
Вы можете также вставить в раздел implementation новый метод класса и нажать Ctrl+Shift+C - редактор вставит прототип метода в объявление класса в секции interface.
П1.2.5.3. Навигация внутри модуля
Клавиши курсора Вверх (Up) и Вниз (Down) в сочетании с нажатыми и удерживаемыми клавишами Ctrl и Shift осуществляют переключение между секциями interface и implementation текущего модуля. Если в секции interface вас заинтересовала реализация того или иного метода, щелкните по нему мышью и нажмите Ctrl+Shift+Down - редактор отыщет реализацию и покажет ее вам. Наоборот, чтобы из секции implementation переместиться к заголовку метода в секции interface, нажмите Ctrl+Shift+Up.
П1.2.5.4. Вставка текстовых заготовок и окно Code Insight
Редактор может вставлять в текст множество текстовых заготовок, позволяющих сэкономить время ввода кода программы.
Просмотреть имеющиеся текстовые заготовки и при необходимости добавить к ним собственные можно с помощью Tools | Editor Options | Code Insight.
В средней части окна (Рисунок П1.14) с помощью списка Templates можно выбрать имя и краткое описание образца, а в окне Code увидеть и при желании отредактировать соответствующую текстовую заготовку.
С помощью кнопки Add можно добавить новый образец, с помощью Edit — изменить его имя и краткое описание, а с помощью Delete - удалить его.
При редактировании имеющейся или вставки новой заготовки учтите, что символ “|” определяет позицию текстового курсора после вставки заготовки в текст программы.
Для вставки заготовки напечатайте ее имя в окне кода и нажмите Ctrl+J - имя заменится на полный текст заготовки.
Если вы не помните всех имен заготовок, их можно выбрать из списка.
Для этого установите текстовый курсор в то место, где вы хотите вставить заготовку, и нажмите Ctrl+J - на экране появится окно с именами и краткими описаниями всех заготовок.
П1 3 1 Точки контрольного останова
П1.3.1. Точки контрольного остановаТочка контрольного останова определяет оператор в программе, перед выполнением которого программа прервет свою работу и управление будет передано среде Delphi. Точка останова задается с помощью опции view | Debug windows | Breakponts.
Окно точек останова (Рисунок П 1.16) содержит список всех установленных в проекте точек, перед выполнением которых происходит прекращение работы программы и управление получает среда Delphi.
Для добавления новой точки следует щелкнуть по окну правой кнопкой мыши и выбрать опцию Add. В этом случае появляется окно, с помощью которого можно указать положение добавляемой точки: FileName - определяет имя файла;
Line number - номер строки от начала файла (в момент появления окна оно содержит файл и строку с текстовым курсором). В строке Condition можно указать условие останова в виде логического выражения (например, MyValue = Мах-Value-12), а в строке Pass count - количество проходов программы через контрольную точку без прерывания вычислений.
П1 3 3 Принудительное прерывание работы программы
П1.3.3. Принудительное прерывание работы программыЕсли программа запущена из среды Delphi, ее работу можно прервать в любой момент G помощью клавиш Ctrl+F2, кнопки, опцией Run | program pause или, наконец, установив точку контрольного останова в той части программы, которая выполняется в данный момент или будет выполнена.
П1 3 4 Трассировка программы
П1.3.4. Трассировка программыПеред исполнением оператора, в котором установлена точка контрольного останова, работа программы будет прервана, управление получит среда Delphi, a в окне наблюдения отразится текущее значение наблюдаемых переменных и/или выражений. Теперь программист может прослеживать работу программы по шагам с помощью клавиш F7 и F8 или инструментальных кнопок. При нажатии F8 будут выполнены запрограммированные в текущей строке действия, и работа программы прервется перед выполнением следующей строки текста программы. Замечу, что контрольная точка останова выделяется по умолчанию красным цветом, а текущая прослеживаемая строка - синим. Если программа остановлена в контрольной точке, т.е. когда текущая строка совпадает со строкой останова, строка выделяется красным цветом, Признаком текущей строки является особое выделение строки в служебной зоне слева в окне редактора (см. Рисунок П1.18).
П1 3 5 Действия в точках прерывания
П1.3.5. Действия в точках прерыванияВ Delphi 5 и 6 с любой точкой можно связать одно или несколько действий. Для этого нужно активизировать окно точек останова, вызвать его локальное меню (щелчок правой кнопкой) и выбрать продолжение Properties. В появившемся окне свойств щелкнуть по кнопке Advanced (Рисунок П1.19).
В нижней части окна имеется панель Actions, с помощью которой и определяются действия для точки останова, указанной в верхней части окна.
Break - простой останов перед выполнением помеченного оператора.
ignore subsequent exceptions - если переключатель установлен, игнорируются все возможные последующие исключения в текущем отладочном сеансе до очередной точки останова, в которой, возможно, это действие будет отменено.
Handle subsequent exceptions - после установки этого переключателя отменяется действие предыдущего переключателя и возобновляется обработка возможных исключений.
С помощью Log message вы можете указать произвольное сообщение, связанное с точкой останова, а с помощью Eval expression - вычислить некоторое выражение и поместить его результат в это сообщение.
П1 3 6 Группировка точек прерывания
П1.3.6. Группировка точек прерыванияВ Delphi 5 и б имеется возможность объединения точек останова в группы. Для этого используется все то же окно Рисунок П1.20: в строке Group следует указать имя группы, к которой принадлежит точка, а в строках Enable Group и Disable Group соответственно разрешить или запретить действие всех точек останова, относящихся к соответствующей группе.
П1 3 7 Вычисление выражений и изменение значений
П1.3.7. Вычисление выражений и изменение значенийС помощью окна Evaluate/Modify (Рисунок П1.20) можно узнать значение любого выражения или установить в переменную другое значение. Это окно вызывается в режиме отладки после нажатия Ctrl+F7.

Рис 1.20. Окно прослеживания изменения значении
Это окно - модальное, т. е. оно прерывает отладку программы до тех пор, пока не будет закрыто. В строке Expression можно написать имя переменной или интересующее вас выражение. После щелчка по кнопке Evaluate в поле Result появится текущее значение переменной (выражения). Если в Expression содержится имя переменной, одновременно становится доступной кнопка Modify, а в строке New value повторяется текущее значение переменной. Если изменить эту строку и нажать Modify, в переменную будет помещено новое значение, которое и будет использоваться при дальнейшем прогоне программы (если определяется значение выражения, кнопка Modify и строка New value будут недоступны).
В Delphi 5 и 6 используются также дополнительные кнопки этого окна Watch и inspect. Если вы щелкните по первой из них, выражение (переменная) из окна Evaluate будет перенесено в окно наблюдений watch, щелчок по второй отображает выражение (переменную) в специальном окне Inspect.
П1 3 ОТЛАДКА ПРОГРАММ
П1.3. ОТЛАДКА ПРОГРАММВ Delphi имеется мощный встроенный отладчик, значительно упрощающий отладку программ. Основными инструментами отладки являются точки контрольного останова и окно наблюдения за переменными.
Подменю File среды Delphi
Рисунок 18.5. Подменю File среды DelphiКак видим, опции Open, open Ptoject, Save и т. д. снабжены небольшими пиктограммами. Введение пиктограмм в меню, с одной стороны, повышает наглядность меню, а с другой - способствует унификации пиктограмм в рамках механизма действий (см. п. 17.7). Если опция меню связана с каким-то действием своим свойством Action, а компонент TActionList, в котором это действие описано, в свою очередь, связан с хранилищем пиктограмм TimageList (см. 18.5.3), индекс нужной пиктограммы можно задать в свойстве ImageIndex. В этом случае пиктограмма, указанная в свойстве BitMap (если она указана в нем), игнорируется.
Тип TMenu.gif" >
При ее выборе раскрывается подменю
Приложение 1СРЕДА РАЗРАБОТЧИКА
П 1.1. ГЛАВНОЕ МЕНЮ
П 1.1.1. Опция File
| New | Опция-заголовок. При ее выборе раскрывается подменю со следующими опциями |
| Application | Создает новую программу для Windows |
| CLX Application | Создает новую программу для Windows и Linux |
| Data Module | Создает новый модуль данных |
| For.gif" > |
с любой программой, поэтому объявленные
Приложение 2ПЕРЕМЕННЫЕ, ПРОЦЕДУРЫ И ФУНКЦИИ МОДУЛЯ SYSTEM
Модуль SYSTEM автоматически связывается с любой программой, поэтому объявленные в его интерфейсной части типы, константы, переменные и подпрограммы доступны программисту в любой момент. В этом приложении приводится (в алфавитном порядке) список всех объявлений модуля в его интерфейсной секции. Следует заметить, что большинство объявлений осталось неизменным еще со времен давнего предшественника Delphi - системы программирования Turbo Pascal. Кроме того, многие подпрограммы описаны в других разделах книги (работа с файлами, с вариантами, преобразование строк и т. п.).
| function Abs(X) ; | Возвращает абсолютную величину выражения x (целого или вещественного типа) |
| function Addr(X): Pointer; | Возвращает адрес переменной или подпрограммы х |
| var AllocMemCount: Integer; | Возвращает полное количество блоков памяти, выделенных программе |
| var A11 о cMemS ize: Integer; | Возвращает полное количество памяти (в байтах), выделенное программе |
| procedure Append (var F: Text); | Открывает текстовый файл f для добавления новых строк |
| function ArcTan(X: Extended): Extended; | Возвращает Арктангенс (в радианах) x |
| procedure Assert (expr : Boolean [;const msg: Strings; | Проверяет условное выражение ехрг. Выдает сообщение msg и останавливает программу, если выражение имеет значение False, в противном случае ничего не делает |
| procedure AssignFile (var F; File Name: String) ; | Связывает файловую переменную F с файлом, указанным в FileName |
| function Assigned (var P) : Boolean; | False, если указатель р связан с nil (т. е. не указывает на область памяти) |
| procedure BlockRead(var F: File;
var Buf; Count: Integer [; var AmtTransferred: Integer]); |
Читает из файла, связанного с f, в буфер Buf не более count блоков и возвращает в AmtTransfered истинное количество прочитанных блоков |
| procedure BlockWrite (var f: File;
var Buf; Count: Integer [; var pa Buf не более Count блоков и возвращает AmtTransferred: Integer]);procedure Break; |
Записывает в файл, связанный с F, в AmtTransfered истинное количество записанных блоковНемедленно прекращает выполнение циклов for, while или repeat |
| procedure ChDir(S: Strings; | Изменяет умалчиваемый каталог на каталог, заданный выражением s |
| function Chr(X: Byte): Char; | Преобразует байт х в символ |
| procedure Close(var F) ; | Закрывает файл F |
| procedure CloseFile(var F); | Закрывает файл f |
| var CmdLine: PChar; | Содержит параметры запуска программы |
| var CmdShow: Integer; | Содержит статус окна, открытого API-
функцией showwindow |
| function CompToCurrency(acomp:
Comp): Currency; cdecl; |
Преобразует тип Comp к типу currency |
| function CompToDouble(acomp:
Comp): Double; cdecl; |
Преобразует тип Comp к типу Double |
| function Concat(sl [, s2,..., sn]: String): String; | Объединяет строки Si в единую строку |
| procedure Continue; | Прекращает очередную итерацию цикла for, while или repeat |
| function Copy(S; Index, Count:
Integer): Stringy; function Copy(S; Index, Count: Integer): array; |
Возвращает подстроку или сегмент динамического массива |
| function Cos(X: Extended): Ex
tended/ |
Возвращает косинус аргумента X, заданного
в радианах |
| procedure CurrencyToComp
(acurrency: Currency; var result: Comp); cdecl; |
Преобразует тип currency к типу Comp |
| var DLLProc: Pointer; | Указывает точку входа в DLL-процедуру,
которая выполняется в данный момент |
| procedure Dec(var X [ ; N: Long-
Int]); |
Уменьшает х на n, а если n опущено - на 1. х, n - любые порядковые типы, в том числе Int64 |
| var Default8087CW: Word; | Содержит 0, если в ПК нет арифметического сопроцессора, в противном случае разряды слова указывают некоторые технические
параметры сопроцессора |
| procedure Delete(var S: String;
Index, Count: Integer); |
Удаляет из строки s count символов начи
ная с символа с номером index |
| procedure Dispose(var P:
Pointer) ; |
Освобождает память, связанную с указателем p |
| function DoubleToComp(adouble:
Double; var result: Comp); cdecl; |
Преобразует тип Double к типу Comp |
| var EmptyParam: OleVariant; | Указывает, что умалчиваемый параметр
дуального интерфейса не используется |
| procedure EnumModules(Func:
TEnumModuleFunc; Data: Pointers- overload; procedure EnumModules(Func: TEnumModuleFuncLW; Data: Pointer); overload; |
Реализует обратный вызов (callback) для
всех модулей и всех пакетов программы |
| procedure EnumResourceModules(Func: TEnumModuleFunc; Data: Pointer); | Реализует обратный вызов (callback) для всех ресурсных модулей программы |
| procedure EnumResourceMod-
ules(Func: TEnumModuleFuncLW; Data: Pointer) ; |
|
| function Eof(var F): Boolean; | Возвращает True, если достигнут конец файла f (любого типа) |
| function Eoln [(var F: Text) ]:
Boolean- |
Возвращает True, если достигнут конец строки или конец текстового файла |
| procedure Erase(var F) ; | Уничтожает файл, связанный с переменной F |
| var ErrorAddr: Pointer; | Содержит адрес исполняемого оператора,
вызвавшего ошибку при прогоне программы |
| var ErrorProc: Pointer; | Содержит адрес входа в умалчиваемый обработчик ошибок |
| var ExceptProc: Pointed; | Содержит адрес входа в низкоуровневый
обработчик исключений |
| procedure Exclude(var S: set of
T;I:T) ; |
Исключает элемент i из множества s |
| procedure Exit; | Завершает работу подпрограммы |
| var ExitCode: Integer; | Возвращает код завершения программы. В
современных разработках используйте для этих целей секцию finalization |
| var ExitProc: Pointer; | Содержит адрес входа в процедуру завер
шения программы |
| function Exp(X: Real): Real; | Возвращает х°, где е - основание натурального логарифма |
| var FileMode: Byte; | Указывает режим файла, открытого процедурой Reset: 0 - только чтение; 1 - только запись; 2 - чтение и запись |
| function FilePos(var F): Longint; | Возвращает текущую позицию в файле F |
| function FileSize(var F): Integer; | Возвращает размер нетекстового файла |
| procedure FillChar(var X; Count:
Integer; Value: Byte); |
Заполняет переменную х не более Count
байтами со значением value |
| procedure Finalize( var V [;
Count: Integer] ) ; |
Освобождает динамически распределенную
память, связанную с F |
| function FindClassHIn-
stance(ClassType: TClass): Long Word; |
Возвращает дескриптор модуля, в котором определен экземпляр класса ClassType |
| function FindHInstance( Address:
Pointer): LongWord; |
Возвращает дескриптор модуля, в котором определен адрес Address |
| function FindResourceHInstance
(Instance: LongHord): LongWord; |
Возвращает дескриптор ресурсного файла
для экземпляра instance |
| procedure Flush(var F: Text); | Записывает буфер файла на диск |
| function Frac(X: Extended): Ex
tended; |
Возвращает дробную часть х |
| procedure FreeMem(var P:
Pointer[; Size: Integer]); |
Освобождает динамически распределенную
память, связанную с P |
| procedure GetDir(D: Byte; var S: String) ; | Возвращает имя диска по его номеру |
| procedure GetMem(var P: Pointer;Size: Integer); | Связывает с указателем p size байт динамической памяти |
| procedure GetMemoryManager(var
MemMgr: TMemoryManager); |
Возвращает точку входа в менеджер динамической памяти |
| procedure Halt [ ( Exitcode: Integer) ] ; | Прекращает выполнение программы с кодом завершения ExitCode |
| var HeapAllocFlags: Word = 2; | Указывает, какую память получает менеджер динамической памяти от операционной системы (по умолчанию - gmemmoveable) |
| function Hi(X): Byte; | Возвращает старший байт 16-разрядного числа |
| function High(X); | Возвращает наивысшее значение диапазона порядкового типа, строки или открытого массива, к которому принадлежит х |
| function lOResult: Integer; | Возвращает статус последней операции
ввода-вывода |
| procedure Inc(var X [ ; N: LongInt ] ); | Наращивает х на n, а если n отсутствует - на
единицу |
| procedure Include(var S: set ofT; I:T); | Включает элемент i в множество S |
| procedure Initialize(var V [ ;
Count: Integer ] ); |
Инициализирует динамически распределенную переменную v, если она была создана не процедурой New |
| var Input: Text; | Системный файл ввода |
| procedure Insert(Source: String;
var S: String; Index: Integers; |
Вставляет подстроку source в строку s начиная с символа index |
| function Int(X: Extended): Ex
tended; |
Возвращает целую часть вещественной переменной |
| var IsConsole: Boolean; | Содержит True, если выполняется приложение консольного типа |
| var IsLibrary: Boolean; | Содержит True, если выполняется подпрограмма из DLL |
| function IsMemoryManagerSet: Boolean; | Возвращает True, если менеджер динамической памяти был изменен процедурой Set-MemoryManager |
| var IsMultiThread: Boolean; | Содержит True, если в программе инициировано несколько потоков |
| var JITEnable: Byte; | Указывает тип обработки исключения, возникающего в процессе отладки |
| function Length (S): Integer; | Возвращает длину строки |
| function Ln(X: Real): Real; | Возвращает натуральный логарифм х |
| function Lo(X): Byte; | Возвращает младший байт аргумента |
| function Low(X); | Возвращает наименьшее значение диапазона порядкового типа, строки или открытого массива, к которому принадлежит х |
| var Mainlnstance: LongWord; | Содержит дескриптор экземпляра главного
модуля программы |
| var MainThreadID: LongWord; | Содержит дескриптор главного потока для
текущего модуля |
| const Maxint = High(Integer); | Содержит максимальное значение типа integer (2 147 483 647) |
| const MaxLongint = High(Longint); | Содержит максимальное значение типа
Longint(2 147 483 647) |
| procedure MkDir(S: String); | Создает новый каталог |
| procedure Move(const Source; var
Dest; Count: Integers; |
Переносит не более count байт из источника Source в приемник Dest |
| procedure New(var P: Pointer); | Создает новую динамическую переменную
и связывает ее с p |
| var NoErrMsg: Boolean=False; | Указывает, будут ли ошибки периода исполнения программы сопровождаться сообщениями (False - будут) |
| var Null: Variant; | Используется для указания значения Null переменной вариантного типа |
| function Odd(X: Longint): Boolean; | Возвращает True, если аргумент - нечетное число |
| procedure OleStrToStrVar (Source:
PWideChar; var Dest: String); |
Копирует “широкую” (двухбайтную) строку
в обычную строку Object Pascal |
| function Ord(X): Longint; | Возвращает порядковое значение перемен
ной порядкового типа (в том числе и Int64) |
| var Output: Text; | Файл системного вывода для консольных приложений |
| function ParamCount: Integer; | Возвращает количество параметров запуска программы |
| function ParamStr(Index: Integer) : String; | Возвращает параметр запуска под номером index (для index=0 - имя исполняемого файла) |
| function Pi: Extended; | Возвращает число it=3,141592653589793 |
| function Po3(Substr: String; S:String): Integer; | Возвращает номер символа, начиная с которого в строке s располагается подстрока Substr |
| function Pred(X) ; | Возвращает предыдущее значение для выражения х порядкового типа |
| function Ptr(Address: Integer):
Pointer; |
Преобразует Address в указатель |
| var RandSeed: Longint; | Определяет стартовое значение для генератора псевдослучайных последовательностей |
| function Random [ ( Range: Integer) ] ; | Возвращает очередное псевдослучайное число. |
| procedure Randomize; | Инициирует генератор псевдослучайных последовательностей. |
| procedure Read(var F / VI [/ V2,...,Vn ] ); | Читает из файла f заданное количество значений и помещает их в переменные vi |
| procedure Readin([ var F: Text; ]
VI [, V2, . . ., Vn ] ) ; |
Читает из файла f заданное количество строк и помещает их в переменные vi |
| procedure ReallocMem(var P:
Pointer; Size: Integers; |
Изменяет размер динамической переменной |
| procedure Rename(var F; Newname:String) ;
procedure Rename(var F; Newname:PChar) ; |
Переименовывает файл, связанный с файловой переменной f |
| procedure Reset(var F [: File;
RecSize: Word ] ) ; |
Открывает существующий файл для чтения и/или записи |
| procedure Rewrite(var F: File [;
Recsize: Word ] ) ; |
Создает новый файл и открывает его для записи |
| procedure RmDir(S: Strings; | Удаляет пустой каталог s |
| function Round(X: Extended):
Int64; |
Округляет вещественное число до ближайшего целого |
| procedure RunError [ ( Errorcode:
Byte ) ]; |
Останавливает работу программы и сообщает код ошибки |
| procedure Seek(var F; N: Long-
Int) ; |
Пропускает n байт от начала файла |
| function SeekEof [ (var F: Text)
]: Boolean; |
Пропускает все байты до конца файла |
| function SeekEoln [ (var F: Text)
]: Boolean; |
Пропускает все символы текстового файла до конца текущей строки |
| procedure Set8087CW(NewCW: Word); | Временно устанавливает новый режим работы арифметического сопроцессора |
| procedure SetLength(var S;
NewLength: Integer); |
Устанавливает новую длину строки или
динамического массива |
| procedure SetMemoryManager (const
MemMgr: TMemoryManager); |
Устанавливает новый менеджер динамической памяти |
| procedure SetString(var s: String; buffer: PChar; len: Integer) ; | Копирует Len символов буфера Buffer в строку s |
| procedure SetTextBuf(var F: Text;
var Buf [ ; Size: Integer] ); |
Устанавливает внешний буфер Buf длиной size символов для файловой переменной f |
| function Sin(X: Extended): Ex
tended; |
Возвращает синус аргумента (в радианах) |
| function SizeOf(X): Integer; | Возвращает длину переменной х в байтах |
| function Slice(var A: array;
Count: Integer): array; |
Возвращает открытый массив, содержащий первые count элементов массива а |
| function Sqr(X: Extended): Extended; | Возвращает квадрат аргумента |
| function Sqrt(X: Extended): Extended; | Возвращает корень квадратный из аргумента |
| procedure Str(X [: Width [: Decimals ] ]; var S) ; | Преобразует х целого или вещественного
типа в строку s с учетом длины width и количества знаков после запятой Decimals |
| function StringOfChar(Ch: CharCount: Integer): String; | Создает строку, состоящую из Count раз повторенного символа Ch |
| function StringToOleStr(const Source: String): PWideChar; | Копирует обычную строку в двухбайтную |
| function StringToWideChar(const
Source: String; Dest: PWideChar; DestSize: Integer): PWideChar; |
Преобразует обычную строку в строку с
символами UNICODE |
| function Succ(X) ; | Возвращает следующее значение для порядкового аргумента х |
| function Swap(X) ; | Меняет местами байты в 16-разрядном слове |
| function Trunc(X: Extended): Int64; | Преобразует вещественное число к целому путем отбрасывания дробной части |
| procedure Truncate(var F) ; | Отсекает оставшуюся часть файла до его конца |
| const Unassigned: Variant; | Используется для указания варианта с не
связанным (пустым) значением |
| function UpCase(Ch: Char): Char; | Преобразует строчный символ Ch в заглавный |
| procedure Val(S: String; var V;var Code: Integer); | Преобразует строковое значение в целую или вещественную величину |
| function VarArrayCreate(const
Bounds: array of Integer; VarType: Integer): Variant; |
Создает вариантный массив |
| function VarArrayDimCount(consfc
A: Variant): Integer; |
Возвращает количество измерении вариантного массива |
| function VarArrayHighBound
(const A: Variant; Dim: Integer): Integers; |
Возвращает верхнюю границу измерения
вариантного массива |
| function VarArrayLock(var A:
Variant): Pointers; |
Блокирует вариантный массив и возвращает указатель на его данные |
| function VarArrayLowBound(const
A: Variant; Dim: Integer): Integer; |
Возвращает нижнюю границу измерения вариантного массива |
| procedure VarArrayRedim(var A:
Variant; HighBound: Integer) ; |
Перестраивает вариантный массив |
| function VarArrayRef(const A:
Variant): Variants- |
Преобразует вариантный массив к форме, необходимой при обращении к API- функциям |
| procedure VarArrayUnlock(var A:
Variant) ; |
Отменяет действие функции VarArrayLock |
| function VarAsType(const V: Variant; VarType: Integer): Variants; | Преобразует вариант к заданному типу |
| procedure VarCast(var Dest: Variant; const Source: Variant; VarType: Integer); | Преобразует вариант к заданному типу и сохраняет результат в Dest |
| procedure VarClear(var V : Variant) ; | Помещает в вариант пустое значение |
| procedure VarCopy(var Dest: Vari
ant; const Source: Variants; |
Копирует вариант-источник Source в вариант-приемник Dest |
| function VarFromDateTime
(DateTime: TDateTime): Variants; |
Преобразует дату-время в значение варианта |
| function VarIsArray(const V:
Variant): Boolean; |
Возвращает True, если v - вариантный массив |
| function VarIsEmpty(const V:
Variant): Boolean; |
Возвращает True, если вариант имеет пустое значение |
| function VarIsNull(const V: Variant) : Boolean; | Возвращает True, если вариант имеет значение Null |
| function VarToDateTime(const V:
Variant): TDateTime) ; |
Преобразует вариант в значение дата-время |
| function VarToStr(const V: Variant) : String; | Преобразует вариант в строку. |
| function VarType(const V: Vari
ant) : Integers; |
Возвращает тип хранящегося в варианте результата |
| procedure WideCharLenToStrVar
(Source: PWideChar; SourceLen: Integer; var Dest: String); |
Преобразует не более SourceLen символов
строки UNICODE к обычной строке |
| function WideCharLenToString
(Source: PWideChar; SourceLen: Integer): Strings; |
Преобразует не более SourceLen символов
строки UNICODE к обычной строке |
| procedure WideCharToStrVar
(Source: PWideChar; var Dest: String); |
Преобразует строку UNICODE к обычной строке |
функция АгсТап модуля System не
Приложение 3ПРОЦЕДУРЫ И ФУНКЦИИ МОДУЛЯ MATCH
| Тригонометрические подпрограммы | |
| function ArcCos(X: Extended): Extended; | Арккосинус |
| function ArcSin(X: Extended): Extended; | Арксинус |
| function ArcTan2(Y, X: Extended): Ex tended; | Вычисляет арктангенс Y/X и возвращает угол в правильном квадранте ( функция АгсТап модуля System не учитывает квадрант) |
| function Cotan(X: Extended): Extended; | Котангенс |
| function Hypot (X, Y: Extended): Extended; | Корень квадратный из (X** 2 + Y** 2)-гипотенуза прямоугольного треугольника по двум катетам |
| procedure SinCos (Theta: Extended; va: '"Sin, Cos: Extended); | Возвращает одновременно синус и косинус угла Theta (почти в 2 раза быстрее, чем раздельное получение синуса и косинуса) |
| function Tan(X: Extended): Extended; | Тангенс |
| Функции преобразования углов | |
| function CycleToRad(Cycles: Extended) : Extended; | Radians := Cycles * 2PI |
| function DegToRad(Degrees: Extended) Extended; | Radians := Degrees * PI / 18 |
| function GradToRad(Grads: Extended): Extended; | Radians := Grads * PI / 200 |
| function RadToDeg(Radians: Extended) Extended; | Degrees := Radians * 180 / PI |
| function RadToGrad(Radians: Extended) : Extended; | Grads := Radians * 200 / PI |
| function RadToCycle(Radians: Extended) : Extended; | Cycles := Radians / 2PI |
| Гиперболические функции |
| function ArcCosh(X: Extended): Extended; | Гиперболический арккосинус |
| function ArcSinh(X: Extended): Extended; | Гиперболический арксинус |
| function ArcTanh(X: Extended): Extended; | Гиперболический арктангенс |
| function Cosh(X: Extended): Extended; | Гиперболический косинус |
| function Sinh(X: Extended): Extended; | Гиперболический синус |
| function Tanh(X: Extended): Extended; | Гиперболический тангенс |
| Логарифмические функции | |
| Function LnXP1 (X: Extended) : Exteaded; | Логарифм натуральный от (Х+1). Используется, когда Х близок к нулю |
| functios Extended): Extended; | Десятичный логарифм |
| functior extended): Extended; | Двоичный логарифм |
| function LogN(Base, X: Extended): Extended; | Логарифм от X при основании Base |
| Экспоненциальные функции | |
| function IntPower(Base: Extended; Expopient: Integer) : Extended; | Возведение Base в целочисленную степень Exponent |
| function Power(Base, Exponent: Extended) : Extended; | Возведение Base в вещественную степень Exponent |
| Подпрограммы разного назначения | |
| function Ceil(X: Extended): Integer; | Ближайшее меньшее целое |
| function Floor (X: Extended): Integer; | Ближайшее большее целое |
| procedure Frexp(X: Extended; var Mantissa: Extended; var Exponent: Integer); | Возвращает мантиссу и степень вещественного числа |
| function Ldexp(X: Extended; P: Integer) : Extended; | Возвращает Х*Р*P |
| Статические программы | |
| function Мах(А,В: Int64): Int64; overload; |
|
| function Мах (А, В: Integer): Integer; overloads; | Возвращает максимальное из двух чисел |
| function Poly(X: Extended; const Coefficients: array of Double): Extended; | Значение полинома A*X"+B*X" '+.. .+Z. Коэффициенты задаются в порядке возрастания степени |
| function Мах(А,В: Single): Single/overload; | |
| function Max(А,В: Double): Double/overload; |
|
| function Max(А,В: Extended): Extended; overload; |
|
| function MaxIntValue(const Data: array of Integer): Integer; | Возвращает максимальное из набора целых чисел |
| function MaxValue(const Data: array of Double): Double; | Возвращает максимальное из Тнабора вещественных чисел |
| function Mean(const Data: array of
Double): Extended; |
Вычисляет арифметическое среднее для набора вещественных чисел |
| procedure MeanAndStdDev(const Data: array of Double; var Mean, StdDev: Extended) ; | Вычисляет арифметическое среднее и стандартное отклонение для набора вещественных чисел |
| function Min(А/В: Integer): Integer/overload/function Min(А,В: Int64): Int64; overload; | Возвращает минимальное из двух чисел |
| function Min(A,B: Single): Single/overload;
function Min(A,B: Double): Double; overload/function Min(A,B: Extended): Extended; overload/ |
|
| function MinIntValue(const Data: array of Integer): Integer; | Возвращает минимальное из набора целых чисел |
| function MinValue(const Data: array of Double): Double; | Возвращает минимальное из набора вещественных чисел |
| procedure MomentSkewKurtosis (const Data: array of Double;
var Ml, M2, МЗ, М4, Skew, Kurtosis: Extended); |
Вычисляет статистические моменты порядков с первого по четвертый, а также асимметрию Skew и эксцесс Kurtosis для набора чисел |
| function Norm(const Data: array of Double): Extended; | Возвращает норму (квадратный корень из суммы квадратов) вещественных чисел |
| function PopnStdDev(const Data: array of Double): Extended; | Выборочное стандартное отклонение. Отличается от обычного стандартного отклонения тем, что использует выборочное значение дисперсии (см.ниже PopnVariance) |
| function PopnVariance(const Data: array of Double): Extended; | Выборочная дисперсия. Использует “смещенную” формулу TotalVariance/N (см. ниже TotalVariance) |
| function RandG(Mean, StdDev: Extended) : Extended; | Генерирует нормально псевдораспределенную последовательность чисел с заданным средним значением Mean и стандартным отклонением StdDev |
| function StdDev(const Data: array of Double): Extended; | Вычисляет среднеквадратическое отклонение для набора чисел |
| function Sum(const Data: array"orDouble): Extended register; | Вычисляет сумму чисел |
| procedure SumsAndSquares(const Data: array of Double; | Одновременное вычисление суммы и суммы квадратов для набора чисел |
| function Sumint(const Data: array of Integer): Integer register; | Сумма наоора целых чисел |
| function SumOfSquares(const Data: array of Double): Extended; | Сумма квадратов чисел |
| function TotalVariance(const Data: array of Double): Extended; | Сумма квадратов расстояний всех величин от их среднего арифметического |
| function Variance(const Data: array
of Double): Extended; |
Выборочная дисперсия для набора чисел. Использует ^несмещенную” формулу TotalVariance/(N-1) |
| Финансовые функции | |
| type TPaymentTime = (ptEndOfPeriod,
ptStartOfPeriod) ; |
Перечисляемый тип, используемый в финансовых функциях |
| function DoubleDecliningBalance (Cost, Salvage: Extended; Life, Period: Integer): Extended; | Вычисление амортизации методом двойного баланса |
| function FutureValue(Rate: Extended; NPeriods: Integer; Payment, Pre-sentValue: Extended; PaymentTime: TPaymentTime): Extended; | Будущее значение вложения |
| - function InterestPayment(Rate: Extended; Period, NPeriods: Integer; PresentValue, FutureValue: Extended; PaymentTime: TPaymentTime): Extended; | Вычисление процентов по ссуде |
| function InterestRate(NPeriods: Integer; Payment, PresentValue, Future-Value: Extended; PaymentTime: TPaymentTime) : Extended; | Норма прибыли, необходимая для получения заданной суммы |
| function InternalRateOfReturn (Guess: Extended} const CashFlows: array of Double): Extended; | Вычисление внутренней скорости оборота вложения для ряда последовательных выплат |
| function NetPresentValue(Rate: Extended; const CashFlows: array of Double; PaymentTime: TPaymentTime): Extended; | Вычисление чистой текущей стоимости вложения для ряда последовательных выплат с учетом процентной ставки |
| function NumberOfPeriods(Rate, Payment, PresentValue, FutureValue: Extended; PaymentTime: TPaymentTime): Extended/ | Количество периодов, за которые вложение достигнет заданной величины |
| function Payment(Rate: Extended; NPeriods: Integer; PresentValue, Future-Value: Extended; PaymentTime: TPaymentTime) : Extended/ | Размер периодической выплаты для погашения ссуды при заданном числе периодов, процентной ставке, а также текущем и будущем значениях ссуды |
| function PeriodPayment(Rate: Extended; Period, NPeriods: Integer; PresentValue, FutureValu'e: Extended; PaymentTime: TPaymentTime): Extended; | Платежи по процентам за заданный период |
| function PresentValue(Rate: Extended; NPeriods: Integer; Payment, Future-Value: Extended; PaymentTime: TPaymentTime) : Extended; | Текущее значение вложения |
| function SLNDepreciation (Cost, Salvage: Extended; Life: Integer): Extended; | Вычисление амортизации методом постоянной нормы |
| function SYDDepreciation (Cost, Salvage: Extended; Life, Period: Integer) : Extended; | Вычисление амортизации методом весовых коэффициентов |
использования компонента Tchart
Рисунок 18.18. Пример использования компонента Tchartиспользования компонента ТСотbоВохЕх
Рисунок 18.34 . Пример использования компонента ТСотbоВохЕх
Специфичные свойств а компонента:
| property Images: TCustomImageList; | Определяет объект-хранилище изображении |
| property ItemsEx: TComboExItems; | Определяет строки списка выбора |
| property MaxLength: Integer; | Определяет максимальное количество символов, которые пользователь может ввести в окне редактора |
| type TComboBoxExStyle = (csExDropDown, csExSimple, csEx-DropDownList) ; property Style: TComboBoxExStyle; | Определяет стиль компонента: csExDrop-Down с кнопкой раскрытия списка и возможностью ручного ввода текста; csExSim-ple - без кнопки (список всегда раскрыт), высота списка определяется свойством Height; csExDropDownList -с кнопкой раскрытия списка, но пользователь не может ввести текст выбора вручную |
property Comboltems[const Index: Integer]: TComboExItem; property Items[const Index: Integer] : TListControlItem; default; type TLi'stItemsSortType = (stNone, stData, stText, stBoth); property SortType: TSortType;
Класс TListControlItem имеет три специфичных свойства: caption (String), Data (Pointer) И Imagelndex (integer), с помощью которых описываются текст элемента, а также связанные с ним данные и индекс изображения. Для установки значений этих свойств используются методы SetCaption, SetData И Setlmagelndex класса TListControlItem.
Класс TComboExitem, с помощью которого описываются строки списка в целом, имеет такие свойства:
| property Caption: Strings-property Data: Pointed; | Текст элемента выбора Указатель на связанные с элементом данные |
| property Imagelndex: Timagelndex; | Индекс изображения для невыбранного элемента |
| property Indent: Integer; | Отступ элемента от левого края списка |
| property Overlaylmagelndex: Timagelndex; | Индекс изображения-маски |
| property SelectedlmageIndex: Timagelndex; | Индекс изображения для выбранного элемента |
использования компонента TTreeView
Рисунок 18.27. Пример использования компонента TTreeView
Для наполнения списка на этапе конструирования программы нужно щелкнуть по компоненту правой кнопкой мыши и выбрать Items Editor., либо щелкнуть по нему дважды, либо, наконец, щелкнуть по кнопке в свойстве Items - во всех случаях на экране появится окно редактора компонента (Рисунок 18.28).
использования компонента
Рисунок 18.30. Пример использования компонента THeaderControl для управления положением и размерами других компонентовconst
Delta = 10;// Зазор между границами заголовка и компонентами
procedure TFor.gif" >
использования компоненты
Рисунок 18.14 . Пример использования компоненты TSplitter (помечен черными квадратиками)
использования окна пояснений
Рисунок 21.2. Пример использования окна пояснений
Чтобы показать раздел в окне пояснений, нужно выделить текст перекрестной ссылки шрифтом с одинарным подчеркиванием, на пример:
Для проверки АSI-шиныASI и связанных с ней реле и датчиков используется опция Сервис | Контроль шины главного меню.
В выделенную скрытым текстом часть ссылки можно вставить следующие дополнительные управляющие символы:
* отменяет выделение текста ссылки цветом;
% отменяет выделение текста ссылки цветом и подчеркиванием;
@ указывает HLP-файл, в котором расположена нужная тема; > указывает тип окна для отображения раздела.[ Методика работы с Microsoft Word дается для версии 97. Для других версий могут быть незначительные отличия. ]
Символы “*” и “%” вставляются непосредственно перед идентификатором раздела и, так же как и он, оформляются скрытым текстом. Например:
ГИПЕРТЕКСТ %НУРЕРТЕХТ
Теперь в справочном окне слово гипертекст ничем, кроме формы расположенного над ним указателя мыши, не будет отличаться от обычного текста справки, тем не менее щелчок по нему вызовет переход к теме hypertext. В ссылке можно указать только один из символов отмены выделения - “*” или “%”.
Символы “@” и “>”, наоборот, вставляются в конце скрытого текста и за ними должны следовать:
ГИПЕPTEKCT HYPERTEXT@C:\PRQBA\PROBA.HLP>WIND
Обратите внимание: символы “@” и “>”, как и следующие за ними символы маршрута и имени типа окна, должны оформляться скрытым текстом. Если, как в приведенном примере, в ссылке одновременно указываются и маршрут, и тип окна, порядок их следования безразличен, однако в одной ссылке можно указать только один символ “@” и (или) один символ “>”. Замечу, что имя типа окна нужно указывать заглавными буквами, даже если в файле проекта оно определено строчными.
использования таблицы TDrawGrid
Рисунок 18.11. Пример использования таблицы TDrawGrid для отображения картинок и текста
Если вы захотите повторить пример, следует сначала подготовить пустую форму главного окна. Дайте ей имя fmDrawGrid и вставьте в описание класса TfmDrawGrid такое поле:
public
sIBitMap: TSringList;
Это поле будет использоваться для хранения текстовых строк и картинок. Его необходимо создать и наполнить в момент создания окна и уничтожить при его уничтожении. Поэтому создайте следующие Обработчики событий OnCreate и OnDestroy для формы:
procedure TfmDrawGrid.For.gif" >
использования TPaintBox
Рисунок 18.35. Пример использования TPaintBox
procedure TFor.gif" >
использования TStringList
Рисунок 18.10. Пример использования TStringList
Создайте такой обработчик события OnClick для кнопки BitBtn1:
procedure TfmStGrid.BitBtnIClick(Sender: TObject) ;
Function GetWord(var S: String): String;
{ Вспомогательная функция для выделения очередного слова из
строки }
const // Множество символов слова:
Letters: set of Char = ['a'..'z', 'A'..'Z', 'A'..'я'];
begin
Result := '' ;
{ Уничтожаем в начале строки все символы, не относящиеся к слову }
while (S о '') and not (S[1] in Letters) do
Delete (S, 1, 1);
// Формируем очередное слово
while (S<> '') and (S[1] in Letters) do
begin
Result := Result + S[1];
Delete (S, 1, 1)
end;
end; //Get Word
var
F: TextFile; // Файл с текстом S,
Word: String; // Вспомогательные строки
NCol, NRow: Integer;// Номер текущей колонки и текущего ряда Words: TStringList; // Список отсортированных слов из файла
begin
// С помощью стандартного диалога получаем имя файла
if not OpenDialogI.Execute then
Exit; // Пользователь отказался выбрать файл
// Пытаемся открыть файл
AssignFile(F, OpenDialogI.FileName) ;
try
Reset(F) ;
except
// Файл нельзя открыть:
ShowMessage('Невозможно открыть файл ' +OpenDialogI.FileName) ;
Exit;
end;
// Готовим список Words:
Words := TStringList.Create;
Words.Sorted := True; // Сортируем строки Words.Duplicates := duplgnore; // Отвергаем дубликаты
// Изменяем курсор перед длительной работой
Screen.Cursor := crHourGlass;
// Читаем файл по строкам
while not EOF(F) do
begin
ReadLn(F, S); // Читаем очередную строку
// Выделяем из строки слова и заносим их в список Words
while S о '' do
begin
Word := GetWord(S) ;
if Word о '' then
Words.Add(Word) // He вставляем пустые строки
end
end;
Screen.Cursor := crDefault; // Восстанавливаем курсор
CloseFile(F); // Закрываем файл
if Words.Count=0 then
Exit; // Пустой файл - выходим
with sgWords do
begin
NCol := 1; // Номер первого столбца слов
// Цикл формирования таблицы
while Words.Count > 0 do
begin
{Формируем заголовок столбца и начальное значение номера ряда}
Cells [NCol, 0] := Words[0][1];
NRow := О
// Цикл заполнения очередного столбца
while (Words.Count > 0) and
(Words[0][1] = Cells[NCol, 0]) do
begin
inc(NRow); // Номер текущего ряда
if NRow = RowCount then
begin // Расширяем длину таблицы
RowCount := RowCount + 1;
{Для свойства RowCount нельзя, использовать функцию инкремента inc!} Cells [0, NRow] := IntToStr(NRow);
end;
Cells[NCol, NRow] :=Words[0];
Words.Delete(0) ;
end;
// Переходим к следующему столбцу
if Words.Count=0 then
Break; // Кончаем работу, если слов больше нет
inc(NCol); // Переходим к следующей колонке
ColCount := ColCount+1 // Расширяем таблицу справа
//на 1 колонку
end;
end;
end;
Пример компонента с тремя панелями
Рисунок 18.31 . Пример компонента с тремя панелями и кнопкой изменения размеров окна
На Рисунок 18.31 показан компонент TStatusBar с тремя панелями и кнопкой изменения размеров окна, созданный таким обработчиком события OnCreate для формы For.gif" >
Пример многоколенчатого меню
Рисунок 18.6. Пример многоколенчатого менюВ отличие от других видимых компонентов строка Hint для опций меню задает только расширенное сообщение, которое отображается на панели статуса.
Для элемента меню определено единственное событие Onciick, которое возникает при щелчке на опции или при нажатии Enter, если в этот момент данная опция была выбрана (подсвечена). Обработчик события становится доступен после двойного щелчка на опции в окне конструктора меню
Пример страницы диаграмм
Рисунок 2.9. Пример страницы диаграмм
Для сложных форм с множеством компонентов можно подготовить несколько диаграмм. Дав каждой диаграмме уникальное имя, можно в любой момент с помощью выпадающего списка выбрать нужную.
Страницу диаграмм можно напечатать.
Пример структуры программы
Рисунок 8.1. Пример структуры программы
Procedure A; Procedure Al;
begin
end {A1};
Procedure A2;
begin
end {A2};
begin {A}
end {A};
Procedure B;
Procedure Bl;
begin
end {Bl};
, Procedure B2;
Procedure B21;
И Т. Д.
Подпрограмма любого уровня имеет обычно множество имен констант, переменных, типов и вложенных в нее подпрограмм низшего уровня. Считается, что все имена, описанные внутри подпрограммы, локализуются в ней, т. е. они как бы “невидимы” снаружи подпрограммы. Таким образом, со стороны операторов; использующих обращение к подпрограмме, она трактуется как “черный ящик”, в котором реализуется тот или иной алгоритм. Все детали этой реализации скрыты от глаз пользователя подпрограммы и потому недоступны ему. Например, в рассмотренном выше примере из основной программы можно обратиться к процедурам а и в, но нельзя вызвать ни одну из вложенных в них процедур a1,
А2, В1
И Т. Д.
Сказанное относится не только к именам самих подпрограмм, но и вообще к любым объявленным в них именам - типам, константам, переменным и меткам. Все имена в пределах подпрограммы, в которой они объявлены, должны быть уникальными и не могут совпадать с именем самой подпрограммы.
При входе в подпрограмму низшего уровня становятся доступными не только объявленные в ней имена, но и сохраняется доступ ко всем именам верхнего уровня. Образно говоря, любая подпрограмма как бы окружена полупрозрачными стенками: снаружи подпрограммы мы не видим ее внутренности, но, попав в подпрограмму, можем наблюдать все, что делается снаружи. Так, например, из подпрограммы В21 мы можем вызвать подпрограмму а, использовать имена, объявленные в основной программе, в подпрограммах в и в2, и даже обратиться к ним. Любая подпрограмма может, наконец, вызвать саму себя - такой способ вызова называется рекурсией.
Пусть имеем такое описание:
var V1 : ... ;
Procedure A;
var V2 : ...;
end {A};
Procedure В;
var V3 : . . . ;
Procedure B1;
var V4 : . . . ;
Procedure В 11;
var V5;
Из процедуры B11 доступны все пять переменных v1,...,v5, из процедуры в1 доступны переменные v1,...,v4, из центральной программы-только v1.
При взаимодействии подпрограмм одного уровня иерархии вступает в силу основное правило Object Pascal: любая подпрограмма перед ее использованием должна быть описана. Поэтому из подпрограммы в можно вызвать подпрограмму а, но из а вызвать в невозможно (точнее, такая возможность появляется только с использованием опережающего описания, см. п. 8.5.) Продолжая образное сравнение, подпрограмму можно уподобить ящику с непрозрачными стенками и дном и полупрозрачной крышей: из подпрограммы можно смотреть только “вверх” и нельзя “вниз”, т. е. подпрограмме доступны только те объекты верхнего уровня, которые описаны до описания данной подпрограммы. Эти объекты называются глобальными по отношению к подпрограмме.
В Object Pascal допускается произвольная последовательность описания констант, переменных, типов, меток и подпрограмм. Например, раздел var описания переменных может появляться в пределах раздела описаний одной и той же подпрограммы много раз и перемежаться с объявлениями других объектов и подпрограмм. Для Object Pascal совершенно безразличен порядок следования и количество разделов var, type, const и label, но при определении области действия этих описаний следует помнить, что имена, описанные ниже по тексту программы, недоступны из ранее описанных подпрограмм, например:
var V1 : ; . . ;
Procedure S;
var V2 : . . . ;
end {S};
var V3 : . . . ;
Из процедуры s можно обратиться к переменным v1 и v2, но нельзя использовать V3, так как описание этой переменной следует в программе за описанием процедуры s.
Локализованные в подпрограмме имена могут совпадать с ранее объявленными глобальными именами. В этом случае считается, что локальное имя “закрывает” глобальное и делает его недоступным, например:
var
i : Integer;
Procedure P;
var
i : Integer;
begin
IbOutput.Caption := IntToStr(i);
end {P};
begin
i := 1;
P
end;
Что выведет эта программа на экран? Все что угодно: значение внутренней переменной i при входе в процедуру p не определено, хотя одноименная глобальная переменная имеет значение 1. Локальная переменная “закроет” глобальную, и на экран будет выведено произвольное значение, содержащееся в неинициированной внутренней переменной.
Если убрать описание
var
i : integer;
из процедуры p, то на экран будет выведено значение глобальной переменной i,t. е. 1.
Таким образом, одноименные глобальные и локальные переменные - это разные переменные. Любое обращение к таким переменным в теле подпрограммы трактуется как обращение к локальным переменным, т. е. глобальные переменные в этом случае попросту недоступны.
TToolBar с кнопками TToolButton
Рисунок 18.32. Пример TToolBar с кнопками TToolButton
| property AllowAlIUp: Boolean;. | Если содержит True, синхронизирует свое состояние с состоянием других кнопок в той же группе: в любой момент может быть нажата только одна кнопка группы. Игнорируется, если Grouped=False |
| property Caption: String; | Содержит связанный с кнопкой текст, который будет показан, если свойство ShowCaptions компонента TTooiBar имеет значение True |
| property Down: Boolean; | Определяет состояние кнопки: если содержит True, кнопка утоплена |
| property DropdownMenu.gif" > |
задания перекрестных ссылок
Рисунок 21.1. Пример задания перекрестных ссылок
Для задания скрытого текста в редакторе Word необходимо выделить текст и применить к нему команду Hidden. Для этого можно воспользоваться опцией Формат | Шрифт и в разделе Эффекты щелкнуть по опции скрытый.
Примечание
Примечание
Поскольку эту последовательность действий; при написании текста, справочной службы придется выполнять очень часто, полезно предварительно настроить Word: выберите Сервис | Настройка, на панели.
Команды в окне категории выберите все команды, а в окне Команды - Hidden и “перетащите” мышью (нажав и не отпуская, левую, кнопку) эту команду на инструментальную, панельку. Теперь, чтобы выбрать скрытый текст, достаточно выделить его и щелкнуть по новой кнопке. Для Задания перечеркнутого или дважды подчеркнутого текста нет специальной команды, поэтому автоматизировать соответствующие действия нужно с помощью макроса. Чтобы создать Макрос сначала выделите текст, затем выберите Сервис | Макрос | Начать запись, в окне Запись макроса укажите подходящее имя (например, Зачеркнутый) и щелкните по кнопке ''Панели, затем из окна Настройка перетащите имя макроса на панель инструментов и накройте окно. Теперь указатель мыши будет иметь вид кассеты с лентой, а на экране появится соответствующая панелька управления. Выберите Формат | Шрифт [Зачеркнутый и остановите запись макроса щелчком по левой кнопке панельки управления или с помощью Сервис | Макрос |Остановить запис ь.
Любой вызываемый раздел может отображаться в основном окне справки или в окне пояснений. Это окно появляется поверх основного окна (такие окна иногда называют “всплывающими”) и обычно используется для пояснений (Рисунок 21.2).
ы использования компонента TDateTimePicker
Рисунок 18.26. Примеры использования компонента TDateTimePicker
При показе даты в режиме DateMode=dmComboBox календарь можно не раскрывать и установить дату вручную в верхнем окне. Это удобно, если нужно установить сразу и день, и месяц, и год. На раскрытом календаре изменить месяц можно небольшими кнопками вверхней части компонента. Календарь закрывается после выбора даты или при щелчке по раскрывающей кнопке. Установив в свойство Kind значение dtkTime, можно заставить компонент отображать время (справа на рисунке). Это время в момент установки компонента на форму соответствует системному времени, и в дальнейшем его можно изменить, задав новое значение в свойство Time.
Свойства компонента:
| TDTCalAlignment = (dtaLeft, dtaRight) ; | Определяет положение раскрывающегося календаря: dtaLeft - слева от компонента; |
| property CalAlignment: TDTCalAlignment; | dtaRight - справа от компонента. Учитывается только ДЛЯ Kind = dtkDate и Date-Mode = dmComboBox |
| property CalColors: TDateTimeColors; | С календарем связан объект класса
TDateTimeColors, свойства которого определяют цвета календаря |
| property Checked: Boolean; | Если Checked=True И ShowCheckBox=True,
независимый переключатель рядом с датой (временем) будет иметь состояние Выбрано |
| property Date: TDate;TDTDateFor.gif" > |
Примеры комбинированных списков
Рисунок 18.7. Примеры комбинированных списков
Свойство DropDownCount определяет количество элементов списка, появление которых еще не приводит к необходимости прокрутки списка. По умолчанию это свойство имеет значение 8: если в списке указано 9 и более элементов (т. е. больше, чем содержит DropDownCount), при его раскрытии к окну будет добавлена полоса прокрутки. Свойство DroppedDown определяет, раскрыт ли в данный момент список. Это свойство доступно также для записи, что позволяет программно управлять состоянием списка. Событие OnDropDown происходит при изменении состояния списка.
Наполнение списка ведется методами Add, Append, Insert и т. п. его свойства Items класса TStrings (см. п. 16.3.1). По поводу использования свойства items и программной прорисовки элементов списка см. замечания в п. 18.1.10.
Различные формы компонента TGauge
Рисунок 18.45. Различные формы компонента TGauge
Свойства компонента:
| property Back.gif" > | Содержание | Вперед |
Размещение компонента Label
Рисунок 3.1. Размещение компонента Label
Надпись на компоненте в окне формы тут же соответствующим образом изменит свои свойства. Delphi обладает замечательной способностью визуальной реализации любых изменений свойств компонента не только на этапе прогона программы, но и на этапе проектирования формы.
Щелкните мышью внутри обрамляющих надпись черных прямоугольников и, не отпуская левую кнопку мыши, сместите ее указатель так, чтобы он расположился левее в центре окна, после чего отпустите кнопку. Таким способом можно буксировать компонент по форме, добиваясь нужного его положения.
С помощью обрамляющих черных квадратиков можно изменять размеры компонента. Для этого следует поместить острие указателя мыши над одним из них (в этот момент указатель меняет свою форму на двунаправленную стрелку), затем нажать левую кнопку мыши и, не отпуская ее, буксировать сторону или угол компонента в нужном направлении, после чего отпустить кнопку.
Замечу, что все видимые компоненты[ В Delphi могут использоваться как видимые, так и невидимые компоненты. Невидимые компоненты не имеют визуального отображения на этапе прогона программы. ] имеют свойства Left (Слева), тор (Сверху), width (Ширина) и Height (Высота), числовые значения которых определяют положение левого верхнего угла компонента и его размеры в так называемых пикселях, т. е. в минимальных по размеру точках экрана, светимостью которых может управлять программа. При буксировании компонента или изменении его размеров мышью эти значения автоматически меняются и наоборот - изменение этих свойств в окне Инспектора объектов приводит к соответствующему изменению положения и размеров компонента. В Delphi 4, 5 и 6 значения Left и тор автоматически появляются в небольшом окне рядом с указателем мыши при буксировке компонента по форме.
Размещение компонентой на TScrollBox
Рисунок 18.13. Размещение компонентой на TScrollBox
Разновидности кнопок TBitBtn
Рисунок 18.9. Разновидности кнопок TBitBtn
Нажатие любой из них, кроме bkCustom и bkHelp, закрывает модальное окно и возвращает в программу результат mrxxx: bkok - mrОk, bkCancel - mrCancel И Т. Д. Кнопка bkClose для модального окна возвращает mrCancel, а для главного окна программы - закрывает его и завершает работу программы. Кнопка bkHelp автоматически вызывает раздел справочной службы, связанный с Heipcontext формы, на которую она помещена. Если у кнопки была изменена пиктограмма Glyph, Delphi автоматически присвоит ей Kind=bkCustom. Это произойдет также в случае, когда кнопка указана как умалчиваемая (Defauit=True), но Kind не содержит bkok или bkYes, а также если ее свойство Cancel содержит True, a Kind нe содержит bkCancel или bkNo.
Свойства Cancel, Default И ModalResult кнопка TBitBtn унасле-довала у своего родительского класса TButton, остальные специфичные свойства указаны ниже:
| property Glyph: TBitmap;
TBitBtnKind = (bkCustom, bkOK, bkCancel, bkHelp, bkYes, bkNo, bkClose, bkAbort, bkRetry, bklg-nore, bkAll) ; property Kind: TBitBtnKind; |
Определяет от 1 до 4 связанных с кнопкой растровых изображения (см. ниже) Определяет разновидность кнопки (Рисунок 18.9) |
| TButtonLayout = (bIGlyphLeft, bIGlyphRight, bIGlyphTop, bIGlyphBottom) ; property Layout: TButtonLayout; | Определяет край кнопки, к которому прижимается пиктограмма: bIGlyphLeft - к левому; bIGlyphRight - к правому; bIGlyphTop - к верхнему;biGlyphBottom - к нижнему) |
| property Margin: Integer; | Определяет расстояние в пикселях от края кнопки до пиктограммы |
| TNumGlyphs: 1..4 ; property NumGlyphs: TNumGlyphs; | Определяет количество растровых изображений (см.ниже) |
| property Spacing: Integer; | Определяет расстояние в пикселях от пиктограммы до надписи на кнопке |
| TByttonStyle = (bsAutoDetect, bsWinSI, bsNew) ;
property Style: TButtonStyle; |
Определяет стиль оформления кнопки, зависящий от операционной системы. Стиль bsNew соответствует 32-разрядным версиям Windows. Стиль bsAutoDetect изменяет оформление кнопки в зависимости от ОС, под управлением которой работает программа в данный момент |
Примечание
При разработке собственных растровых изображений для использования в кнопках следует учесть, что изображения должны меняться? при изменении состояния кнопки. Таких состояний может быть четыре: нормальное, запрещенное, нажатое и утопленное (последнее используется только в кнопках TSpeedButton). В соответствии с этим! разрабатывается до 4 пиктограмм, расположенных по горизонтали ввиде одного длинного растра. Например, стандартный размер пиктограммы для размещения на кнопке равен 16х16 пикселей. Если создаются 3 пиктограммы, размер растра должен составлять 48х16. Количество пиктограмм в растре задается свойством NumGlyphs. Если каждая; пиктограмма - квадратная и длина растра делится без остатка; на его высоту, Delphi автоматически распознает количество пиктограмм. Если задана только одна пиктограмма, ее изображение, меняется автоматически: в состоянии “нажатая” пиктограмма смещается! на один пиксель вправо и, вниз, а в состоянии “запрещенная” все цвета, кроме черного, меняются на светло-серый, а черный на белый, что обеспечивает эффект "вдавленности" изображения. Следует так же учесть, что самый левый нижний пиксель растра определяет цвет прозрачности: на кнопке этот цвет будет заменяться цветом поверхности кнопки.
Как и в кнопках TButton, программист не может управлять цветом поверхности кнопки, но в отличие от TButton может менять цвет надписи на ней. С помощью свойства Default кнопку можно сделать умалчиваемой - в этом случае нажатие Enter автоматически вызывает обработчик ее события OnClick. Однако умалчиваемыми можно сделать только кнопки bkYes и bkNo, остальные значения свойства Kind будут заменяться на bkcustom при размещении в Default значения True и наоборот - в Default автоматически помещается False при установке в Kind любого значения, кроме bkYes, bkNo или bkcus-tom.
Разветвленная структура меню
Рисунок 18.4. Разветвленная структура менюВ Delphi 4 (5 и 6) появилась возможность связывать с опциями меню небольшие изображения. Эти изображения можно задать либо свойством BitMap, либо свойством imageindex. В последнем случае предполагается, что для меню в целом определено свойство Images либо (только для версии 6) свойство SubMenu.gif" >
Редактор компонента TActionList
Рисунок 18.8. Редактор компонента TActionList
События TAction:
| property OnExecute: TNotifyEvent; | Возникает при щелчке мышью на одном из компонентов, связанных общим действием. Обработчик этого события должен реализовать нужное действие |
| THintEvent = procedure (var HintStr: String; var CanShow: Boolean) of object; property OnHint: THintEvent; | Возникает при перемещении указателя мыши над одним из связанных общим действием компонентов. Его умалчиваемый обработчик создает окно оперативной подсказки и показывает в нем строку HintStr |
| property OnUpdate: TNotifyEvent; | Возникает, когда очередь сообщений для приложения пуста или когда обновляется содержимое списка действий |
Примечание
В версии Delph6 введена группа компонентов (См. ниже пп. 18.2.23), обеспечивающая более мощную Поддержку механизма действий, в том числе создание настраиваемого пользовательского интерфейса, Таким образом, компонент TActionList используется лйщБ;яД&Рвместимо(дхс более разними версиями,, . .
Редактор компонента TActionManager
Рисунок 18.20. Редактор компонента TActionManagerРедактор компонента
Рисунок 18.28. Редактор компонента
Чтобы начать наполнение, щелкните по кнопке New item и введите связанный с узлом текст в поле Text. С помощью image index панели item properties устанавливается индекс связанной с узлом пиктограммы, с помощью selected index - индекс пиктограммы для выбранного узла. Для ввода подузла любого уровня сначала нужно щелкнуть в окошке Items по узлу, который должен стать родительским, и лишь затем - на кнопке New subitem.
Для ввода списка в режиме прогона программы широко используется центральное свойство компонента - items типа TTreeNodes, открывающее индексированный доступ ко всем узлам списка. Каждый узел описывается классом TTreeNode, имеющим свои собственные методы и свойства. В частности, его свойство item содержит список всех подузлов данного узла; с помощью многочисленных методов свойства TTreeview. items к этому списку можно добавить новый подузел, а с помощью метода TTreeNode. MoveTo - переместить узел в любую позицию дерева иерархии.
Следующий обработчик события oncreate формы создал Рисунок 18.29:
procedure TFor.gif" >
Puc. 18.29. Создание подузлов на этапе прогона программы
Свойства компонента TTreeview:
| lean;TBorderStyle =
bsNone..bsSingle; property BorderStyle: TBorderStyle; |
Определяет стиль рамки, охватывающей компонент: bsNone - нет рамки; bsSingle - рамка толщиной в 1 пиксель |
| property ChangeDelay: Integer; | Указывает задержку (в миллисекундах) перед раскрытием узла |
| property DropTarget: TTreeNode; | Указывает узел, который может служить приемником операций Drag&Drop |
| property HideSelection:Boolean; | Указывает, будет ли убираться выделение узлов, когда компонент теряет фокус ввода |
| property Images: TImageList; | Содержит набор изображений, которые будут использоваться при прорисовке узлов |
| property Indent: Integer; | Определяет отступ в пикселях от левого угла узла для всех его подузлов |
| property Items: TTreeNodes; | Открывает доступ к любому узлу по его индексу.
Индексация начинается с нуля и соответствует просмотру всех узлов полностью раскрытого списка |
| property MultiSelect: Boo
lean; |
Разрешает/запрещает одновременный выбор несколь ких узлов |
| type TMultiSelectStyles =
(msControlSel-ect, msShift Select, msVisibleOnly, msSiblingOnly) ; TMultiSelectStyle = set of TMultiSelectStyles; property MultiSelectStyle: TMultiSelect-Style default [msControlSelect]; |
Определяет способ выбора нескольких узлов: msControiselect - с нажатой и удерживаемой клавишей Ctrl для выбора узлов в произвольном порядке;
msShiftSelect - с нажатой и удерживаемой клавишей Shift для выбора сплошного диапазона; msVisibleOnly - подобно msShiftSelect, но в диапазон не включаются дочерние нераскрытые узлы; msSiblingOnly - подобно msShiftSelect, но в диапазон включаются только узлы одного уровня |
| property Readonly: Boolean; | Запрещает/разрешает редактирование надписей в узлах |
| property RightClickSelect:
Boolean; |
Разрешает выбор узлов правой кнопкой мыши |
| property Selected:
TTreeNode; |
Содержит список всех выбранных узлов или nil, если таких нет |
| property SelectionCount:
Cardinal; |
Содержит количество выбранных узлов |
| property Selections[Index:
Integer]: TTreeNode; |
Обеспечивает индексированный доступ к выбранным узлам |
| property RowSelect: Boolean; | Разрешает цветовыделение линий выбранных узлов. Игнорируется, если showLinesFalse |
| property ShowButfcons: Boolean; | Разрешает/запрещает показ стандартных кнопок раскрытия подузлов. По умолчанию содержит True. Если False, узел раскрывается двойным щелчком мыши |
| property ShowLines: Boolean; | Разрешает/запрещает показ линий |
| property ShowRoot: Boolean; | Разрешает/запрещает показ линий, идущих от самого верхнего уровня иерархии. Игнорируется, если ShowLines=False |
| TSortType = (stNone,
stData, stText, stBoth) ; property SortType: TSort Type; |
Указывает способ сортировки узлов: stNone - нет сортировки; stData - сортировка по данным; stText - сортировка по тексту надписей; stBoth - сортировка по тексту и по данным. См. также событие OnCompare |
| property Topitern: , TTreeNode; | Определяет корневой узел |
| Методы компонента: |
| function AlphaSort: Boolean; TTVCompare = function (IParamI, lParam2, IParamSort: Longint) Integer stdcall; tfunction CustomSort(SortProc: TTVCompare; Data: Longint): Boolean; | Сортирует узлы по тексту и возвращает
True, если сортировка прошла успешно Определяет нестандартную сортировку с помощью функции SortProc. Эта функция должна рассматривать IParamI и lParam2 как объекты TTreeNode и возвращает отрицательное число, если lParaml |
| procedure FullCollapse; | Прячет все узлы, кроме узлов самого верх
него уровня иерархии |
| Procedure FullExpand; | Показывает все узлы дерева иерархии |
| function GetNodeAt(X, Y: Integer) : TTreeNode; | Возвращает узел, располагающийся в указанной точке, или nil, если точка не принадлежит ни одному узлу |
| function IsEditing: Boolea' | Возвращает True, если пользователь редактирует какой-либо узел |
| procedure LoadPromFile(const
FileName: String); |
Загружает дерево иерархии из файла |
| procedure SaveToFile(const File
Name: String) ; |
Сохраняет в файле дерево иерархии |
| procedure SaveToStream(Stream: TStream) ; | Сохраняет в потоке данных дерево иерархии
события: С компонентом связаны такие |
| TTVChangedEvent = procedure(Sender: TObject; Node: TTreeNode) of object; property OnChange: TTVChangedE vent; | Возникает при смене состояния выбора у
одного из узлов. Node - узел, который изменил состояние |
| TTVChangingEvent = procedure(
Sender: TObject; Node: TTreeNode; var AllowChange: Boolean) of objectproperty OnChangir.g: TTVChang ingEvent; |
Возникает перед сменой состояния выбора
у одного из узлов. Node - узел, который будет выбран. Обработчик в параметре AllowChange разрешает или запрещает выбор узла |
| TTVExpandedEvent = procedure(
Sender: TObject; Node: TTreeNode) of object;property OnCollapsed: TTVExpand edEvent; |
Возникает при закрытии списка подузлов узла Node |
| TTVCollapsingEvent = procedure(
Sender: TObject; Node: TTreeNode; var AllowCollapse: Boolean) of object; property OnCollapsing: TTVCollapsingEvent; |
Возникает перед закрытием списка подуз лов узла Node. В параметре AllowCollapse обработчик разрешает или запрещает закрыть список |
| TTVCompareEvent = procedure(
Sender: TObject; Nodel, Node2: TTreeNode; Data: Integer; var Compare: Integer) of object; property OnCompare: TTVCom pareEvent; |
Возникает при сравнении двух узлов
Nodel И Node2. В параметре Compare обработчик должен вернуть отрицательное число, если Nodel |
| TTVExpandedEvent = procedure(
Sender: TObject; Node: TTreeNode) of object; property OnDeletion: TTVExpand edEvent; |
Возникает при удалении узла Node из дерева иерархии |
| TTVEditedEvent = procedure(Sender: TObject; Node:
TTreeNode; var S: String) of object; property OnEdited: TTVEditedEvent; |
Возникает при завершении редактирования надписи в узле Node: S - новая надпись |
| TTVExpandedEvent = procedure(
Sender: TObject; Node: TreeNode) of object; property OnExpanded: TTVExpand edEvent; |
Возникает при распахивании списка подузлов узла Node |
| TTVExpandingEvent = procedure(
Sender: TObject; Node: TTreeNode; var AllowExpansion: Boolean) of object; property OnExpanding: TTVExpand ingEvent; |
Возникает перед открытием списка подузлов узла Node. В параметре AllowExpansion обработчик разрешает или запрещает
открыть список |
| TTVExpandedEvent = procedure(
Sender: TObject; Node: TreeNode) of object;property OnGetImageIndex: TTVEx pandedEvent; |
Возникает при необходимости получения
индекса изображения для прорисовки узла Node в обычном состоянии |
| TVExpandedEvent == procedure(
Sender: TObject; Node: TTreeNode) of object; property OnGetSelectedIndex: TTVExpandedEvent; |
Возникает при необходимости получения
индекса изображения для прорисовки узла Node в выбранном состоянии |
Свойства класса TTreeNodes:
| property Count: Integer; property Item[Index: Integer]: TTreeNode; default-property Owner: TCustomTreeView; | Количество узлов, входящих в items Открывает индексированный доступ к узлам Содержит ссылку на родительский список |
| Методы класса TTreeNodes: | |
| function Add(Node: TTreeNode; const S: String): TTreeNode;
function AddChild(Node: TTreeNode; const S: String): TTreeNode; function AddChildFirst(Node: TTreeNode; const S: String): TTreeNode; function AddChildObject(Node: TTreeNode; const S: String; Ptr: Pointer): TTreeNode; function AddChildObjectFirst( Node: TTreeNode; const S: String; Ptr: Pointer): TTreeNode; |
Добавляет узел в конец того списка, в котором зарегистрирован узел Node. Если Node=NlL, добавляется корневой узел для всего компонента Добавляет узел в конец списка item дочерних узлов узла Node
Добавляет узел в начало списка Item дочерних узлов узла Node Добавляет узел и данные в конец списка item дочерних узлов узла Node. На данные ссылается указатель Ptr. Связанная с данными область памяти не освобождается автоматически при уничтожении списка Добавляет узел и данные в начало списка item дочерних узлов узла Node. На данные ссылается указатель Ptr. Связанная с данными область памяти не освобождается автоматически при уничтожении списка |
| function AddFirst(Node:
TTreeNode; const S: String): TTreeNode; |
Добавляет узел в начало того списка, в котором зарегистрирован узел Node |
| function AddObject(Node:
TTreeNode; const S: String; Ptr: Pointer): TTreeNode; |
Добавляет узел и данные в конец того же списка, в котором зарегистрирован узел
Node. На данные ссылается указатель Ptr. Связанная с данными область памяти не освобождается автоматически при уничтожении списка |
| function AddObjectFirst(Node:
TTreeNode; const S: String; Ptr: Pointer): TTreeNode; |
Добавляет узел и данные в начало того же списка, в котором зарегистрирован узел Node. На данные ссылается указатель Ptr. Связанная с данными область памяти не освобождается автоматически при уничтожении списка |
| procedure Assign(Source: TPersistent) ; | Связывает список текущего компонента со списком компонента Source |
| procedure BeginUpdate; | Блокирует обновление экрана до тех пор, пока не будет выполнен метод EndUpdate.
Используется при одновременной вставке нескольких элементов списка для предотвращения мерцания экрана |
| procedure Clear; | Очищает список всех узлов и подузлов компонента |
| procedure Delete(Node:
TTreeNode); |
Уничтожает узел Nods |
| procedure EndUpdate; | Отменяет действие метода BeginUdate |
| function GetFirstNode: TTreeNode; | Возвращает самый первый узел в списке Items[0] |
| function GetNode(Itemid:
HTreeItem): TTreeNode; |
Возвращает узел по его идентификатору Itemid |
| function Insert(Node: TTreeNode;
const S: String): TTreeNode; |
Вставляет узел непосредственно перед узлом Node |
| function InsertObj ect(Node:
TTreeNode; const S: String; Ptr: Pointer): TTreeNode; |
Вставляет узел и данные непосредственно
перед узлом Node |
Свойства TTreeNode:
| property Absolutelndex: Integer; | Возвращает абсолютный индекс узла (с учетом всех подузлов) |
| property Count: Integer; | Содержит количество подузлов в списке Item |
| property Cut: Boolean; | Вырезает узел и помещает его в clipboard |
| property Data: Pointer; | Указывает на связанные с узлом данные |
| property Deleting: Boolean; | Содержит True, если для узла вызван De-story |
| property DropTarget: Boolean; | Содержит True, если узел может служить приемником операции Drag&Drop |
| property Expanded: Boolean; | Содержит True, если узел распахнут |
| property Focused: Boolean; | Содержит True, если узел сфокусирован |
| property HasChildren: Boolean; | Содержит True, если узел имеет дочерние узлы |
| property Imagelndex: TImageIndex; | Содержит индекс связанной с узлом пиктограммы |
| property Index: Longint; | Содержит индекс узла в списке дочерних узлов его родительского узла |
| property IsVisible: Boolean; | Содержит True, если узел виден |
| property Item[Index: Integer]:
TTreeNode; |
Открывает индексированный доступ ко всем дочерним узлам |
| property Itemid: HTreeItem; | Содержит уникальный Windows-дескриптор узла |
| property Level: Integer; | Содержит иерархический уровень узла |
| property Overlaylndex: Integers- | Содержит индекс оверлейной пиктограммы.
Оверлейная пиктограмма вычерчивается поверх основной, чтобы, например, указать, что узел стал недоступен |
| property Owner: TTreeNodes; | Содержит ссылку на владельца данного узла |
| property Parent: TTreeNode; | Содержит ссылку на родительский узел |
| property Selected: Boolean; | Содержит True, если узел выделен цветом |
| property Selectedlndex: Integer; | Содержит номер пиктограммы для выделенного узла |
| property Text: Strings- | Содержит текст узла |
| property TreeView: TCustomTree-
View; |
Содержит ссылку на компонент TreeView, к которому принадлежит узел |
| function AlphaSort: Boolean; | Сортирует узлы по алфавиту свойств Text и возвращает True в случае успеха |
| procedure Assign(Source: TPersis tent); override; | Связывает список подузлов с источником Source |
| procedure Collapse(Recurse: Boolean) ; | Закрывает все узлы (Recource=True) или только распахнутые(Resource=False) |
| type TTVCompare = function(
IParamI, lParam2, IParamSort: Longint): Integer stdcall; func tion CustomSort(SortProc: TTVCom pare; Data: Longint): Boolean; |
Реализует нестандартную сортировку узлов |
| procedure Delete; | Удаляет текущий узел |
| procedure DeleteChildren; | Удаляет дочерние узлы |
| function DisplayRect(TextOnly:
Boolean): TRect; |
Возвращает очерчивающий прямоугольник узла. Если TextOnly=True - возвращает
очерчивающий прямоугольник текста |
| function EditText: Boolean; | Переводит текст узла в режим редактирования |
| procedure EndEdit(Cancel Boo
lean) ; |
Заканчивает редактирование текста и со храняет его изменения, если Cancel=False |
| procedure Expand(Recurse: Boo
lean) ; |
Открывает узел (и его подузлы, если Recurce=True) |
| function GetFirstChild: TTreeNode; | Возвращает ссылку на первый подузел или nil, если нет подузлов |
| function GetLastChild: TTreeNode; | Возвращает ссылку на последний подузел или nil, если нет подузлов |
| function GetNext: TTreeNode;
function GetNextChild(Value: TTreeNode): TTreeNode; |
Возвращает ссылку на очередной подузел dозвращает ссылку на подузел после value
(или nil, если такового нет). |
| function GetNextSibling:
TTreeNode; |
Возвращает ссылку на очередной узел в том же списке. |
| function GetNextVisible:
TTreeNode; |
Возвращает ссылку на очередной видимый узел (для которого раскрыты все дочерние
узлы) |
| function GetPrev: TTreeNode; | Возвращает ссылку на предыдущий узел в том же списке независимо от его видимости |
| function GetPrevChild(Value:
TTreeNode): TTreeNode; |
Возвращает ссылку на предыдущий по отношению к value дочерний узел |
| function GetPrevSibling:
TTreeNode; |
Возвращает ссылку на предыдущий узел того же уровня |
| function GetPrevVisible:
TTreeNode; |
Возвращает ссылку на видимый узел того же уровня |
| function HasAsParent(Value:
TTreeNode): Boolean; |
Возвращает True, если value - родительский узел |
| function IndexOf(Value:
TTreeNode): Integer; |
Возвращает идентификатор узла value |
| procedure MakeVisible; | Если родительский узел видимый, делает видимыми все дочерние узлы |
| type TNodeAttachMode = (naAdd,
naAddFirst, naAddChild, naAddChildFirst, nalnsert) ; procedure MoveTo(Destination: TTreeNode; Mode: TNodeAttach Mode) ; |
Перемещает текущий узел в позицию относительно Destination в зависимости от параметра Mode: naAdd - добавляет в конец списка узла того же уровня; naAddFirst -
делает первым в списке узлов того же уровня; naAddchild - добавляет в конец списка дочерних узлов; naAddChildFirst -делает первым в списке дочерних узлов; nalnsert - вставляет непосредственно перед узлом |
Окно репозитория Delphi
Рисунок П 1.1. Окно репозитория DelphiОкно настройки параметров среды
Рисунок П 1.11. Окно настройки параметров среды
Закладка Preferences открывает доступ к параметрам среды Delphi: Editor files - перед прогоном автоматически сохраняются все измененные файлы; Project Desktop - перед прогоном автоматически сохраняется информация о состоянии экрана; Desktop Only - при выходе из программы сохраняется информация о состоянии экрана, Desktop and Symbols - при выходе из программы сохраняется информация о состоянии экрана и символах программы на момент последней удачной компиляции; Auto drag docking - разрешает причаливать одно инструментальное окно к другому; Show compiler progress - показывать окно отображения процесса компиляции; Warn on package rebuild - предупреждать о перекомпиляции пакетов; Minimize On Run - минимизировать окна Delphi в момент старта программы; Hide Designers On Run - прятать вспомогательные окна (окно Инспектора объектов и окна форм) в момент старта программы; Directory -содержит путь к окну расположения файла репозитория DELPHI32.DRO; если путь не указан, используется каталог bin каталога размещения Delphi.
Закладка Designer содержит настройки для процесса конструирования форм:
Display Grid - показывать сетку на пустой форме; Snap to Grid - привязывать расположение компонентов к узлам сетки; Show component captions - показывать имена компонентов на этапе конструирования программы; show designer hints - показывать оперативную подсказку об именах компонентов и их типах на этапе конструирования; show extended control hints - показывать ярлычки оперативной подсказки с расширенной информацией; New For.gif" >
Окна справочной службы
Рисунок П 1.12. Окна справочной службы
П1.1.9.1. Служба OpenHelp
Служба OpenHelp предназначена для модификации справочной службы Delphi: с ее помощью можно удалять ненужные разделы и, что наиболее важно, вставлять новые. Последнее связано с тем, что существует множество относительно небольших фирм, занимающихся разработкой и продажей пакетов компонентов для Delphi и C++ Builder (пакеты компонентов для этих двух инструментов идентичны), а также компонентов ActiveX. Сама Delphi имеет развитые средства создания новых компонентов (см. главы части 8). Поставщики компонентов обычно поставляют вместе с ними нужные файлы справочной помощи, которые OpenHelp может сделать частью справочной службы Delphi.
Служба OpenHelp вызывается опциями Help | Customize главного меню. Ее окно показано на Рисунок П 1.13.
Четыре закладки этого окна управляют содержанием справочной службы (закладка Content), набором файлов помощи (index), контекстно-чувствительной помощью (Link) и проектами (Project). Чтобы удалить раздел содержания, файл справки или проект, нужно на соответствующей закладке щелкнуть по удаляемому компоненту и выбрать в меню Edit | Remove Files или щелкнуть по инструментальной кнопке.
Для добавления к содержанию нового раздела требуется предварительно создать два специальных файла: файл с таблицей содержания (с расширением .toe) и файл содержания (.cnt). toe-файл, как следует из документации, есть стандартный файл содержания cnt, создаваемый утилитой hcw.exe (детальное описание процесса создания справочных файлов и файлов содержания вы найдете в гл. 21), за тем отличием, что в нем нельзя использовать секции include. Файл cnt, в свою очередь, отличается от стандартного тем, что в нем должны быть только две директивы: base и title, причем содержимое title у обоих файлов должно быть одинаковым и они должны располагаться в одной папке. После создания файлов вызывается OpenHelp, и на закладке Content щелкается кнопка или вызывается опция Edit |Add Files. В появляющемся вслед за этим диалоговом окне нужно указать положение файла toe.
Окно связывания точки псптнови с действием
Рисунок П.1.19. Окно связывания точки псптнови с действием
Окно масштабирования компонентов
Рисунок П 1.5. Окно масштабирования компонентов
Окно менеджера проекта
Рисунок П.1.6. Окно менеджера проектаП1.1.4.2. Менеджер трансляции
Менеджер трансляций упрощает создание локализованных версий программных продуктов. Он становится доступным только после указания языков, на которые будут переводится текстовые сообщения, надписи, опции и другие текстовые ресурсы программы. Для каждого языка создается своя динамически подключаемая библиотека ресурсов. Изменение этой библиотеки перед компиляцией программы изменяет ее язык (см. выше “Менеджер проекта”).
Для выбора языка (языков) локализации используется опция меню Project [Language (см. с. 619). Главным языком программы по умолчанию считается язык локализации Windows, так что если Delphi работает под управлением русскоязычной Windows, главным языком будет русский.
Окно менеджера трансляций показано на Рисунок П1.7. Для представленного на нем примера главным языком программы является русский, а языком локализации - английский (Великобритания). Переводится надпись Введите пароль (Enter password).
Пример списка ТОDO
Рисунок П 1.8. Пример списка ТО-DO
В списке можно указать приоритет сообщения (колонка “! ”), его собственника (Owner) и категорию.
Эти параметры можно задать с помощью соответствующих ключей непосредственно в комментарии (см. Рисунок П1.8) или после вызова редактора сообщения в списке (он вызывается после активизации сообщения и нажатия клавиши F2).
П1.1.4.4. Браузер объектов
Браузер объектов доступен только после успешного прогона программы. Он представляет в наглядной форме используемые в проекте и доступные объекты, позволяя просмотреть их иерархию и входящие в них свойства и методы.
Окно выбора языков локализации
Рисунок П 1.9. Окно выбора языков локализацииВ нем указывается один или несколько проектов, для которых осуществляется локализация, и главный язык проекта (код $419 соответствует русскому языку). В следующем окне (после щелчка по кнопке Next) вы сможете выбрать языки локализации, отметив их флажками. На следующем шаге эксперт предложит вам указать каталоги размещения библиотек, которые будут содержать локализованные ресурсы. Все библиотеки имеют одинаковое название хххх. drc (хххх - имя проекта), поэтому они должны размещаться в разных каталогах. Для компиляции программы с тем или иным языком локализации используются менеджер проекта и опция Project | Language I Set Active.
П1.1.4.2. Управление опциями проекта
Управление опциями проекта осуществляется с помощью диалогового окна, вызываемого опцией Project | Options.
На странице For.gif" >
П1 10 Окно опций проекта
Рисунок П1.10. Окно опций проектаНа странице Application указывается подпись под пиктограммой свернутой программы (Title), сама пиктограмма (Icon) и имя Help-файла (Help file).
На странице Compiler собраны переключатели, управляющие параметрами процесса компиляции. В том числе (в фигурных скобках указана соответствующая директива компилятора): Optimizations - включает режим оптимизации {$0}, Aligned record fields - размещает данные, выравнивая их на границу 32-разрядного слова {$а}; Stack frames - заставляет компилятор создавать стековые рамы для всех процедур и функций {$W}. Pentium-Safe fdiv - вырабатывает код, предохраняющий от ошибок в вещественных вычислениях на процессорах Pentium ранних выпусков {$U}; Range Checking - создает код проверки выхода за границы массивов {$R}; l/o Checking создает код проверки корректности выполнения операций ввода/вывода {$I}; Overflow checking - вырабатывает код проверки переполнения при выполнении целочисленных операций ($Q}. Strict var-Strings - определяет строгую проверку соответствия строковых типов при обращении к подпрограммам {$V}. Complete Boolean Eva1 - определяет полное вычисление логических выражений {$B}; Extended Syntax - включает расширенный синтаксис Object Pascal {$xf; Typed @ Operator - контролирует типы указателей в операции @ {$Т}; open Parameters - разрешает использование открытых параметров в подпрограммах {$р}. Huge Strings - связывает зарезервированное слово String с длинными строками {$Н}; Assignable Typed Constants - разрешает присваивание типизированным константам {$J}; Debug information - помещает в DCU-файл отладочную информацию {$D}; Local Symbols - создает отладочную информацию о локальных символах программы {$l};
Symbol information - создает отладочную информацию о символах программы {$y}, Show Hints - заставляет компилятор выдавать рекомендации; Show Warnings - заставляет компилятор выдавать предупреждающие сообщения; Assertions - заставляет вырабатывать код для отладочных процедур Assertion {$C}.
Страница Linker определяет параметры компоновщика, в том числе: Off - запрещает создавать карту распределения памяти; Segments - карта содержит список модулей и адреса точек входа всех подпрограмм; Publics - дополняет Segments отсортированным списком символов секций public; Detailed - дополняет Public детальной информацией о модулях; Generate dcus - создает стандартные для Delphi DCU-фаЙлы; Generate С Object files - создает файлы в формате объектов языка С; Generate C++ Object files - создает файлы для связывания с программой, созданной С помощью C++ Builder; Generate Console Application - создает консольную программу; include TD32 Debug info - помещает в исполняемый файл информацию для внешнего отладчика; include remote debug symbols-используется для удаленного вызова отладчика; Min Stack Size-устанавливает минимальный размер стека; мах Stack size - устанавливает максимальный размер стека; image Base - указывает начальный адрес для загрузки изображений (для dll); exe Descriptor - информационная строка длиной до 255 символов, которая включается в исполняемый файл (например, для объявления авторских прав).
Страница Directories/Conditionals задает каталоги размещения и условные символы: Output Directory - указывает каталог размещения исполняемого файла; Unit Output Directory - указывает каталог размещения Dcu-файлов;
Search Path - каталог размещения файловых с исходными текстами программы, если они не обнаружены в текущем каталоге; при необходимости указать несколько каталогов в любом из описанных выше окон они разделяются точкой с запятой; Debug source path - определяет каталог размещения внешнего отладчика; bpl output directory - указывает папку размещения файлов компиляции пакетов; dcp output directory - определяет каталог размещения файлов для локализации программ; Conditional Defines - определяет символы для условной компиляции; Unit Aliases-определяет псевдонимы модулей.
На странице Versioninfo сосредоточены параметры управления информацией о версии программы: include version information in project - если переключатель выбран, в проект включается информация о версии программы, которую можно прочитать после щелчка правой кнопкой мыши на пиктограмме программы и выборе Properties; Module Version Number - поля Major, Minor, Release, Build определяют составной номер версии; Auto-increment build number - если переключатель активен, номер версии автоматически наращивается при каждой компиляции программы; Debug Build - указывает на создание отладочной версии программы; Pre-Release - указывает на создание некоммерческой версии программы; Special Build - казывает на специальную версию программы; Private Build - указывает на версию, не предназначенную для широкого распространения; dll - создается динамическая библиотека; Language id - идентификатор языка, на который рассчитана программа.
П1 13 Окно службы OpenHelp
Рисунок П1.13. Окно службы OpenHelp
Для добавления справочного файла (.hlp) выбирается закладка index, щелкается та же кнопка и указывается положение hlp-файла.
Как показывает практика, эти два действия вполне достаточны для нормального подключения к справочной службе новой информации. Если вы закроете окно OpenHelp, появится запрос - нужно ли обрабатывать внесенные изменения. После утвердительного ответа новый вариант справочной службы будет готов к работе.
П1 14 Окно настройки параметров Coda Insight
Рисунок П1.14 . Окно настройки параметров Coda Insight
Остальные элементы окна Code insight:
Code Completion - разрешает/запрещает появление окна с именами свойств и методов класса после ввода имени объекта и точки (Рисунок П 1.15).
Code Parameters - разрешает/запрещает появление окна с именами формальных параметров обращения к подпрограмме после ввода имени подпрограммы и открывающей скобки (Рисунок П 1.15).
Tooltip Expression Evaluations - разрешает/запрещает появление окна с указанием текущего значения переменной, над именем которой располагается указатель мыши в режиме отладки
Tooltip Symbol Insight - разрешает/запрещает появление окна с указанием параметров идентификатора, над которым располагается указатель мыши.
Delay - определяет задержку в секундах включения механизма показа окон Code Insight.
П1 15 Окна Code Insight
Рисунок П1.15. Окна Code Insight
П1 16 Окно точек останова
Рисунок П1.16. Окно точек останова (слева) и окно добавления новой точки (справа)
П1 17 Окно наблюдения
Рисунок П1.17. Окно наблюдения и окно добавления в него нового выражения
П1 18 Фрагмент окна редактора в режиме отладки
Рисунок П1.18. Фрагмент окна редактора в режиме отладки
Кстати, чтобы установить/снять точку контрольного останова, достаточно щелкнуть мышью по служебной зоне слева от нужной строки или установить в эту строку текстовый курсор и нажать F5.
При нажатии F7 среда выполняет те же действия, что и при нажатии F8, однако, если в текущей строке содержится вызов подпрограммы пользователя, программа прервет свою работу перед выполнением первого исполняемого оператора этой подпрограммы, т.е. клавиша F7 позволяет прослеживать работу вызываемых подпрограмм.
После трассировки нужного фрагмента программы можно продолжить нормальную ее работу, нажав клавишу F9.
П1 2 Окно регистрации формы в репозитории
Рисунок П1.2 . Окно регистрации формы в репозиторииВновь размещенную форму можно сделать главной. Такая форма создается при старте нового проекта (опция главного меню File | New Application). Для определения главной формы выберите опцию Tools [Repository, укажите страницу размещения в левом списке Радез диалогового окна и форму в правом списке Objects, после чего установите флажок в переключателе Main For.gif" >
П1 3 Окно выравнивания компонентов
Рисунок П1.3 . Окно выравнивания компонентовПереключатели этого окна определяют выравнивание всех выделенных компонентов относительно самого первого выделенного компонента (эталона):
П1 4 Окно изменения размеров компонентов
Рисунок П1.4. Окно изменения размеров компонентов
С помощью окна Scaling factor вводится коэффициент масштабирования в процентах от текущих размеров.
П1 7 Окно менеджера трансляций
Рисунок П1.7. Окно менеджера трансляций
П1.1.4.3. Список ТО-DO
Список то-do предназначен для координации работы нескольких программистов в рамках одного проекта.
Этот список содержит все комментарии проекта, которые начинаются символами //todo: (Рисунок П1.8).
Комментарии содержат сообщения руководителя проекта и/или программистов об обнаруженных ошибках и обычно располагаются там, где обнаружена неточность.
После вызова списка то-do переход к нужному комментарию осуществляется двойным щелчком мыщи на соответствующей строке списка.
Программист может сообщить об устранении ошибки, отметив переключатель в левой части строки списка, - в этом случае текст строки выводится перечеркнутым шрифтом.
Содержание справочной службы Delphi
Рисунок 21.8. Содержание справочной службы Delphi:
После создания файла содержания его нужно сохранить в том же каталоге, что и нlр-файл, - после этого содержание станет доступно в момент запуска нlр-файла или с помощью кнопки содержание окна справочной службы.
Сообщение об ошибке вызова раздела
Рисунок 21.10. Сообщение об ошибке вызова раздела
Стандартное окно компонента TColorDialog
Рисунок 18.41 . Стандартное окно компонента TColorDialog
Стандартное окно компонента TFindDialog
Рисунок 18.43 . Стандартное окно компонента TFindDialog
Его значения имеют следующий смысл:
| frDown frFindNext | Устанавливает поиск вперед по тексту |
| frHideMatchCase | Сообщает программе, что пользователь нажал кнопку Найти далее Убирает выбор в переключателе с учетом регистра |
| frHideWholeWord | Убирает выбор в переключателе только слово целиком |
| frHideUpDown | Прячет кнопки выбора направления поиска |
| frMatchCase | Устанавливает выбор в переключателе с учетом регистра |
| frDisableMatchCase | Запрещает выбор С учетом регистра |
| frDisableUpDown | Запрещает выбор направления поиска |
| frDisableWholeWord | Запрещает выбор только слово целиком |
| frReplace | Используется в компоненте TReplacteDialog и указывает на необходимость замены текущего выбора |
| frReplaceAll | Используется в компоненте TreplaceDialog и указывает на необходимость замены всех вхождений образца поиска |
| frWholeWord | Устанавливает выбор в переключателе Только слово целиком. |
| frShowHelp | Включает в окно кнопку Help |
TNotifyEvent, которое возникает всякий раз, когда пользователь нажимает кнопку найти далее. Обработчик события должен найти образец в тексте и показать его пользователю. Пусть, например, компонент Memol содержит отыскиваемый фрагмент и поиск идет с учетом регистра. Тогда обработчик может иметь такой вид:
procedure TFor.gif" >
Стандартное окно компонента TPrintDialog
Рисунок 18.42. Стандартное окно компонента TPrintDialog
Свойства компонента:
| property Collate: Boolean; | Если имеет значение True, окно показывается с выбранным переключателем разобрать (collate). Если этот переключатель выбран, печать нескольких копии документа будет идти по копиям: сначала первая копия, затем вторая и т. д., в противном случае - по страницам: сначала все копии первой страницы, затем второй и т. д |
| property Copies: Integer; | Определяет количество копии (0 - одна копия) |
| property FromPage: Integer | Определяет начальную страницу печати |
| property MaxPage: Integers; | Определяет верхнюю границу диапазона страниц для свойств FromPage, ToPage |
| property MinPage: Integer; | Определяет нижнюю границу диапазона страниц для свойств FromPage, ToPage |
| TPrintDialogOption =
(poPrintToFile, poPageNums, poSe- lection, poWarning, poHelp, poDisablePrintToFile) ; TPrintDialogOptions = set of TPrintDialogOption; property Options: TPrintDialogOptions; |
Определяет настройку окна: poPrintToFile - печатать в файл; poPrintToFile - разрешает выбор диапазона страниц; poSelection - разрешает печать выбранного текста; poWarning - предупреждать пользователя о неустановленном принтере; poHelp вставить в окно кнопку Help; poDisablePrintToFile - запрещает печать в файл |
| TPrintRange = (prAllPages, prSelection, prPageNums) ;
property PrintRange: TPrintRange; |
Определяет диапазон печатаемых страниц: prAllPages - все страницы; preelection - выделенный фрагмент текста; prPageNums - страницы по номерам |
| property PrintToFile: Boolean; | Содержит True, если пользователь выбрал печать в файл |
| property ToPage: Integer; | Определяет конечную страницу печати |
Стандартное окно компонента TReplaceDialog
Рисунок 18.44 . Стандартное окно компонента TReplaceDialog
Класс TReplaceDialog является прямым потомком класса TFindDialog и наследует от него большинство свойств. Дополнительно в компоненте определено свойство RepiaceText: string, в котором содержится текст замены, и событие OnRepiace, которое возникает
При нажатии кнопки заменить или з аменить все.
Стандартное окно TFontDialog
Рисунок 18.40. Стандартное окно TFontDialog
Диапазон возможных значений размеров шрифтов определяется свойствами MinFontSize и MaxFontSize. Значения этих свойств задаются в пунктах (1 пункт равен1/72 дюйма, что приблизительно равно 0,36 мм). Если свойства содержат 0, ограничения на размер шрифта отсутствуют.
Свойство
TFontDialogOption = (fdAnsiOnly, fdTrueTypeOnly, fdEffects, fdFixedPitchOnly, fdFor.gif" >
Стандартное окно TOpenDialog
Рисунок 18.38 . Стандартное окно TOpenDialog
Свойство Filter: string используется для фильтрации (отбора) файлов, показываемых в диалоговом окне. Это свойство можно устанавливать с помощью специального редактора на этапе конструирования формы или программно, как это сделано в предыдущем примере. Для доступа к редактору достаточно щелкнуть по кнопке в строке Filter окна Инспектора объектов. При программном вводе фильтры задаются одной длинной строкой, в которой символы “|” служат для разделения фильтров друг от друга, а также для разделения описания фильтруемых файлов от соответствующей маски выбора. Например, оператор
OpenDialogI.Filter := 'Текстовые файлы|*.txt| Файлы Паскаля|*.раs';
задает две маски - для отбора файлов с расширениями раs и TXT.
Установить начальный каталог позволяет свойство InitialDir string. Например:
OpenDialogI.InitiaiDir := 'c:\program files\borland\delphi5\source';
С помощью свойства DefaultExt: String [ 3 ] формируется полное имя файла, если при ручном вводе пользователь не указал расширение. В этом случае к имени файла прибавляется разделительная точка и содержимое этого свойства.
В диалоговом окне для ручного ввода предусмотрен элемент TEdit, который при желании можно заменить на TCоmbовох. Для этого необходимо свойству FileEditStyle придать значение fsComboBox вместо умалчиваемого fsEdit. Если выбран комбинированный список, с ним можно связать протокол выбора имен. Для этого используется свойство HistoryList: TStrings, содержимое которого будет появляться в выпадающем списке. Этот список не пополняется автоматически, поэтому за его содержимым должна следить программа. Например:
if OpenDialogI.Execute then
begin
HistoryList.Add(OpenDialogI.FileName);
end;
Настройка диалога может варьироваться с помощью свойства
TOpenOption = (ofReadOnly, ofOverwritePrompt, ofHideReadOnly, ofNoChangeDir, ofShowHelp, ofNoValidate, ofAllowMultiSelect, ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofCre-atePrompt, ofShareAware, ofNoReadOnlyReturn, ofNoTestFileCre-ate, ofNoNetworkButton, ofNoLongNames, ofOldStyleDialog, of-NoDereferenceLinks) ;
TOpenOptions = set of TOpenOption;
property Options: TOpenOptions;
Значения этого свойства имеют следующий смысл:
| ofReadOnly | Устанавливает переключатель Только для чтения |
| ofOverwritePrompt | Требует согласия пользователя при записи в существующий файл |
| ofHideReadOnly | Прячет переключатель Только для чтения |
| OfNoChangeDir | Запрещает смену каталога |
| ofShowHelp | Включает в окно кнопку Help |
| ofNoValidate | Запрещает автоматическую проверку правильности набираемых в имени файла символов |
| OfAllowMultiSelect | Разрешает множественный выбор файлов |
| ofExtensionDifferent | При завершении диалога наличие этого значения в свойстве options говорит о том, что пользователь ввел расширение, отличающееся от умалчиваемого |
| ofPathMustExist | Разрешает указывать файлы только из существующих каталогов |
| ofFileMustExist | Разрешает указывать только существующие файлы |
| ofCreatePrompt | Требует подтверждения для создания несуществующего файла |
| ofShareAware | Разрешает выбирать файлы, используемые другими параллельно выполняемыми программами |
| OfNoReadOnlyReturn | Запрещает выбор файлов, имеющих атрибут Только для чтения |
| ofNoTestFileCreate | Запрещает проверку доступности сетевого или локального диска |
| OfNoNetworkButton | Запрещает вставку кнопки для создания сетевого диска |
| ofNoLongNames | Запрещает использование длинных имен файлов |
| ofOldStyleDialog | Создает диалог в стиле Windows 3-х |
| Назад |
Стандартное окно TopenPictureDialog
Рисунок 18.39. Стандартное окно TopenPictureDialog
Стандартные курсоры Delphi
Рисунок 17.2. Стандартные курсоры Delphi
В практике программирования часто возникает необходимость изменения формы указателя для всех окон программы. Например, при выполнении достаточно длительного по времени процесса указатель мыши часто принимает вид crHourGlass, а после завершения процесса - восстанавливает свой первоначальный вид. Чтобы изменить форму указателя для всех окон программы одновременно, используется свойство cursor у глобального объекта screen, который автоматически создается для каждой программы:
Screen.Cursor := crHourGiass;
..... //Делаем длительную работу
Screen.Cursor := crDefault; // Восстанавливаем начальную
// форму указателя
Программист может создать и использовать нестандартный указатель. При этом он должен:
Структура типов данных
Рисунок 7.1. Структура типов данных
Для целых типов функция ord(x) возвращает само значение х, т. е. Ord(X) = х для х, принадлежащего любому целому типу. Применение Ord(x) к логическому, символьному и перечисляемому типам дает положительное целое число в диапазоне от 0 до 1 (логический тип), от 0 до 255 (символьный), от 0 до 65535 (перечисляемый). Тип-диапазон сохраняет все свойства базового порядкового типа, поэтому результат применения к нему функции ord(X) зависит от свойств этого типа.
К порядковым типам можно также применять функции:
pred(x) - возвращает предыдущее значение порядкового типа (значение, которое соответствует порядковому номеру
ord (X) -1), т. е. Ord(Pred(X)) = Ord(X) - 1;
succ (X) - возвращает следующее значение порядкового типа, которое соответствует порядковому номеру ord (X) +1, т. е.
Ord(Succ(X)) = Ord(X) + 1.
Например, если в программе определена переменная
var
с : Char;
begin
с := '5';
end;
то функция PRED(C) вернет символ '4', а функция SUCC(C) - символ '6'.
Если представить себе любой порядковый тип как упорядоченное множество значений, возрастающих слева направо и занимающих на числовой оси некоторый отрезок, то функция pred(x) не определена для левого, a succ (X) - для правого конца этого отрезка.
Целые типы. Диапазон возможных значений целых типов зависит от их внутреннего представления, которое может занимать один, два, четыре или восемь байтов. В табл. 7.1 приводятся названия целых типов, длина их внутреннего представления в байтах и диапазон возможных значений. Таблица 7.1. Целые типы
| Название | Длина,байт | Диапазон значений |
| Cardinal | 4 | 0. .. 2 147 483 647 |
| Byte | 1 | 0...255 |
| Shortint | 1 | -128...+127 |
| Smallint | 2 | -32 768...+32 767 |
| Word | 2 | 0...65 535 |
| Integer | 4 | -2 147 483 648...+2 147 483 647 |
| Longint | 4 | -2 147 483 648...+2 147 483 647 |
| Int64 | 8 | -9*10 18 . ..+9*10 18 |
| LongWord | 4 | 0. . .4 294 967 295 |
Примечание
Типы LongWord и Int64 впервые введены в версии 4, а типы Smallint и Cardinal отсутствуют в Delphi 1. Тип integer для этой версии занимает 2 байта и имеет диапазон значений от -32768 до +32767, т. е. совпадает с Smallint.
При использовании процедур и функций с целочисленными параметрами следует руководствоваться “вложенностью” типов, т. е. везде, где может использоваться word, допускается использование Byte (но не наоборот), в Longint “входит” Smallint, который, в свою очередь, включает в себя Shortint.
Перечень процедур и функций, применимых к целочисленным типам, приведен в табл. 7.2. Буквами b, s, w, i, l обозначены выражения соответственно типа Byte, Shortint, Word, Integer И Longint,
х - выражение любого из этих типов; буквы vb, vs, vw, vi, vl, vx обозначают переменные соответствующих типов. В квадратных скобках указывается необязательный параметр.
Таблица 7.2. Стандартные процедуры и функции, применимые к целым типам
| Обращение | Тип результата | Действие |
| abs (x) | x | Возвращает модуль x |
| chr(b) | Char | Возвращает символ по его коду |
| dec (vx [, i] ) | - | Уменьшает значение vx на i, а при отсутствии i - на 1 |
| inc(vx[,i]) | - | Увеличивает значение vx на i, а при отсутствии i -на 1 |
| Hi(w) | Byte | Возвращает старший бант аргумента |
| Hi(I) | То же | Возвращает третий по счету байт |
| Lo(i) | “ | Возвращает младший байт аргумента |
| Lo(w) | “ | То же |
| odd(l) | Boolean | Возвращает True, если аргумент-нечетное число |
| Random(w) | Как у параметра | Возвращает псевдослучайное число, равномерно распределенное в диапазоне 0...(w-l) |
| sqr(x) | X | Возвращает квадрат аргумента |
| swap(i) | Integer | Меняет местами байты в слове |
| swap (w) | Word | Тоже |
Например, при прогоне следующей программы на экране появится значение 0:
procedure TfmExample.bbRunClick(Sender: TObject) ;
var
k: Word;
begin
k := 65535; // Максимальное значение типа Word
k := k+1; // По правилам математики
k=65536 IbOutput.Caption := IntToStr(k); // На самом деле k=0!
end;
Если активизировать переключатель project | options | Compiler I Range checking и повторить компиляцию с помощью Project | Build All, компилятор вставит в программу код проверки переполнения и при прогоне программы возникнет исключительная ситуация, которую при желании можно соответствующим образом обработать. Замечу, что, если изменить программу следующим образом:
k := 65535; // Максимальное значение типа Word
IbOutput.Caption := IntToStr(k + 1);// Будет выведено 65536
переполнения не произойдет, т. к. 32-разрядный компилятор версий Delphi 32 автоматически преобразует операнды выражения k+i к 4-байтным величинам.
Логические типы. К логическим относятся типы Boolean, ByteBool, Bool, wordBool и LongBool. В стандартном Паскале определен только тип Boolean, остальные логические типы введены в Object Pascal для совместимости с Windows: типы Boolean и ByteBool занимают по одному байту каждый, Bool и WordBool - по 2 байта, LongBool - 4 байта. Значениями логического типа может быть одна из предварительно объявленных констант False (ложь) или True (истина). Для них справедливы правила:
Ord(False) = 0;
Ord(True) <> 0;
Succ(False)= True;
Pred(True) = False.
Поскольку логический тип относится к порядковым типам, его можно использовать в операторе цикла счетного типа, например:
var
l : Boolean;
begin
for l := False to True do ....
Однако необходимо помнить, что в Delphi 32 для Boolean значение
Ord (True) = +1, В ТО Время как для других типов (Bool, WordBool И Т.Д.)
Ord (True) = -1, поэтому такого рода операторы следует использовать с осторожностью!. Например, для версии Delphi 6 исполняемый оператор showMessage (' --- ') в следующем цикле for не будет выполнен ни разу:
var
L: Bool;
k: Integer;
begin
for L := False to True do ShowMessage ('--);
end; __
Если заменить тип параметра цикла l в предыдущем примере на Boolean, цикл будет работать и сообщение дважды появится на экране.[ Для Delphi версии 1 и 2 ord (True) =+1 для любого логического типа. ]
Символьный тип. Значениями символьного типа является множество всех символов ПК. Каждому символу приписывается целое число в диапазоне О...255. Это число служит кодом внутреннего представления символа, его возвращает функция ord.
Для кодировки в Windows используется код ANSI (назван по имени American National Standard Institute - американского института стандартизации, предложившего этот код). Первая половина символов ПК с кодами 0... 127 соответствует таблице 7.3. Вторая половина символов с кодами 128...255 меняется для различных шрифтов. Стандартные Windows-шрифты Arial Cyr, Courier New Cyr и Times New Roman для представления символов кириллицы (без букв “ё” и “Ё”) используют последние 64 кода (от 192 до 256): “А”... “Я” кодируются значениями 192..223, “а”... “я” - 224...255. Символы “Ё” и “ё” имеют соответственно коды 168 и 184.
Таблица 7.3. Кодировка символов в соответствии со стандартом ANSI
| Код | Символ | Код. | Символ | Код. | Символ | Код | Символ |
| 0 | NUL | 32 | BL | 64 | @ | 96 | ' |
| 1 | ЗОН | 33 | ! | 65 | А | 97 | а |
| 2 | STX | 34 | “ | 66 | В | 98 | b |
| 3 | ЕТХ | 35 | # | 67 | С | 99 | с |
| 4 | EOT | 36 | $ | 68 | D | 100 | d |
| 5 | ENQ | 37 | % | 69 | Е | 101 | е |
| 6 | ACK | 38 | & | 70 | F | 102 | f |
| 7 | BEL | 39 | ' | 71 | G | 103 | д |
| 8' | BS | 40 | ( | 72 | Н | 104 | h |
| 9 | HT | 41 | ) | 73 | I | 105 | i |
| 10 | LF | 42 | * | 74 | J | 106 | j |
| 11 | VT | 43 | + | 75 | К | 107 | k |
| 12 | FF | 44 | f | 76 | L | 108 | 1 |
| 13 | CR | 45 | - | 77 | М | 109 | m |
| 14 | SO | 46 | 78 | N | 110 | n | |
| 15 | SI | 47 | / | 79 | 0 | 111 | о |
| 16 | DEL | 48 | 0 | 80 | Р | 112 | P |
| 17 | DC1 | 49 | 1 | 81 | Q | 113 | q |
| 18 | DC2 | 50 | 2 | 82 | R | 114 | r |
| 19 | DC3 | 51 | 3 | 83 | S | 115 | s |
| 20 | DC 4 | 52 | 4 | 84 | Т | 116 | t |
| 21 | NAK | 53 | 5 | 85 | U | 117 | u |
| 22 | SYN | 54 | 6 | 86 | V | 118 | v |
| 23 | ETB | 55 | 7 | 87 | W | 119 | W |
| 24 | CAN | 56 | 8 | 88 | х | 120 | x |
| 25 | EM | 57 | 9 | 89 | Y | 121 | У |
| 26 | SUB | 58 | : | 90 | Z | .122 | z |
| 27 | ESC | 59 | ; | 91 | t | 123 | { |
| 28 | FS | 60 | < | 92 | \ | 124 | 1 |
| 29 | GS | 61 | = | 93 | ] | 125 | } |
| 30 | RS | 62 | > | 94 | Л | 126 | ~ |
| 31 | US | 63 | f | 95 | 127 | r |
К типу char применимы операции отношения, а также встроенные функции:
Сhr (в) - функция типа char; преобразует выражение в типа Byte в символ и возвращает его своим значением;
UpCase(CH) - функция типа char; возвращает прописную букву, если сн - строчная латинская буква, в противном случае возвращает сам символ сн (для кириллицы возвращает исходный символ).
Перечисляемый тип. Перечисляемый тип задается перечислением тех значений, которые он может получать. Каждое значение именуется некоторым идентификатором и располагается в списке, обрамленном круглыми скобками, например:
type
colors = (red, white, blue);
Применение перечисляемых типов делает программы нагляднее. Если, например, в программе используются данные, связанные с месяцами года, то такой фрагмент программы:
type
ТипМесяц=(янв,фев,мар,апр,май,июн,июл,авг,сен,окт,ноя,дек);
var
месяц : ТипМесяц;
begin
if месяц = авг then
IbOutput.Caption := 'Хорошо бы поехать к морю!';
end.
был бы, согласитесь, очень наглядным. Увы! В Object Pascal нельзя использовать кириллицу в идентификаторах, поэтому мы вынуждены писать так:
type
TypeMonth=(jan,feb,mar,may,jun,jul,aug,sep,oct,nov,dec);
var
month: TypeMonth;
begin
if month = aug then
IbOutput.Caption := 'Хорошо бы поехать к морю!';
end.
Соответствие между значениями перечисляемого типа и порядковыми номерами этих значений устанавливается порядком перечисления: первое значение в списке получает порядковый номер О, второе - 1 и т. д. Максимальная мощность перечисляемого типа составляет 65536 значений, поэтому фактически перечисляемый тип задает некоторое подмножество целого типа word и может рассматриваться как компактное объявление сразу группы целочисленных констант со значениями 0, 1 и т. д.
Использование перечисляемых типов повышает надежность программ благодаря возможности контроля тех значений, которые получают соответствующие переменные. Пусть, например, заданы такие перечисляемые типы:
type
colors = (black, red, white);
ordenal= (one, two, three) ;
days = (Monday, Tuesday, Wednesday);
С точки зрения мощности и внутреннего представления все три типа эквивалентны:
Ord(black)=0, ... , Ord(white)=2,
Ord(one)=0, ... , Ord(three)=2,
Ord(Monday)=0, ... , Ord(Wednesday)=2.
Однако если определены переменные
var
col : colors;
num : ordenal;
day : days ;
то допустимы операторы
col := black;
num := Succ(two);
day := Pred(Tuesday);
но недопустимы
col := one;
day := black;
Как уже упоминалось, между значениями перечисляемого типа и множеством целых чисел существует однозначное соответствие, задаваемое функцией Ord(X). В Object Pascal допускается и обратное преобразование: любое выражение типа Word можно преобразовать в значение перечисляемого типа, если только значение целочисленного выражения не превышает мощности этого типа. Такое преобразование достигается применением автоматически объявляемой функции с'именем перечисляемого типа. Например, для рассмотренного выше объявления типов эквивалентны следующие присваивания:
col := black;
col := colors (0) ;
Разумеется, присваивание
col := 0;
будет недопустимым, т. к. перечисляемому типу нельзя присвоить целое значение.
Переменные любого перечисляемого типа можно объявлять без предварительного описания этого типа, например:
var
col: (black, white, green);
Тип-диапазон. Тип-диапазон есть подмножество своего базового типа, в качестве которого может выступать любой порядковый тип, кроме типа-диапазона.
Тип-диапазон задается границами своих значений внутри базового типа:
<мин.знач.>..<макс.знач.>
Здесь <мин. знач. > - минимальное значение типа-диапазона; <макс. знач. > - максимальное его значение.
Например:
type
digit = '0'..'9';
dig2 = 48 .. 57;
Тип-диапазон не обязательно описывать в разделе type, а можно указывать непосредственно при объявлении переменной, например:
var
date : 1. .31;
month: 1..12;
Ichr : 'А'..'Z';
При определении типа-диапазона нужно руководствоваться следующими правилами:
type
days = (то,tu,we,th,fr,sa,su);
WeekEnd = sa .. su;
var
w : WeekEnd;
begin
w := sa;
end;
to ord(w) вернет значение 5, в то время как pred(W) приведет к ошибке.
В стандартную библиотеку Object Pascal включены две функции, поддерживающие работу с типами-диапазонами:
High(X) - возвращает максимальное значение типа-диапазона, к которому принадлежит переменная х;
Low (X) - возвращает минимальное значение типа-диапазона.
Свойства компонента bbRun
Рисунок 11.2. Свойства компонента bbRunСвойства компонента
Свойства компонента:
| property AutoComplete: Boolean; | Определяет, будет ли компонент автоматически получать фокус ввода при нажатии пользователем на клавиатуру |
| type TBorderStyle = bsNone..-bsSingle; property Border-Style: TBorderStyle; | Определяет стиль рамки: bsNone - нет рамки; bssingle - рамка толщиной 1 пиксель |
| property Canvas: TCanvas; property Columns: Longing; | Канва для программной прорисовки элементов Определяет количество колонок элементов в списке |
| property Count: Integer; | Содержит количество строк в компоненте |
| property ExtendedSelect: Boolean; | Если ExtendedSelect =True и MultiSelect==True, выбор элемента без одновременного нажатия Crtl или Alt отменяет предыдущий выбор |
| property IntegralHeight:Boolean; | Если IntegralHeight=True и Style<>lb0wner-DrawVariabe, в списке показывается целое число элементов |
| property ItemHeight: Integer; | Определяет высоту элемента в пикселях для Style=lbOwnerDrawFixed |
| property Itemlndex: Integer; | Содержит индекс сфокусированного элемента. Если MultiSelect=False, совпадает с индексом выделенного элемента |
| property Items: TStrings; | Содержит набор строк, показываемых в компоненте |
| property MultiSelect: Boolean; | Разрешает/отменяет выбор нескольких элементов |
| property SelCount: Integer; | Содержит количество выбранных элементов |
| property Selected[X: Integer] : Boolean; | Содержит признак выбора для элемента с индексом х (первый элемент имеет индекс 0) |
| property Sorted: Boolean; | Разрешает/отменяет сортировку строк в алфавитном порядке |
| type TListBoxStyle =
(IbStandard, IbOwnerDrawFixed, IbOwnerDrawVariable) ; property Style: TListBoxStyle; |
Определяет способ прорисовки элементов:
IbStandard - элементы рисует Windows; ibOwnerDrawFixed - рисует программа, все элементы имеют одинаковую высоту, определяемую свойством ItemHeight;IbOwnerDrawVariable -рисует программа, элементы имеют разную высоту |
| property TabWidth: Integer; | Задает ширину табуляционного пробела |
| property Toplndex: Integer; | Индекс первого видимого в окне элемента |
Для компонента определены два события, связанные с программной прорисовкой элементов списка:
type
TOwnerDrawState = set of (odSelecred, odGrayed, odDisabied, odChecked, odFocused) ;
TDrawItemEvent = procedure(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState) of object-property OnDrawItem: TDrawItemEvent;
type
TMeasureItemEvent = procedure(Control: TWinControl; Integer;
var Height: Integer) of object/property OnMeasureItem: TMeasureItemEvent;
Первое событие возникает в момент, когда программа должна нарисовать очередной элемент. Обработчик события получает ссылку на список выбора control, индекс изображаемого элемента index, границы элемента Rect и его состояние State. Прорисовка ведется с помощью свойства Canvas.
Примечание
Примечание
Поскольку программная прорисовка обычно связана с изображением рисунков, сохраняемых вместе с текстом в наборе Items; параметр Control задан как абстрактный объект TWinGontrol, поэтому в обработчике должно проводиться необходимое преобразование типов.
В следующем примере в каждом элементе рисуется растровое изображение и текст.
procedure TFor.gif" >
Определяет рамку компонента: bsNone нет
Свойства компонента:| property BorderStyle: TBorderStyle; | Определяет рамку компонента: bsNone нет рамки; bsSingle - рамка толщиной 1 пиксель |
| property Cells[ACol, ARow: Integer] :String; | Определяет содержимое ячейки с табличными координатами (ACol, ARow) |
| property Col: Longint; | Содержит номер столбца сфокусированной ячейки |
| property ColCount: Longing- | Содержит количество столбцов таблицы |
| property Cols[Index: Integer]:
TStrings; |
Содержит все строки колонки с индексом Index |
| property ColWidths[Index: Longint] : Integer; | Содержит ширину столбца с индексом Index |
| property DefaultColWidth: Integers; | Содержит умалчиваемое значение ширины столбца |
| property DefaultDrawing: Boolean; | Разрешает/запрещает автоматическую прорисовку служебных элементов таблицы - фиксированной зоны, фона и прямоугольника сфокусированной ячейки и
т. п. |
| property DefaultRowHeight: Integers; | Содержит умалчиваемую высоту рядов |
| property EditorMode: Boolean; | Разрешает/запрещает редактирование ячеек. гнорируется, если свойство Options включает goAlwayseShowEditor или не включает goEditing |
| property FixedColor: TColor; | Определяет цвет фиксированной зоны |
| property FixedCois: Integers; | Определяет количество столбцов фиксированной зоны |
| property FixedRows: Integers; | Определяет количество рядов фиксированной зоны |
| property GridHeight: Integers; | Содержит высоту таблицы |
| property GridLineWidth: Integers; | Определяет толщину линий, расчерчивающих таблицу |
| property GridWidth: Integers; | Содержит ширину таблицы |
| property LeftCol: Longint; | Содержит номер самого левого столбца, видимого в зоне прокрутки |
| property Objects [ACols ARow: Integer] : TObject; | Обеспечивает доступ к объекту, связанному с ячейкой (ACol, ARow) |
| property Options: TGridOptions; | Содержит параметры таблицы (см. ниже) |
| property Row: Longing; | Содержит номер ряда сфокусированной ячейки |
| property RowCount: Longint; | Содержит количество рядов таблицы |
| property RowHeights[Index: Long int] : Integer; | Содержит высоту ряда с индексом index |
| property Rows[Index: Integer]: TStrings; | Содержит все строки ряда с индексом
Index |
| type TScrollStyle = (ssNone,
ssHorizontal, ssVertical, ssBoth) ; |
Определяет полосы прокрутки: ssNone -нет полос; ssHorizontal - в таблицу вставляется горизонтальная полоса; |
| property ScrollBars: TScroll
Style; |
ssVertical - вставляется вертикальная
полоса; ssBoth - вставляются обе полосы |
| TGridRect = record
case Integer of 0: (Left,Top,Right,Bottom: Long int) ; 1: (TopLeft, BottomRight: TGridCoord) ; end; |
Определяет группу выделенных ячеек в
координатах левая верхняя и правая нижняя ячейки(нумерация столбцов и рядов идет от нуля, включая столбцы и ряды фиксированной зоны). После выделения сфокусированной окажется правая нижняя ячейка |
| property Selection: TGridRect;
property TabStops[Index: Long int] : Boolean; |
Разрешает/запрещает выбирать столбец с индексом index при обходе ячеек клавишей Tab. Игнорируется, если Options не содержит goTabs |
| property TopRow: Longint; | Содержит номер самого верхнего ряда, видимого в прокручиваемой зоне ячеек |
| property VisibleColCount: Integer; | Содержит количество столбцов, полностью видимых в зоне прокрутки |
| property VisibleRowCount: Integer; | Содержит количество рядов, полностью видимых в зоне прокрутки |
type
TGridOption = (goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goRowSizing, goColSizing, goRowMoving, goColMoving, goEditing, goTabs, goRowSelect, goAlwaysShowEditor, goThumbTracking);
TGridOptions = set of TGridOptions;
Элементы множества TGridOptions имеют следующий смысл:
| goFixedVertLine | Столбцы фиксированной зоны разделяются вертикальными линиями |
| goFixedHorzLine | Ряды фиксированной зоны разделяются горизонтальными линиями |
| goVertLine | Столбцы рабочей зоны разделяются вертикальными линиями |
| goHorzLine | Ряды рабочей зоны разделяются горизонтальными линиями |
| goRangeSelect | Разрешено выделение нескольких ячеек. Игнорируется, если включен элемент goEdit |
| goDrawFocus Selected | Разрешено выделять сфокусированную ячейку так же, как выделенные |
| goRowSizing goColSizing goRowMoviog | Разрешено ручное (мышью) изменение высоты строк Разрешено ручное изменение ширины рядов Разрешено ручное перемещение рядов (нажать левую кнопку мыши на фиксированной ячейке перемещаемого ряда и, удерживая кнопку нажатой, переместить ряд на новое место) |
| goColMoving goEditing | Разрешено ручное перемещение столбца Разрешено редактирование ячейки. Игнорируется, если включен элемент goRowSelect. Редактирование начинается после щелчка мыши или нажатия клавиши F2 и завершается при щелчке по другой ячейке или нажатии клавиши Enter |
| goTabs goRowSelect | Разрешено обходить ячейки клавишей Tab (Shift+Tab) Обязывает выделять сразу все ячейки ряда и запрещает редактирование ячеек Разрешено редактировать сфокусированную ячейку: редактирование возможно после выбора ячейки клавишей Tab (Shift+Tab). Игнорируется, если не включен элемент goEditing |
| goAlwaysShowEditorgoThumbTracking | Разрешено обновление при прокрутке. Если этот элемент отсутствует, обновление ячеек произойдет только после окончания прокрутки |
| function CellRect(ACol, ARow: TRect; Longint): | Возвращает прямоугольник ячейки по номерам столбца ACol и ряда Arow |
| procedure MouseToCell(X, Y: Integer; var ACol, ARow: Longint); | Возвращает табличные координаты ячейки ACol и arow по экранным координатам(X,У)точки |
| TMovedEvent = procedure (Sender: TObject; Fromlndex, Tolndex: Longint) of object; property OnColumnMoved: TMovedEvent; TDrawCellEvent; | Возникает при перемещении столбца с индексом Fromlndex в положение, определяемое индексом ToIndex |
| TGridDrawState = set of (gdSelected, gdFocused, gdFixed) ; TDrawCellEvent = procedure (Sender: TObject; Col, Row: Longint; Rect: TRect; State: TGridDrawState) of object-property OnDrawCell: | Возникает при необходимости перерисовать ячейку с табличными координатами (Col, Row): Rect - прямоугольник прорисовки; State - состояние ячейки (gdSelected -ячейка выделена; gdFocused - ячейка сфокусирована; gdFixed - ячейка принадлежит фиксированной зоне таблицы). Для прорисовки используется табличное свойство Canvas |
| GetEditEvent = procedure
(Sender: TObject; ACol, ARow: |
Возникает при редактировании текста в
ячейке с табличными координатами |
| Longint; var Value: String) ofobject;
property OnGetEditMask: TGetE ditEvent; |
(ACol.ARow). В параметре value обработчик должен вернуть шаблон для редактора TeditMask |
| property OnGetEditText: TGetE
ditEvent; |
Возникает при редактировании текста в ячейке с табличными координатами (ACol.ARow). В параметре value обработчик должен вернуть текст для редактора TEditMask (см. событие OmGetEditMask) |
| property OnRowMoved: TMovedEvent; | Возникает при перемещении ряда с индексом Fromindex в положение, определяемое
индексом ToIndex (см. событие onColMoved) |
| SelectCellEvent = procedure (Sender: TObject; Col, Row: Long int; var CanSelect: Boolean) of object;
property OnSelectCell: TSe lectCellEvent; |
Возникает при попытке выделить ячейку с табличными координатами (col.Row). В параметре CanSelect обработчик сообщает о возможности выделения ячейки |
| TSetEditEvent = procedure
(Sender: TObject; ACol, ARow: Longint; const Value: String) of object; property OnSetEditText: TSetEditEvent; |
Возникает при завершении редактирования
ячейки (ACol.ARow). В параметре value обработчик получает результат ввода или редактирования текста |
| property OnTopLeftChanged: TNotifyEvent; | Возникает после изменения значения ТоpRow или LeftCol в результате прокрутки рабочей зоны |
в переключателях третье состояние cbGrayed
Свойства компонента:
| property AllowGrayed: Boolean; | Разрешает/запрещает использовать в переключателях третье состояние cbGrayed |
| property BorderStyle: TBorderStyle; | Определяет тип рамки, очерчивающей компонет: bsNone - нет рамки; bsSingie - рамка толщиной в 1 пиксель |
| property Canvas: TCanvas; | Это свойство используется для программной прорисовки опций |
| property Checked[Index:
Integer]: Boolean; |
Содержит выбор пользователя типа Да/Нет для переключателя с индексом index. Состояния cbUnchecked И cbGrayed отражаются как False |
| property Columns: Integers; | Определяет количество колонок опций |
| property Flat: Boolean; | Разрешает/запрещает трехмерную прорисовку окошек выбора |
| property Header[Index: Integer] : Boolean; | Запрещает прорисовку окошка выбора для опции с индексом index. Таким образом вставляются заголовки отдельных секций |
| property HeaderBack.gif" > |
Учебная программа INTMULT
Учебная программа INTMULTВ описываемой ниже программе пользователь вводит два целых числа, а программа вычисляет и показывает их произведение. В этой программе мы также познакомимся с преобразованием типов. На Рисунок 5.5. показан вид окна работающей программы.[ В версии Delphi 1 тип Integer занимает 2 байта и содержит число в диапазоне от -32 768 до +32 767. ]
Управление календарем с помощью TTabControl
Рисунок 18.22. Управление календарем с помощью TTabControl
Помимо события OnChange, возникающего после выбора новой закладки, для компонента определено также событие OnChanging, которое возникает перед сменой закладки:
type TTabChangingEvent =
procedure (Sender: TObject;
var AllowChange: Boolean) of object;
property OnChanging: TTabChangingEvent;
Обработчик события может запретить выбор закладки, вернув в параметре Alliowchange значение False.
Вид окна CollBar
Рисунок 18.33. Вид окна CollBar
Свойства TCoolBand:
| property Bitmap: TBitmap; | Определяет изображение, которое будет циклически повторяться по всему пространству полосы |
| property BorderStyle: TBorder-Style; | Определяет наличие рамки у полосы: bsNone - нет рамки; bssingle - рамка толщиной в 1 пиксель |
| property Break: Boolean; | Если содержит True, полоса располагается в новой строке, в противном случае - в той же строке, что и предыдущая полоса |
| property Control: TWinControl; | Указывает элемент, который содержит полоса |
| property FixedBack.gif" > |
Видеоклипы свойства Соmmоn АVI
Рисунок 18.25 . Видеоклипы свойства Соmmоn АVIМетоды компонента:
| procedure Play(FromFrame, ToFrame: Word; Count: Integer); | Демонстрирует Count раз подряд фрагмент клипа, начиная с кадра FromFrame по ToFrame включительно (нумерация кадров начинается с 1) |
| procedure Reset;
procedure Seek(Frame: Smallint) ; procedure Stop; |
Восстанавливает исходное состояние компонента. Свойство Open вновь становится True, но свойство Active = False Пропускает и не показывает кадр с номером Frame (нумерация кадров начинается с 1) Прекращает показ клипа |
| Для компонента определены следующие события: | |
| property OnClose: TNotifyEvent;
property OnOpen: TNoti-fyEvent; property OnStart: TNoti-fyEvent; property OnStop: TNotifyEvent; |
Возникает при установке значения False в свойство Open. Например, когда компонент демонстрирует несколько видеоклипов подряд Возникает при установке значения True в свойство Open Возникает в момент начала демонстрации
Возникает в момент прекращения демонстрации |
Возможные виды графиков компонента TChart
Рисунок 18.19. Возможные виды графиков компонента TChart
Компонент впервые появился в версии 3.
Вставки названия раздела
Рисунок 21.4. Вставки названия раздела
Взаимодействие вызывающей программы и процедуры
Рисунок 5.8. Взаимодействие вызывающей программы и процедуры
С примерами процедур и функций мы уже сталкивались - это
Стандартные процедуры Exit, ShowMessage, функции StrToInt, FioatToStr, Random, математические функции и др. Стандартными они называются потому, что созданы одновременно с системой Delphi и являются ее неотъемлемой частью. В Delphi имеется много стандартных процедур и функций. Наличие богатой библиотеки таких программных заготовок существенно облегчает разработку прикладных программ. Однако в большинстве случаев некоторые специфичные для данной прикладной программы действия не находят прямых аналогов в библиотеках Delphi, и тогда программисту приходится разрабатывать свои, нестандартные процедуры и функции.
Нестандартную подпрограмму необходимо описать, чтобы компилятор смог установить связь между оператором вызова и теми действиями, которые предусмотрены в подпрограмме. Описание подпрограммы помещается в разделе описаний (до начала исполняемых операторов).
Учебная программа UPSTRING
Не вдаваясь в дальнейшие подробности, попробуем составить собственную процедуру, чтобы пояснить сказанное. Пусть в этой процедуре преобразуется некоторая символьная строка таким образом, чтобы все строчные буквы заменялись соответствующими прописными. В Object Pascal имеется стандартная функция upcase (см. гл. 6), которая выполняет аналогичные действия над одиночным символом. Наша процедура (назовем ее upString) будет преобразовывать сразу все символы строки, причем сделаем ее пригодной не только для латинских букв, но и для букв русского алфавита[ В Delphi имеется стандартная функция AnsiUpperCase, реализующая те же действия. ].
Разработку программы проведем в два этапа. Сначала сконструируем основную (вызывающую) часть программы. Ее действия очень просты: она должна получить входную строку из компонента edinput, преобразовать ее с помощью процедуры upString в выходную строку и поместить результат в iboutput.Text. Эти действия нетрудно запрограммировать в обработчике bbRunciick:
procedure TfmExample.bbRunClick(Sender: TObject);
procedure UpString(stinp: String; var stOut: String);
{ Эта процедура преобразует все буквы строки stinp в прописные и помещает результат в выходную строку stOut }
begin
stOut := stinp;
end; // UpString var
SI, S2: String;
begin
SI := edinput.Text; // Получаем исходную строку
UpString(SI,S2); // Преобразуем ее
IbOutput.Caption := S2; // Выводим результат
edinput.Text := '' ;
edinput.SetFocus ;
end ;
В этой программе используется замещение процедуры UpString так называемой “заглушкой”, т. е. процедурой, в которой на самом деле не осуществляется нужных нам действий, а выходная строка просто копирует входную. (Однако эта программа синтаксически абсолютно правильна, и при желании ее можно запустить на счет.) Заглушка понадобилась нам по двум причинам. Во-первых, приведенная программа очень проста, в ней отсутствует детальная реализация процедуры, и это позволяет наглядно проиллюстрировать механизм ее описания. Во-вторых, на ее примере мы знакомимся с универсальным методом конструирования сложных программ, получившим название нисходящее программирование. В соответствии с этим методом создание программы начинается “сверху”, т. е. с разработки самого главного, генерального алгоритма. На верхнем уровне обычно еще неясны детали реализации той или иной части программы, поэтому эти части следует заменить временными заглушками. Желательно, чтобы временный вариант программы был синтаксически правильным, тогда можно его откомпилировать и убедиться в отсутствии в нем синтаксических ошибок. Такой прогон даст определенную уверенность перед разработкой и реализацией алгоритмов нижнего уровня, т. е. перед заменой заглушек реально работающими процедурами. Если реализуемый в заглушке алгоритм достаточно сложен, его вновь структурируют, выделяя главный алгоритм и применяя новые заглушки, и т. д. Процесс продолжается “вниз” до тех пор, пока не будет создан полностью работоспособный вариант программы.
Как видим, описание процедуры начинается зарезервированным словом procedure, за которым следуют имя процедуры и список формальных параметров. Список параметров заключается в круглые скобки и содержит перечень параметров с указанием их типа. Заметим, что перед параметром stout, с помощью которого в вызывающую программу возвращается результат преобразования, стоит зарезервированное слово var. Именно таким способом компилятору указываются те параметры, в которых процедура возвращает вызвавшей ее программе результат своей работы (подробнее см. гл. 10). Зарезервированное слово procedure, имя процедуры и список ее параметров образуют заголовок процедуры. За заголовком следует тело процедуры, содержащее новый раздел описаний (этот раздел пока еще пуст) и раздел исполняемых операторов (оператор stout:= stInp).
Приступим к разработке алгоритма процедуры. Для этого учтем, что в соответствии с принятой в Windows кодировкой символов (так называемой ANSI-кодировкой) символы кириллицы (русского алфавита) располагаются сплошным массивом от “А” до “я”, за исключением “ё” и “Ё”, которые предшествуют “А”. Кроме того, символ “я” имеет внутренний код 255, т. е. максимально возможное значение одного байта (для каждого символа строки выделяется по одному байту).
Вот возможный вариант процедуры:
Procedure UpString(stinp: String; var stOut: String);
{ Эта процедура преобразует все буквы строки stinp в прописные и помещает результат в выходную строку stOut } var
k: Integer;// Параметр цикла
begin
stOut := stinp;
// Цикл побуквенного преобразования
for k := 1 to Length(stOut) {Length - длина строки} do
begin
stOut[k] := UpCase(stOut[k]); // Преобразуем латиницу
if stOut[k] >= 'a' then // Строчная буква кириллицы?
st0ut[k] := // Да: преобразуем ее
Chr(ord('A') + ord(st0ut[k]) - ord('a'));
if stOut[k]='e' then
stOut[k] := 'Ё'; // Преобразуем ё в Ё
end;
end; // UpString
Комментарий к программе
В процедуре вначале с помощью оператора
stOut := stinp;
исходная строка копируется в выходную строку. Затем реализуется циклический перебор всех символов выходной строки для преобразования букв. Для доступа к отдельным символам строки используется замечательное свойство типа данных string, позволяющее рассматривать строку как набор (массив) символов. Первый символ этого набора имеет индекс 1, второй - 2 и т. д. Индекс указывается сразу за именем строки в квадратных скобках. Таким образом, stOut [i] - это г-ный символ строки stOut. Перебор символов реализован в виде счетного цикла от 1 до длины входной строки stOut (эта длина получается с помощью стандартной функции Length), в ходе которого каждый символ сначала преобразуется функцией UpCase (эта функция возвращает прописную латинскую букву для строчной буквы, передаваемой ей в параметре вызова; функция не работает с кириллицей). Затем осуществляется проверка принадлежности буквы к русской строчной (оператор if st0ut[k] >= 'a' then; символ “а” - русская буква) и осуществляется необходимая коррекция ее внутреннего кода. При коррекции используются отмеченные выше свойства непрерывности и монотонности массивов кодов, т. е. за “А” идет “Б”, за “Я” - “а”, за “а” - “б” и т. д. Стандартная функция ord возвращает внутренний код символа, который передается ей в качестве параметра обращения, а функция chr преобразует код в символ. Поскольку буква “ё” стоит особняком, ее преобразование осуществляется отдельным оператором.
Рассмотрим иной способ реализации той же программы - оформим алгоритм преобразования в виде функции:
procedure TfmExample.bbRunClick(Sender: TObject) ;
Function UpString(stinp: String): String;
{ Эта функция преобразует все буквы строки stinp в прописные и помещает результат в выходную строку Result }
var
k: Integer; // Параметр цикла begin
Result := stinp;
// Цикл побуквенного преобразования
for k := 1 to Length(Result) do
begin
Result[k] := UpCase(Result[k]);// Преобразуем латиницу
if Result[k] >= 'a' then // Строчная буква кириллицы?
Result[k] := // Да: преобразуем ее
Chr(ord('A') + ord(Result[k]) - ord('a'));
if Result[k]='e' then
Result[k] := 'Ё'; // Преобразуем ё в Ё
end;
end; // UpString
begin
{ В следующем операторе исходная строка edinput.Text преобразуется и помещается в выходную строку IbOutput.Caption: }
IbOutput.Caption := UpString(edinput.Text);
edinput.Text := '';
edinput.SetFocus ;
end;
Комментарий к программе
При описании функции необходимо за списком используемых для ее вызова параметров указать тип возвращаемого ею результата. Именно поэтому за закрывающей круглой скобкой в заголовке функции стоит двоеточие и тип string. В теле любой функции определена стандартная переменная Result, которая трактуется как результат, возвращаемый функцией.
С помощью оператора
Result := stInp;
мы сначала присвоили результату входную строку, а затем в цикле осуществили перебор символов и их коррекцию. Единственный оператор
IbOutput.Caption := UpString(edInput.Text);
заменил сразу три первых оператора в предыдущей реализации программы.
Программирование: Языки - Технологии - Разработка
- Программирование
- Технологии программирования
- Разработка программ
- Работа с данными
- Методы программирования
- IDE интерфейс
- Графический интерфейс
- Программирование интерфейсов
- Отладка программ
- Тестирование программ
- Программирование на Delphi
- Программирование в ActionScript
- Assembler
- Basic
- Pascal
- Perl
- VBA
- VRML
- XML
- Ada
- Lisp
- Python
- UML
- Форт
- Языки программирования
Открывает доступ к Репозиторию Объектов. Эквивалент опции File | New | Other (этой кнопки нет в версиях 1, 2 и 3)
Открывает существующий файл. Эквивалент опции File | Open File
Сохраняет файл на диске. Эквивалент опции File | Save File (клавиши быстрого доступа Ctrl-S)
Сохраняв все файлы проекта. Эквивалент опции File | Save All
Открывает созданный ранее проект программы. Эквивалент опции File | Open Project (клавиши быстрого доступа Ctrl-F11)
Добавляет новый файл к проекту. Эквивалент опции Project | Add to project (клавиши быстрого доступа Shift-F11)
Удаляет файл из проекта. Эквивалент опции Project | Remove from Project
Выбирает модуль из списка модулей, связанных с текущим проектом. Эквивалент опции View | units (клавиши быстрого доступа Shift-F12)
Выбирает форму из списка форм, связанных с текущим проектом. Эквивалент опции View | For.gif" >
настройку для отладочного режима, эта стройка появится автоматически, как только среда перейдет в режим отладки.
btStop
btNext
btPrev
btStep
btBack.gif" >