448

Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

  • Upload
    -

  • View
    5.110

  • Download
    46

Embed Size (px)

Citation preview

Page 1: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА
Page 2: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

И. Ю. БАЖЕНОВА

Delphi 7САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal

Доступ к реляционным базам данныхКлассы палитры компонентов Delphi

BDE и InterBaseODBC и OLE DB

Работа с базами данныхСоздание отчетов в Rave Reports

Разработка SDI и MDI приложенийСОМ и CORBA

Серверы и контейнеры автоматизацииПубликация данных в Internet

КУДИ1_1-ОБРАЗМосква • 2003

Page 3: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 1

ИНТЕГРИРОВАННАЯ СРЕДАРАЗРАБОТКИ IDE

Интегрированная среда разработки IDE Delphi предоставляет средства для соз-дания, тестирования и редактирования проекта. Эта глава познакомит вас с ос-новными инструментальными средствами, такими, как менеджер проекта, ре-дактор кода, инспектор объектов, редактор меню и редактор изображений.Вы узнаете, что такое проект, из каких файлов он состоит, как его создаватьи редактировать.

ПЕРВЫЙ вход в DELPHIПри первом запуске Delphi перед вами откроются пять окон, расположенных от-дельно на рабочем столе Windows (рис. 1.1). В верхней части экрана будет распо-ложено окно, содержащее меню и панели инструментов Delphi. Оно называетсяглавным окном интегрированной среды проектирования. Строка заголовка главногоокна содержит имя приложения Delphi 7 и имя текущего проекта. Дополнительново время выполнения проекта в строку заголовка добавляется признак [Running].Под строкой меню располагается область, в которую помещаются встроенныепанели инструментов. Любая панель инструментов, однако, может находитьсякак во встроенном режиме, так и отображаться в виде отдельного окна. Переходв режим окна выполняется при двойном щелчке мыши на двойной вертикальнойл и н и и в левой части панели инструментов. Обратно, для встраивания панели вглавное окно достаточно, расположив курсор м ы ш и над заголовком окна, отбук-сировать его в место сброса над областью панелей инструментов главного окна.Первоначально в главном окне отображаются шесть панелей инструментов:Standard, View, Debug, Custom, Component Palette, Desktops. По щелчку правойкнопкой мыши в области расположения панели инструментов можно дополни-тельно отобразить панель Internet или выполнить настройку отображаемых пане-лей инструментов, добавить или удалить отдельные кнопки панелей инструментов.Панель Component Palette называется палитрой компонентов. Она содержиткнопки компонентов Delphi, тематически распределенные по 33 страницам (пре-дыдущая версия содержала 27 страниц компонентов). Более подробно содержа-ние палитры компонентов будет рассмотрено в главе «Объекты и компоненты».Компоненты используются для создания графического интерфейса пользователяразрабатываемого приложения. Они образуют так называемую библиотеку визу-альных компонентов Delphi {УСЬ-бибпиотеку).Одновременно с главным окном Delphi открываются окно проводника кода CodeExplorer совместно с окном редактора кода, окно инспектора объектов ObjectInspector, окно формы Forml и окно дерева объектов Object TreeView.

Page 4: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Глава 1

Рис. 1.1. Интегрированная среда разработки - IDE

ОКНО РЕДАКТОРА КОДАОкно редактора кода первоначально открывается состоящим из двух частей: ок-на проводника кода Code Explorer и самого окна редактора кода, содержащего двестраницы Code и Diagram. Сам редактор кода расположен па странице Code. Стра-ница Diagram окна редактора кода предоставляет визуальный инструментарийдля определения логических взаимоотношений между визуальными и невизу-альными компонентами, отображаемыми в окне Object TreeView. СтраницаDiagram может быть использована как инструментарий для документированияпроекта, так как позволяет выводить на печать схематически представленныевзаимоотношения между компонентами.

Окно кода представляет собой мощный редактор для создания и редактированиякода модулей программы. Он поддерживает такие возможности, как:

и цветовое и позиционное отображение кода модуля;

« контекстно предлагаемый набор шаблонов операторов языка программиро-вания, которые можно добавлять в код модуля;

• редактирование и добавление шаблонов предлагаемого набора операторов;

* отображение классов, функций, методов;

Page 5: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE

* вывод списка параметров функции при вводе ее имени;

* просмотр значений переменных при отладке;

* просмотр кода объявления для идентификаторов.

Различные элементы кода модуля отображаются разными цветами. В верхнейчасти окна кода расположены вкладки страниц отдельно для каждого открытогомодуля.

Для переключения между модулями достаточно только щелкнуть на вкладкес именем этого модуля.

При необходимости можно создать окно редактора кода с копией текущего мо-дуля. Для этого следует выполнить команду меню View|New Edit Window. Такоеокно содержит только одну страницу.

С помощью пункта контекстного меню Properties можно выполнять настройкупараметров окна редактора кода.

Редактор кода предоставляет набор средств Code Insight, настройку которых можнопроизвести на вкладке Code Insight (рис. 1.2), выполнив команду меню TooLs|EditorOptions или пункт контекстного меню Properties окна редактора кода.

Editor Properties *1ieneralj Souice Options j Display]

Automatic features

^r Code gmjJetion

(S TooHipiyniboljusigW_LodansigN Lolois

Abstract Syn ibol [Ц ;.ес

Cmitant Syrr^ot [• Giseri

function Symbol |B Blue

iabel Syrnbot |il teal

Procedure Syiiibol \Щ Teal

^eyMapr>ings| Cola

Delay.

1 J

G.U*c

jj Prcpsity Symbo

j IVP* Symbo

_^J Unit Syrnbo

_^J Variable Symbo

3 Eacka, .

OK С

Cods Insight j

1.5 sec

• Navy _-|

Ш f"ive _-J j

И Black -И

• Maraon ^

Q Window Bad _-J;

arccl tWp

Рис. 1.2. Настройка средств Code Insight

При вводе кода в окне редактора можно пользоваться шаблонами кода, значи-тельно упрощающими и облегчающими ввод стандартных конструкций. Длятого чтобы создать собственный шаблон или просмотреть существующие шаб-лоны кода, следует выбрать вкладку Source Option диалога Editor Properties(рис. 1.3) и щелкнуть по кнопке Edit Code Templates.

Page 6: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Глава 1

Editor Properties

General Source Options j Display j Key Mappings ] Color | Ccdelnsightj

Source file type: jpesca'i New Delete

Options—

Extensions: |pas;dpr;dpk;inc;dfm;:<Jm,dpkw

& £ulo indeiil mode

Г" Use tab ehardcter

f~ Smart lab

Г" SP'i elfill

p" Backspace unindents

Г" iieep trailing blanks

f Show tab character

Г" Show s^ace character

Syntax Highlighter: Pascal

Block .indent: \2

Tab stops; |2

d

Edit Code templates .

Of. Cancel Help

Рис. 1.3. Страница Source Option диалога Editor Properties

Диалог Code Templates (рис. 1.4) состоит из двух панелей - Templates и Code.

/ Code Templates

-Code Т empires-

Templates: I Name j Description

чг-i''d ar ran declaration fva)array declaration (const)case statement

fidd... Edit... Delete

£ode: array[Q. . j ] of ;

LJImpoit...i Ejport...

OK Cancel

Рис. 1.4. Диалог Code Templates

Page 7: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE

Панель Templates отображает список всех существующих шаблонов кода, указы-вая в столбце Name имя шаблона. Панель Code отображает код шаблона, которыйбудет вставлен вместо имени шаблона после нажатия пользователем клавишCtrl+J. Если пользователь введет имя шаблона не полностью, то после нажатияклавиш Ctrl+Л в ниспадающем окне будут отображены все шаблоны, начинаю-щиеся с введенной последовательности символов.

Для отображения полного списка шаблонов кода (рис. 1.5) следует нажатьклавиши Ctrl+J. При двойном щелчке мышью на выбранном в списке шаб-лоне оператора он автоматически добавляется в указанное место кода моду-ля. Для ограничения поиска можно предварительно ввести ключевое слово(или начальные буквы), а затем нажать клавиши Ctrl+3.

Unitl. pas

Unitl

procedure TFocwl . But t-onlC lick (Sender

begin

• array declaration [eons,!)

end;

end.

. 1 '

array declaration [var]

case statement (with else)

case statement

class declaration [wilh Great e/Destro^ overrides]

class declaration [no parts)4\ \33: 6 | Modified j Insert

: TObject] ; _-J

an<vcz m^man ay dс as ее 1

cases — 1

classc

eland - Д]

_yA

Рис. 1.5. Отображение списка шаблонов кода

Для того чтобы показать список переменных (рис. 1.6), свойств, методови обработчиков событий, следует нажать клавиши Ctrl+Space. При двойномщелчке мышью на выбранном в списке элементе он автоматически добав-ляется в указанное место кода модуля.

О Unitl.раз

procedure TFotml-EuttonlClicK[Sender :begin

Sell: TFocmlSender: Т ObjectLabell . TL^btlL2 : TUbelButtonl : TBullon

prcceduie Butlonl Click/ proceduislSender: Т Object) _^

Рис. 1.6. Отображение списка имен

Page 8: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Глава 1

При вводе имени процедуры и открывающей круглой скобки редактор кода ав-томатически отображает всплывающую строку подсказки (Hint) со списком па-раметров этой процедуры (рис. 1.7).

1 Unitl.pas

- *- . -К - | Un»1 [

procedure TFotml. BuctonlCHch (Sender : TC»3eCt);•Jiegin

MessageBox (| ,end,- hWnd: HWND; IpText: PChai; IpCaplioi: PChar. uTjipe: Cardnal

34: 15 .Modified |i™«t

Рис. 1.7. Отображение списка параметров

При щелчке мышью на идентификаторе, например имени переменной или типеданных, внизу отображается всплывающая подсказка (рис. 1.8) для этого иден-тификатора.

В Unitl.pas

Unit!

vac. riurnl: Inc

toe-in type

nuroi:^T7i - system pas (11 1|

nimil: -numl+l;

f ""33. 15 ] Modified [insert

Рис. 1.8. Отображение всплывающей подсказки для типа данных

Окно редактора кода позволяет выполнять перемещение выделенного фрагментатекста с помощью мыши. При одновременном нажатии клавиши Ctrl и левойкнопки мыши выполняется копирование выделенного фрагмента текста.

Для перехода в окно редактора кода можно выполнить двойной щелчок мышьюна форме или расположенном в ней компоненте. При этом в код модуля будетдобавлен (если его еще нет) обработчик события и курсор будет расположенвнутри блока begin end;. При щелчке мышью на форме это будет процедураprocedure TForral.FormCreate(Sender: T C b j e c t ) ; . а при щелчке на компонентетипа TEdit - процедура procedure TForral.Edit2Change (Sender: TObject);. Бо-лее подробно обработчики событий будут рассмотрены в главе "Библиотекакомпонентов Delphi — VCL".

Код модуля записывается на языке программирования Object Pascal. Условноможно считать, что каждый модуль состоит из пяти секций: заголовка модуля,секции интерфейсов (interface-секции), секции реализации {impiementation-секции) и двух необязательных секций — инициализации и завершения.

Page 9: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE

ОКНО ПРОВОДНИКА КОДАОкно Code Explorer можно автономно закрывать или открывать, а также распола-гать как отдельное окно. Для отображения окна Code Explorer следует выполнитькоманду меню V1ew|Code Explorer. Как правило, окно проводника кода встраива-ется слева в окно редактора.

В окне проводника кода отображается древовидная диаграмма, содержащая всетипы, классы, свойства, методы, глобальные переменные и глобальные процеду-ры, определенные в текущем модуле. Окно Code Explorer значительно облегчаетпереходы между различными классами, компонентами, переменными и метода-ми текущего модуля. При двойном щелчке мышью на любом элементе в про-воднике кода автоматически выполняется переход на соответствующую пози-цию в окне редактора кода. Для быстрого поиска внутри окна проводника кодаможно использовать ввод первых символов названия искомого элемента.

В окне проводника кода используются следующие кнопки:

— Классы;

— Интерфейсы;

— Модули (Units);

— Константы или переменные (включая поля);

-—Методы или процедуры: Процедуры (зеленая);

— Методы или процедуры: Функции (желтая);

— Свойства;

— Типы.

, Для переключения между окном Code Explorer и окном редактора кода мож-но нажать Ctrl+Shift+E или. вызвав щелчком правой кнопки мыши контекст-ное меню, выбрать соответственно View Editor или View Explorer.

Для добавления или удаления нового элемента достаточно в контекстном менюпроводника кода выбрать пункт New или Rename.Например, для того чтобы добавить в окно формы новый объект класса TLabel(надпись), достаточно выбрать пункт контекстного меню New и ввести черездвоеточие имя нового элемента и его тип (NameLabel : TLabel).

Для настройки параметров окна Code Explorer следует выполнить команду менюTools] Environment Options и выбрать вкладку Explorer.

Page 10: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

10 Глава 1

ИНСПЕКТОР ОБЪЕКТОВИнспектор объектов позволяет редактировать свойства компонентов и опреде-лять для них обработчики событий. Он представляет собой окно, содержащеедве вкладки: свойства и обработчики событий (рис. 1.9).

Obicct Inspector

Forml

Properties j Events |

E BotdeilconsE orderS lyleBorderWidbhCaptionCSenlH eightClentWidthColor

H ConstraintsDI3DCursorDelaultMonitorDockSieDrajjKindDragWode

' EnabledJEFont

FoimStyleHeigWHelpCo'nteSHelpFileHelpKeywordHelpTypeHint

SHoriScroUBatIconKeyPrevieisLeftMenuНзтеObjeclMenultem

All shown

•n 2TFuriil jj

[biSiistemMenu.biMiniiwe.biM: » 1bsSijeable0Foiml1Э5824^]clBlnFece(TSiieConstt dints]TruecrDefaultdmftctiveFormFalsedkDrajcli.iMcni.ilTrue[TFonl]fsNormal2220

htConlerf

ITControlScrollUai][None]False190

azmi~,\_ . __jA

Object Inspector

Form!

Properties Events |

ActionActive ControlMenuObjectMenultemQrAelivaleOnCsnRej.zeOnCfckOnCto»eOrCloteQueiyQnConstrainedResizeOnContextPopupOnCreateOnDbOckOnOeactivateOnDestroyOnOockDropOnOockOverDnOragDiopOnDragOverQnEndDock

OnGetSitelnioDnHelpDnHkieDnKeyDownOnKeyPressDnKeyUpOoMouseDownDnMouseMoveOnMou:eLJpOnMouseWheel

All shown

MHR *'TFaiml _J

I b

FoiraCieate

..--d

/s.

Рис. 1.9. Инспектор объектов

В верхней части инспектора объектов расположен список всех компонентов,размещенных в форме. Иногда этот список называется селектором объектов.Вкладка Properties содержит в левой части список всех доступных во время про-ектирования свойств для текущего объекта, а в правой части — их значения.Символ + перед именем свойства указывает, что это свойство является состав-ным и содержит другие вложенные свойства. Для распахивания или сворачива-ния составного свойства следует щелкнуть мышью на расположенном слева отнего символе + или - соответственно.Для изменения значения свойства необходимо ввести это значение или выбратьего из предлагаемого списка.

Page 11: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE 11

Если свойство отображено красным цветом, то оно может содержать ссылку надругой компонент (назовем его связываемым компонентом). Если такая ссылка ус-тановлена, то для данного свойства будут доступны вложенные свойства — свойствакомпонента, на который установлена ссылка. Вложенные свойства и обработчикисобытий для связываемого компонента отображаются зеленым цветом.При добавлении в форму компонента информация о нем автоматически поме-шается в инспектор объектов. Для того чтобы изменить в инспекторе объектовзначения свойств или определить обработчики событий какого-либо компонен-та, достаточно выбрать имя объекта в селекторе объектов инспектора объектовили щелкнуть на компоненте в окне формы.

'' / Для вызова инспектора объектов можно нажать клавишу F11.

Интегрированная среда разработки IDE обеспечивает автоматическую синхрон-ность внесения изменений, произведенных разработчиком в одном окне, во всевзаимосвязанные окна IDE. Так, при внесении изменений в окно формы (добав-ление или удаление компонентов, перемещение и изменение размера и т. п.) ониавтоматически отображаются, и в инспекторе объектов и в редакторе кода моду-ля. Или наоборот, при изменении в инспекторе объектов значения свойстваName (имя компонента) это сразу автоматически отображается и в окне формы,и в тексте модуля в окне кода. При этом также изменяются и имена процедур,вызываемых для обработчиков событий, как в секции интерфейса, так и в сек-ции реализации. Однако если в самом коде модуля были добавлены вызовы та-кой процедуры, то ее имя автоматически обновлено не будет.

ПРОЕКТЫРазработка любого приложения начинается с создания проекта. Проект представ-ляет собой совокупность всех модулей приложения и ряд вспомогательных файлов.При создании нового приложения автоматически создается ряд файлов: файл моду-ля, файл описания формы, файл ресурсов, файлы конфигурации и файлы проекта.

Для того чтобы создать пустой проект, содержащий только одну форму, достаточновыполнить команду меню File |New|Application или команду FiLe|New|Other, выбравзатем на странице New пиктограмму Application (рис. 1.10).При этом будет создан проект, состоящий из одного файла модуля Unitl.pas, фай-ла описания формы Unitl.dfm, файла проекта Projectl.dpr и нескольких вспомога-тельных файлов. После компиляции для каждого файла модуля создается двоич-ный файл с расширением .dcu, а затем после линкования всех модулей создаетсявыполнимый файл с расширением .ехе или динамическая библиотека с расшире-нием .dtt. Приведем листинги основных создаваемых файлов проекта,

Листинг файла Unitl.pas:

unit Unitl;interfaceuses

Windows, Messages, SysUtils, Variants, Classes,

Page 12: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1

Graphics, Controls, Forms, Dialogs;type

TForml = class(TForm)private

{ Private declarations }public

( Public declarations }end;var

Forml: TForml;implementation{$R * . D F M )end.

Глава 1

У 7 New Items •

IntraWeb WebServices j Business | WebSnap W*b Documents | Corba

Hew ActiveX | Multilier | Projeel! | Form! j Dialogs ] Projects | Data Modules

•ря— i jrtfc r— i p==

^& ? *н1

ШИ ИЙ BatchFile CLX Component Console ControlPanelApplicat on Application Application

Control Panel Data Module DLL Wizard Form Frame PackageModule

tB ГЙ! |6f H*1

PioiectGmup Resource DLL Service Service Text ThreadQbjeclWi!ard Application

t ^ ТГ!) ]*I-1Unit Webserver XML Data

Application Binding

Г Сод Г Irte.f Г i:-.-

3t. Cancel Help

Рис. 1.10. Страница New диалога New Items

Для каждого файла описания формы (например, Unitl.dfm) имеется соответст-вующий ему файл модуля (например, Unitl.pas). В файле описания формы со-храняется информация о свойствах формы и расположенных в ней компонентах.После сохранения файла модуля в этом же каталоге размещается файл описанияформы. Разработчику нет необходимости редактировать его содержание. Он ис-пользует для этого инспектор объектов. Однако иногда удобно иметь текст всехсвойств и компонентов формы. Для этого достаточно выполнить команду менюFile j Open и указать имя файла.

Page 13: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE 13

Листинг файла Unitl.dfm:

(Это файл свойств}object Forml: TForml

Left = 3 4 4Top = 351Width = 544Height = 375Caption = 'Forml 'Color = clBtnFaceFont.Charset = DEFAULT_CHARSETFont.Color = clWindowTextFont.Height = -11Font.Name = 'ИЗ Sans SerifFont.Style - []OldCreateOrder = FalsePixelsPerlnch = 96TextHeight = 13

end

Группы проектовПри входе в Delphi автоматически создается новый проект, входящий в группупроектов. Вообще говоря, любой проект всегда входит в группу проектов. Груп-па проектов может содержать как один проект, так и несколько проектов.И даже в том случае, если группа проектов состоит из одного проекта, то для неевсе равно создается файл группы проектов с расширением .Ьрд.

МЕНЕДЖЕР ПРОЕКТАВся информация о группе проектов отображается в окне менеджера проекта(рис. 1.11). Для того чтобы показать это окно, достаточно выполнить командуменю ViewjProject Manager или нажать клавиши Ctrl+Alt+Fll.

Project Manager

New - Remove

Fib: Path

.fflf ProjeclGroupl C. Program Files\Borland\D«lphi5VProjecls

" -ЗР БЁЭЭШЭ С ^Program Files^BorlandVDelphfi^ProiectsВ-Щ] About CAPmgrarnFi!e!VBorlanid\Delphi5\Proiects

if] ABOUT.PAS CAProgrstnFiles\Borland\DslphiE\Proiecti

3 AboulBtw CAProgram FilesVBorlandVDelphS'iProiects

H (|0 SDIMAIN C.VProgramFile:\Borland\Delphi5\Proiects5] SDIMAIH.pai C:\PiogtamF]es\Borland\D*lphi5\Proiects

3 SDIApr>Foim C:\Program RlesS6o(tand\.Detphi5'iPioiects

;C;\PrograiriFJes\Boriand\Delphi5\Proiect!\!diapp.dpr ^

Рис. 1.11. Диалог Project Manager

Page 14: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

14 Глава 1

Группа проектов представляется древовидной диаграммой. Для перехода в окноредактора кода или в окно формы достаточно выполнить двойной щелчок мы-шью на соответствующем элементе диаграммы дерева проектов.В зависимости от выделенного элемента диаграммы дерева проектов при щелчкеправой кнопкой мыши вызывается соответствующее контекстное меню. Так, дляэлемента ProJectGroup контекстное меню включает команды добавления новогопроекта, сохранения группы проектов и т. п. Для элемента выполнимый файлпроекта (в нашем примере - sdiapp.exe) контекстное меню (рис. 1.12) включаеткоманды добавления новых модулей, удаления файлов, сохранения, настройкиопций проекта, закрытия и удаления проекта.

Add...

Remove File,.,

Save

Options.,,

Activate

Compile

Build

View Source

Remove Project

tj.>j :• oner Oil+Up

Compfe Аи From Herft

Build Al From Here_^___

[*• Toolbar

[~уП Status ear-.

Stay on Top

•s Dockable

Рис. 1.12. Контекстное меню менеджера проектов

Для того чтобы настроить параметры проекта, следует выполнить командуOptions контекстного меню менеджера проектов. Открываемый при этом диалогProject Options (рис. 1.13) содержит семь страниц.На странице Forms устанавливается главная форма приложения и список автома-тически создаваемых форм. На странице Directories/Conditionals можно опреде-лить каталоги для различных файлов проекта.

Page 15: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE

• Pioject Options Ei

Duectoties /Conditionals ) Vetsionlnfo Packages

Forms Application CorapilH } Linker j

Auto-creatE forms Available iorms.

• SDIAppFoim ( 1AboutE ox — —1

1 "

II

Г DefauB OK Cancel Help

Рис. 1.13. Диалог Project Options

ШАБЛОНЫ ПРИЛОЖЕНИЙНаряду со стандартным для различных современных сред программированияалгоритмом создания приложения Delphi предоставляет возможность созданияготового шаблона приложения, включающего линейку меню, работу с рядомстандартных диалогов и многое другое. Для того чтобы создать готовый шаблонприложения, достаточно выполнить команду File |New|Other и на страницеProjects выбрать нужную пиктограмму (рис. 1.14),

fS New Items

| WebServices • Busies! j WebSnau j Web Documents | Cwba

(Jen I ActiveX I Multilier ', Foms Dialogs Projects Data Modules

ВCIXMDI MDI SDI WinJDOBLoQo Win35/93

Application ApplicaCion Applicdticn Application LogoAp..

ff Сои- Г .rher,' Г <Ji?

OK Cancel

Рис. 1.14. Странииа Projects диалога New Items

Если выбрать пиктограмму MDI Application или SDI Application, то после запросаимени создаваемого приложения и каталога для его размещения сразу будетсоздан проект, содержащий шаблон готового приложения, обладающего свойст-

Page 16: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

16 Глава 1

вами соответственно MDI-интерфейса (Multi Document Interface) илиSDI-интерфейса (Single Document Interface).

При выборе пиктограммы Application Wizard будет открыт диалог (рис. 1.15) длянастройки требуемых возможностей создаваемого шаблона приложения.

application Wizard

You applicelon can contain a rrienu bar by checking one or more o' the followingslandsid WirxJorts menu!:

File ) Г Це menu

The fife menu contains items such as Open, Save and EJ&

Г" Edit menu

The Edil rranu corJains Undu, Cut, Copy and Pasle items

Г~ Window menu

The Window menu contains window management lurclion?specially designed >oi MD! application!.

Г" Help menu

menupfoviduSoCceislo^oui appicelion'i help file, as well asilem lo show Jhs About box.

Cancel

Рис. 1.15. Диалог Application Wizard

При создании приложения с SDI-интсрфейсом автоматически будут созданы двеформы (рис. 1.16) и соответствующие им файлы модуля. Также будет созданглавный файл приложения (в данном случае Sdiapp). Файлы модулей кода фак-тически являются объявлениями классов для определяемой формы, а в главномфайле приложения выполняется создание объектов на основе объявленныхв модулях кода классов и создание главного окна приложения.

*jr SDI Application SHE ':File Edit Help

Djs: e|: Jt|ia](m|

''яша-з-п ' " "1 /,.

t

'

:: About BOB]

Г ' -Producl Name

Version1 J

Copynghj

Comments

- - n OK

Рис. 1.16. Формы для SDI-приложения

Главной формой является форма SDI Application. Форма About отображаетсяпри выполнении команды меню Help|About.Приведем с некоторыми пояснениями листинги трех автоматически созданныхфайлов шаблона приложения.

Page 17: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE 17

Листинг главного файла приложения:Для просмотра главного файла приложения в окне редактора кода следует вы-полнить команду меню ProjectjView Source.

program Sdiapp;uses

Forms,SDIMAIN in 'SDIMAIN.pas' ISDIAppForm],About in 'ABOUT.PAS' (AboutBoxi;

(SR '.RES)

begin

Application.Initialize;(Создание форм}

Application.CreateForm(TSDIAppForm, SDIAppForm);Application.CreateForm(TAboutB'ox, AboutBox);

Application.Run; {Запуск первой созданной формы)

end.

(Стандартный диалог Open}(Стандартный диалог Save]

(Панель инструментов](Кнопки панели инструментов)

Листинг модуля для г л а в н о г о окна п р и л о ж е н и я :unit Sdimain;

interface

uses Windows, Classes, Graphics, Forms, Controls,

Menus, Dialogs, StdCtrls, Buttons, ExtCtrls,

ComCtrls, IragList, StdActns, ActriList, ToolWin;

type

TSDIAppForm = class(TForm)OpenDialog: TOper.Dialoq;SaveDialog: TSaveDialog;

ToolBarl: TToolBar;ToolButtor.9: TToclButton;

ToolButtonl:ToolButtonZ:

ToolButton3:

ToolButton4:ToolButtonS:

ToolButton6:

ActionListl:FileNewl: TAction;

FileOpenl: TAction;

FileSavel: TActicn;FileSaveAsl: TAction;

FileExitl: TAction;

EditCutl: TEditCut;EditCopyl: TEditCopy;

EditPastel: TEditPaste;

TToolButton;

TToolButton;

TToolButton;TToolButton;

TToolButton;

TToolButton;

TActionList;(Обработка команд меню}

Page 18: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

18 Глава 1

HelpAboutl: TAction;StatusBar: TStatusBar;IraageListl: TlmageList;MainMenul: TMainMenu;Filel: TMenuItem;FileNewItem: TMenuItem;FileOpenltem: TMenuItem;FileSaveltem: TMenuItem;EileSaveAsItem: TMenuItem;

N1: TMenuItem;FileExitltem: TMenuItem;Editl: TMenuItem;Cut I tent: TMenuItem;Copyltem: TMenuItem;Pasteltem: TMenuItem;Helpl: TMenuItem;HelpAboutltem: TMenuItem;procedure FileHewlExecute(Sender: TObject);procedure FileOpenlExecute(Sender: TObject);procedure FileSavelExecute(Sender: TObject);procedure FileExitlExecute(Sender: TObject);procedure HelpAboutlExecute(Sender: TObject);

private{ Private declarations I

publicf Public declarations }

end;varSDIAppForm: TSDIAppForm;

iirplementationuses About;

{SR '.DFMIprocedure TSDIAppForm.FileNewlExecute!Sender: TObject);begin

{ Do nothing }end;procedure TSDIAppForra.FileOpenlExecute(Sender: TObject);beginOpenDiaiog.Execute; (Отображение диалога)

end;procedure TSDIAppForm.FileSavelExecute(Sender: TObject);beginSaveDialog.Execute;

end;procedure TSDIAppForm.FileExitlExecute(Sender: TObject];

Page 19: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE 19

beginClose;

end;procedure TSDIAppForm.HelpAboutlExecute(Sender: TObject);begin

AboutBox.ShowModal;

end;end.

Листинг модуля для диалога About:unit About;

interfaceuses Windows, Classes, Graphics, Forms, Controls, StdCtrls,

Buttons, ExtCtrls;type

TAboutBox = class(TForm)

Panell: TPanel;

OKButton: TButton;

Prograralcon: TIraage;ProductHame: TLabel;

Version: TLabel;Copyright: TLabel;

-oraments: TLabel;

private

{ Private declarations }public

{ Public declarations }

end;varAboutBox: TAboutBcx;

implementation

iSR -.DFM}end.

РЕДАКТОР МЕНЮДля создания меню в интегрированной среде разработки IDE используется ре-дактор меню. Для того чтобы его вызвать, достаточно расположить на формекомпонент типа TMainMenu или TPopupMenu, а затем выполнить на этом ком-поненте двойной щелчок мышью.Редактор меню (рис. 1.17) дает возможность пользователю в графическом режимевводить имена команд меню. При этом автоматически создаются объекты типаTMenuItem для каждой команды меню. Вводимые имена команд одновременноотображаются в инспекторе объектов в свойстве Caption. Окно формы также ото-бражает все элементы меню TMainMenu, определяемые в редакторе меню.

Page 20: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

20 Глава 1

1 -* • 9 i rJ ;- £, s, ^_.:?~ a: f. - II i j

Seaj. * *d^ f '

#- Cfl ICUBvU

N?, О ItlJll}

'•.'*•"'. jy

S"1^11.--^AI " Xi ^F гЗ,- irT" in-ffte-i

СгИОп Раи*

|

AJUXJV

&Wd«J i A&iKftf - WnS | S't»n.| E**iAc(«;;r Dv«Cor«[41 dt£«nft i QWaSwl tCE A^L 1 Ho^ml WebSarail InHnAlij.

;^u Э^" T^ A f** - B s sl =""-"- ^ '._ JJшэнян.:: , :....'Д

.

шяннн

U* | f - ^ -unit TJ..14;

RW ЕДГ Г 1

tjnpe

TTOfinl • CJ.IIB iTTocBi)

Л»1цП*г.и!: TftainHer.j;

Hi: THcnu'cciu;taJ(J: Trtsmjl^jv

C4H= Tl ^uci»;

,Л";.IUiIi!fl'

14ri: d*^"ri*fiff J

Hi;

-

; 16 и НН>У«] i .ы \С2йЛЁщ™и/

^ЯХ,

Рис. 1.1 7. Редактор меню и инспектор объектов

Компоненты, добавляемые на форму при создании меню, автоматически ото-бражаются в окне дерева объектов.

Более подробно разработка меню приложения и контекстного меню рассматри-вается в главе "Создание приложений в среде Delphi".

РЕДАКТОР ИЗОБРАЖЕНИЙРедактор изображений, называемый иногда редактором ресурсов, можно вызы-вать как отдельную утилиту Image Editor или посредством выполнения командыменю Toots]Image Editor.В этом редакторе можно создать растровое изображение — BMP-файл, пикто-грамму - ICO-файл или курсор - CUR-файл. Также редактор изображений(рис. 1.18) позволяет создавать и редактировать файл ресурсов RES-файл, кото-рый содержит именованные ресурсы: изображения, курсоры и пиктограммы.Для использования файла ресурсов его надо добавить в приложение. Для этогов главном файле приложения следует включить директиву компилятора{SR *.RES} . При создании приложения автоматически создается и одноименный

По умолчанию при создании нового приложения гакая директива уже присутствует

в файле проекта.

Page 21: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE Л

файл ресурсов. Файл ресурсов отображается деревом, содержащим имена всехсозданных ресурсов. Эти имена можно использовать п коде приложения для бы-строй загрузки ресурсов. Загрузка изображения непосредственно из BMP-файлавыполняется значительно медленнее, чем из файла ресурсов, и дополнительнотребует доступа к этому ВМР-фай.чу.

Mintage Editor

Fi!a flesouiee V^indow Kelp

Рис. 1.1 8. Редактор изображений

ВСТРОЕННЫЙ ОТЛАДЧИКВстроенный отладчик позволяет выполнять пошаговую отладку приложений.Точки, в которых производится остановка выполнения приложения, называютсяконтрольными точками (breakpoint).

Вставить контрольную точку очень просто: достаточно щелкнуть в редакторе кодана серой полосе слева от кода строки. Контрольная точка отмечается красным бул-летом. Строка с контрольной точкой также выделяется красным фоном.

Дополнит&тьно, используя команду меню Run|Add Breakpoint, можно устанаапиватьконтрольные точки на конкретный адрес или на загрузку определенного модуля.

Если в приложении установлены контрольные точки, то при запуске приложе-ния, например нажатием клавиши F9. автоматически будет запущен встроенныйотладчик. Выполнение приложения прервется на первой контрольной точке. Та-кая точка будет в окне кода отмечена зеленой стрелкой (рис. 1.19).

Page 22: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

22 Глава 1

^ ^ ^ ^В В Umtl pas__ , x]

f1 'K^ TForrnlВ О Variables/Cg CJ Uses

UnM Projaetl j *• • -4

with ScringGrldl dobegin

(Заполнение 1-ой строки^for I :» 0 to ColCount - 1 do

.

в*

Cells[I,0] := 'Столбец Ч- IncToStclI){Заполнение элементов массива, начинаяагорой строки вгорс-гр столбца)

fur I :~ 1 to ColCount-I йоJOE J:= 1 to RoaCount-1 do

begin

lJ | _il AJ 1 Л| 37: 1 IModified [Insert

X

^

^Рис, 1.1 9. Окно кода с контрольными точками

Для продолжения процесса отладки соответствующую команду можно выбратьиз меню Run {рис. 1.20).

^ RunJ? Attach toProcess...

|ji>_i Parameter:,,.

F9

IJritegi*t.(rt Ad.iw'' Server

1Г-«Й!1 ' SttS

"e* Step Over FS

"£ Trace Into F7

^5; Trace to Next Source Line Shift+F7

^Eit Run to Cursor F4

_' f-U t.l.",Ci K.t'.:in Sbirt 'Fc,

|| Program f-'=uit*

Irfspect...

Evaluate/Modify,,.

Add watch...

Add Breakpoint

Ctrl+F7

Ctrl+FS

Рис. 1.20. Меню Run для управления процессом выполнения и отладкиприложения

Для того чтобы продолжить выполнение приложения, следует выбрать один изрежимов пошагового выполнения:Step Over - переход к следующей строке кода и останов, исключая переходывнутрь процедур;

Page 23: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Интегрированная среда разработки IDE

Trace Into - переход к следующей строке кода и останов. Если текущая строкаявляется вызовом процедуры или функции, то будет выполнен переход на пер-вую строку этой процедуры или функции;Trace to Next Source Line - переход к следующей строке кода и останов;Run to Cursor - переход к строке, в которой находится позиция ввода.В момент останова пользователь имеет возможность просмотреть текущие значениявыражений, переменных и свойств. При необходимости он может изменить ихвручную. Встроенный отладчик также позволяет в процессе выполнения приложе-ния отслеживать изменение ряда указанных выражений, переменных или свойств.Для этого можно вызвать диалог Evaluate jModi fy (рис. 1.21), нажав на клавишиCtrl+F7 или выполнив команду меню Run |Evaluate |Modi fy .

valuate/Hodify

Eyabala

p*? * П fc.*>IS! too ^4Modify Watch Inspect Kelp

^^Я xl

Expression:

StringGtidl

Result:

1,11

lew value:

1.1'

Rows[£tiingGhdT Row]-5trings(1 ] Z\

i3

Рис. 1.21, Диалог Evaluate/Modify

Отметим, что этот диалог доступен только в момент приостановки выполненияпрограммы: заголовок главного окна Delphi после имени проекта отображаетсостояние [Stopped].В первое поле этого диалога Expression следует ввести выражение (или имя пе-ременной или свойства). Текущее значение этого выражения будет отображенов поле Result. Для установки нового значения его надо ввести в поле New value,а затем нажать клавишу Enter.Чтобы иметь возможность отслеживать пошаговое изменение каких-либо выраже-ний, их следует ввести в поле Expression, а затем щелкнуть по кнопке Inspect.В результате будет открыт постоянно отображаемый диалог Debug Inspector(рис. 1.22). Такой диалог можно создавать для каждого отслеживаемого выражения.

Щелчком мыши по кнопке с тремя точками справа от поля значения можно вы-звать диалог для изменения текущего значения отслеживаемого свойства илипеременной.

Page 24: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Глава 1

J: Register esi

Data j

~ FT

1 Debug Inspector

ji Registe' ebx

D«ta

1 1

'Register

•jtl

3

'"1

^Рис, 1.22. Диалог Debug Inspector

Кнопка Watch диалога Evaluate/Modify позволяет отобразить окно Watch List(рис. 1.23), содержащее список всех запрошенных в этом диалоге выраженийи их текущие значения.

watch I ixi

1:31:3SHingG[id1,Rom[SWngGiidl.Row].Sttingi[3]: '3 , Т

StringGrid1.RowsISlringGrid1.Row) Strings^]: '2 , Т

StringGridl Name: 'StringGridVButton! .Caption: 'Заполнить таблицу'

Рис. 1.23. Окно Watch List

Это окно является самым удобным средством для одновременного отслежива-ния текущих значений выражений, изменяемых в процессе отладки.

Page 25: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Г Л А В А 2

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕПРОГРАММИРОВАНИЕ

Delphi является объектно-ориентированной средой программирования. В каче-стве языка программирования используется язык Object Pascal. Эта глава позна-комит вас с основными понятиями объектно-ориентированного программирова-ния и с терминологией, используемой для среды программирования Delphi.

ОСНОВНЫЕ понятияОбъектно-ориентированное программирование позволяет программироватьв терминах классов:

* определять классы;

с конструировать новые и производные (дочерние) классы на основе сущест-вующих классов;

* создавать объекты, принадлежащие классу (экземпляры класса).

Класс описывает свойства (атрибуты) объекта и его методы (включая обработ-чики событий).При создании объекта он наследует структуру (переменные) и поведение (мето-ды) своего класса.

В свою очередь, класс, называемый потомком, производным или дочерним клас-сом (подклассом), также может быть создан на основе другого родительскогокласса (предка) и при этом наследует его структуру и поведение.

Любой компонент (элемент управления) или объект в Delphi всегда являетсяэкземпляром класса.Программно объект представляет собой переменную объектного типа.

Для каждого компонента Delphi существует свой класс, наследуемый отTComponent.

Предком всех объектов, включая компоненты, является класс TObject.

Наследование позволяет определять новые классы в терминах существующихклассов.Инкапсуляция - это создание защищенных объектов, доступ к свойствам и мето-дам которых разрешен только через определенные разработчиком «точки вхо-да». Иначе говоря, инкапсуляция - это предоставление разработчику конкретно-го набора свойств и методов для управления поведением и свойствами объекта,определяемыми внутри класса.

Page 26: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

26 Глава 2

Полиморфизм - это возможность различных объектов реагировать по-разномуна одни и те же события.

Синтаксис языка поддерживает общепринятую для объектно-ориентированногопрограммирования нотацию: имя_рбъекгшсвойство для ссылки на свойство объ-екта или имя_объекта.ме»юд для вызова метода объекта. При этом имя_объектаможет содержать как простую, так и квалифицированную ссылку. Квалифициро-ванная ссылка содержит отделенные точкой имена родительских объектов.

СОЗДАНИЕ нового КЛАССАОбъявление типа

Для того чтобы создать новый класс, в interface-секции кода модуля следуетзаписать:

typeTNewClass = class(ParentClass)

end;

В модуле на языке Object Pascal может быть описано произвольное количествоклассов. Однако каждая форма в проекте, разрабатываемом в Delphi, описывает-ся отдельным модулем (создаваемым автоматически при создании новой фор-мы). Этот модуль описывает новый класс для компонента Form. Первоначальнопо умолчанию создается класс TForml, наследуемый от класса TForm изVCL-библиотеки. Это автоматически записывается в модуле следующим обра-зом:

type (Объявление класса}TForml = class(TForm)private

[Объявление private переменных и методов}public

{Объявление общедоступных переменных и методов}end;

varForml: TForml; {Создание экземпляра класса}

implementation{Секция реализации методов)

end.

Объявление п е р е м е н н ы х и методов классаПеременные класса указываются после модификаторов доступа (public, private,protected, published, automated), определяющих их область видимости. Модифи-каторы доступа определяют область видимости переменной и более подробнорассматриваются в главе "Object Pascal".

Page 27: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объектно-ориентированное программирование 27

Свойства, указанные после модификатора доступа published, являются обще-доступными и отображаются в инспекторе объектов.После имени переменной или списка имен, разделенных через запятую, указы-вается символ : и тип переменной. Типом может быть как базовый тип Delphi(например. Integer, Boolean), так и производный тип, в том числе реализуемыйкак некоторый класс. Такой тип иногда называется объектным типом.При объявлении методов класса перед именем метода указывается ключевоеслово function или procedure. Для функций также после имени функции черезсимвол указывается тип возвращаемого значения.Например:

typeTNewClass = class(ParentClass]{Модификатор доступа public)public

Varl: Integer,-Var2, Var3: TVarTypeClass;procedure PI;function Fl : Integer;

end,-

Объявление класса содержит только объявление переменных и методов. Реализацияметодов - функций и процедур - записывается в implementation-секции модуля.

РАБОТА с КЛАССАМИКаждый модуль, создаваемый на основе разрабатываемой формы, представляетсобой описание класса. Как правило, производного от класса TForm. Любой ком-понент, располагаемый в форме, также является экземпляром некоторого класса.Классы в Delphi образуют некоторое иерархическое дерево. Будем называть клас-сы из VCL-библиотеки Delphi базовыми массами. Иерархическое дерево для не-которого класса любого компонента имеет корневым элементом класс TObjectПосмотреть иерархию классов-потомков можно в окне Exploring. Для того что-бы перейти в него, достаточно выполнить команду меню View|Browser или на-жать клавиши Shift+CtrL+B.На рис. 2.1 представлена страница Classes окна Exploring Classes. На ней отображеноиерархическое дерево наследования для класса TForm 1. В правой части окна распо-ложена панель, содержащая три страницы - Scope, Inheritance, References.

Страница Scope содержит древовидную диаграмму всех объектов, переменныхи методов выделенного на левой панели класса. При этом ветвь Inherited содержитимена класса-предка и класса-потомка. Страница Inheritance содержит поддеревоиерархии классов, начиная с класса-предка для выделенного на левой панеликласса.

Page 28: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

28 Глава 2

На странице References можно узнать имена всех модулей и номера строк,в которых встречается имя данного класса.

Exploimg Classes

Globals | Classes ; Units

'-! Щ TObject

- >^ TPersisterit

,-; k^ Т Component

.£ Т Control

=_ »5i TWinConlrolS *5 TScroliingWiriContiol

Ы TCustoniForrn

?i »J Т Form

>* TForml

hj TFovm

Scope Inheritsnce | References j

- _| Р«Ыю

+. 1J Inherited

Рис. 2.1. Окно просмотра классов

Для того чтобы добавить в проект собственные описания производных классов,наиболее целесообразно создать отдельный модуль и в interface-секции модулязаписать все объявления классов.

Все классы VCL-библиотеки Delphi разбиты на группы, которые расположеныв моделях Object Pascal в каталоге Delphi 7\Source\VCL.

Для того чтобы просмотреть файл библиотеки, достаточно выполнить File | Openи выбрать каталог и имя файла. Справа в окне кода программы (рис. 2.2) будетпоказан код модуля, а слева — список всех объявленных в нем классов.

Ё CAPiogiam Files \Borl dud \Oelphi5\SouiceWcl\ but tons, pas

S

attК

* *&

-*: »4

±i *5

± *1

» L-J

^a

ISO:

vl

^J Private2J Piolected_| Public_| Published

TBultorGlvBliTG()iphCacheTGIyphLblTSpeedButtonPiuceduresT^pesVariables/Cmstant;Uses

end;

TBitBtriKintl - (taKCustom, bh:OKbkAboct

TBlcBtn -

yrivatPFCanvea

FGlypb:

FScyle:FKind:

F Lay out

JLJJ16 ; Insert

, bkRetcy, bklgnote,

class (TButton)

: TC&nva^ ;

Pointer;

TButconStyle;TEitBtnKind;

: TBucuoriLayout;

"* *

1

1, bkCancel,bklll) ;

J,й

Рис. 2.2. Окно кода программы для модуля Buttons из VCL-библиотеки

Приведем пример объявления класса кнопки TBilBtn из модуля Butlons.pas:

[Объявление класса кнопки TBitBcn(приводится с сокращениями)J

type

Page 29: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объектно-ориентированное программирование 29

TBitEtn = class(TButton)private

FCanvas: TCanvas;

FGlyphi Pointer;FStyle: TButtonStyle;

FKind: TBitBtnKind;

FLayout: TButtonLayout;FSpacing: Integer;IsFocused: Boolean;

FModifiedGlyph: Boolean;procedure Drawltemfconst DrawIteraStruct: TDrawItemStruct);

procedure SetGlyph(Value: TBitmap);

function GetGlyph: TBitmap;publicconstructor Create(AOwner: TComponent); override;destructor Destroy; override;procedure Click; override;publishedproperty Action;

property Caption stored IsCustoraCaption;property Default stored IsCustom;property Enabled;property Glyph: TBitmap read GetGlyph write SetGlyph stored IsCustom;property ShowHint;property Style: TButtonStyle read FStyle write SetStyle default

bsAutioDeiect;property Spacing: Integer read FSpacing write SetSpacing default 4;property TabOrder;property Tabstop;property Visible;property OnEnter;property OnExit;end;

Ключевое слово property обозначает свойство объекта, которое в отличие отобычных полей (переменных) класса имеет спецификаторы доступа read и/илиwrite, обеспечивающие контроль доступа к свойствам объекта.

Page 30: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

30 Глава 2

СВОЙСТВА/ МЕТОДЫ и ОБРАБОТЧИКИСОБЫТИЙКаждый объект обладает набором свойств. Свойства могут быть как наследуе-мые от родительского класса, так и добавленные индивидуально для создавае-мого объекта. Список всех свойств объекта и их значений отображается в диало-говом окне Object Inspector.Ссылка на свойство в программном модуле записывается какИмя_объекта.Свойство.Метод - это процедура или функция, ассоциируемая с некоторым объектом.Ссылка на методов программном модуле записывается как Имя_0бъекта. Метод.Delphi-приложение выполняется в среде Windows, и как любое Windows-приложение, получает сообщения о возникающих для него событиях. Управле-ние приложением фактически сводится к обработке получаемых сообщений.Методы, в которых содержится код обработки события, называются обработчи-ками событий (Event Handler).Delphi автоматически генерирует процедуры обработки событий - обработчикисобытий для любого компонента. При этом имя обработчика событий формиру-ется из имени компонента и названия события (например, EditlClick). Имя обра-ботчика события автоматически квалифицируется именем класса формы.Например: TForml.ButtonlClick(Sender: TObject); ./Зля каждого компонента предусмотрено одно стандартное событие. Напри-мер, для командной кнопки, флажка, списка, поля ввода - это событие Click,а для формы - событие FormCreate.Для того чтобы автоматически добавить в модуль объявление и описание разра-ботчика стандартного события, достаточно выполнить на компоненте формыили самой форме двойной щелчок мышью. Объявление события добавляетсяв interface-секцию модуля, а пустое описание события - в implementation-секциюмодуля. Далее в редакторе кода внутри уже имеющегося блока begin end; сле-дует только ввести код обработчика события.Например:

procedure TForml.ButtonlClick(Sender: TObject);begin

(место для введения кода!end;

Для того чтобы добавить обработчик любого события, можно выбрать в инспек-торе объектов страницу Events и выполнить двойной щелчок мышью в поле,расположенном справа от имени события. Это поле представляет собой комби-нированное окно списка - в него можно вводить новое значение имени обработ-чика события двойным щелчком м ы ш и или выбирать имя уже существующейпроцедуры. Это позволяет при необходимости определять одну процедуру обра-ботки событий одновременно для нескольких событий.

Page 31: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Г Л А В А 3

OBJECT PASCAL

В этой главе приводится краткое описание синтаксиса языка Object Pascal и рас-сматриваются стандартные процедуры и функции.

СТРУКТУРА ПРОГРАММЫСреда Delphi поддерживает в качестве языка программирования приложенийобъектно-ориентированный язык программирования Object Pascal.Программы средь: Delphi обычно разбиваются на ряд модулей, называемых про-граммными единицами (units). Каждый модуль сохраняется в отдельномPAS-фаЙле и компилируется в отдельный DCU-файл. При построении приложе-ния происходит линкование всех DCU-файлов модулей проекта.Один модуль может использоваться одновременно в нескольких проектах.Главный файл проекта - главный модуль также записывается на языке ObjectPascal и хранится в DPR-файле.Для просмотра в окне редактора кода главного модуля следует выполнитькоманду меню Project] View So и гее.

В минимальной конфигурации программно каждый проект должен состоять изглавного файла проекта и одного или нескольких модулей.

Delphi автоматически при добавлении новой формы создает новый модуль/ и добавляет его в проект. При создании нового приложения Delphi создает

новый проект с одной формой, автоматически формируя код двух модулей:

• модуля формы (по умолчанию Form I.pas);

* главного модуля приложения (по умолчанию Projectl.dpr).

Компилятор предполагает, что исходный код на языке Object Pascal записанв одном из следующих трех типов файлов:

• в файле с расширением .PAS - модуле;

• файле с расширением .DPR - главном файле проекта;

• файле с расширением .DPK - пакете (DLL-библиотеке).

Каждая программа обычно начинается с заголовка, указывающего имя програм-мы (модуля):

• для главного файла проекта:program Projectl;

• для модуляunit Unitl;

Page 32: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

32 Глава 3

Далее в модуле начинается interface-секция. Эго указывается директивой interface.Затем может следовать оператор uses, в котором через запятую перечисляютсявсе модули, которые должны быть прилинкованы при построении приложения .Оператор uses должен быть первым записываемым после зарезервированногослова interface.Например, для указания того, что данному модулю будет доступен модульForms из VCL-библиотеки. предоставляемой средой Delphi, и модуль Unitl изфайла Unitl.pas, секция uses должна быть записана следующим образом:

usesForms,Unitl in 'Uni t l .pas ' {Forml};

Список модулей VCL-библиотеки. как правило, редактируется вручную, тогдакак список используемых модулей проекта добавляется при помощи командыменю File|Use Unit.

ОСНОВЫ СИНТАКСИСАОсновную синтаксическую единицу языка будем называть фразой. Фраза состо-ит из элементов фразы.Оператор - это некоторое действие, которое может быть выполнено в програм-ме. Выражение может использоваться в операторах и с операторами и означаетнекоторое значение.Объявление описывает идентификатор (имя переменной или процедуры), кото-рый может использоваться в выражениях и операторах. Как правило, при объяв-лении переменной под нее выделяется память.Программа состоит из последовательности фраз, отделенных друг от друга точ-кой с запятой. Каждый элемент фразы может быть отделен друг от друга запятойили пробелом - как требует синтаксис (пробелы, как правило, можно опускать).В одной строке может быть записано несколько фраз. Например:

Count:=50;Index:=3;Одна фраза также может быть расположена на нескольких строках, но переносвыполняется только после элемента.Элементом может быть идентификатор, зарезервированное ключевое слово, ди-ректива, метка, число, строка символов, специальный символ.

Специальные символыСпециальными символами являются:

в одиночные символы #,$, S, ' , { , ) , * . + , м - , . , / . : , ; , < , = , > , @, [,], л, ( , } ;

« пары символов (*, { . . * ) , . ) , . . , / / . :=.<=,>=.<>.

1 Так «ак вся информация о линкуемых модулях хранится в коде самого модуля, то ObjectPascal не требует никаких заголовочных файлов или директив прекемпилвции типа include.

Page 33: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 33

ИдентификаторыИдентификаторы обозначают константы, переменные, поля, типы, свойства,процедуры, функции, программы, модули, библиотеки и пакеты.Длина идентификатора может быть произвольна, но значащими символами яв-ляются первые 255. Идентификатор может начинаться с буквы или символаподчеркивания, также может содержать буквы или цифры, но не может содер-жать пробелов. Зарезервированные ключевые слова не могут являться иденти-фикаторами. Строчные и прописные буквы в идентификаторе отличаются.Однако при написании операторов строчные и прописные буквы не различают-ся. Так, следующие два оператора абсолютно эквивалентны:

beginend;

BeginEnd;

Квалификация именДля определения того, какому модулю или объекту принадлежит идентифика-тор, следует указывать квалификацию идентификатора модулем или объектом.Имя квалифицирующего модуля или объекта указывается слева через точку.Например:

(Идентификатор identifier! -лз модуля Unit2}Unit2. ident i f ier l=lC;

(Метод Click для кнопки Buttonl формы Forml}Forml.Buttonl.Click

БлокиБлок - это набор объявлений и следующий за ним составной оператор begin -end. Все объявления всегда располагаются в начале блока.

Блок описывается следующим синтаксисом:

Объявленияbegin

Операторыend

Секция объявлений может содержать в произвольном порядке объявления пере-менных и констант, объявления типов, процедур, функций и меток.Место размещения объявлений определяет их область видимости.Идентификатор, объявленный в программе, функции или процедуре, видентолько в пределах того блока, в котором он объявлен.Идентификатор, объявленный в interface-секции модуля Unitl, имеет областьювидимости весь модуль Unitl, а также любой другой модуль, включивший в свойоператор uses имя модуля U n i t l . Такие идентификаторы называются глобальными.Идентификатор, объявленный внутри процедуры или функции, называется ло-кальным. Без указания квалификации имени идентификатора в процедуре илифункции всегда будет использоваться локальный идентификатор.

2 Зак. 11

Page 34: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

34 Глава 3

КомментарииКомпилятор игнорирует любой комментарии.

Комментарий может быть указан:

* между парными фигурными скобками { ];

* между символами {* и *);

* после символов // и до конца строки.

Директивы компилятораЕсли после символа { или символов * следует знак $, то это называется дирек-тивой компилятора.В следующей таблице приведено описание наиболее часто используемых дирек-тив компилятора.

Директива

$0

SHINTS

$1

SJ

$L

$0

$fl

SR

SRUNONLY

SWARNINGS

[№}...{SEND1F} ...

Описание

Директива-переключатель, инициирующая генерацию информации дляотладчика

Директива-переключатель, позволяющая использовать в приложении длин-ные строки

Директива-переключатель,

Директива-переключатель

Директива-переключательзначений типизированных

Директива с параметрами

Директива-переключательвремени выполнения

Директива с параметрамивыделяется под стен

Директива-переключательпрограммного кода

инициирующая генерацию подсказок компилятора

инициирующая проверну ошибок ввода/вывода

позволяющая выполнять модификациюконстант

указывающими линкуемые объектные файлы

инициирующая генерации) информации о типе

, указывающими размер памяти, которая

указывающая на необходимость оптимизации

Дирентивз-переключатель, инициирующая проверку принадлежностизначения заданному диапазону

Директива с параметрамив выполняемый ЕХЕ-файл

Директива-переключательпакета выполнения

Директива-переключателькомпилятора

, указывающими, какие ресурсы будут включены

указывающая, что производится генерация

инициирующая генерацию предупреждений

Директивы условной компиляции, определяющие компиляцию толькоодной ветви кода

Page 35: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 35

Директива

или

{$IF} ...

{$ELSE} ..I J

{SENDIF}...

$IFDEFиSIFNDEF

SIFOPT

Описание

Директивы условной компиляции, инициирующие компиляцию только вслучае, если указанный в директиве идентификатор определен(для SIFNDEF - не определен)

Директива условной компиляции, инициирующая компиляцию только вслучае, если указанная директива-переключатель находитсяв указанном состоянии

том

том

Состояние директивы-переключателя указывается символом + или -.Например: {SD+].

В директиве с параметрами после названия директивы следует соответствующийпараметр. Например, директива ($R *.res} означает, что к выполняемому файлу бу-дут добавлены все ресурсы, описанные в файлах *.res текущего каталога проекта.Директивы условной компиляции используются для исключения или включениякода, следующего за этими директивами, в компилируемый код проекта.

ВыраженияВыражение - это всегда некоторая конструкция, возвращающая значение.

Примеры выражений:

MyNum { переменная }@ MyNum { адрес переменной }45 { целая константа jC a l c ( X , Y ) | вызов функции jX " Y ( выражение, содержащее операцию * }

MyNum = 7 . 5 { логическое выражение }С in Rangel { логическое выражение }not Done { логическое отрицание }['Г, '2', '3 '] { множество }

ОперацииВ языке Object Pascal предусмотрены следующие операции:

* арифметические операции:+, -, *, /, div (целая часть от), mod (остаток от);

в логические операции:not, and, or, xor;

* логические побитовые операции:

not, and. or, xor, sh! (сдвиг значения влево на указанное количество бит), shr(сдвиг значения вправо);

Page 36: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

36 Глава 3

• операции отношений:=, о, <, >, <=, and >=;

• операции над строками:+ (конкатенация строк);

•> операции над указателями: -+, -, Л (получение значения, находящегося по адресу), =, о;

• операциями над множествами:+, -, *, <=, >=, о (не равно), in (член множества);

• операции над классами:as, is, =, <>;

• операция получения адреса- @.

Примеры операиий:

not (С in MySet)al and (a2 > 0)"Строка! '4"CTpOKa2'4strMyValal in Sstlsetl т set2Q <= mySetl

В Object Pascal установлен следующий приоритет выполнения операций:

• @, not (выполняются первыми);

• *, /, div, mod. and, sh], shr, as;

» +, -, or. xor;

« -, <>, <, >. <-, >=, in, is.

Типы данныхВсе переменные и константы, используемые в программе, всегда принадлежаткакому-либо типу. Вызов функции также возвращает значение определенноготипа.Типы данных языка Object Pascal можно разбить на следующие группы:

базовые типы данных:

* целочисленный тип;

* действительный тип;

* логический тип;

* символьный тип;

» строковый тип;

Page 37: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 37

производные типы данных;

простые типы данных:

.. порядковый тип;

• перечислимый тип;

структурированные типы данных:

• множества;

• массивы;

• записи;

• файлы;

• объектный тип (тип класса);

• тип ссылки на класс;

указатели;

процедурный тип данных.

Базовые типы данныхЦелочисленный тип

Тип

Integer

Cardinal

Shortint

Smallint

Longint

Int64

Byte

Word

Longword

Диапазон значений

-2147483648..2147483647

0..4294967295

-128..127

-327Б8..32767

-2147483648..2147483647

-2"63..2л63-1

0..255

0..65535

0..4294967295

Формат

signed 32-bit

unsigned 32-bit

signed 8-bit

signed 16-bit

signed 32-bit

signed 64-bit

unsigned 8-bit

unsigned 16-bit

unsigned 32-bit

Для указания шестнадцатеричмого значения перед ним ставится знак $.

Действительный тип

Тип

Real

Real48

Single

Double

Диапазон значений

5.0 *Ю*-324.. 1.7* 10*308

2.9* 10*-39..1.7" 10^38

1.5" 10л-45.. 3.4' 10"38

5.0* 10*-324..1.7" 10*308

Значащие цифры

15-16

11-12

7-8

15-16

Размер в байтах

8

6

4

8

Page 38: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

38 Глава 3

Тип

Extended

Camp

Currency

Диапазон значений

3.6~10л-4951 ..1.1 ' 10~4932

-2л63+1..2А63-1

-922337203Б85477.5808..922337203685477.5807

Значащие цифры

19-20

19-20

19-20

Размер в байтах

10

8

8

Для указания значения действительного типа можно использовать экспоненци-альный формат (например, значение 1.4Е-2 эквивалентно 1.4я'10"").

Логический тип

Тип

Boolean

ByieBocI

WordBool

LongBool

Диапазон значений

True или False

True млн False

True или False

True или False

Размер в байтах

1

1

2

4

Символьный тип

Тип

Char

AnsiChar

WideChar

Диапазон значений

ANSI-символ

ANSI-символ

Unicade-символ

Размер в байтах

1

1

2

Примеры;

var В: Char;Б := C h r { 6 5 ) ;

Строковый тип

присваивает символ А } 1

Тип

string

ShortString

AnsiStringin.'hhnB строМ

WideString

Максимальная длина

Определяется директивойкомпилятора SH

255 символов

— 2А31 символов

— 2"30 символов

Требуемая память

От 2 до 256 bytes

От4до26В

О т 4 д о 2 6 В

Использование

Для совместимости

8-bit (ANSI) -символы

Символы Unicode

Для строковых переменных выполняются следующие правила:

» строки могут быть постоянной или переменной длины: при объявлении стро-ки можно указать только идентификатор или идентификатор и в квадратныхскобках длину строки. Далее при любом присваивании значение будет усе-каться до указанной длины строки;

Page 39: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 39

. значение строки указывается в одинарных кавычках или как последователь-ность ASCII-символов, перед каждым из которых указывается знак if;

• доступ к символу строки можно выполнять по индексу, указываемому вквадратных скобках (например, MyString [2] := ' А ' ; ) ;

* операция сравнения (>, <) использует порядок символов в множестве и длястрок с различной длиной учитывает длину строки.

Строки типа AnsiString также называются длинными строками (long string),представляющими динамически размещаемые строки, длина которых ограниче-на только доступной памятью. Такие строки используют 1-байтовое представле-ние ANSI-символов.Реально переменная типа AnsiString является указателем, состоящим из 4 байт.Если строка пустая, т. е. ее длина равна 0, то указатель равен nil и для хранениястроки никакой памяти не используется. Если строка не является пустой, тоданная переменная указывает на динамически размещаемый блок памяти, со-держащий значение строки, на 32-битовое значение длины строки и на32-битовое значение счетчика ссылок на строку.

Несколько строк могут ссылаться на одну строку. При этом им не будет выделятьсядополнительная память, а только будет выполняться увеличение счетчика ссылок.

Примеры:

var SI

var S2MyStrMyStr

MyStr

MyStr

MyStr

MyStr

MyStr

string; {Объявление строковой переменнойпроизвольной длины)

string[3]; (Объявление строковой переменной длиной 3 символа]

= 'Присвоение значения строковой переменной';

= 'Объединение ' + 'подстрок';

= MyStr + 'Объединение со значением переменной';

= ' '; (Строка содержит пробел}

= ''; {Пустая строка |

MyStr[ ] := UpCase[MyStr[I]); (Преобразование в прописные}

#89#101|115 ; (Эта строка эквивалентна строке 'Yes1

'Строка! 1'113#10!Строка2'; {Вставка между строками

символов перевода каретки и конца строки }

'АВ' > 'А' возвращает значение True}

Производные типы данныхДля того чтобы создать переменную производного типа, такой тип сначала дол-жен быть определен. Объявление нового типа начинается с ключевого словаtype. Секция type используется для объявлений типов таким же образом, каксекция var для объявления переменных.

Page 40: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

40 Глава 3

Пример:

typeTMyColor = {Red,Blue,Green}; // Новый перечислнмый тип THyColor

TMyColors = sec ofJTMyColor; // Новый тип множестваvarValCoIorl, ValColor2: TMyColors; // Объявление переменных

// созданного нового типа множестваbeginValCoIorl := [Red];ValColor2 := ValColorl+[Blue];

end.

Множества

Тип. который позволяет определить конечное множество значений, может бытьопределен как:

« порядковый тип - значения внутри указанного интервала;

* перечислимый тип - значения, перечисленные внутри фигурных скобок ичерез запятую;

в множество - набор значений порядкового или перечислимого типа. Множе-ство определяется ключевым словом set of.

Порядковый и перечислимый типы описываются следующим синтаксисом:

в Идентификатор = Начальное_значение . . Конечное_значение;

« Идентификатор = (Знач1, Знач2, ЗначЗ, Знач4);

* Идентификатор = ЗначЗ. ,3нач4;

* Идентификатор = set of порядковый_или перечислимый тип.

Начальным и конечным значением интервала для порядкового типа могут быть:

* символы из кодовой таблицы ASCII (например, цифры или буквы);

* любой диапазон значений ранее определенного перечислимого типа.

Над множеством допустимы операции:

к объединения (+);

* разности(-);

* умножения (*);

* сравнения (<=, >=, =, о);

* принадлежности множеству (in).

Page 41: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 41

Примеры:

type

Count = 1..Э;

LowerChar = а. .я;Name = (N1, N2, N3, N4, N5, N61

MinName = N3..H5;MaxName = set of MinName;NewName= [N1]+[M2];множество )Letter = set of 'A'-.'D';varNewHame: MaxName;ValueLetter : set of 'A' 'D'

{Порядковый тип: значения от 1 до 9}

(Значения N3, 4 и 5}(Множество на основе порядкового типа)(Работа со множеством: переменной типа

(Множество: Letter - новый тип}

(Объявление переменной типа множества}(Множество: ValueLetter -переменная типа множество}

beginNewName := [N3] + [N4];

NewName := NewName - [N4]

endif Letl in Letter then ..

(Работа со множеством: переменной типа MaxNameназначается значение (множество) N3 и N4]

(Работа со множеством: из множествазначений переменной удаляется значение N 4 )

(Если принадлежит множеству, то]

: Подводя итог, напомним основные правила, которым необходимо следоватьпри работе со множествами.

1 . Объявление нового типа множества выполняется в секции type.Например: type TSomelnts = 1. .200; TlntSet = set of TSomelnts;

2. Тип множество может быть создан из любого порядкового или перечис-лимого типа.

5. Создание переменной нового типа множества выполняется в секции var.Например: var Setl: TIntSet;

4. Перед работой с переменной множественного типа ее следует проинициа-лизировать. Значения инициализации указываются в квадратных скобках.Например: begin setl : = [1,2,3,4]; end.

5. Каждая переменная множественного типа может иметь значение - множе-ство. Для изменения значений переменной множественного типа могутиспользоваться операции объединения (+) и разности (-) множеств.Например: begir, setl:=setl +[5,6]; end.

6. Для определения принадлежности значения некоторому множеству ис-пользуется операция in.Например: begin if I in setl

then ShowMessage ('Значение принадлежит множеству1 ) ;end.

Page 42: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

42 Глава 3

МассивыObject Pascal разрешает как одномерные, так и многомерные массивы.В одномерном массиве все элементы массива имеют одинаковый тип.Одномерный массив описывается следующим синтаксисом:

Идентификатор: artау[нач_индеке.. кон_индекс] of Тип_массива;

Примеры:varIntl: array[1..20] of Integer;

Int2: array[1..20] of Integer;

Int3, Int4: array[1..10] of Integer;

type IntArr = array[1..15] of Integer;

Intl := !nt2;

Частным случаем массива можно считать строку символов. В таком массиве на-чальный индекс равен 1.

Примеры:[1. Использование указателя на строку!

var P: PChar; {Указатель на строку}

const TempString: array[0..8] of Char = 'Строка'#0;

P := 'Строка';

P := STempString; {Эквивалентно предыдущей фразе}

{2. Эквивалентность типов)

varMyArray: array[0..8] of Char;

HyPointer: PChar;

begin

MyArray := 'Строка';

MyPointer := MyArray;

MyProcedurelMyArray);

HyProcedure(HyPointer);

end;

{3.Присвоение значений элементам массива j

const

Numbers: array[0. .9] of PChar = ( ' S e r e ' , 'One ' , ' T w o ' ,'Three', 'Four ' , 'Five ' , ' S ix ' , 'Seven' , 'Eight ' , ' N i n e ' 1 ;

Многомерный массив описывается следующим синтаксисом:

аггау[Диапазон_первого,индекса, . . . , Диапазон_п_индекса] of Базовый_тип

аггау[диапазон] of аггау[диапазон] of аггауЕдиапазон) of Гип;

Page 43: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 43

Примеры:

( Эти два определения массива эквивалентны)type MyMatrix = array[1. .10] of array[1..50] of Real;type MyMatrix = array[1 . .10, 1 . .50] of Real;

MyMatr ix [2 ,45] := 47;

Массив может быть статическим или динамическим,

Память под статический массив выделяется при его создании.Динамический массив не имеет фиксированного размера или длины. Память поддинамический массив выделяется не при его объявлении, а при присвоении зна-чения массиву или при вызове процедуры SetLength.Создание динамического массива описывается следующим синтаксисом:

array of Тип_элементов_массива;

Пример:

var MyArray: array of Real; (Объявление динамического массива)(Определение количества элементов в динамическом массиве:}SetLength(MyArray, 2 0 ) ;

При работе с динамическими массивами необходимо учитывать следующиеправила:

• элементы динамического массива всегда индексируются с 0;

• переменная типа динамического массива является указателем и к ней приме-нимы операции над указателями;

• для освобождения памяти, занимаемой динамическим массивом, следуетприсвоить nil переменной, ссылающейся на массив;

• динамический массив длины 0 равен значению nil;

с к переменной типа динамического массива нельзя применять операцию по-лучения значения (л);

• если переменные А и В являются динамическими массивами одного типа, тоА:-В; означает, что массив А равен массиву В, но при этом в отличие от ста-тического массива копирование значений элементов не будет выполнено. На-пример, при выполнении следующего кода значение элемента массива А[0]будет равно 5. Если бы массивы А и В были статическими массивами, то А[0]остался бы равным 1.

var А, В: array of Integer;begin

SetLength[A, 1];; E := A; B [ 0 ] := 5;end;

• количество элементов динамического массива определяется процедуройSetLength, и выход за границу массива не влечет выделения памяти (напри-мер,А[12] := 1;);

Page 44: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

44 Глава 3

• при сравнении переменных типа динамического массива выполняется срав-нение их ссылок, а не значений их элементов. Например, хотя элементы сле-дующих массивов равны (А[0] = В[0] вернет значение True), но сравнениемассивов (А = В вернет значение False):

var А, В: array of Integer,1

beginSetLengthfA, 1); 5etLength(3, 1]; A [ 0 ] := 2; B[0] := 2;

end;

* для усекания динамического массива можно использовать функцию Сору.Например: А := C o p y f A , 0, 20); {Оставляет 20 элементов массива А)

• функция Length возвращает количество элементов в динамическом массиве;

* если при объявлении функции или процедуры формальный параметр задаетсякак array of Тип массива, то эта функция или процедура может обрабаты-вать любой массив указанного типа вне зависимости от его размера, индекса-ции его элементов и от того, статический он или динамический.

ЗаписиЗапись - это структура, состоящая ич набора полей различных типов.

Каждый элемент структуры называется полем. Поле имеет свой идентификатори свой тип.Поля записи бывают двух видов:

* фиксированные поля, которые если определены, то всегда присутствуютв создаваемом экземпляре записи;

• вариантные поля (располагаются всегда после фиксированных): память присоздании экземпляра записи выделяется только под одно самое наибольшееполе из варианта.

Вариантные поля позволяют на основе одного типа записи создавать экземпля-ры записей, содержащие различные поля. Это значительно экономит память.

Запись описывается следующим синтаксисом:

type Имя_типа_записи = recordПоле_1_или_список_полей: Тип_1; [фиксированные поле)

Поле_г._или_список_полей: Тип_п;case тег: Тип_варианта of {вариантные поля)

константа_или_список1: (вариант!};

константа_или_списокп: (варианта);end;

Объявление типа записи должно удовлетворять следующим правилам:

» после зарезервированного слова type следует имя создаваемого типа, а далее= record;

Page 45: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 45

« все фиксированные поля располагаются перед вариантной частью;

т описание каждого фиксированного поля состоит из его идентификатора (илисписка идентификаторов) и типа;

* описания полей разделяются точкой с запятой;

* вариантная часть объявления записи начинается с зарезервированного словаcase;

а константа_или_список является константой или списком констант, перечис-ленных через запятую;

* тег и символ двоеточия могут быть опущены в том случае, если:

* Тип_варианта описывает существующий тип,

* каждая константа (константа_или_список) в вариантной части являетсязначением типа Тип_варианта;

* ни одно значение не может быть представлено в списке более одного раза;

* если тег присутствует, то он функционирует как поле в невариантной части записи;

* каждый вариант описывается аналогично описанию фиксированных полейи представляет собой имя константы, двоеточие и заключенный в скобкисписок определений полей.

Например: Fl : (f ieldListl : typel; fieldListn: typen];.

а тип не может быть длинной строкой, динамическим массивом, типом Variantили интерфейсом, но он может быть указателем на эти типы.J

Для создания переменной типа записи можно;

* сначала определить новый тип записи, а затем объявить переменную данного типа;

* указать при объявлении переменной тип record и далее сразу описать поляобъявляемой записи.

Пример:

type (Объявление типа записи}

MyDateRec = record

Year: Integer; {Первое поле}

Month: (Jan, Feb, Mar, Apr, May, Jun,

Jul, Aug, Sep, Oct, Nov, Dec); (Второе поле}

Day: 1..31; (Третье поле}

end;

var Recordl, Record2: MyDateRec; (Объявление переменных}

Recordl.Year := 1904; {Доступ к полю Year}

Recordl.Month := Jun; {Доступ к полю Month }

Recordl.Day := 16;

Page 46: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

46 Глава 3

with Recordl do {Доступ к полям записи}

begin

Year := 1904; Month : = Jun; Day : = 16;

end;

{Копирование значений полей Recordl в RecordS }Record2:= Recordl;

var S: record {Объявление записи одновременно }

Name: string; {с определением ее полей}

Age: Integer;

end;

type {Объявление записи с вариантными полями}

TPerson = record

FirstName, LastName: string[4Q];

BirthDate: TDate;

case Citizen: Boolean of

True: (Birthplace: string[40]);

False: {Country: string[20]; EnDate, ExitDate: TDate);

end;

type (Объявление записи с вариантными полями}

TShapeList = (Rectangle, Circle, Other, Ellipse);

TFigure = record

case TShapeList of

Rectangle: (Height, Width: Real);

Circle: (Radius: Real);

Ellipse, Other: (J;

end;

Файлы

Файлом называется упорядоченный набор элементов одного типа.Стандартные процедуры ввода/вывода используют предопределенный типTextFile, или Text, который представляет файл как упорядоченный набор строксимволов.Определение типа file описывается следующим синтаксисом:

type Гип_файла = file of Тип; {описание типа}var Идентификатор: file of Тип_файла; {объявление переменной типаf i le}var Идентификатор: file; {объявление переменной типа нетипиэированного

f i le для низкоуровневого доступа к файлу}

Для создания переменной типа fi le можно:

* предварительно определить тип, а затем объявить переменную созданного типа;

• сразу объявить переменную типа tile, указав его тип.

Page 47: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 47

Примеры:

typePhone = record

FirstName, LastName: s ^ r i n g [ 2 0 ] ;PhoneNumber: string[15];

end;PhoneList = file of Phone; {Объявление типа Phop.eList }var Lis t l : PhoneList;

(объявление переменной типа f i le с указанием его типа)var LisL2: file of Phone;

Обьектный тип (тип класса)Тип класса, называемый также объектным типом, объявляется всегда как гло-бальный для модуля или программы. Объявление типа класса, следовательно,не может быть расположено внутри процедуры или функции.Класс - это набор методов и переменных (иногда называемых полями или свой-ствами].Методы и поля класса также называются членами масса.Описание (объявление) класса - это создание нового типа, содержащего пере-менные и методы.Объявление переменной типа класса - это создание экземпляра класса (объекта).Описание класса (типа класса) указывается следующим синтаксисом:

type Имя_класса = class (Имя_кг.асса_предка)private [тело класса)

Список_членов классаprotected

Список_членов классаpublic

Список_членов классаend;

Модификаторы доступа определяют область видимости переменных и методовкласса:

published — переменные и методы класса общедоступны в любом месте моду-ля, переменные будут отображены как свойства в инспекторе объектов;public — общедоступны в любом месте модуля;protected - доступны только для данного класса и его потомков;private - доступны только внутри класса.

Класс может не содержать ни одного метода или переменной.При создании новой формы в Delphi автоматически создается модуль с описани-ем класса, производного от TForm. Каждый новый компонент, располагаемый наформе, добавляется как переменная член класса.Тело класса содержит только объявления методов (процедур или функций), а ихреализация описывается далее в implementation-секции модуля.

Page 48: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

48 Глава 3

Пример:

type {Определение типа TForral ]TForml = class(TForm)private

{ Private declarations }public

i Public declarations }end;

var Forml: TForml; {Объявление переменной типа TForml }

Переменной типа класса предка всегда можно присвоить значение типа классапотомка (может ссылаться на экземпляр класса потомка).

Пример:

(Переменной Fig можно присвоить значение типа TFig, TRect или TSquare}

type

TFig = class (TObject);

TRect = class[TFig);

TSquare = class(TRect);

varFig: TFig;

Тип ссылки на классТип ссылки на класс, иногда называемый метаклассом, является указателем натип класса.

Тип ссылки на класс описывается следующим синтаксисом:

type Имя_ ссылки = class of Тип_класса_для_ссылки;

Ссылки на класс используются для вызова метода класса, чей тип неизвестенв момент компиляции.

Код type TClass = class of TObject; var AnyObj: TClass; определяет пере-менную AnyObj, которая может содержать ссылку на любой класс.

Если присвоить переменной ссылки на класс типа TObject значение какого-либопроизводного класса, то затем идентификатор ссылки (AnyObj в данном случае)можно использовать для вызова методов класса. Например: AnyObj=TEdit;NewEditl= AnyObj .Create(Forml) ; .

УказателиУказатель — это переменная, содержащая адрес памяти.

Например, переменная типа массива - это указатель, содержащий адрес первогоэлемента массива.

Указатель позволяет создавать переменные, ссылающиеся (содержащие адрес)на данные задаваемого типа. Размер указателя равен 4 байтам.

Основными операциями, выполнимыми над указателями, являются:

Page 49: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 49

» " после переменной типа указателя - получение значения, находящегося поадресу, расположенному в переменной типа указателя. Например: Value := РЛ;

Л перед идентификатором L M L I L I - создание указателя на :1срсм..чт\ю \ к а ч ; ш -ноготипа. Например: Р; "Integer;;

* @ - получение адреса переменной (процедуры или функции).

Объявление и создание указателя описываются следующим синтаксисом:type Тип_указателя = Тип; (описание типа "указатель на тип"]

var Идентификатор: "Тип; {объявление переменной типа указателя}

Пример:

varX, У: Integer; {Объявление переменных X и '/ типа Integer}Р:

AInteger; ( (Р - это указатель на тип Integer}

beqin

X := 33; {Присваивание значения переменной X}Р := @Х; {Указателю Р присваивается адрес переменной X}Y := Р А ; {Получение значения, находящегося по

адресу, содержащемуся в переменной Р;присвоение этого значения переменной У}

end; {Значение X равно значению У и равно 33}

Для назначения адреса существующему указателю можно использовать проце-дуры New и GetMem.

Функции Addr и Ptr возвращают указатель на заданный адрес или значение.

Указателю может быть присвоено -значение nil, В этом случае говорят, что ука-затель не определен.Указатели можно использовать и при квалификации имен.Например: Pl".PointIntA .

В Delphi определено много типов указателей для данных различных типов. Так.для символьных типов Clmr, AnsiChur и WideChar существуют типы-указателина них: PChar, PAnsiChar и PWideChar.Модули Delphi System и SysUtils определяют много стандартных ти-пов-указателей: PAnsiString, PString, PByteArray, PCurrency, PExtended.POleVariant, PShortString, PTcxtBuf, PVarRec. PVariant, PWideString, PWordArray.

Структурированный типСтруктурированный ппт - PJTO набор значений различных типов. Такой тип мо-жет включать типы множеств, массивов, записей, файлов, классов, ссылок наклассы и типы-интерфейсы.Если при определении структурированного типа указано зарезервированноеслово packed, то данные будут храниться в сжатом состоянии.

Page 50: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

50 Глава 3

Многомерный массив можно рассматривать как структурированный тип, кото-рый описывается следующим синтаксисом:

array [Диапазон_первого, индекса , . . . , Диапазон_п_индекса] of Еазовый_тип

packed array [Тип__или_диапазон] of packed аггау[Тип__или_диапазон] ofpacked array [Тип_или_диапазон] of Тип;

Примерами структурированного типа являются классы, массивы, записи, файлымножества и другие типы.

Определение типа и объявление переменных

Определение типаДля определения типа используется зарезервированное слово type.

В предыдущих разделах был рассмотрен синтаксис объявления различных типовязыка Object Pascal.

Примеры:

type {Определение типа, равного Integer}

Tl = Integer;

12 = Tl;ТЗ = Integer;

Т4 = Т2;type TMylnteger = type Integer; {Определение типа, отличного

от типа Integer }

type {Определение двух различных типов)

TS1 = set of Char;

TS2 = set of Char;var [Объявление двух переменных различных типов}

SI: string[10] ;32: str ing[10] ,-

var SI, S2: string[10] ; {Объявление двух переменных одного типа]

Объявление переменныхТип переменной или константы и ее идентификатор определяются при объявлении. .

Перед объявляемой переменной или списком переменных указывается операторобъявления var.Например: var Numi integer; Str: string;.

Объявление переменной описывается следующим синтаксисом:

Идентификатор_перем1 : Тип; {Тип - любой достоверный тип данных)Идентификатор_переы2 : Тип;

При описании функции объявляются тип возвращаемого значения и типы фор-мальных параметров,. передаваемых в функцию.

Page 51: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 51

Объявление функцийОбъявление функции описывается следующим синтаксисом:

function Функция(Список_парам1: Тип1; Список___парам2: Т и п 2 ) : ТипЗ;I Список_парам содержит имя переменной или список переменных одного типа }

Объявление функции (или процедуры) должно удовлетворять следующим пра-вилам:

* формальные параметры указываются в круглых скобках;

* список переменных одного типа указывается через запятую;

• тип формального параметра (или списка параметров) указывается после сим-вола двоеточия;

« сами формальные параметры отделяются друг от друга точкой с запятой;

• порядок перечисления параметров при вызове функции должен соответство-вать порядку формальных параметров при объявлении функции.

КонстантыКонстанты бывают двух видов:

• простые константы:

s которые не могут содержать значения типа массива, записи указателя илизначения процедурного типа;

• могут использоваться в выражениях;

* типизированные константы:

• которые не могут использоваться в выражениях;

« могут содержать значения типа массива, записи, указателя, или значенияпроцедурного типа;

• при определении которых указывается не только значение, но и его тип.

Если указана директива компилятора {$J+|, то значение типизированной кон-станты можно изменять во время выполнения (по умолчанию). Такая константаведет себя как проинициализированная переменная. Если указана директивакомпилятора (SJ—}, то значение типизированной константы нельзя изменять вовремя выполнения. Ее поведение аналогично переменной только для чтения.

Определение констант описывается следующим синтаксисом:

const Идентификатор: Тип = Значение; (типизированная константа!const Идентификатор = Константное_выражение; (простая константа)

Примеры:

const Max: Integer = 100;

const Min = 1;

Page 52: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

52 Глава 3

const Expr = 3+Min;const Message = 'Сообщение1;

Константным выражением называется такое выражение, которое может бытьинтерпретировано компилятором без выполнения программы. Оно может со-держать выражение, состоящее из других констант, значений True, False и ni l ,цифр и символов, значений перечислимого типа. Константное выражение неможет включать переменных, указателей или вызовов функций, за исключениемследующих: Abs. Chr, Hi. High, Length, Lo, Low. Odd, Ord, Pred, Round, SizeOf.Succ, Swap, Trunc.

Примеры:

{Константные выражения могут быть определены как:

100

'А'(7.5 + 1) / (7.5 - Ц'Строка!

1 + ' ' + 'Строка2'

Chr(32)

Ord('Z') -Ord('A') + 1

Константа массивДля определенийя константы массив следует:

* после зарезервированного слова const указать имя массива (после const мо-жет быть перечислено несколько различных типов констант);

* далее после двоеточия указать конструкцию array [Ин-де кс_нач..Индекс_ксш] of Тип_элементов_массива =, для многомерного мас-сива диапазоны индексов отделяются запятой;

а после знака равенства в круглых скобках перечислить значения всех элемен-тов. Иногда, например для массивов, представляющих строки с ограничиваю-щим нулем, скобки могут быть опущены, а значение указано одной строкой.

Примеры:const MyChar: array[0. .9] of Char - ( ' 0 ' , ' ! ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' ,

' 6 ' , ' 7 ' , ' 8 ' , - 9 ' ) ;const MyChar: array[0..9] of Char = '0123456789'; {Трехмерный массив:}type АггЗ = array[0. .1, 0..1, 0 . . 1 ] of Integer;const MyArr: Arr3 = ( ( ( 0 , 1], (2, 3 ] ) , ( ( 4 , 5 ) , ( 6 , 7 ) » ;(Это эквивалентно массиву, элементы которого равны:}M y A r r [ Q , Q , O j = 0; MyArr[0,0, l] = 1;M y A r r [ 0 , I , 0 ] = 2; МуАгг[0,1,1] = 3;М у А г г [ 1 , С , 0 ] = 4; М у А г г [ 1 , 0 , 1 ] = 5;МуАгг[1,1,0] = 6; МуАгг[1,1,1] = 7;

Page 53: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 53

Константа записьДля определения константы запись следует указать значение каждого поля.

Например:

typeMyPoint = recordX, Y: Integer;

end;MyLine = a r r a y [ 0 . . l ] of MyPcint;

const (Определение констант)ConPoint: MyPoint = (X: 7 / Y : 13];

ConLine: MyLine = ( ( X : 3 ; Y: 1), ( X : 15; Y: 9 ) ) ;

Процедурные константыДля определения процедурной константы следует указать идентификатор про-цедуры или функции, совместимый с типом константы. Процедурной константеможно присваивать значение n i l .

Например:

function Plus(X, Y: Integer): Integer;begin ...end;type MyFun = function(X, Y: Integer): Integer;const ConFunction: HyFun = Plus; [Определение константы)(Использование процедурной константы вместо вызова функции:}Surama:= ConFunction(5, 1 } ;

Указатели константыПри определении константы указателя следует инициализировать ее значением,которое может рассматриваться компилятором как адрес. Наиболее просто этоможно выполнить, указав:

• операцию взятия адреса- @ для функции или глобальной переменной ';

> значение nil;

* строку символов" для константы типа PCIiar.

Например:

const PI: "'Integer = @1; {Если I глобальная переменная типа Integer }const PF: Pointer = @MyFunct ionl ;const PStr: Khar = 'Глобальная строковая константа 1 ;

Константе указатель нельзя присваивать значения адреса локальных (размещае-мых в стеке) или динамических (размещаемых в куче) переменных.

1 Глобальная переменная является частью сегмента кода: поэтому компилятор можетопределить ее адрес.

Строка символов размещается а памяти кап глобальная константа.

Page 54: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

54 Глава 3

Приведение типов

Для переменных может выполняться процедура явного или неявного приведениятипа. Например, при делении переменной целочисленного типа на другую пере-менную целочисленного типа результат может не быть целочисленным типом.В этом случае выполняется неявное приведение типа результата.Явное приведение типа описывается следующим синтаксисом:

Идентификатор_типа(Выражение]

Примеры:

var I: Integer;

[Явное приведение символьного типа к целочисленному:}!:=Integer('C');

var MyCr.ar: char;

Shortint(MyChar) := 112; (Явное приведение типа}

Не следует путать приведение типов и преобразование данных из одного типав другой. В первом случае явно или неявно указывается допустимое приведениетипов. Во втором случае используются функции преобразования типа.

Пример:

(Рассмотрим ферму, содержащую три поля (рис. 5.1): два для значений типа

Integer и одно для Real; вычисление полей выполняется при щелчке мышьюв любом месте формы}

varIl,l2:Integer;Rl: Real;

Forml: TForml;

implementationprocedure TForml.FormGlick(5ender: TObject);

beginII:=StrroInt[Edit1.Text); {Преобразование типа)12:=SttToInt(Edit2.Text);

R1:=I1/I2; (Неявное приведение типа}EditS.Text:= FloatToStrF(Rl,ffGeneral,5,5);end;

Wftuml

[32

Рис. 5.1. Отображение значений типа Integer и Real в компонентах rnnaTEdit

Page 55: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 55

Совместимыми типами являются типы, для которых выполняется одно из сле-дующих правил:

в тип класса совместим с любым родительским типом;

* оба типа целочисленные;

* оба типа действительные;

* оба типа процедурные и тип результата, количество параметров и их типыидентичны;

* оба типа - это указатели на переменные одного типа;

* оба типа - это множество и его подмножество.

Для совместимых типов всегда доступно неявное приведение типов.Явное приведение типов можно указывать как справа, так и слева от знака при-сваивания. Функции преобразования типа указываются только в выражениисправа от операции присваивания.

Пример:

(Явное приведение типов}

type

TByteRec = record Lo, Hi: Byte; end;TWordRec = record Low, High: Word; end;PByie = "Byte;

varB: Byte; W: Word; L: Longini; ?: Pointer;

begin

W

в13

LW

вв

= $6789;

= TByteRec (W) .Lo;

'teRec(W).Hi := 0;= $01234567;

= TWordRec (L) .Low;

= TByteRec (TWordRec (L|= PBytetL)";

(Доступ[Доступ

(Доступ

.Low] .Hi;

Y.

K.

к

младшемустаршему

младшему

байту)

байту}

слову }

end;

ПРОУЕЛУРЫ и шункиииОпределение процедур и функиий

Определение процедуры описывается следующим синтаксисом:

procedure procedureName(Список_параметров|; директивы;С е кцкя_ло кал ь ных_объ я вл е ний;begin

операторыend;

Page 56: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

56 Глава 3

Блок описывается следующим синтаксисом:

function functionName(CnMCOK_napaMeTpoB) : returnType; директивы;Секция_локальных_объявлений;begin

операторыResult :=возврашемое значение; (Глобальная переменная Result )functionName:=возвращаемое значение;

end;

Процедура или функция может иметь список параметров. Для задания спискапараметров применяются следующие правила:

• список формальных параметров1 указывается при описании процедуры илифункции в круглых скобках;

• в списке параметров определяется количество, порядок и тип передаваемыхпараметров;

• тип формального параметра должен соответствовать типу фактического па-раметра, передаваемого при вызове процедуры или функции, при этом пере-даваемый параметр может указываться выражением;

• любому параметру может быть назначено значение по умолчанию, котороеуказывается после символа равенства. Параметры, имеющие значения поумолчанию, должны завершать список формальных параметров;

• при определении параметров перед ними можно указывать зарезервирован-ные слова var и const;

• если процедура или функция не имеет списка параметров, то при их описа-нии круглые скобки после идентификатора процедуры или функции не ука-зываются;

• возвращаемое функцией значение присваивается или переменной Result, илиимени функции.

Примеры:

function PO(X: Real; Y: Integer): Real;procedure Pi(X, Y: Real);

procedure P2!var S: string; X: Integer);procedure P3(HWnd: Integer,- Text, Caption: PChar) ;

procedure P4(const P; I: Integer);

procedure P5;

function F l f X : Real; Y : Integer): Real;beginResult := 1.0; ( Эквивалентно оператору Fl:= 1.0;}end;

1 Иногда формальные параметры называют просто параметрами процедуры или функции.

Page 57: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 57

В теле функции можно многократно присваивать возвращаемое значение илипеременной Result, или имени функции. После выхода из функции будет воз-вращено последнее присвоенное значение.При определении процедуры или функции могут быть указаны следующие ди-рективы, определяющие соглашения о вызове:

Директива

register

pascal

cdecl

stdcall

safecall

Порядок передачипараметров

Слева направо

Слева направо

Справа налево

Справа налево

Справа налево

Где выполняетсявыгрузка параметров

В вызываемой процедуре

В вызываемой процедуре

В вызывающей процедуре

В вызываемой процедуре

В вызываемой процедуре

Использование регистровдля передачи параметров

Да

Нет

Нет

Нет

Нет

При вызове функций из DLL-библиотеки, разработанной на C++, следует указы-вать директиву cdecl, а для вызова Windows API-функций используются дирек-тивы stdcall или safecall.

Перегрузка процедур и функцийЕсли в одной области видимости (программа или модуль) определены более од-ной процедуры (функции) с одинаковыми идентификаторами, директивойoverload и различными списками параметров, то такие процедуры (функции) на-зываются перегружаемыми. При вызове будет выбрана та перегружаемая про-цедура (функция), чей список формальных параметров соответствует списку пе-редаваемых параметров вызываемой процедуры (функции).

Пример:

function Divide(X, Y: Real): Real; overload;

begin Result := X/Y; er.d;

function Divide(X, Y: Integer): Integer; overload;

begin Result := X div Y; end;

ОПЕРАТОРЫОператор присваивания

Оператор присваивания описывается следующим синтаксисом:

переменная := выражение;

Примеры:

I := 3;

LogVar := (I >= 1) and (I < 5 ) ;

Page 58: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

58 Глава 3

VarColorl := [Blue, S u c c ( C ) ) ;IntVar := Sqr(J) -I ' K;Shortint(MyChar) := 112;

Вызовы процедур и функцийВызов процедуры или функции - это простой оператор, состоящий из иденти-фикатора вызываемой процедуры или функции и списка передаваемых парамет-ров. После него, как и после любого оператора, следует указывать символ ;.

Структурированные операторыЯзык Object Pascal содержит ряд структурированных операторов. Такие опера-торы позволяют управлять ходом выполнения программы и содержат в себе дру-гие операторы. Условно структурированные операторы можно разбить наследующие группы:

••:>, составной оператор, который выполняет последовательность операторов(оператор begin...end):

. условные операторы, которые выполняют различные последовательностидействий в зависимости от задаваемого условия (операторы if...then, case);

* операторы цикла, повторно выполняющие одну и ту же последовательность(операторов repeat, while, for. with...do);

*, операторы исключений, предназначенные для определения и обработки оши-бок (операторы raise, try...except н try...finally).

Составной оператор begin...endОператор begin...end также иногда называется б.чоком.Составной оператор - это последовательность других операторов (простых илиструктурированных), выполняемая в порядке их написания.

Пример:

beginI := 10; J := I; I := 50;

end;

Отметим, что перед end можно не ставить символ ;.

В Object Pascal составной оператор также используется в тех местах, где синтак-сис требует простого оператора. Например, в операторах цикла, в процедурахи функциях.

Оператор i f . . . thenУсловный оператор if может иметь две формы: if...then и if...then...else.

Этот оператор описывается следующим синтаксисом:

Page 59: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 59

if выражение then оператор; {первая форма)

if выражение then оператор! else оператор2; {вторая форма}

if выражение! then {вложенные if-сператоры}if выражение2 then

оператор!

elseоператор2;

Выражение возвращает значение типа Boolean. Если это значение равно True, товыполняется оператор, указанный после then; если выражение равно False, тов операторе первой формы никаких действий не выполняется, а в операторе вто-рой формы выполняется оператор, указанный после else.Оператором может быть любой оператор, включая составной операторbegin...end, содержащий последовательность других операторов, а также самоператор if.

Пример:

if (I > 0| and (I < 15) then Count := 1*1; else Count := I;{Следующие два if-оператора эквивалентны)

if I <> 0 then Count := Max/I;

if I - 0 then Exit else Count := Max/I;

Оператор case...endОператор case реализует выполнение одного из нескольких вложенных блоков(операторов) в зависимости от значения условного выражения.Оператор case описывается следующим синтаксисом:

case условное_выражение ofсписок_значений!: оператор!;

список^значенийп: операторп;else {необязательная часть}оператор;end;

Условное выражение в операторе case может быть выражением любого упорядо-ченного типа, включая целочисленный, символьный (но не строковый), логиче-ский, перечислимый, а также диапазоны значений. Упорядоченным типомв языке Object Pascal называется такой тип, у любого значения которого, за ис-ключением первого и последнего, однозначно определено предыдущее и после-дующее значение.Список значений в операторе case может быть представлен одним значениемили набором значений, перечисленных через запятую. Каждое значение из спи-ска значений может быть числом, объявленной константой или другим выраже-нием, чей тип совместим с типом условного выражения. Дополнительно требу-ется, чтобы компилятор мог определить указываемое выражение без выполне-ния программы.

Page 60: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

60 Глава 3

Из сказанного следует, что ни переменные, ни вызовы функций не могут бытьуказаны в списке значений .

Элемент фразы else оператора case определяет необязательную часть, в которойуказывается оператор, выполняемый в том случае, если условное выражениене равно ни одному значению из списка значений.Отметим, что для более быстрого выполнения оператора case списки значенийследует упорядочивать по возрастанию.

Пример:

{Определение диапазона, к которому принадлежит значение}

case I of

1..10: Caption := '1-10';

11. .20: Caption := '11-20';

О, 10..99: Caption := 'Недопустимое значение';

else

beginCaption := ";

Beep;

end;end;

Операторы никлаЦиклы реализуют повторное выполнение заданной последовательности опера-торов. Object Pascal имеет три типа операторов цикла: repeat, while и for.

Для выхода из цикла следует вызвать процедуру Break, а для перехода на началоследующей итерации выполнения последовательности операторов - процедуруContinue.

Оператор for

В операторе for, в отличие от других операторов цикла, должно быть указаноколичество итерации (выполнений последовательности операторов).Оператор for описывается следующим синтаксисом:

for счетчик_цикла := нач_значение to кон_значение do оператор;(или;for счетчик_цикла := нач_эначен^е downto кон_значекие do оператор;

При входе в цикл счетчику будет присвоено начальное значение. Количествоитераций определяется как кон_значение - нач_значение+1 (при увеличениисчетчика).

При каждой новой итерации значение счетчика увеличивается (элемент фразыto) или уменьшается (элемент фразы downto).

1 Некоторые функции, которые могут быть в константном выражении, такие, как Abs, Chr,HI, могут соответственно присутствовать в списке значений.

Page 61: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 61

Последняя итерация будет выполнена при значении счетчика, равном указанно-му конечному значению.J

Начальное и конечное значения определяются выражениями допустимого типа(упорядоченного).

Оператором цикла может быть любой простой или структурированный опера-тор. Ни один из операторов, указываемых внутри цикла, не должен изменятьзначение счетчика цикла.

После завершения цикла значение счетчика неопределенно.

Вместо оператора for можно записать слудующие операторы, включающиецикл while:

begincounter := initialValue;

while counter <= finalValue do

begin

statement;counter := Succ(counter); (Увеличение счетчика)

end;end

Основным отличием между операторами цикла for и whi le является то, что опера-тор for всегда выполняется хотя бы один раз, а оператор while проверяет условиеперед первой итерацией и поэтому может не быть выполненным ни одного раза.

Пример:

Мах :- AData[1] ;for I := 1 to 24 do {Нахождение максимального элемента!

if AData[I] > Max then (Структурированный оператор)beginMax := AData[I ] ; Iraax := I;

end;

Оператор while

Оператор whi le описывается следующим синтаксисом:

while лсгическое_выражение do оператор;

Логическое выражение оператора while проверяется до выполнения операторавнутри цикла. Этот оператор выполняется только тогда, когда значение логиче-ского выражения равно True.

Оператором в цикле while может быть любой простой или структурированныйоператор.

Пример:

while not Eof(InputMyFile) dobegin Readln(InputMyFile, Lire); end;

Page 62: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

62 Глава 3

Оператор repeat

Оператор repeat описывается следующим синтаксисом:

repeat оператор!; . . . ; оператор"; until логическое_выражение;

Логическое выражение оператора repeat проверяется после выполнения вло-женных операторов. Поэтому операторы в цикле repeat выполняются хотя быодин раз.

Цикл выполняется до тех пор, пока логическое выражение не вернет значение True.

Оператор repeat, в отличие от других операторов цикла, может иметь не одинпростой или составной выполняемый оператор, а последовательность таких опе-раторов.

Пример:

repeatWrite!'Введите символ[1..9): '); Readln(I);

until (I >= 0) and (I <= 9);

Оператор withОператор with позволяет в сокращенной форме, без квалификации имени, ссы-латься на поля записи или методы, свойства и поля объекта.

Оператор with описывается следующим синтаксисом:

with объект do оператор;{или)with объект!, . . . , объектп do оператор;

Если оператор with содержит несколько объектов, квалифицирующих доступ, тосначала для поля, метода или свойства будет выбран объектп. Если он не подхо-дит как квалификатор имени, то будет выбран объект объект п-1 и т. д.

Пример:

type TDatePhone = record {Тип запись}

Name: string[24];

Phone: string[14];

Fax: string[I4];end;var EntryPhone: TDatePhone; {Объявление переменной)

with EntryPhone do ' (Доступ к полям записи]

if Name <> nil then

beginPhone:= ' (095)Ч Phone;

Fax:= ' (095)Ч Fax;

er.d;

Page 63: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 63

Операторы goto и labelОператоры goto и label описываются следующим синтаксисом:

label Метка!, Метка2;

goto Кетка!;

Метка!: оператор;

Оператор goto называется оператором безусловного перехода. Он указываетметку, на которую следует перейти для дальнейшего выполнения программы.Метка перехода должна быть предварительно объявлена оператором label. Дляопределения точки перехода следует укачать идентификатор метки и символдвоеточия.Меткой может быть любой допустимый идентификатор или число в диапазонеот 0 до 9999.Объявление метки и операторы gone и label должны быть расположены внутриодного блока.Нельзя выполнять безусловный переход внутрь цикла или других структуриро-ванных операторов.

Операторы исключений

Объявление исключенияИсключение* или исключительная ситуация, происходит в программе в том слу-чае, когда возникает какая-либо ошибка, определяемая программно или опера-ционной системой. К ошибкам, которые фиксирует операционная система, отно-сятся попытка деления на нуль, ошибки при выполнении операций вво-да/вывода, ошибки обращения к памяти. Модуль SysUtils содержит ряд предо-пределенных исключений (например, EDivByZero - ошибка деления на нуль).

Для того чтобы ваше приложение не давало непредвиденных сбоев или «зависа-ний» операционной системы, очень важно заранее предусмотреть возникнове-ние всех возможных исключительных ситуаций и определить для каждого ис-ключения блок действий для обработки ошибки.В языке Object Pascal для работы с исключениями реализованы следующие опе-раторы:

» raise - для создания объекта исключение;

« try. . .except-для определения блоков обработки конкретных исключений;

* try. .. finally - для определения одного блока обработки всех исключений.

После оператора try размещается последовательность операторов, в которойвозможно возникновение исключения. После элемента фразы except или finallyразмещаются блоки обработки ошибок.

Page 64: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

64 Глава 3

Исключения - это классы, производные от класса Exception. Тип исключениеобъявляется так же, как и любой другой класс. Информацию об исключенииможно получить из следующих свойств класса Exception: Message (сообщениеоб ошибке) и KelpContext (контекст файла справки).

Модуль SysUtils содержит несколько стандартных процедур для обработки ис-ключений (например, ExceptObject, ExceptAddr, ShowException).

Пример:

type {объявление исключений}

EMathError = class (Exception);

EZeroDivide = class(EMathError};

EOverflow = class (EMathError);

Управление и с к л ю ч е н и я м и

Оператор raiseСоздание объекта исключение - это фактически программный путь инициацииошибки. Иногда это называется бросать ш-ключепие.Обработка исключений реализуется одинаково как для исключений, определяе-мых операционной системой, так и для инициированных программно.

Для создания объекта исключение следует в операторе raise вызвать конструк-тор класса. Например: raise EMathError.Create;.

Оператор try...exceptОператор try...except состоит как бы из двух частей. Первая - это последова-тельность операторов, указываемая между try и except, называемая блокомвозможного возникновения исключения. Вторая часть - это блоки обработкиисключений: оптип_исключепия do оператор.

Оператор try...except описывается следующим синтаксисом:

tryоператоры

excepton идентификатор!: тип_исключения! do оператор!

(двоеточие и тип исключения могут быть опущены}on идентификатора: тил_исключеничп do операторп

else (необязательная часть}оператор_для_любого_исключения

end

Если перед типом исключения указан идентификатор объекта исключение, тоего можно использовать для доступа к объекту исключение в операторе, указан-ном после элемента фразы o n . . . do.

Элемент фразы else является необязательным и позволяет определить оператор,который будет выполняться в том случае, если для возникшего исключения не

Page 65: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 65

найден ни один обработчик исключений: тип исключения, указанный после эле-мента фразы on, не совпадает с типом произошедшего исключения.

Пример:

tryX := Y/Z;

except {Попытка деления на 0}

on EDivByZero do ProcZeroDivide;end;try

excepton E: Exception do ErrorDialog(E.Message, E.HelpContext);

end;

При возникновении исключения внутри оператора t ry . . .except последователь-ное выполнение программы прерывается и управление передается на блок обра-ботки исключения.При возникновении исключения внутри процедуры или функции, указаннойвнутри блока try, стек освобождается и управление передается на блок обработ-ки исключения в вызывающей процедуре. Таким образом, все процедурыи функции, вызванные после оператора try, в котором возникло исключение,будут удалены из стека.Если какое-либо обрабатываемое исключение является предком других обраба-тываемых исключений, то его следует указывать последним.

Пример:

try

excepton EZeroDivide do ProcZeroDiv;on EOverflow do ProcOverflow;

{Если EMathError указать первым, то другие исключения никогда не будутнайдены, так как EZeroDivide и EOverflow являются его потомками)

on EMathError do ProcMathErr;end;

Если в блоке обработки исключений выполняется бросок другого исключения,так называемого вложенного исключения, то управление передается на обработ-ку этого нового исключения. При этом обработка первоначального исключенияне будет завершена.

Пример:

typeETrigError = class(EMathError};

3 Эак. 1 1

Page 66: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

66 Глава 3

function M y T a n ( X : Extended): Extended;begin

tryResult := S i n ( X ) / C o s ( X ) ;

excepton EMathError do

{Бросок исключения внутри блока обработки исключений:}raise ETrigError.Create ('Неправильный п а р а м е т р ' ) ;

{управление будет передано на обработку исключенияETrigError }

end;end;

При выполнении приложения в среде Delphi перехват исключения выполняет непрограмма, а сама среда выполнения. Для того чтобы в целях отладки отклю-чить перехват исключений средой Delphi, следует выполнить команду менюTools| Debugger Options и на вкладке Language Exceptions снять флажок Stop onDelphi Exception.

Оператор try...finallyОператор try. . - f inal ly позволяет определить блок действий, выполняемыйвсегда: и при возникновении исключения, и при его отсутствии.Оператор try. .. f inally описывается следующим синтаксисом:

tryсписок_опеpaтopов1

finallyсписок_операторов2

end;

Пример:

{И при возникновении ошибки обработки файла, и в случае успешногозавершения обработки файл всегда будет закрыт}try

{Открытие и чтение файла F)finally

CloseFile(F);end;

Стандартные классы исключенийВ библиотечных модулях Object Pascal объявлены классы стандартных исклю-чений, которые также называются предопределенными исключениями.Основные классы исключений определены в модуле SysOtils. Это следующиеклассы:ЕАЬогс - исключение, при котором не отображается сообщение об ошибке;

Page 67: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 67

EAbstractError - исключение происходит при попытке вызова абстрактного ме-тода класса;EAccessViolation - исключение происходит при ошибке доступа к памяти;

EAssertionFailed - исключение происходит, если процедуре Assert передаетсялогическое выражение, равное False;EControlC - исключение происходит, если пользователь в процессе выполненияконсольного приложения нажимает клавиши Ctrl-t-C;EConvertError - исключение происходит при попытке недопустимого преобра-зования данных из строки в целочисленное или действительное значение, а так-же в значение типа даты или обратно. Также это исключение происходит приневерной попытке присвоения одного типа компонента, производного отTPcrsistent, другому;EDivByZero - исключение происходит при делении на нуль целочисленных зна-чений;EExternal — при броске исключения посредством Windows содержит структурус информацией об исключении;EHeapException - ошибка распределения памяти «в куче»;

EInOutError-исключение происходит при ошибке ввода/вывода;

EIntError - этот класс является предком всех классов исключений для арифме-тических ошибок над целыми числами;EIntOverflow - исключение происходит при получении слишком большого це-лочисленного значения (для размещения его в регистре) и только в том случае,если установлена директива компилятора {$Q+(;EIntfCastError - исключение происходит при ошибке приведения типа интер-фейса в операторе as;EInvalidCast - ошибка приведения типа;

EInvalidOp - исключение происходит при неопределенной операции или пере-полнении стека для чисел с плавающей запятой;EInvalidPointer - исключение происходит при ошибке в операциях над указателя-ми;EKathError - класс исключений для вычислений над числами с плавающей запя-той. Является предком следующих классов: EIn valid Argument, ElnvalidOp,EOverflow, EUnderflow, EZeroDivide;EOutOfMemory - исключение происходит при неудачной попытке выделения памя-ти;EOverflow - исключение происходит при получении слишком большого значе-ния числа с плавающей запятой (для размещения его в регистре);EPackageError - класс исключений для ошибки загрузки или выполнения пакета;

EPrivilege - нарушение привилегий процессора;

EPropReadOnly - исключение происходит при неудачной попытке установитьзначение свойства, используя OLE-автоматизацию;

Page 68: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

68 Глава 3

EPropWriteOnly - исключение происходит при неудачной попытке прочитатьзначение свойства, используя OLE-автоматизацию;

ERangeError — исключение происходит при попытке присвоения слишком боль-шого значения целочисленной переменной;

EStackOverflow - класс исключений для переполнения стека;

EUnderflow - класс исключений для значений, являющихся слишком малыми,чтобы быть представленными числом с плавающей точкой;

EVariantError - класс исключений для ошибки с данными типа variant;

EWin32Error - класс исключений для ошибок Windows;

EZeroDivide - исключение происходит при делении на нуль чисел с плавающейзапятой;

Exception - базовый класс для всех классов исключений.

Библиотека VCL содержит слишком большое число исключений, чтобы описать ихвсех в рамках данной книги. Поэтому приведем только некоторые наиболее частоиспользуемые исключения, реализованные в других библиотечных модулях Delphi:

EAppletException (модуль ctlpanel) - класс исключений для ошибок приложе-ния Control Panel Applicaiion;

EArrayError (модуль mxarrays) - класс исключений для ошибок работы с потом-ками класса TBaseArray (например, неправильный индекс элемента массива);

EBitsError (модуль classes) - исключение происходит при неудачной попыткедоступа к массиву логических значений (экземпляру класса TBits) с указаниемслишком большого (больше, чем значение свойства Size) или слишком малень-кого (меньше 0) индекса элемента массива;

EClassNotFound (модуль classes) - исключение происходит при попытке чтенияиз потока компонента неизвестного типа;

EComonCalendarError (модуль comctrls) - исключение происходит при неудач-ной попытке ввода в компонент типа TCommonCalendar;

EComponentError (модуль classes) - исключение происходит при неудачной по-пытке регистрации или переименования компонентов;

EDBClient (модуль dbclient) - класс исключений для ошибок, возникающих прииспользовании объекта TClientDataSet;

EDBEditError (модуль mask) - исключение происходит при попытке использова-ния данных, несовместимых с заданной для поля маской в свойстве EditMask;

EDBEngineError (модуль dbtables) - класс исключений для ошибок машины базданных BDE (Borland Database Engine);

EDatabaseError (модуль db) - класс исключений для ошибок базы данных;

EFCreateError (модуль classes) - исключение происходит при неудачной по-пытке приложения создать файл;

EFOpenError (модуль classes) - исключение происходит при неудачной попыткеприложения открыть файл;

Page 69: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 69

EFilerError (модуль classes) - класс исключений для ошибок работы с файлом.Этот класс является предком следующих классов исключений для ошибок чте-ния и записи потока: EReadErtor (ошибка чтения указанного числа байт),EWriteError (ошибка записи указанного числа байт), EClassHotFound (не опреде-лен тип компонента), EInvalidlmage (ошибка чтения файла ресурсов);

EInvalidGraphic (модуль graphics) - класс исключений для ошибок работы сграфическими файлами (например, попытка загрузки файла неграфическогоформата или изображение не соответствует формату, указанному при вызовеLoadFromClipboardFormat);EInvalidGraphicOperation (модуль graphics) - класс исключений для ошибокв операциях над изображениями;EInvalidGridOperation (модуль grids) - класс исключений для ошибок в операцияхнад таблицами (например, попытка доступа приложения к несуществующей ячейке);ElnvalidOperation (модуль classes) - класс исключений для ошибок в операци-ях над компонентами (например, попытка операции, требующей дескриптораокна над компонентом, не имеющим родителя, или попытка выполнения опера-ции перемещения и сброса над формой);EListError (модуль classes) - класс исключений для ошибок со списками, состроками и с объектами типа TStringList;EMenuError (модуль menus) — класс исключений для ошибок над элементами ме-ню (например, попытка удаления несуществующего элемента меню);EOleCtrlError (модуль olectrls) - класс исключений для ошибок с элементамиуправления ActiveX;EPrinter (модуль printers) - класс исключений для ошибок, возникающих приработе с принтером.

СТАНДАРТНЫЕ ПРОЦЕДУРЫ и ФУНКЦИИБиблиотечные модули Delphi содержат большое количество стандартных проце-дур и функций. В этом разделе мы рассмотрим только наиболее часто исполь-зуемые из них.

Математические процедуры и функции

function Abs(X);Возвращает абсолютное значение параметра X. Параметр может быть выра-жением целочисленного или действительного типа.

function Ceil(X: Extended):Integer;Округляет значение параметра до первого наибольшего целого.

function Floor(X: Extended): Integer;Округляет значение параметра до первого наименьшего целого.

Page 70: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

70 Глава 3

function Frac(X: Extended): Extended;Возвращает дробную часть параметра X.

Очевидно, что Frac(X) = X - I n t ( X ) ; .

procedure Frexp(X: Extended; var Mantissa: Extended; var Exponent:Integer) register;Возвращает отдельно мантиссу и экспоненту параметрах.

function lnt(X: Extended): Extended;Возвращает целую часть параметра X.

function Max(A,B: Integer): Integer; overload;function Max(A,B: Int64): Int64; overload;function Max(A,B: Single): Single; overload;function Ma\(A,B; Double): Double; overload;

function Max(A,B: Extended): Extended; overload;Функции Max возвращают наибольшее из двух значений, указанных пара-метрами.

function Min(A,B: Integer): Integer; overload;function Min(A,B: Int64): Int64; overload;function Min(A,B: Single): Single; overload;function Min(A,B: Double): Double; overload;function Min(A,B: Extended): Extended; overload;

Функции Min возвращают наименьшее из двух значений, указанных пара-метрами,

function RoundfX: Extended): Int64;Возвращает округленное значение параметра (округление до ближайшего це-лого). Результатом является целое типа Int64. Если округляемое число одина-ково «отстоит» от ближайших целых, то округленное значение всегда будетчетным.

function Sqr(X: Extended): Extended;Возвращает возведенное в квадрат значение параметра.

function Sqrt(X: Extended): Extended;Извлекает квадратный корень из значения, заданного параметром.

function TruncfX: Extended): Int64;Возвращает целое число типа Irit64, равное целой части параметра X. Еслизначение X больше, чем предполагает тип [nt64, то инициируется исключениеElnvalidOp.

function MaxlntValue(const Data: array of Integer): Integer;Возвращает наибольшее целое из массива, указанного параметром Data.

Page 71: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 71

function MaxValue(const Data: array of Double): Double;Возвращает наибольшее значение типа Double из массива Data.

function Mean(const Data: array of Double): Extended;Возвращает среднее арифметическое всех значений массива Data.

function MinlntValue(const Data: array of Integer): Integer;Возвращает наименьшее целое из массива, указанного параметром Data.

function MinValue(const Data: array of Double): Double;Возвращает наименьшее значение типа Double из массива Data.

function Sum(const Data: array of Double): Extended; register;Возвращает сумму всех элементов массива, указанного параметром Data.

function Sumlnt(const Data: array of Integer): Integer register;Возвращает сумму всех элементов массива, указанного параметром Data.

function SumOfSquares(const Data: array of Double): Extended;Возвращает сумму квадратов всех элементов массива, указанного парамет-ром Data.

procedure SumsAndSquares(const Data: array of Double; var Sum,SumOfSquares: Extended) register;Отдельно определяет для массива Data сумму всех элементов и сумму квад-ратов всех элементов массива.

Процедуры и функции над действительнымичислами

Дополнительно к основным базовым типам Object Pascal в функциях и методахпреобразования типов используются следующие типы и константы:

type TFloatRec = recordExponent: Smallint; {Положительная или отрицательная степень числа 10}Negative: Boolean; {False, если число равно 0 или положительно }Digits: a r r a y [ 0 . . 2 0 ] of Char; {до 18 (для типа Extended) или до 19

(для типа Currency) значащих цифр числа}type TFloatValue = (fvExtended, fvCurrency) ;'fvExtended значение типа с плавающей точкой.fvCurrency значение типа currency}

type TFloatFormat = (f fGeneral , f fExponent, f fFixed, ffNumber,f fCurrency);

procedure FloatToDecimaKvar DecVal: TFloatRec; const Value; ValueType:TFloatValue; Precision, Decimals: Integer);Преобразовывает значение с плавающей точкой, указываемое параметромValue, в значение в десятичном представлении.

Page 72: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

72 Глава 3

Параметр ValueType определяет тип фактического параметра Value (Extendedили Currency). Если тип фактического параметра Extended, то параметрPrecision указывает количество значащих цифр. Параметр Decimals опреде-ляет максимальное число цифр слева от десятичной точки.

function FloatToStr(Value: Extended): string;Преобразовывает значение с плавающей точкой, указываемое параметромValue, в строку (используется формат с 15 значащими цифрами).

function FloatToStrF(Value: Extended; Format: TFI oat Format; Precision,Digits: Integer): string;Преобразовывает значение с плавающей точкой, указываемое параметромValue, в строку в соответствии с заданным форматом.Значение Precision должно быть меньше 8 для типа Single, меньше 16 длятипа Double и меньше 19 для типа Extended.Используемые символы-разделители для десятичной точки и для отделения ты-сяч содержатся в глобальных переменных DecimalSeparator иThousandSeparator.Если указанное параметром Value значение не является числом требуемогоформата, то метод возвращает значение 'NAN'; если преобразовываемое числоположительно, то - значение TNF, а если отрицательно, то - значение '-INF.

function FIoatToText(Buffer: PChar; const Value; ValueType: TFIoatValue;Format: TFloatFormat; Precision, Digits: Integer): Integer;Преобразовывает значение с плавающей точкой, указываемое параметром Value,в неограниченную строку символов в соответствии с заданным форматом.Функция возвращает длину строки символов, записанной в указанный буферBuffer-

function FloatToTextFmt(Buffer: PChar; const Value; ValueType:TFIoatValue; Format: PChar): Integer;Преобразовывает значение с плавающей точкой, указываемое параметромValue, в неограниченную строку символов в соответствии с форматом, опре-деляемым параметром Format. Правила описания форматов как строки сим-волов приведены для функции FormatFloat.Функция возвращает длину строки символов, записанной в указанный буферBuffer.Отличие этой функции от предыдущей состоит в том, что она не используетпредопределенные форматы, а позволяет описать свой необходимый форматдля преобразования значения.

function FormatFloat(const Format: string; Value: Extended): string;Форматирует значение Value в соответствии с форматом, указанным пара-метром Format, и возвращает отформатированное значение как строку симво-лов.Параметр Format может содержать следующие символы:

Page 73: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 73

О -- позиция цифры: если значение форматируемого числа в указаннойпозиции имеет цифру, то эта цифра заносится в форматируемую строку;в противном случае проставляется цифра 0;

# - позиция цифры: если значение форматируемого числа в указаннойпозиции имеет цифру, то эта цифра заносится в форматируемую строку;в противном случае в указанную позицию ничего не записывается;

. - десятичная точка: позицию десятичной точки определяет место первогопоявления этого символа в строке Format. Символ, который будетотображаться в качестве десятичной точки в отформатированном значении,содержится в глобальной переменной Decimal Separator;

, - разделитель тысяч: если в строке Format присутствует символ разделителятысяч, то в отформатированном значении будут присутствовать символыразделителя тысяч, определяемые глобальной переменной ThousandSeparator;

Е+ - определяет форматирование значения в экспоненциальном виде;

Чх7»хх» - символы, заключаемые в одинарные или двойные кавычки, простозаписываются и не влияют на форматирование;

; • • разделяет описания форматов для положительного, отрицательногои нулевого значений.j

В следующей таблице приведен результат форматирования различных значенийфункцией FormatFioat.

Формат

5138

0

0.00

ИМ

fl.lt/iQ.QQ

#,МО.ОО:(;ШО.ОО)

#,##0.00;;Zero

O.OOOE + QQ

ОМЕ-0

Форматируемое значение

5133 -5138 0.5 0

Результат форматирования

-5138

5138

5138.00

5138

5,138.00

5,138.00

5,138.00

5.138Е + 03

5.138ЕЗ

0.5

-5138

-5138.00

-5138

-5,138.00

[5, 138.00)

-5,138.00

5.138Е+03

-5.138ЕЗ

0

5

0.50

.5

0.50

0.50

0.50

5.000Е-05

5Е-5

0

0.00

0.00

0.00

Zero

О.ОООЕ + 00

ОЕО

function StrToCurr(const S: string): Currency;Преобразовывает строку, содержащую значение с плавающей точкой, в зна-чение типа Currency.

Page 74: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

74 Глава 3

function StrToFloat{const S: string): Extended;Преобразовывает строку, содержащую значение с плавающей точкой, в зна-чение типа Extended.

function Те xt To Float{ Buffer: PChar; var Value; ValueType: TFIoatValue):Boolean;Преобразовывает строку с ограничивающим нулем , указанную фактическимпараметром Buffer, в значение с плавающей точкой.

Процедуры и функции даты/времениДополнительно к основным базовым типам Object Pascal в функциях и методахдля даты/времени используются следующие типы и константы:

constSecsPerDay = 24 * 60 * 60;

{Количество секунд в 24 часах}MSecsPerDay = SecsPerDay * 1000;

глобальные переменные, используемые для определения формата числового илисимвольного представления даты/времени:

var CurrencyString: string;var CurrencyFormat: Byte;var NegCurrFormat: Byte;var ThousandSeparator: Char;var DecimalSeparator: Char;var CurrencyDecimals: Byte;var DateSeparator: Char;var ShortDateFormat: string;var LongDateFormat: string;var TimeSeparator: Char;var TimeAMString: string;var TimePMString: string;var ShortTimeFormat: string;var LongTimeFormat: string;var ShortMonthHames: array[1. .12] of string;var LongMonthNames: array[1. .12] of string;var ShortDayNames: array[1. .7 j of string;var LongDayNames: array[1. .7] of string;var SysLocale: TSysLocale;var EraNames: array[1. .7] of string;var EraYearOffsets : array[1..7] of Integer;var TwoDigitYearCenturyWindow: Word = 50;var TListSeparator: Char;type TDateTime = type Double;

Строка с ограничивающим нулем иногда также называется nuil-огрэннченной строкой.

Page 75: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 75

type TTimeStarnp = record

Time: Integer; {Количество миллисекунд после 12 часов }Date: Integer; { Количество дней после 1/1/0001 }

end;.

function Date: TDateTime;Возвращает текущую дату как значение типа TDateTime.Целая часть числа содержит дату, а дробная часть - время.Например:О соответствует 12/30/1899 12:00 am, a2.75 соответствует 1/1/1900 6:00 рт.

function DateTimeToFileDate(DateTime: TDateTime): Integer;Возвращает значение даты в формате DOS.

function DateTimeToStr(DateTime: TDateTime): string;Преобразовывает заданную дату и время в строку, используя формат опреде-ляемый глобальными переменными ShortDateFormat и LongTimeFormat. Еслизначение DateTime не имеет дробной части, то отформатированная строкане будет содержать значения времени.

procedure DateTimeToString(var Result: string; const Format: string;DateTime: TDateTime);Преобразовывает заданную дату и время в строку, используя формат, указан-ный фактическим параметром Format.

procedure DateTimeToSystemTime(DateTime: TDateTime; var SystemTime:TSystemTime);Преобразовывает значение типа TDateTime в значение типа TSystemTime.

function DateTimeToTimeStamp(DateTime: TDateTime): TTimeStarnp;Преобразовывает значение типа TDateTime в значение типа TTimeStamp.

function DateToStr(Date: TDateTime): string;Преобразовывает дату, указанную параметром Date, в строку в соответствиис форматом, определяемым глобальной переменной ShortDateFormat.

function DayOfWeek(Date: TDateTime): Integer;Возвращает номер дня недели для даты, указанной параметром Date. Длявоскресенья возвращается значение 1, для понедельника -2 и т. д.

procedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word);Разбирает значение Date на составляющие и записывает в параметры Year,Month и Day значения года, месяца и дня. Если значение, указанное парамет-ром Date, меньше или равно 0, то для всех, параметров устанавливается зна-чение 0.

Page 76: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

76 Глава 3

procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word);Разбирает значение Time на составляющие и записывает в параметры Hour,Min, Sec, MSec значения часа, минут, секунд и миллисекунд.

function EncodeDatefYear, Month, Day: Word): TDateTime;

Собирает значение даты из заданных составляющих Year, Month и Day и воз-вращает его как значение типа TDaieTime.

function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;Собирает значение времени из заданных составляющих Hour, Min, Sec, MSecи возвращает его как значение типа TDuteTime.

function FormatDateTime(const Format: string; DateTime: TDateTime): string;Преобразовывает значение параметра DateTime в соответствии с форматомFormat и возвращает его как строку символов.

Параметр Format может указываться следующими символами:

с - дата отображается в соответствии с глобальной переменной ShortDateFormac,а время - в соответствии с глобальной переменной LongTimeFormat;

d - отображение даты без лидирующего нуля (1-31);•

dd-отображение даты с лидирующим нулем (01-31);

ddd - отображение названия дня недели (Sun-Sat), используя строки,определяемые в глобальной переменной ShortDayNames;

dddd - отображение названия дня недели (Sunday-Saturday), используястроки, определяемые в глобальной переменной LongDayNames;

ddddd - дата отображается в соответствии с глобальной переменнойShortDateFormat;

dddddd - дата отображается в соответствии с глобальной переменнойLongDaieFormat;

m- отображение без лидирующего нуля (1-12);

mm- отображение месяца с лидирующим нулем (01-12);

mmm отображение названия месяца (Jan-Dec), используя строки,определяемые в глобальной переменной ShortMonthNames;

mmmm отображение названия месяца (January-December), используястроки, определяемые в глобальной переменной LongMonthNames;

уу - отображение двух конечных цифр года (00-99);

уууу - отображение года в четырехзначном формате (0000-9999);

h - отображение часа без лидирующего нуля (0-23);

hh - отображение часа с лидирующим нулем (00-23);

Page 77: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal

n - отображение минут без лидирующего нуля (0-59);

nn - отображение минут с лидирующим нулем (00-59);

s - отображение секунд без лидирующего нуля (0-59);

ss - отображение секунд с лидирующим нулем (00-59);

С-время отображается в соответствии с глобальной переменной ShortTimeFormat;

tt - время отображается в соответствии с глобальной переменной LongTimeFormat;

am/pm- отображение даты в 12-часовом формате;

/ - отображение разделителя даты, определенного в глобальной переменнойDateSeparator;

: отображение разделителя времени, определенного в глобальнойпеременной TimeSeparator;

'хх'/»хх» - символы, заключенные в двойные кавычки, только записываются,не влияя на форматирование.

Если параметр Format содержит пустую строку, то дата отображается в соответ-ствии с глобальной переменной ShortDateFonnat, а время - в соответствиис глобальной переменной LongTimeFormat.

function lncMonth(const Date: TDateTime; NumberOfMonths: Integer):TDateTime;Возвращает значение даты, увеличенное на указанное параметромNumberOfMonths количество месяцев.

function IsLeapYeaKYear: Word): Boolean;Определяет, является ли год, указываемый параметром Year, високосным годом.

function MSecsToTimeStamp(MSecs: Comp): TTimeStamp;Преобразовывает заданное параметром HSecs количество миллисекунд в зна-чение типа TTimeStamp.

function Now: TDateTime;Возвращает значение текущей даты и времени.

procedure ReplaceDate(var DatcTime: TDateTime; const NewDate:TDateTime);Заменяет в параметре DateTime значение даты на новое значение, указывае-мое параметром NewDate. Значение времени при этом не изменяется.

procedure ReplaceTime(var DateTime: TDateTime; const NewTime:TDateTime);Заменяет в параметре DateTime значение времени на новое значение, указы-ваемое параметром NewDate. Значение даты при этом не изменяется.

Page 78: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

78 Глава 3

function StrToDate(const S: string): TDateTime;Преобразовывает значение строки, > называемое параметром S, в дату типаTDateTime.Отметим, что если параметр S не содержит дату в формате, таком, как m/d/y,d/m/y или d/m, то функция инициирует исключение EConvertError.

function StrToDateTime(const S: string): TDateTime;Преобразовывает значение строки, указываемое параметром S, в дату и времятипа TDateTime.Параметр S должен содержать дату и время в формате, таком, как mm/dd/yyhh:mm:ss.

function StrToTime(const S: string): TDateTime;Преобразовывает значение строки, указываемое параметром S, в значениевремени типа TDateTime.

function SystemTimeToDateTinie(const SystemTime: TSystemTime):TDateTime;Преобразовывает значение времени типа TSystemTime в значение типаTDateTime.

function Time: TDateTime;Возвращает текущее значение времени.

function TimeStampToDateTime(const TimeStamp: TTimeStamp):TDateTime;Преобразовывает значение даты/времени типа TTimeStamp в значение типаTDateTime.

function TimeStampToMSecs(const TimeStamp: TTimeStamp): Comp;Возвращает значение TimeStamp типа TTimeStamp как общее количествомиллисекунд.

function TimeToStr(Time: TDateTime): string;Преобразовывает заданное время в строку, используя формат, определяемыйглобальной переменной LongTimeFormat.

Процедуры и функиим преобразования типовДополнительно к основным базовым типам Object Pascal в функциях и методахпреобразования типов используются следующие типы и константы:

typeTRect = record

case Integer of0: (Left, Top, Right, Bottom: Integer);

1: (TopLeft, BottomRight: TPoint);

end;

Page 79: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 79

type TPoint = recordX: Longint;Y : Longint;

end;

function Bounds(ALeft, ATop, AWidth, AHeight: Integer): TRect;Возвращает объект типа TRect (прямоугольник) указанных размеров.

function CompToCurrency(acomp: Comp): Currency; cdecl;Преобразовывает значение типа Comp в значение типа Currency.

function CompToDouble(acomp: Comp): Double; cdecl;Преобразовывает значение типа Comp в значение типа Double.

procedure CurrencyToComp(acurrency: Currency; var result: Comp); cdecl;Преобразовывает значение типа Currency в значение типа Сотр.

function Point(AX, AY: Integer): TPoint;Создает и возвращает объект типа TPoint для указанных координат.

function RectlALeft, ATop, ARight, ABottom: Integer): TRect;Создает и возвращает объект типа TRect (прямоугольник) указанных разме-ров. Функция Rect используется для формирования параметров функций,требующих тип TRect.

function StrTolnt(const S: string): Integer;Преобразовывает значение типа string в значение типа Integer. Параметр S со-держит строку, представляющую целочисленное значение в десятичном илишестнадцатеричном представлении.Отметим, что если параметр S содержит недопустимое значение, то функцияинициирует исключение EConvertError.

function StrTolnt64(const S: string): Int64;Преобразовывает значение типа string в значение типа Int64.

Параметр S содержит строку, представляющую целочисленное значение в де-сятичном или шестнадцатеричном представлении.Отметим, что если параметр S содержит недопустимое значение, то функцияинициирует исключение EConvertError.

function StrTolnt64Def(const S: string; Default: Int64): Int64;Преобразовывает значение типа string в значение типа Int64.

Если параметр S содержит недопустимое значение, то функция возвращаетзначение, указанное параметром Default.

Page 80: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

80 Глава 3

function StrTolntDef(const S: string; Default: Integer): Integer;Преобразовывает значение типа siring в значение типа Integer. Параметр 5 со-держит строку, представляющую целочисленное значение в десятичном илишестнадцатеричном представлении.

Если параметр S содержит недопустимое значение, то функция возвращаетзначение, указанное параметром Default.

function CurrToStr(Value: Currency): string;Преобразовывает значение типа Currency в строку.

function CurrToStrF(Value: Currency; Format: TFIoatFormat; Digits:Integer): string;Преобразовывает значение типа Currency в строку с учетом заданного формата.

function DoubleToCompladouble: Double; var result: Comp); cdecl;Преобразовывает значение типа Double в значение типа Сотр.

function IntTo Hex (Value: Integer; Digits: Integer): string; overload;function lntToHex(Va!ue: Int64; Digits: Integer): string; overload;

Возвращает строку, содержащую шестнадцатеричное представление числаValue. Параметр Digits указывает минимальное число возвращаемых шест-надцатеричных знаков.

function lntToStr(Value: Integer): string; overload;function lntToStr(Value: Int64): string; overload;

Преобразовывает целочисленное значение в строку.

Процедуры и функции АЛЯ работы со строкамии символами

Обработка строк с ограничивающим нулем

Тип РСпаг является указателем на строку символов типа Char с ограничиваю-щим нулем.При указании параметра функции или процедуры типа PChar можно:выполнить приведение типа, например PChar (Edit l .Text) ; .

Определить параметр как массив символов и указать его адрес, например:

var buf : array[0. .MAX_SIZE] of char;S: string;

begini := Funl(@buf, SizeOf(bufi); {Использует @buf как параметр типа

PChar,

a SizeOf возвращает размер буфера}S := buf; (Переход к значению типа string}

end;

Page 81: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 81

При использовании параметров и возвращаемых значений типа PChars всегдаследует помнить, что этот тип является только указателем на память и эта па-мять должна быть выделена вне тела процедуры. Возвращаемому значению типаPChars никогда нельзя присваивать указатель на строки, которые создавалиськак локальные переменные.Строка типа string существует, пока счетчик ссылок на нее не равен нулю, а зна-чение типа PChar никак не влияет на счетчик ссылок. Это необходимо помнитьпри приведении типа PChar(Strl): разработчик должен сам следить, чтобы ис-пользуемая переменная типа siring существовала на все время применения соз-данного указателя.При использовании международных наборов символов следует применятьфункции, начинающиеся с префикса Ansi. Эти функции учитывают установлен-ный драйвер языка и соответственно используют 8-битовые символы. А функ-ции, не имеющие в своем названии префикса Ansi, работают с 7-битовымиASCII-символами.

function AnsiStrComp(Sl, S2: PChar): Integer;Выполняет сравнение двух строк с учетом регистра. Если строка SI > S2. тофункция возвращает положительное значение, если SI < S2, функция возвраща-ет отрицательное значение, и если 31 = 32, то возвращается значение 0.

function AnsiStrlComp(S1, S2: PChar): Integer;Выполняет сравнение двух строк без учета регистра.

function AnsiStrl_Comp(S1, S2: PChar; MaxLen: Cardinal): Integer;Выполняет сравнение двух строк с учетом регистра. Если строка S1 или S2длиннее, чем указано параметром MaxLen, то выполняется сравнение толькопервых MaxLen байт.

Если строка S1 > 32, то функция возвращает положительное значение, еслиSI < S2, функция возвращает отрицательное значение, и если первые MaxLenбайт S1 = 32, то возвращается значение 0.

function AnsiStrLlComp(S1, S2: PChar; MaxLen: Cardinal): Integer;Выполняет сравнение двух строк без учета регистра. Если строка 31 или 32длиннее, чем указано параметром MaxLen., то выполняется сравнение толькопервых MaxLen байт.

function AnsiStrLower(Str: PChar): PChar;Возвращает строку, указанную параметром Str, в которой все символы пре-образованы в символы нижнего регистра (в строчные буквы).

function AnsiStrPos(Str, SubStr: PChar): PChar;Возвращает указатель на первое вхождение строки SubStr в строке Str. Есливхождение не найдено, то функция возвращает значение nil.

Page 82: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

82 Глава 3

function AnsiStrRScan(Str: PChar; Chr: Char): PChar;Возвращает указатель на последнее вхождение символа Chr в строке Str. Ес-ли вхождение не найдено, то функция возвращает значение nil.Отметим, что ограничивающий строку 0-символ рассматривается как частьстроки.

function AnsiStrScan(Str: PChar; Chr: Char): PChar;Возвращает указатель на первое вхождение символа Chr в строке Str. Есливхождение не найдено, то функция возвращает значение nil.

function AnsiStrUppeKStr: PChar): PChar;Возвращает строку, указанную параметром Str, в которой все символы пре-образованы в символы верхнего регистра (в прописные буквы).

function LineStart(Buffer, BufPos: PChar): PChar;Ищет в буфере Buffer начиная с позиции BufPos и к началу буфера символконца строки \п. Если этот символ не найден, то функция возвращает указа-тель на Buffer-

function StrCaUDest: PChar; const Source: PChar): PChar;Конкатенация строк. Функция добавляет строку Source в конец строки Destи возвращает полученную строку. Длина возвращаемой строки будет равнаStrLen(Dest}+StrLen(Source)+1.

function StrComplconst Str1, Str2 : PChar): Integer;Выполняет сравнение двух строк с учетом регистра. Если строка Strl > Str2,то функция возвращает положительное значение, если Strl < Str2, функциявозвращает отрицательное значение, и если Strl = Str2. то возвращаетсязначение 0.

function StrCopy(Dest: PChar; const Source: PChar): PChar;Копирует строку Source в строку Dest. При этом проверки размера буфера,в который выполняется копирование, не происходит. Поэтому нужно сле-дить, чтобы его размер был не менее чем StrLen(Source)+l.

function StrECopy(Dest: PChar; const Source: PChar): PChar;Копирует строку Source в строку Dest и возвращает указатель на коней стро-ки (StrEnd(Dest)).

function StrEnd(const Str: PChar): PChar;Возвращает указатель на конец строки (на ограничивающий строку0-символ).

function StrlComp(const Strl, Str2:PChar): Integer;Выполняет сравнение двух строк без учета регистра. Если строка Strl > Str2,то функция возвращает положительное значение, если Strl < Str2, функция

Page 83: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 83

возвращает отрицательное значение, и если Strl = Str2, то возвращаетсязначение 0.

function StrLCat(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar;Конкатенация строк с учетом размера буфера. Функция добавляет MaxLen -StrLen(Dest) символов строки Source в конец строки Dest и возвращает по-лученную строку. MaxLen указывает максимально допустимый размер воз-вращаемой строки..

function StrLComp(const Strl, Str2: PChar; MaxLen: Cardinal): Integer;Выполняет сравнение первых MaxLen символов из двух строк. Если строкаStrl > Str2, то функция возвращает положительное значение, если Strl <Str2, то функция возвращает отрицательное значение, и если Strl = Str2, товозвращается значение 0.

function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar;Копирует первые MaxLen символов строки Source в строку Dest и возвращаетуказатель на Dest.

function StrLIComp(const Strl, Str2: PChar; MaxLen: Cardinals): Integer;Выполняет сравнение первых MaxLen символов из двух строк без учета реги-стра. Если строка Strl > Str2, то функция возвращает положительное значе-ние, если Strl < Str2, то функция возвращает отрицательное значение, и ес-ли Strl = Str2, то возвращается значение 0.

function StrLen(const Str: PChar): Cardinal;Возвращает длину строки Str без учета символа конца строки.

function StrLower(Str: PChar): PChar;Возвращает строку, указанную параметром Str, в которой все символы пре-образованы в символы нижнего регистра (в строчные буквы).

function StrMove(Dest: PChar; const Source: PChar; Count: Cardinal): PChar;

Копирует первые MaxLen символов строки Source в строку Dest и возвращаетуказатель на Dest. При этом строки Source и Dest могут быть перекрываю-щимися.

function StrPCopy(Dest: PChar; const Source: string): PChar;Копирует строку Source типа string в строку Dest и возвращает указатель наDest. При этом проверки размера буфера, в который выполняется копирова-ние, не происходит. Поэтому нужно следить, чтобы его размер был не менеечем StrLen(Source)+l.

Page 84: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

84 Глава 3

function StrPLCopy(Dest: PChar; const Source: string; MaxLen: Cardinal):PChar;Копирует первые MaxLen символов строки Source типа string в строку Destи возвращает указатель на Dest.

function StrPos(const Strl, Str2: PChar): PChar;Возвращает указатель на первое вхождение строки Str2 в строку Strl. Еслистрока Str2 не содержит искомой строки, то функция возвращает значение nil.

Пример:(Поиск строки, расположенной в компоненте Edit2, в строке,

находящейся в компоненте Editl (поле редактирования) }if StrPos(PChar(Edit l .Text),PChar(Edit2.Text))<> nil

thenShowMessagef 'Строка из Bdit2 найдена')

elseShowMessage ( 'Строка из Edit2 не найдена');

function StrRScanfconst Str: PChar; Chr: Char): PChar;Возвращает указатель на последнее вхождение символа Chr в строку Str. Еслистрока Str не содержит указанного символа, то функция возвращает значение njl-

function StrScan(const Str: PChar; Chr: Char): PChar;Возвращает указатель на первое вхождение символа Chr в строку Str. Еслистрока Str не содержит указанного символа, то функция возвращает значениеnil.Отметим, что ограничивающий 0-символ рассматривается как часть строки.

function StrUpper(Str: PChar): PChar;Возвращает строку, указанную параметром Str, в которой все символы пре-образованы в символы верхнего регистра (в прописные буквы).

Обработка строкФункции, выполняющие обработку строк типа string, в основном аналогичныфункциям, использующим параметры типа PChar. Поэтому во избежание повто-рений в этом разделе будет только кратко описано назначение функций.

function AdjustLineBreaks(const S: string): string;Находит в указанной строке S все символы CR и LF и упорядочивает ихв последовательности пар CR/LF.

function AnsiCompareStr(const S1, S2: string): Integer;Сравнивает значение двух строк 31 и S2 с учетом регистра.

function AnsiCompareText(const SI, S2: string): Integer;Сравнивает значение двух строк SI и S2 без учета регистра.

Page 85: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 85

function AnsiExtractQuotedStrlvar Src: PChar; Quote: Char): string;Преобразовывает строку Src, удаляя из нее начальный и конечный символQuote, и возвращает полученную строку. Указатель Src устанавливается напервый символ возвращаемой строки.

Если первым символом строки Src является символ, отличный от указанного па-раметром Quote, то функция возвращает пустую строку. Если не найден конеч-ный символ, равный Quote, то Src будет указывать на ограничивающий0-символ.

function AnsiLowerCase(const S: string): string;Копирует строку S, возвращая ее как строку, в которой все символы преобра-зованы в символы нижнего регистра (в строчные буквы).

function AnsiPos(const Substr, S: string): Integer;

function Pos(Substr: string; S: string): Integer;Возвращает позицию подстроки Substr в строке S начиная с 1.

Если строка S не содержит заданной подстроки, то функция возвращает зна-чение 0.

function AnsiQuotedStr(const S: string; Quote: Char): string;function QuotedStr(const S: string): string;

Возвращает строку S, заключенную в символы Quote. При этом каждый внут-ренний символ Quote, находящийся в строке, удваивается.

function AnsiSameSMconst S1, S2: string): Boolean;Сравнивает значения двух строк SI и S2 с учетом регистра и возвращает зна-чение True при полном совпадении строк.

function AnsiSameTextfconst SI, S2: string): Boolean;Сравнивает значения двух строк SI и S2 без учета регистра.

function AnsiUpperCasefconst S: string): string;Копирует строку S. возвращая ее как строку, в которой все символы преобра-зованы в символы верхнего регистра (в прописные буквы).

function CompareStr(const S1, S2: string): Integer;Сравнивает значения двух строк SI и S2 с учетом регистра.

function CompareText(const S1, 52: string): Integer;Сравнивает значения двух, строк SI и S2 без учета регистра и без учета основ-ного языка Windows.При сравнении учитывается только порядок символов в таблице ASCII-кодов.Например, 'АВ» будет меньше, чем 'аа'.

Page 86: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

86 Глава 3

function Concat(s1 [, s2,..v sn]: string): string;Возвращает строку, являющуюся результатом конкатенации строк, заданныхпараметрами.

function Copy(S; Index, Count: Integer): string;function CopyfS; Index, Count: Integer): array;

Возвращает подстроку или сегмент динамического массива, содержащиеCount символов или элементов массива, начиная с S[Index].

Если значение Index превышает длину строки, то возвращается пустая стро-ка. Если значение Count превышает количество оставшихся символов, то ко-пируются все символы до конца строки.

procedure Delete(var S: string; Index, Count: Integer);Удаляет подстроку длиной Count символов из строки S начиная с S[Index].

procedure lnsert(Source: string; var S: string; Index: Integer);Вставляет подстроку длиной Count символов в позицию S [Index] строки S.Отметим, что Index определяет номер символа, а не номер байта.

function lsDelimiter(const Delimiters, S: string; Index: Integer): Boolean;Определяет, содержит ли строка 5 начиная с позиции S[Index] какой-либо изсимволов, указанных параметром Delimiters. Параметр Index определяетномер байта начиная с 0.

function LastDelimiter(const Delimiters, S: string): Integer;Возвращает позицию последнего вхождения символа из строки Delimitersв строку S.

Например, вызов функции LastDelimiter ( ' \ . : ' , ' c : \ f i l e l . t x t ' ) вернет зна-чение 9.

Отметим, что параметр Delimeters должен содержать 1-байтовые символы.

function Length(S): Integer;Возвращает длину строки в символах (или число элементов массива символов).Если строка имеет тип WideString (для Unicode), то Length возвращает коли-чество байт, деленное на 2.

function LowerCase(const S: string): string;Копирует строку S, возвращая ее как строку, в которой все символы преобра-зованы в символы нижнего регистра {в строчные буквы).

const NullStr: PString = ©EmptyStr;Возвращает указатель на пустую строку.

procedure SetLength(var S; NewLength: Integer);Устанавливает длину строки.

Page 87: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 87

Для короткой строки функция просто устанавливает новое значение индика-тора длины строки (символ S|0|), которое может быть между 0 и 255.

Для длинной строки функция SetLengtll выполняет новое выделение памятидля переменной. И в случае ее отсутствия инициирует исключениеEOutOfMemory.Отметим, что для длинных строк вызов функции SetLength устанавливаетсчетчик ссылок на строку равным 1.

procedure SetString(var S: string; Buffer: PChar; Len:: Integer);Устанавливает новую длину строки s и, если содержимое параметра Bufferне равно nil, копирует в нее первые Len символов строки. Buffer. ФункцияSetString выделяет память аналогично функции SetLength.

Отметим, что параметр S может указывать как строку, так и массив символов.

procedure Str(X [: Width [: Decimals ]]; var S);Преобразовывает числовое значение X в строку S. Параметр X является выраже-нием целочисленного или действительного типа, а параметры Widthи Decimals — это целочисленные выражения, определяющие форматированиестроки S.

function StringOfChar(Ch: Char; Count: Integer): string;Возвращает строку, содержащую Count раз повторенный символ Ch.

function StringReplaceCconst S, OldPattern, NewPattern: string; Flags:TReplaceFlags): string;Возвращает строку, в которой подстрока CldPattern заменена на подстрокуNewPattern. Количество замет определяется параметром Flags(type TReplaceFlags = set of (rfReplaceAll, rJ'JgnoreCase);). Если Flags не вклю-чает значение rfReplaceAll, то выполняется замена только первого вхожденияподстроки.

Если Flags включает значение rflgnoreCase, то поиск подстроки OldPatternвыполняется без учета регистра.

function Trim(const S: string): string;Удаляет из строки лидирующие и завершающие пробелы, а также управляю-щие символы.

function TrimLeft(const S: string): string;Возвращает копию строки 5 с удаленными лидирующими пробеламии управляющими символами.

function TrimRight(const S: string): string;Возвращает копию строки S с удаленными завершающими пробеламии управляющими символами.

Page 88: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

88 Глава 3

function UpperCase(const S: string): string;Копирует строку 5, возвращая ее как строку, в которой все символы преобра-зованы в символы верхнего регистра (в прописные буквы).

procedure Val(S; var V; var Code: Integer);Преобразовывает строку S в числовое значение.

Параметр S должен содержать последовательность символов, которая можетбыть воспринята как действительное число со знаком. Параметр V можетбыть как действительным, так и целочисленным. Во втором случае параметрS также должен представлять целочисленное значение.В параметр Code заносится код выполнения преобразования: 0, если преобра-зование выполнено успешно, или номер позиции, в которой произошлаошибка. Для строк с ограничивающим нулем номер позиции возвращается наединицу больше, чем для строки, представленной как массив символов.Если установлена директива компилятора {$R+(, то при превышении диапа-зона допустимых значений инициируется ошибка времени выполнения.

function WrapTextfconst Line, BreakStr: string; nBreakChars: TSysCharSet;MaxCol: lnteger):string; overload;

function WrapText(const Line, MaxCol: Integer = 45):string; overload;Ищет в строке длиной до MaxCol любой символ, указанный параметромnBreakChars, и вставляет вместо последнего вхождения этого символа символконца строки, указанный параметром BreakStr. Параметр nBreakChars опре-деляется значением типа суре TSysCharSet = set of Char;.

Если параметры BreakStr и nBreakChars опущены, то функция WrapTextищет последний до MaxCol символ пробела, тире или табуляции и заменяетего на пару символов CR/LF.Например, вызов функции

WrapText('Пример разбиения одного предложения на 2 строки. ' ,(113110, ( ' . ' , ' М9,'-'Ь 2 5 ) ;

приведет к следующему результату:

Пример разбиения одногопредложения на 2 строки.

function Chr(X: Byte): Char;Возвращает символ, указанный его ASCII-кодом.

Функции для работы с указателями и адресами

function Addr(X): Pointer;Возвращает адрес указанного объекта. Вызов этой функции эквивалентенприменению оператора @.

Page 89: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 89

function Ptr(Address: Integer): Pointer;Преобразовывает заданный адрес в указатель.

Процедуры и функции Аналогов и сообщенийРеализации различных диалогов сообщений, использующие функции данногораздела, рассмотрены в главе «Разработка интерфейса».

function lnputBox(const ACaption, APrompt, ADefault: string): string;Отображает диалог с однострочным полем ввода и двумя кнопками - ОКи Cancel. Параметр ACaption определяет заголовок диалога; параметр APrompt- текст, отображаемый над полем ввода; параметр ADefault - значение поумолчанию, первоначально показываемое в поле ввода.Если для завершения диалога пользователь щелкнет на кнопке - ОК, то воз-вращается значение из поля ввода, а если на кнопке Cancel (или нажмет кла-вишу Esc), то возвращается значение, указанное параметром ADefault.

function mputQuery(const ACaption, APrompt: string; var Value: string):Boolean;Отображает диалог с однострочным полем ввода и двумя кнопками ОКи Cancel.Если для завершения диалога пользователь щелкнет на кнопке ОК, то функ-ция возвращает значение True, а если на кнопке Cancel (или нажмет клавишуEsc) - значение False.

Параметры ACaption и APrompt определяют заголовок диалога и надпись дляполя ввода. Параметр Value содержит значение, отображаемое и редактируе-мое в поле ввода.

function LoginDialog(const ADatabaseName: string; var AUserName,APassword: string): Boolean;

function LoginD!alogEx(const ADatabaseName: string- var AUserName,APassword: string; NameReadOnly: Boolean): Boolean;Отображает стандартный диалог Login, позволяющий ввести имя пользовате-ля, пароль и имя базы данных (значение свойства DatabaseName компонентаTDatabase).Если пользователь прервал диалог, то функция возвращает значение False.

При этом вторая функция имеет параметр NameReadOnly, определяющий, можетли пользователь изменять значение параметра AUserName (имя пользователя).

function MessageDlg(const Msg: string; DlgType: TMsgDIgType; Buttons:TMsgDlgButtons; HelpCtx: LongintJ: Word;Отображает диалог типа DlgType с сообщением, указываемым параметромMsg, и с кнопками, указываемыми параметром Buttons. Параметр HelpCtx оп-ределяет ГО контекста файла справки.Параметр DlgType может определять различные типы диалогов, содержащиеследующие изображения:

Page 90: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

90 Глава 3

Ф - mtError;

%9 - mtConfirmation;

v|y- rntWarning;

О - mtlnformation.Без изображения - mtCustom.

Параметр Buttons указывается множеством типа TMsgDIgBtn, которое опре-деляет следующие кнопки:mbYes, mbNo, mbOK, mbCancel, mbAbort, tiibRetry, mhlgnore, mbAll,mnNoToAll, mbYesToAli, mbilelp. inbYc'sNoCance/, mbOKCancel,inbAbonReiry Ignore.

Для того чтобы указать несколько кнопок, следует использовать операцию +или перечислить их всех в квадратных скобках и через запятую. Например:mbOK+mbHelp или [mbOK, mbHelp].

Функция возвращает одно из следующих значений, определяющих выбран-ную пользователем кнопку:

mrNone, mrAbort, mrYes. inrOk, nirReny, inrNo, mrCfincet, mrlgnore, mrAll.

Пример:

procedure TForml.ButtonlClick(Sender: TObject);begin

if MessageDlgC Завершить приложение?',mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then

beginMessageDlgS'Приложение завершено. ' , mtlnformation,

[mbOk], 0, mbOk);Close;

end;end;

function MessageDlgPos(const Msg: string; DlgType: TMseDlgType; Buttons:TMsgDIgButfons; HelpCtx: Longint; X, Y: Integer): Word;Отображение диалога в указанной позиции экрана.

Показывает диалог типа DlgType с сообщением, указываемым параметромMsg, и с кнопками, указываемыми параметром Buttons. Параметр HelpCtx оп-ределяет Ш контекста файла справки.

В отличие от предыдущей функции, MessageDlgPos отображает диалог в по-зиции, указанной параметрами X, Y (экранные координаты).

function MessageDlgPosHelp(const Msg: string; DlgType: TMsgDlgType;Buttons: TMsgDIgButtons; HelpCtx: Longint; X, Y: Integer; constHelpFileName: string): Word;Отображение диалога в указанной позиции экрана и с используемым файломсправки, отличным от заданного по умолчанию.

Page 91: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 9

Показывает диалог типа DlgType с сообщением, указываемым параметром Msg,и с кнопками, указываемыми параметром Buttons. Параметр HelpCtx опреде-ляет Ю контекста файла справки, а параметр HelpFileName - имя файла оправ-ки. Тема справки отображается, когда пользователь нажимает клавишу F1.

function SelectDirectqry(const Caption: string; const Root: WideString; outDirectory: WideString): Boolean;Отображает диалог, в котором пользователь может выбрать имя каталога,а также просмотреть все диски, каталоги и файлы.Функция SelectDirectory отображает диалог Browse for Folder (рис. 5.2). Па-раметр Caption указывает надпись над панелью, в которой отображается де-рево каталогов (аналогично левой части Проводника Windows).

owse (or Folder j JEJEJ

-its:

iga

Desklopf"^ My DocumentsL3 ffiHBfflWHI

У 3.5 Floppy (A:)

Т j SYSTEM (С:)+. i Local Disk (D )

- EP £э PROGRAM (EO

• •_! Local Di5k(F

.+. ' J BOOKS JGi)

:+ GD Local Disk (H

)

:)- £*i -^} Removable Disk (I:)

.+, ii>lRC_N£WO:):d

Cancel

Рис. 5.2. Диалог, отображаемый функцией SeIectDirectory

Выбранное пользователем имя каталога заносится в параметр Directory.

Параметр Options может указываться набором следующих значений:sdAltowCreate, sdPerformCreate, sdPrompt. Если этот параметр равен пустомумножеству, то пользователь не может внутри данного диалога создавать новыекаталоги.Если пользователь выбрал каталог и щелкнул на кнопке ОК. то функции воз-вращают значение True.

Пример:

procedure TForml-ButtonlClick(Sender: TObject);

var strl: WideString; res: Boolean;

const str2: WideString= 'D:';

const str3: string = 'Files:';

Page 92: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

92 Глава 3

beginres:=SelectDirectory (str3 ,str2,strl);

end;

Отметим, что для использования данной функции в секцию uses следует доба-вить библиотеку QDialogs.

procedure ShowMessage(const Msg: string);Отображает диалог с заданным сообщением Msg и кнопкой ОК.В строке заголовка данного диалога выводится имя выполнимого файла при-ложения.

Процедуры и ф у н к ц и и для работы с файламии каталогами

В функциях и процедурах, работающих с файлами, используется три различныхспособа указания файла:

• имя файла (или каталога) - как правило, используется для поиска или опре-деления атрибутов доступа и времени записи;

w файловая переменная, определяемая и инициируемая следующим образом:

var F: TextFile;AssignFilefF, FileName);

• дескриптор файла, используемый в функциях Windows API, который опреде-ляется и инициализируется следующим кодом:

var FileHandle : Integer;FileHandle := FileOpen(FileName,fmOpenWrite);

procedure AssignFile(var F; FileName: string);Выполняет инициализацию файловой переменной. F может быть файловойпеременной для любого типа файла. FileName указывает имя файла, ассоции-руемое далее во всех операциях с файловой переменной F. Если параметрFileName является пустой строкой, то файловая переменная F ассоциируетсясо стандартными файлами ввода (Reset (F)) или вывода (Rewrite (F)).

Пример:var F: TextFile; S: string;begin

if OpenDialogl.Execute thenbegin { Показать диалог Open }AssignFilefF, OpenDialogl.FileName);

tFileName определяет имя файла, выбранное в диалоге}Reset(F); {Открываем файл}

ReadlnfF, S); {Читаем из файла первую строку}

Page 93: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 93

Editl.Text := 3; (Помещаем эту строку в компонент типа TEdit}CIoseFile(F); {Закрываем файл}

end;end;

procedure ChDir(S: string);Изменяет текущий каталог и, если указан, текущий диск.

procedure CloseFile(var F);procedure Close(var F);

Закрывает файл, ассоциированный с файловой переменной F. Ранее этот файлбыл открыт вызовом одной из функций: Reset, Rewrite или Append.

function CreateDir(const Dir: string): Boolean;Создает новый каталог и при успешном завершении возвращает значение True.

Пример:

beginif not D i r e c t o r y E x i s t s ( ' C : \ M y W o r k ' ) then

if not CreateDir( 'C:\MyWork ' ) thenraise Exception.Create [He могу создать C : \ M y W o r k 1 ! ;

end;

function DeleteFilefconst: string): Boolean;Удаляет файл с именем FileKame и при успешном завершении возвращаетзначение True.

function DirectoryExists(Name: string): Boolean;Определяет, существует ли каталог с указанным именем.

function DiskFree(Drive: Byte): Int64;Определяет количество свободного места на диске (в байтах). Параметр Driveуказывает проверяемый диск:

О-текущий диск;

1 -диск А;

2 — диск В;

3 -диск С;

4 - диск D и т. д.

Если диск указан неверно, то функция возвращает значение - 1.

function DiskSize(Dr!ve: Byte): Int64;Определяет размер диска (в байтах). Параметр Drive указывает проверяемыйдиск:

0 — текущий диск;

1 — диск А;

Page 94: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

94 Глава 3

2-диск В;

3 - диск С;

4 —диск D и т. д.

Если диск указан неверно, то функция возвращает значение - 1.

procedure FileClosefHandle: Integer);Закрывает файл, открытый вызовом функции FileOpen или FileCreate.Отметим, что при использовании файловой переменной закрывать файл сле-дует вызовом процедуры CloseFile.

function FileDateToDateTime(FileDate: Integer): TDateTime;Преобразовывает формат даты, используемый функциями FileGetDateи FileAge (дата в формате DOS), R формат типа TDateTime, используемыйдругими функциями и процедурами VCL-библиотеки.

function FileExists(const FileName: string): Boolean;Определяет, существует ли файл, укачанный параметром FileMarae.

function FileGetAttr(const FileName: string): Integer;Возвращает атрибуты файла в виде строки би'юв. Возвращаемое значениеможет быть комбинацией атрибутов, приведенных в следующей таблице.

Константа

faReadQnly

faHidden

faSysFile

faVolumelD

faQirectory

faArchive

faAnyFile

Значение

$00000001

S00000002

SOOOOD004

$00000008

$00000010

$00000020

$OQOQQQ3F

Описание

Доступ только для чтения

Файл скрыт

Системный файл

Идентификатор диска

Наталог

Архивный файл

Любой файл

При возникновении ошибки функция возвращает значение - 1.

function FileGetDate(Handle: Integer): Integer;Возвращает дату и время (в формате DOS) создания или последнего измене-ния файла. Если указан неверный параметр Handle, то функция возвращаетзначение - 1.

Для преобразования полученного значения даты в значение типа TDateTimeследует использовать функцию FileDateToDaleTime.

function FileOpen(const FileName: string; Mode: LongWord): Integer;Открывает указанный файл. Параметр FileName определяет имя открываемо-го файла, а параметр Mode - режим использования открытого файла.

Page 95: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 95

При успешном завершении функция возвращает дескриптор открытого фай-ла, используемый в дальнейшем в процедурах и функциях для доступа к это-му файлу. При неудачном завершении функция возвращает значение - 1.

Отметим, что Object Pascal предоставляет свой более удобный способ досту-па к файлам через файловую переменную, а использование дескриптора фай-ла поддерживается функциями Windows API.

Пример:

var FileHandle : Integer;

begin

FileHandle := FileOpen(FileName, fmOpenWrite);

if FileHandle < 0 then

ShowMessage('He могу открыть файл');

end;

function FileRead(Handle: Integer; var Buffer; Count: Integer): Integer;Читает из файла, указанного дескриптором Handle, заданное количество байт.Параметр Count определяет количество читаемых байт, а параметр B u f f e r -буфер, в который записываются читаемые байты.

Функция возвращает количество реально прочитанных байт.

function FileSearch(const Name, DirList: string): string;Выполняет поиск файла в указанных каталогах. Параметр Name определяетимя искомого файла, а параметр DirList - список каталогов, в которых вы-полняется поиск, разделенных символом ;.

Если файл найден, то функция возвращает полный путь доступа к файлу,а если нет - пустую строку.

function FileSeek(Handle, Offset, Origin: Integer): Integer; overload;function FileSeek{Handle: Integer; const Offset: Int64; Origin: integer):

Int64; overload;Перемещает указатель текущей позиции файла, открытого функциямиFileOpen или FileCreate.Параметр Offset определяет отступ в байтах от позиции, указываемойпараметром Origin.

Параметр Origin указывается одним из следующих значений:

0 - выполнять отступ от начала файла;

1 - выполнять отступ от текущей позиции;

2 - выполнять отступ от конца файла.

При успешном завершении функция возвращает значение новой текущей по-зиции файла. В противном случае возвращается значение- 1.Отметим, что при работе с файловой переменной для перемещения текущейпозиции файла следует использовать функцию Seek.

Page 96: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

96 Глава 3

function FileSetAttr(const FileName: string; Attr: Integer): Integer;Устанавливает новые атрибуты файла.

Например: FileSetAttr f 'MyFile. ini ' , faReadOnly) ; .

function FileWrite(Handle: Integer; const Buffer; Count: Integer): Integer;Записывает в указываемый дескриптором файл Count байт из буфера Buffer.

При успешном завершении функция возвращает количество записанных бай-тов. В противном случае возвращается значение - 1.Отметим, что при работе с файловой переменной для записи в файл следуетиспользовать функции Write, Writeln или BlockWrite.

function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;Выполняет поиск файла с указанными параметром Attr атрибутами в каталогеPath.

Если файл найден, то функция возвращает значение 0, а в параметр F зано-сится информация о найденном файле.

Тип TSearchRec описывается как

type TSearchRec = recordTime: Integer; Size: Integer; Attr: Integer;Name: TFileName; ExcludeAttr: Integer;FindHandle: THandle; FindData: TWin32FindData;end;

function FindNext(var F: TSearchRec}: Integer;Продолжает поиск файла, начатый функцией FindFirs. При нахождении под-ходящего файла информация о нем заносится в параметр F, и функция воз-вращает значение 0.

procedure FindClose(var F: TSearchRec);Прерывает поиск и освобождает память, выделенную при вызове функцииFindFirst.

function GetCurrentDir: string;Возвращает полный путь для текущего каталога.

procedure CetDir(D: Byte; var S: string);Записывает в параметр S текущий каталог для указанного параметром D диска(О — диск по умолчанию, 1 — диск А и т. д.).

function RemoveDir(const Dir: string): Boolean;Удаляет пустой каталог, указанный параметром Dir.

function RenameFilefconst OldName, NewName: string): Boolean;Изменяет имя файла с OldHarae на NewName.

Page 97: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Object Pascal 97

function SetCurrentDirfconst Dir: string): Boolean;Устанавливает текущий каталог.

procedure ProcessPath (const EditText: string; var Drive: Char; varDirPart: string; var FilePart: string);

Выполняет разбор полного имени файла, укачанного параметром EditText, надиск (Drive), путь (DirPart) и имя файла (FilePart).

Процедуры и функции для работы с текстовымифайлами через файловую переменную

procedure AssignPrn(var F:);Назначает файловую переменную типа Text File (Text) текущему принтеру.

Далее всегда следует вызывать процедуру Rewrite. После этого назначениявывод функций Write или Writeln, пишущих в эту переменную, будет перена-правлен на принтер.

Для принтера одновременно может быть создана только одна переменная ти-па TextFile.

Пример:

{Этот код выполняет печать ка текущий принтер строки текста, направляемой

в переменную MyFile, шрифтом, определяемым свойством Font объекта

TCanvas}

varMyFile: TextFile;

begin

AssignPrn(MyFile]; (Назначение переменной}

Rewrite(MyFile);

Hriteln{MyFile, 'Напечатать строку на принтере 1 ] ;System.CloseFile(MyFile];

end;

function Eoln [(var F: Text) ]: Boolean;Определяет, является ли текущая позиция файла концом строки или концомфайла. Если параметр указан, то он определяет файловую переменную.В противном случае используется стандартная переменная Input, ассоции-руемая с устройством ввода (var Input: Texl;). Как правило, устройством вво-да является клавиатура.

Вызов E o l n ( F ) возвращает значение True, если текущая позиция файла ука-зывает на конец строки или на конец файла. Во втором случае одновременнои функция E o f ( F ) должна возвращать значение True.

procedure Erase(var F);Удаляет внешний файл, ассоциируемый с файловой переменной F.

4 Зак. 11

Page 98: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

98 Глава 3

Отметим, что перед удалением файл должен быть закрыт.

procedure Readln([ var F: Text; ] V1 [, V2, ...,Vn ]);Читает строку текста.

Пример:

|Код консольного приложения, читающего ввод с клавиатуры}5 : string;begin

Write('Введите строку текста: ' ) ;R e a d l n l s ] ;W r i t e l n f ' B b u i введен текст: * , з ) ;W r i t e l n i ' Д л я выхода нажмите клавишу E n t e r ' ) ;Readln;

end;

procedure SetTextBuf(var F: Text; var Buf [ ; Size: Integer] );Назначает текстовому файлу F вместо внутреннего 128-байтового буфера но-вый буфер, указываемый параметром Buf.

procedure Writeln([ var F: Text; ] P1 [, P2, ...,Pn ] );Записывает строку текста, включая символы конца строки.

Если параметр F не указан, то для консольного приложения Delphi автомати-чески ассоциирует файл вывода с Output-файлом.

Процедуры и функции обшего назначения

procedure Веер;Выдает звуковой сигнал (вызывая функцию Windows API MessageBeep).

procedure Exit;Выполняет немедленный выход из текущей процедуры.

procedure Break;Выполняет немедленный выход из текущего оператора цикла for, while илиrepeat. Управление передается на следующий после цикла оператор.

procedure Continue;Прерывает текущую итерацию оператора цикла for, while или repeat и пере-ходит на начало следующей итерации.

Page 99: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 4

ОБЪЕКТЫ И КОМПОНЕНТЫ

В этой главе дается краткий обзор компонентов, входящих в VCL-библ истеку.

ОСНОВНЫЕ понятияОбъекты

Объект Delphi представляет собой набор свойств и методов, включающих такжеобработчики событий. Свойства, называемые иногда атрибутами, являются дан-ными, содержащимися в объекте. Методы описывают действия, реализованныедля данного объекта.

Вес объекты имеют общего предка - класс TObject.Объект — это экземпляр класса. Например, форма реализуется классом TForm.При создании формы:

1. Создается класс TForm 1, производимый отТгогт.

2. Объявляется переменная объектною типа (объект) Forml. При объявлениипеременной происходит создание объекта (выделение памяти).Все компоненты, как визуальные, так и невизуальные, добавляемые в формуво время проектировании, становятся дочерними для формы. Для них автома-тически объявляются переменные соответствующего объектного типа.

КомпонентыКомпонент Delphi - это особый вид объектов - визуальный объект (визуальныйдля проектирования, а не для отображения пользователю). Создавать и редактиро-вать такой объект можно как программным путем, так и на этапе проектирования.Компоненты при выполнении программы могут быть визуальными или невизу-альными. Последние не могут быть непосредственно отображены во время вы-полнения программы (например, компонент TDalabase).Все компоненты имеют общего предка - класс TCoinponent.Delphi предоставляет широкий набор компонентов, называемый иногдаVCL-библиотекой. Все компоненты Delphi могут быть доступны через палитрукомпонентов.

Элементы управленияЧасть компонентов является элементами управления. В основном это элементыуправления Windows. Доступ к элементам управления возможен не только наэтапе проектирования, но и во время выполнения приложения.

Page 100: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

100 Глава 4

Элементы управления можно подразделить на оконные и неоконные. Оконныеэлементы могут получать фокус и имеют дескриптор окна. Предком всех окон-ных элементов управления является абстрактный класс TWinControl. Предкомнеоконных элементов управления является абстрактный класс TGraphicControl.

Область экрана, занимаемая элементом управления, называется клиентской об-ластью (client area). Для оконных элементов управления клиентская областьможет быть меньше, чем область окна элемента управления. Например, клиент-ская область формы определяется как прямоугольная область, в которой можноразмещать компоненты. А область окна формы дополнительно включает и стро-ку заголовка.

РАБОТА с ОБЪЕКТАМИ и КОМПОНЕНТАМИПри добавлении в форму любого компонента из палитры компонентов Delphiавтоматически формирует программный код для создания объекта (переменной)данного типа. В приведенном на рис. 4.1 редакторе кода (Code Explorer) даетсяавтоматически сформированный текст модуля Unitl.pas для формы, в которойбыл размещен компонент класса TEdit.

.jnjjcl

'-: tfy TForml

.+! Qj Published5 Qj Vanables.'CofistarHs

Cf Forral

i§ Classes^g Conlroli^g Dialogs

^ Forms*g Graphicste Messages

Э Va/iartsW Windows

Unill j Project! j

Dialogs;

;typeTrorinl • class (TFornij

private Список компонентов,{ Private declarations > размещенных В форме

public

f puWie decJardCions Jend;

vacF o r m l ! TFocml;

{ SR ".dim)

end.

2г 1 .Modified jlnseil ' '\\Co4efo~mgiam/

Рис. 4.1. Редактор кода Code Explorer

При создании новой формы одновременно формируется код на страницах Unitи Project редактора кода. На рис. 4.2 показан проект, при выполнении которогобудет создана форма, описанная в модуле Unitl.

Page 101: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 101

Uni(l Project!

program

usesГо cms,Umtl in • Umtl . pas' (Focial)!

*-•-*-

Appl icat ion.Ini t ia l i se ;Appl icat ion. CreateFocinlTForml, Fotrnll;A p p l i c a t i o n . Rur,;

end.

1: 1 Insert

Рис. 4.2. Вкладка Project редактора кола

При добавлении в проект объекта из VCL-библиотеки, отсутствующего! в палитре компонентов, следует указать в операторе uses имя модуля,

в котором он расположен.Предопределенные модули Delphi, необходимые проекту, такие, как classes,dialogs, windows и другие, также указываются в операторе uses.Информация об используемых предопределенных модулях автоматическидобавляется на основе параметров приложения (которые можно редактиро-вать в диалоге Project Options).По умолчанию Pascal-файлы основных предопределенных модулей нахо-дятся в каталоге Delphi 7\Source\Vcl.Для того чтобы расположить в форме какой-либо компонент, как визуаль-ный, так и невизуальпый, достаточно выбрать его в палитре компонентов,а затем щелкнуть в нужном месте окна формы. Для настройки компонентаследует использовать инспектор объектов. Компонент, в который можнопоместить другие компоненты, называется компонентом-контейнером. Длянастройки такого компонента на пего следует сбросить дочерние компонен-ты, выбрав их предварительно в палитре компонентов.

ПАЛИТРА КОМПОНЕНТОВПалитра компонентов содержит 33 страницы', на которых расположены кнопкикомпонентов Delphi. Каждому компоненту соответствует свой класс. Поэтомудля удобства мы будем называть компоненты именем класса (например, компо-нент класса Tform, или компонент TForm). Так как класс представляет собой

Не все пакеты компонентов Delphi 7 по умолчанию сразу отображаются в палитрекомпонентов. При необходимости палитру компонентов можно расширить.

Page 102: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

102 Глава 4

некоторый объектный тип, то иногда компонент называют объект типа класса(например, объект типа TForm). Более подробно классы компонентов Delphi бу-дут описаны в главе "Библиотека компонентов Delphi - VCL". Далее будет при-ведено содержание основных страниц палитры компонентов.

Страница StandardЭта страница содержит компоненты, которые принято считать стандартнымиэлементами управления Windows.

Пиктограмма

вFrames

MainMenu

Ч,

PopupMenu

АLabel

£БГ

Edit

Memo

• gn"i

Button

Класс

TFrame (обьект соз-дается не прищелчке по кнопкепалитры компонен-тов, а при выполне-нии пункта менюFile New Frame)

TMainMenu

TPopjpMenu

TLabel

TEdit

TMemo

TButton

Описание действия

Открывает диалог, отображающий списокфреймов, включенных в текущий проект.Следует выбрать фрейм и щелкнуть ОК

Создает линейку меню для формы. Для тогочтобы установить обработчики событий по ка-ждому пункту, меню следует добавить компо-нент MainMenu в форму и двойным щелчкоммыши открыть дизайнер меню Menu Designer

Создает всплывающее меню, отображаемоепри щелчке пользователя правой кнопкоймыши. Для того чтобы установить обработчи-ки событий по каждому пункту меню, следу-ет добавить компонент PopupMenu в формуи двойным щелчком мыши открыть дизайнерменю Menu Designer

Показывает текст, который нельзя изменятьинтерактивно с помощью клавиатуры илимыши, но можно изменять программно

Показывает однострочное поле редактирова-ния - обьект типа TEdit. Предназначен дляввода и редактирования строки текста

Показывает многострочное поле редактиро-вания - обьект типа TMemo

Создает командную кнопку - обьект типаTButton

Page 103: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Обьекты и компоненты 103

Пиктограмма

I*

CheckBox

ft

RadioButtQn

ListBox

ComboBox

.•I 1 M

ScrollBar

'LJGrojpBox

RadioGroup

Panel

AclionList

Класс

TCheckBox

TRadioButton

TListBox

TComboBcx

TScmllBar

TGroupBox

TRadioGroup

TPanel

TActionList

Описание действия

Создает флажок - обьект типа TCheckBox,который может переключать значения Да/Нетили Истина/Ложь (True/False). В группе одно-временна МОЖЕТ быть включено [значениеTrue) любое количество флажнов

Создает радионнопку - обьент типаTRadioButton, который может переключатьзначения Да/Нет пли Истина/Ложь(True/False). В группе одновременно можетбыть установлена (значение True) только однарадиакнопка

Показывает список - объект типа TListBox

Показывает комбинированный список -обьект типа TComboBox

Отображает линейку прокрутки - объект типаTScrollBar

Создает в форме контейнер для группы зави-симых флажков

Создает в форме контейнер - объект типаTRadioGroup - для группы зависимых радио-кнопок

Создает панель - объект типа TPanel, на ко-торой могут быть размещены другие компо-ненты (например, инструментальная панель,строка состояния)

Создает набор операций, позволяющий цен-трализировать ответы приложения на дейст-вия пользователя

Страница AdditionalСтраница Additional содержит дополнительный набор компонентов Windows.

Пиктограмма

BitBtn

Класс

TBitBtnОписание действия

Создает кнопку, на которой можно отобра-жать растровые изображения

Page 104: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

104 Глава 4

Пиктограмма

iSpeedButton

.j**I

MaskEdit

aac

SlringGrid

G^DrawGrid

3Image

&Shape

aBevel

•Scrcl lBox

тCheckListBox

4Splitter

Класс

TSpeedButton

TMaskEdit

TStringGrid

TDrawGrid

Tlmage

TShape

TBevel

TScrollBox

TCheckListBox

TSplitter

Описание действия

Создает кнопку-пиктограмму - объект классаTSpeedButton. На такой кнопке может отобра-жаться только рисунок без заголовка [напри-мер, группа кнопок на панели инструментов)

Создает объект типа TMaskEdit. аналогичныйобъекту типа TEdit, но предоставляющий воз-можность отображать наряду с самими дан-ными и некоторые специальные символы(например, тире в номерах телефона)

Создает таблицу для отображения в еестолбцах и рядах стран данных

Создает таблицу для отображения данных

Создает объект для отображения или редак-тирования рисунка (растрового изображения,пиктограммы или метафайла)

Рисует геометрические фигуры, такие, какэллипс, круг, прямоугольник, квадрат

Создает резко обозначенные трехмерныелинии и прямоугольники

Создает контейнер изменяемого размера,который автоматически при необходимостиотображает линейку прокрутки

Создает список аналогично объекту типаTListBox с тем отличием, что перед каждымэлементом списка располагается флажок

Добавляет в форму объект типа TSplitter(линия разбиения) между двумя рядом рас-положенными и выравненными элементамиуправления. Это позволяет пользователямизменять во время выполнения размеры зтихэлементов управления с помощью переме-щения мышью линии разбиения

Page 105: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 105

Пиктограмма

[АStaticText

мControlBar

<«е4,v-

ApplicationEvents

ОChart

rg

ValueListEditorLabel

^_LabeledEdit

sColorBox

SActionManager

ActionMainMenuBar

ЩTActionToolBar

Класс

TSlaticText

TControlBar

TApplicationEvents

TChart

TValueLislEditor

TLabeledEdit

TColorBox

TActionManager

TActionMainMenuBar

TActionToolBar

Описание действия

Создает обьент типа TStaticText (нередзнти-руемый тенет], аналогичный объекту Label,с тем отличием, что он имеет свой дескрип-тор окна. Это можно использовать, если тре-буется, чтобы ключ-акселератор принадле-жал оконному элементу управления

Добавляет менеджер компоновки, предназна-ченный для управления расположением пане-лей инструментов

Добавляет компонент, перехватывающий собы-тия уровня приложения. Это можно использо-вать и для определения на стадии проектирова-ния обработчиков событии уровня приложенияили для назначения обработчиков событий каж-дой отдельной форме приложения

Создает объект типа Tchart, эквивалентныйобъекту ТТаЫе

Предоставляет простой путь для редактиро-вания списка строк, состоящего из паримя/значение

Показывает однострочное помеченное полередактирования - объект типа TLabeledEdit.Предназначен для ввода и редактированиястроки текста. Метка поля редактированияуказывается свойством EditLabel

Показывает компонент типа TColorBox какниспадающий список, содержащий названияи отображения значений типа TColor. Пре-доставляет удобный способ для выбора зна-чения цвета. Свойства Selected содержит те-кущее значение выбранного цвета

Обеспечивает механизм отображенияи управления всеми действиями, входящимив приложение

Реализует специальный контейнер для отобра-жения на экране группы элементов в порядке,определенном компонентом TActionManager

Реализует специальный контейнер для ото-бражения на экране группы злементов -кнопок панели инструментов - в порядке,определенном компонентом TActionManager

Page 106: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

106 Глава 4

Пиктограмма

|pL

TCustomizeDIg

XPColor Map'И-- |

StandardColorMap

Twilighl ColorMap

Класс

TCustomizeDIg

TXPColorMap

TStandardColorMap

TTwilightColorMap

Описание действия

Предоставляет для TActionManager настраи-вающий диалог ActionBands

Позволяет определить индивидуальный видменю или панели инструментов ColorMap

Позволяет определить индивидуальный видменю или панели инструментов в соответст-вии с выбираемым colofmap-обьектом, кото-рый указывается свойством ColorMap

ПОЗВОЛЯЕТ определить индивидуальный видменю или панели инструментов

Страница Win32Эта страница предоставляет доступ к общим компонентам пользовательскогоинтерфейса для Windows 95/98/2000.

Пиктограмма

_,_,

TabControl

PageControl

1 1U*

ImageLisT

Класс

TTabControl

TPageControl

TlmageList

Описание действия

Этот компонент предоставляет множествостилей вкладом [tabs), не связанных с кон-кретными страницами. Это некоторый аналогярлыков в записной книжке

Используется для создания многостранично-го диалога в рамках одного окна. Являетсяконтейнером, в который помещаются стра-ницы диалога

Создает абьект список изображений, являю-щийся набором изображений одинаковогоразмера. Каждый элемент списка можетбыть доступен по его индексу. Этот элементуправления используется при организациидоступа к большому числу пиктограмм илирастровых изображений. Для добавленияизображений в список следует вызвать ре-дактор Image List Editor, выполнив на встав-ленном компоненте двойной щелчок мышью

Page 107: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 107

Пиктограмма

RichEdit

- 1-

TrackBar

• *'ы~

ProgressBar

ilUpDown

1лПГ

HotKey

<*Animate

H!DateTimePicker

^

MonthCalendar

FTreeView

FListView

HeaderCcntrol

Класс

TRichEdit

TT rack Bar

TProgressBar

TUpDown

THotKey

TAnimate

TDateTimePicker

TMonthCa.eri iBr

TTreeView

TListView

THeaderControl

Описание действия

Создает элемент управления поле редакти-рование с поддержкой форматирования, чтовключает возможность установления разме-ра, названии, начертания и цвета шрифта,определения выравнивания, отступов и табу-ляции, а также автоматического перемеще-ния мышью выделенного фрагмента текста

Создает объект типа TTrackBar, который являет-ся индикатором текущего значения и позволяетпосредством перемещения мышью бегункаинтерактивно изменять это значение

Создает прямоугольную область, заполняе-мую слева направо по мере выполнения не-которой операции

Создает обьект типа TUpDown, предназна-чаемый для интерактивного увеличения илиуменьшения значения при щелчке пользовате-ля соответственно по стрелке вверх или вниз

Пристыковывает к любому компоненту обь-ект, определяющий горячий ключ для быст-рого перехода на данный компонент

Создает окно анимации для отображенияAVI-клипа, представляющего собой последо-вательность изображений [без звука)

Отображает окно списка, позволяющеевыбрать дату или время

Отображает помесячный календарь

Создает обьект, позволяющий отображать мно-жество объектов на основе их иерархии как не-которое свертываемое и развертываемое дерево

Предоставляет возможность отображать спи-сок данных в различных видах и по столбцам

Создает обьект, который отображает один илинесколько заголовков столбцов. Текст заголов-ков может быть выравнен влево, вправо или поцентру. Каждый заголовок может быть опреде-лен как некоторая командная кнопнз, при щелч-ке на которой выполняется указанная функция

Page 108: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

108 Глава 4

Пиктограмма

-L2]

StatusBar

I ЖToolBar

CoolBar

Edi>'

PageScrolleri -чТШЖН»>»ЙШ

ComboBoxEx

Класс

TStalusBar

TToolBar

TCoolBar

TPageScroller

TComboBoxEx

Описание действия

Создает область для отображения строкисостояния. Строка состояния может бытьразделена на ряд отдельных панелей, в каж-дой из которых появляется своя информация

Управляет кнопками панели инструментови другими элементами, выравнивая их порядам и автоматически регулируя их разме-ры и расположение

Создает контейнер для отображения различ-ных элементов управлении внутри переме-щаемых и изменяющих свой размер полос(объекты CoolBand)

Содержит в клиентской области некоторыеобъекты, которые можно прокручивать вер-тикально или горизонтально

Показывает компонент ниспадающий список,предоставляя более широкие возможности,чем компонент TComboBox. В частности,элементы списка типа TComboBoxEx могутсодержать изображения

Страница SystemЭта страница содержит специальные системные компоненты, которые могутбыть добавлены в создаваемое приложение.

Пиктограмма

еTimer

&PaintBox

вMediaPlayer

OLE]

OleContainer

pt*Й

DdeClientConv

Класс

TTimer

TPaintBox

TMediaPlayer

TOIeContainer

TDdeClientConv

Описание действия

Создает невизуальный компонент таймер,который инициирует через определенныепромежутки времени событие OnTimer

Определяет внутри формы границы прямо-угольной области для рисования

Отображает управляющую панель (VCR-стиля) для проигрывания и записи мультиме-дийных видео- и звуковых файлов

Создает в форме OLE-контейнер

Устанавливает связь с клиентом при DDE(Dynamic Data Exchangel-обмене

Page 109: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Обьекты и компоненты 109

Пиктограмма

DdeClientltem

РЧ^О

DdeServerConv

'isDdeServerltem

Класс

TDdeClientltem

TDdeServerConv

TDdeServerltem

Описание действия

Определяет данные клиента, передаваемыесерверу при DDE-обмене

Устанавливает связь с сервером приDDE-обмене

Определяет данные сервера, передаваемыеклиенту при DDE-обмене

Страница Data Ac cessЭта страница содержит вспомогательные компоненты, позволяющие работатьс информацией базы данных.

Пиктограмма

О**^

DataSource

ClientDataSet

* с-Jo

DataSietProvider

XML

*XML

XMLTransform

i+XML

teiXMLTransformProvider

P*XML

XMLTransformClient

Класс

TDataSource

TCIientDataSet

TDataSetProvider

XMLTransform

XMLTransformProvider

XMLTransformCtient

Описание действия

Определяет используемый источник данныхи является связующим компонентом междунабором данных и элементом управления,в котором эти данные отображаются или ре-дактируются

Реализует на клиенте извлекаемый результи-рующий набор, полученный из локальногофайла или из другого результирующего набо-ра при помощи провайдера данных

Помещает данные в пакеты, которые могутиспользоваться для передачи клиенту, и при-сваивает изменения, получаемые от клиента

Позволяет выполнять преобразованиеXML-документов в пакеты данных

Позволяет извлекать данные изXML-донумента в клиентский результирую-щий набор и вносить изменения, сделанныев извлеченных данных, обратно в исходныйXML-документ

Позволяет преобразовать данные, получен-ные от провайдера, в XML-документ

Page 110: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

no Глава 4

Страница DataControlЭта страница содержит компоненты,тами управления для работы с полями

,

которые являются специальными элемен-баз данных.

Пиктограмма

DBGrid

DBNavigator

•ЯDBText

шDBEdit

DBMemo

DBImage

DBListBox

DBComboBox

f^L- \18

DBCheckBox

DBRadioGroup

Класс

TDBGrid

TDBNavigator

TDBText

TDBEdit

TDBMemo

TDBImage

TQBListBox

TDBComboBox

TDBCheckBox

TDBRadioGroup

Описание действия

Позволяет отображать данные из попей базыданных в табличной форме. Свойства столбцовтаблицы устанавливаются объектами типа TField

Создает обьент навигатор для перемещенияуназателя текущей записи по набору данных

Создает обьент, аналогичный TLahel, для ото-бражения значения поля тенущей записи

Создает обьект, аналогичный TEdit (одно-строчное поле редактирования), для отобра-жения значения поля текущей записи

Создает обьент, аналогичный ТМето (мно-гострочное поле редактирования), для ото-бражения и редактирования текстовых дан-ных формата BLOB

Создает обьент, аналогичный Tlmage(рисунок), для отображения и изменения (опе-рации вырезания и вставки) графических дан-ных формата BLOB для полей базы данных

Отображает в виде раскрывающегося списказначения из столбца таблицы

Создает объект комбинированный список дляотображения и редактирования значений изстолбца таблицы

Создает обьент флажок для отображенияи редактирования поля типа Booleanв текущей записи

Создает обьент группа радиокнопок для ото-бражения или установки значений столбца

Page 111: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 111

Пиктограмма

DBLookupListBox

Ей

DBLookupComboBox

DBRSchEdit

iiOBCtrlGrid

:F=5

DBChart

Класс

TDBLookupListBox

TDBLookupComboBox

TDBRichEdit

TDBCtrlGrid

TDBChart

Описание действия

Создает объект DBLookupListBox для ото-бражения спада элементов одним из двухспособов: как поля, определенного для набо-ра данных, или как поля - вторичного источ-ника данных (в соответствии со значениемполя и ключа). В любом случае пользовательможет сделать выбор из заданного ограни-ченного множества значений. Выбранноезначение становятся значением соответст-вующего набора данных

Создает обьект DBLookupComboBox, анало-гичный объекту DBLookupListBox, с темлишь отличием, что кроме выбора значенияиз списка можно также ввести это значение

Создает многострочное окно редактирования,позволяющее отображать и сохранять совмест-но с текстом и его форматирование (использу-ется длн форматированных memo-полей)

Объект DBCtrlGrid показывает набор полейиз набора записей на отдельных панеляхв табличной форме. Каждая панель являетсяконтейнером, в котором могут быть распо-ложены различные элементы управления дляработы с полями баз данных

Этот объект используется для отображениядиаграммы, основанной на значениях из на-бора данных

Страница dbExpressЭта страница содержит компоненты, позволяющие приложению взаимодейство-вать с базой данных.

Пиктограмма

[Ш, •

SQLConnection

| РЕКИ

SQLDataSet

Класс

TSQLConnection

TSDLDataSel

Описание действия

Инкапсулирует dbEx press-соединениес базой данных

Представляет данные, извлеченныепосредством dbExpress

Page 112: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

112 Глава 4

Пиктограмма

DEX

SQLQUery

"1- .7 : D

SQLStoredProc

EHSQLTable

DEK^

SQLMonitor

JSimple Data Set

Класс

TSQLQuery

TSQLStoredProc

TSQLTable

TSQLMonitor

TSimpleDataSet

Описание действия

Представляет запрос, выполняемыйпосредством dbExpress

Представляет хранимую процедуру,выполняемую с использованием dbExpress

Представляет таблицу базы данных,доступ к которой осуществляетсяс использованием dbExpress

Отслеживает сообщения, передаваемые ме-жду компонентом, реализующимSQL-соединение, и сервером базы данных,сохраняя эти сообщения как список строк

Реализует результирующий набор на клиен-те, используп TSQLDataSetи TDataSetProvider, кешируя информациюв памяти и сохраняя любые изменения,выполняемые приложением

Страница BDEЭта страница содержит компоненты, предназначенные для доступа к базе дан-ных с использованием машины баз данных ВРЕ (Borland Database Engine).

Пиктограмма

Table

Eql

Query

°fSQL1,

StoredProc

Класс

liable

TQuery

TStoreiiProc

Описание действия

Извлекает данные из таблиц базы данныхпосредством BDE для их отображения ком-понентами и посылает получаемые от этихкомпонентов данные в таблицу базы данных

Создает запрос, определяемыйSQL-оператором, для передачи данных меж-ду таблицами баз данных и компонентами.Доступ к таблицам поддерживается средст-вами BQE, а компонентам данные предос-тавляются через компонент TDataSource

Создает объект хранимая процедура, пред-назначенный для доступа к расположеннымна сервере баз данных хранимым процеду-рам. Посылает посредством BDE данные,получаемые от компонента, в базу данных

Page 113: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 113

Пиктограмма

Database

1 3"*

'э^Session

BatchMove

UpdateSQL

NestedTable

ев*'™*'

BDECIientDataSet

Класс

TDatabase

TSession

TBatchMove

TUpdateSQL

TNestedTable

EBDECIientDataSet

Описание действия

Устанавливает с базой данных постоянноесоединение

Обьент TSession автоматически создаетсядля каждого Delphi-приложения работы сбазой данных. Этот компонент используетсятолько для многопоточных приложений базданных: для каждого потока баз данных своясобственная сессия

Обьент предназначен для выполнения деист-вый над группой записей или всей таблицей.Он позволяет добавлять или удалять записииз таблицы, копировать набор данных длясоздания новой таблицы

Обьект TUpdateSQL позволяет для наборовданных, созданных с доступом только длячтения, поддерживать возможность их об-новления посредством SQL-операторов

Извлекает данные в поля со вложенныминаборами данных

Представляет результирующий набор наклиенте, полученный посредством ВОЕ

Страница ADOЭта страница содержит компоненты, которые позволяют выполнять доступк информации базы данных через объекты данных AciiveX - ADO.

Пиктограмма

Й5о1

45

ADQConnection

£31 SDoU

ADQCommand

Класс

TADQConnection

TADOCommand

Описание действия

Устанавливает постоянную связьс ADO-базой данных и обеспечивает под-держку транзакций

Передает SQL-команды непосредственноADO-базе данных без возвращения резуль-тирующего набора

Page 114: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

114 Глава 4

Пиктограмма

?ЕU°£

ADQDataSet

1|йМ.|

ADQTable

Ч DO

ADOQuery

П-*i ftDOfj

ADOStoredProc

BPSl

ЦН,

RDSConnection

Класс

TADODataSet

TADOTable

TAQOQuery

TADOStoredProc

TRDSConnection

Описание действия

Представляет данные из одной ми несколь-ких таблиц Базы данных, позволяя компо-нентам работы с данными (data-aware)манипулировать ими посредством компо-нента DataSource. Это наиболее общиеAQQ-злементы управления для набора дан-ных, которые могут быть использованыв ADQTable, ADOQuery или ADOStoredProc

Представляет данные из одной таблицы базыданных через ADO и позволяет компонентамработы с данными манипулировать ими по-средством компонента DataSource

Использует SQL-оператор для полученияданных из таблицы базы данных через ADOи позволяет компонентам работы с даннымиманипулировать ими посредством компо-нента DataSource

Позволяет приложению получить доступ черезADO к хранимым процедурам базы данных

Управляет маршалингом данных, при кото-ром объект Recordset передается междупроцессами или машинами

Страница InterBaseЭта страница содержит компоненты, которые позволяют реализовать доступк базе данных InterBase без использования средств BDE или ADO.

Пиктограмма

»IBTable

щ16 m

IBQuery

#JIB d

IBStoredProc

Класс

TIBTable

TIBQuery

TIBStoredProc

Описание действия

Представляет данные из одной таблицы иливида InterBase

Использует SQL-оператор для извлеченияданных из одной или нескольких таблицInterBase. Использование компонентаTIBQuery предоставляет наиболее легкийпуть перехода от локальной InterBaseк удаленной

Позволяет выполнить хранимую процедурубез возврата результирующего набора

Page 115: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 115

Пиктограмма

1В°

IBDataBase

|Щ|2IB'J

IBTransaction

IBEOl

IBUpdateSQL

ЕЯiiIBDataSet

SQL

«9IBSQL

ЙЕB-= l

IBDatabaselnfo

sA1BSQ.L

IBSQLMonitor

&IBEvents

B*IB UlIBExtractл==ilHIBCIientDataSet

Класс

TIBDatabase

TIBTransaction

TIBUpdateSQL

TIBDataSet

TIBSQL

TIBDatabaaelnfo

TIBSQLMonitor

TIBEvents

TIBExtiact

TIBClientDataSet

Описание действия

Позволяет управлять транзакциями и обеспе-чивает параметры соединения для удаленнойбазы данных (объект соединение)

Предоставляет возможность контроля тран-закций для одного или нескольких соедине-ний базы данных. Используется компонен-том IBDataBase

Позволяет применять оператор UPDATE длязапросов с доступом только для чтения

Предоставляет результирующий набор,сформированный SQL-оператором SELECT.IBDataSet позволяет отдельно определитьSQL-операторы для вставки, удаленияи обновления записей

Выполняет SQL-оператор для InterBase. IBSQLне имеет стандартного интерфейса для эле-ментов управления работы с данными

Возвращает информацию о присоединеннойбазе данных: версия QDS (online diskstructure), количество размещенных буфе-ров кеша, количество страниц базы данныхпо чтению или по записи и т. п.

Управляет динамическим SQL-оператором,переданным на сервер InterBase. СобытиеQnSDL получает теист для каждого динами-ческого SQL-оператора

Позволяет управлять событиями от сервераInterBase

Позволяет выполнять извлечение метадан-ных, таких, как список таблиц, представле-ний, ролей, индексов, для сервера InterBase

Кеширует обновление данных, извлеченныхпосредством InterBase Express без использо-вания внешнего провайдера и клиентскогорезультирующего набора

Page 116: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

116 Глава 4

Страница D a t a S n a pЭта страница содержит компоненты, которые предназначены для построенияприложений баз данных с многозвенной архитектурой. Иногда такие приложе-ния также называются многоуровневыми приложениями.

Пиктограмма

tgeoMl*вDCQMConnection

SocketConnection

41SimpleQbjectBroker

%WebCormection

ca'~J

ConnectionBroker

SharedConnection

LocalConnection

Класс

TDCOMConnection

TSocketConnectian

TSimpleObjectBroker

TWebConnection

TConnecttonBroker

TSharedConnection

TLocalConnection

Описание действия

Устанавливает DCQM-соединение с удален-ным сервером при многозвенной архитек-туре приложения баз данных

Устанавливает TCP/IP-соединение с удален-ным сервером при многозвенной архитек-туре приложения баз данных

Определяет для компонента, выполняющегосоединение, сервер из списка доступныхсерверов приложений

Устанавливает НТТР-соединение с удален-ным сервером при многозвенной архитек-туре приложения баз данных

Позволяет централизовать все соединениясервера приложений

Позволяет для приложения-сервера,использующего несколько удаленных мо-дулей данных, устанавливать соединениедля дочернего удаленного модуля данных

Реализует компонент, который действуеткак компонент соединение для провайде-ров, расположенных в том же приложении

Страница InternetЭта страница содержит компоненты, которые предназначены для построенияприложений Web-сервера.

Пиктограмма

WebDispatcher

PageProducer

Класс

TWebDispatcher

TPageProducer

Описание действия

Используется для превращения обычногомодуля данных в Web-модуль, позволяю-щий приложению Web-сервера отвечатьна HTTP-запросы

Преобразует HTML-шаблон в строку HTML,которая может быть интерпретирована Web-броузером на клиенте. Шаблоны преобразу-ются в строки HTML в обработчике событияDnHTMLTag

Page 117: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 117

Пиктограмма

DataSetTableProducer

DataSetPageProducer

%QueryTableProducer

SQLQueryTableProducer

TcpClient

ft*4лг '-TcpSeivei

I

UdpSocket

XMLDocument

WebBrowser

Класс

TDataSetTableProducer

TDataSetPageProducer

TQueryTableProducer

TSQLdjeryTableProducer

TTcpClient

TTcpServer

TUdpSocket

TXMLDocument

TWebBrowser

Описание действия

Создает из значений компонента TDataSetтаблицу, содержащую записи данногорезультирующего набора, представленныев формате HTML для последующей интерпре-тации Web-браузером

Заменяет HTML-шаблон на значение полябазы данных

Создает из значений компонента TQuery таб-лицу, содержащую записи данногорезультирующего набора, представленныев формате HTML для последующей интерпре-тации Web-броузером

Создает из значений компонента TSQLQueryтаблицу, содержащую записи данногорезультирующего набора, представленныев формате HTML для последующей интерпре-тации Web-броузером

Используется для превращения приложенияв TCP/IP-клиента. Позволяет управлятьсоединением с TCP/IP-сервером

Используется для превращения приложенияв TCP/IP-сервер. Позволяет устанавливать со-единения с TCP/IP-клиектами

используется для превращения приложенияв UDP/IP-клиент или сервер

Представляет XML-донумент

Реализует возможности компонента -Web-броузера

Следующие два компонента страницы Internet (автоматически отображаемые наней в предыдущей версии) можно подключить, выполнив команду менюComponent!Install Packages и добавив из каталога Delphi7\Bin пакет ddsockets70.bpl.

Пиктограмма

о|

ClientSocket

Класс

TCIientSocket

Описание действия

Реализует сонет на клиенте, работающийпо протоколу TCP/IP

Page 118: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

118 Глава 4

Пиктограмма

ServerSocket

Класс

TServerSocket

Описание действия

Реализует сонет на сервере, работающийпо протоколу TCP/IP

Страница Internet E x p r e s sЭта страница содержит два компонента, предназначаемых для создания Internet-приложений.

Пиктограмма

да~ . —•"XMLBroker

InetXPageProducer

Класс

TXMLBroker

TlnetXPageProducer

Описание действия

XML-брокер используется для передачиXML-пакетов между сервером приложенийи WEB-броузером

Формирует HTML-страницу, содержащуюданные из базы данных в XML-форматеи Java-скрипты, позволяющие упроститьпросмотр и обновление данных

Страница WebServicesЭта страница содержит компоненты, предназначаемые для создания клиентскихприложений, использующих для доступа к WEB-сервисам простой протоколдоступа к объектам SOAP (Simple Object Access Protocol).

Пиктограмма

SCrtPj

cp1

Suftp j

„SGftP !

Зши

§ШЕ|

fSQAglL'tj?1

.'

Класс

THTTPRIO

THTTPReqResp

TOPToSoapDomConvert

TSoapCtmnection

THTTPSoapDispatcher

Описание действия

Использование HTTP-сообщений для уда-ленного вызова процедур WEB-сервисовчерез SOAP

Определяет взаимодействие с WEB-сервисоми выполняет метод GET или POST для полу-чения параметров и формирования ответа.Сообщения передаются а SQAP-формате

Управляет маршалингом и демаршалингомвызовов методов SOAP

Используется при многозвенных архитек-турах приложений баз данных с клиентскойстороны для установления соединения ме-жду клиентом и удаленным сервером при-ложений, реализованным как WEB сервис

Выполняет передачу SQAP-сообщенийSOAP-анализатору

Page 119: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 119

Пиктограмма

UU5DIJ

•ЦСг

Р

Класс

TWSDLHTMLPublish

THTTPSoapPascallnvoker

Описание действия

Публикует список WSOL-документов,описывающих приложение WEB-сервиса

Интерпретирует SQAP-запрос и выполняетсоответствующий вызываемый метод

Страница WebSnapЭта страница содержит компоненты, позволяющие создавать серверныеWEB-приложения, формирующие управляемые данными WEB-страницы (data-driven WEB-pages).

Пиктограмма

.0,<#"к >

.",; Ц .

<кк>

[хх><SS5i>

(2)

ь%

Класс

TAdaptet

TPagedAdapter

TOataSetAdapter

TLaginFormAdapter

TStringsValuesList

TDataSetValuesList

TWebAppComponents

Описание действия

Включает компоненты поля и компоненты ко-манды и описывает обработчики сообщенийдля извлечения данных и выполнения команд

Позволяет формировать HTTP-ответ в виденабора HTML-страниц

Описывает для компонента TDataSet об-работчики сообщений для извлечения дан-ных и выполнения команд аналогично ком-поненту TAdapter

Содержит поля адаптера и команды адап-тера, используемые для формированияlogin-формы

Предоставляет список пар имя/значение,определяемый элементами свойстваValuesList данного компонента

Предоставляет список пар имя/значение,получаемый при извлечении значенийиз TDataSet

Используется для централизации доступак компонентам, реализующим функциони-рование WebSnap-приложения

Page 120: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

120 Глава 4

Пиктограмма

» - *<я»>

iвейяВкГЯ'т

i&

Класс

TApplicationAdapter

TEndUserAdapter

TEndUserSessionAdapter

TPageDispatcher

TAdapterDispstcher

TLocateFileService

TSessionsService

TWebUserList

TXSLPageProducer

Описание действия

Содержит компоненты поля и компонентыдействия, которые могут быть доступнычерез переменные серверного скрипта.По умолчанию первоначально объектTAppticationAdapter содержит единственноеполе Title. Для отображения значения этогополя можно использовать следующий син-таксис:<%= App!ication.Title%>

Предоставляет информацию о пользовате-ле: имя пользователя, права доступаи подключен ли данный пользователь

Предоставляет информацию о пользовате-ле: имя пользователя, права доступа и ста-тус подключения

Разбирает HTTP-запрос и передает егоWEB-шдулю в соответствии с указаннымURL

Компонент, автоматически добавляемый поумолчанию для всех WehSnap-приложений

Позволяет в режиме выполнения контроли-ровать нахождение файлов шаблонови include-файлое

Позволяет в течение необходимого периодавремени сохранять в памяти информациюо пользователях

Содержит список имен пользователей,паролей и прав доступа

Формирует содержание WEB-страницы, вы-полняя преобразования ХМЬданных на ос-нове XSL-шаблона

Page 121: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Объекты и компоненты 121

Пиктограмма

.« •*оКласс

TAdapterPageProducer

Описание действия

Автоматически формирует значение свой-ства HTML и скрипты JavaScript, необхо-димые для отображения полей адаптераи выполнения команд адаптера

С т р а н и ц а СОМ+Эта страница содержит всего один компонент, поддерживающий технологиюСОМ+.

Пиктограмма

Ф

Класс

TCOMAdminCatalog

Описание действия

Позволяет приложению функционироватькак контроллер автоматизации СОМ-*-

Страница RaveКомпоненты этой страницы предназначены для формирования различных типовRave-отчетов . В состав Delphi 7 входит инструментарий Rave Designer, предос-тавляющий удобные средства визуального формирования Rave-отчетов различ-ной сложности.

Пиктограмма

puf

$йэ

^D,-:-

"^^

Класс

TRvProject

TRvSystem

TRvNDRWriter

TRvCustomConnection

TRvDataSetConnection

Описание действия

Основной компонент, используемый длясоздания отчета

Объединяет функциональность компонен-тов TRvRenderPreview, TRvRenderPrinterи TRvNDRWriter, позволяя отображатьотчет или печатать его

Сохраняет отчет в специальном бинарномформате, пока он отображается компонен-том TRvNDRWriter или печатается компо-нентом TRvRenderPrinter

Используется для определения, каким обра-зом данные посылаются в Rave-отчет. Этоткомпонент позволяет использовать данныене из источника данных (базы данных)

Используется для предоставления данныхот TDataSet визуальнымRave-номпонентам

1 Термин "Rave-отчет" используется для дифференцирования отчета, создаваемого припомощи Rave Designer, от отчетов, создаваемых на основе компонентов страницыQReporl палитры компонентов.

Page 122: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

122 Глава 4

Пиктограмма

. . • rffaг — '— v^ — '

А=--.\

щPDF|

!!*!HTriL

PWRTF|

тTEXT

Класс

TRvTableConnection

TRvQueryConnection

TRvRenderPreview

TRvRenderPrinter

TRvRenderPDF

TRvRenderHTML

TRvRenderRTF

TRvRenderText

Описание действия

Используется для предоставления данныхот компонента ТТаЫе

Используется для предоставления данныхот компонента TQuery

Получает от TRuNDRWriter сформирован-ный файл и направляет его на экран дляпредварительного просмотра

Получает от TRvNDRWriter сформирован-ный файл и направляет его на текущийпринтер

Конвертирует NDR-поток или файлв PDF-формат. При этом поддерживаетсяпреобразование текста, изображений,линий и фигур

Конвертирует NDR-поток или файлв HTML-формат. При этом поддерживаетсяпреобразование текста, изображений, ли-ний и фигур

Конвертирует NDR-поток или файлв RTF-формат. При этом поддерживаетсяпреобразование текста, изображений, ли-ний и фигур

Конвертирует MDR-поток или файл в тек-стовый формат. При этом поддерживаетсяпреобразование только текстовых объек-тов, все другие обьекты игнорируются

Страница DialogsЭта страница содержит компоненты, которые служат для добавления в прило-жение общих диалогов Windows, обеспечивающих стандартный интерфейс длятаких действий, как открытие, сохранение и печать файлов.Такой диалог открывается при вызове метода Execute. При щелчке пользователяна кнопке ОК возвращается значение True, а на кнопке Cancel или клавишеEscape - False. Для настройки появления и поведения диалога используетсясвойство Options. Для того чтобы закрыть диалог программно, следует вызватьметод CloseDialog.

Пиктограмма

тт

Класс

TQpenDialog

TSaveDialog

Описание действия

Отображает стандартный диалог Open

Отображает стандартный диалог Save

Page 123: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Обьекты и компоненты 123

Пиктограмма

т

и73

Лз,]

\штА*Г|

Класс

TOpenPictureDialog

TSavePictureDialoy

TFontDialog

TColorDialog

TPrintDialog

TPrinterSetupDialog

TFindDialog

TReplaceDialog

Описание действия

Отображает стандартный модальный диа-лог для выбора и открытия графическихфайлов. Этот диалог идентичен диалогуOpen, но имеет ДОПОЛНИТЕЛЬНО панель дляпросмотра изображения

Отображает стандартный диалог для сохра-нения графических файлов. Этот диалогимеет панель для просмотра изображении

Выводит стандартный диалог Font, исполь-зуемый для определения шрифта, размераи стиля отображения данных

Отображает стандартный диалог Color

Отображает стандартный диалог Print

Отображает стандартный диалог PrinterSetup

Отображает стандартный диалог Find

Отображает стандартный диалог Replace

Страница Act iveXЭта страница содержит компоненты ActiveX. Для их настройки следует из кон-текстного меню компонента выбрать команду Property. Одновременно можноиспользовать и инспектор объектов.

Пиктограмма

о,

•ф&

*

Класс | Описание действия

TChartfx

TVSSpell

TFIBook

TVtChart

Позволяет создавать настраиваемые диа-граммы

Предназначен для выполнения проверкиорфографии

Создает страницу электронной таблицы,аналогичной Excel, и поддерживает еефункционирование. Этот компонент позво-ляет выполнять ввод данных в ячейки, вводи вычисление формул, перемещение и ко-пирование данных с помощью мыши

Создает трехмерную диаграмму

Page 124: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

124 Глава 4

Страница QReportДля отображения данной страницы (автоматически отображаемой в преды-дущей версии) в палитре компонентов следует выполнить команду менюComponent [Install Packages и добавить из каталога Delpni7\Bin пакет ddqrtTO.bpl.Страница QReport содержит компоненты, которые предназначены для визуаль-ного проектирования быстрых отчетов (Quick Report). Такой отчет может бытьсформирован на основе любого источника данных DaiaSource, включая ТТаЫе,TQuery, списки или массивы. В отчет могут быть включены разлччные общепри-нятые элементы отчетных форм, такие, как заголовки отчета, заголовки страниц,верхние и нижние колонтитулы, группы, суммирование полей и счетчики.

Пиктограмма

QuickRep

QRSubDetail

QR Strings В and

UsQRBand

1J

QRChildBand

1|_

QRGroup

:"kQRLabel

Класс

TQuickRep

TQRSubDetai!

TQRSlringsBand

TQRBand

TORChildBabd

TQRGroup

TQRLabei

Описание действия

Зто визуальный компонент, определяющийпрямоугольную область текущего выбранно'го размера страницы. На основе этой базис-ной формы строятся все отчеты. Для созда-ния отчета следует сбросить на данный ком-понент полосы TQRBand и все печатаемыекомпоненты, соединив их с набором данных

Позволяет добавлять в отчет дополнительныенаборы данных. Обычно для этого междукомпонентами таблица или запросустанавливаются отношения родительская-дочерняя (master/detail). Отношение созда-ется посредством компонента TQRSubDetail

Размещение полос, содержащих строкиформируемого отчета

Размещение полос на компонентеTQuickRep. Для определения поведенияполосы во время генерации отчетаиспользуется свойство BandType

Используется для размещения одних ком-понентов под другими, а также при слиш-ком длинных полосах протяженностьюа несколько страниц

Позволяет группировать полосы и обеспе-чивает управление заголовками и колонти-тулами

Печатает любой статический текст не изисточника данных. Отображаемый теистопределяется свойством Caption. Текстможет располагаться как на несколькихстроках, так и на нескольких страницах

Page 125: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Обьекты и компоненты 125

Пиктограмма

АQRDBText

Э;Ei»1

QRExpr

~£Y£

QRSysData

ORMemo

%QRExprMemo

«bQRRichText

DRDBRichText

%QRShape

t,QRImage

43QRDBImage

QRCompositeReport

Класс

TOROBText

TGRExpr

TQRSysData

TQRMemo

TQRExprMemo

TQRRichText

TQRQBRichText

TQRShape

TQRImaga

TQRDBImage

TQRCompositeReport

Описание действия

Печатает значение поля из источника дан-ных. Это могут быть строковые или число-вые поля, поля-даты и memo-поля. Тенетможет располагаться как на несколькихстроках, так и на нескольких страницах.Источник данных и поле данных определя-ются свойствами DataSource и DataField

Печатает значение поля из источника дан-ных или выражения, включающего значенияполей. Печатаемое значение определяетсясвойством Expression

Печатает системную информацию: заголо-вок отчета, номер текущей страницы и т. п.Печатаемые данные определяются свойст-вом Data, а предшествующий текст -свойством Text

Предназначен для вывода большого тенетане лэ источнина данных

Позволяет программно формировать со-держание, используя выражения QuickReport

Позволяет встраивать в отчет форматиро'ванный текст

Предоставляет отчету иметь доступ к полюданных DBRichText

Рисует в отчете простые фигуры, такие,как прямоугольник, линия или круг

Отображает в отчете рисунок. Может бытьиспользован любой из графических форма-тов, поддерживаемых классом TPicture

Печатает рисунок из двоичного поля (BLOB)данных

Позволяет объединять вместе несколькоотчетов

Page 126: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

126

Пиктпгоамма Класс

Глава 4

| Описание действия

ГЛАВА 5

БИБЛИОТЕКА ОМПОНЕНТОВDELPHI-VCL

Эта глава описывает компоненты VCL-библиотеки, их свойства и методы. Онасодержит справочную информацию, и начинающий программист может сразуперейти к главе — "Создание приложений « среде Delphi", обращаясь к информа-ции из этой главы по мере необходимости.

ИЕРАРХИЯ КЛАССОВ VCL-БИБЛИОТЕКИБиблиотека визуальных компонентов VCL содержит набор классов и общихпроцедур. Классы реализованы таким образом, что каждый класс может иметьодного непосредственного предка, а этот предок - своего одного предка и т. д.На рис. 5.1 приведен пример корневой части дерева иерархии классов.

TControl TTimer

iiП

TScreen TMenullem TMenu TCommonDialog TGIobalComponent

TWinConlrol TGraphicControl TAp plication

TScrollingWinControl TBultonControi

Рис. 5.1. Иерархия классов VCL-библиотеки

При создании формы всегда создается новый класс, производный от сущест-вующего класса TForm VCL-библиотеки.

Page 127: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА
Page 128: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА
Page 129: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 29

КЛАССЫ, ИНКАПСУЛИРУЮЩИЕ ОБШЕЕ

ПОВЕДЕНИЕ КОМПОНЕНТОВ

Класс TObjectРасположен в модуле System

Класс TObject инкапсулирует общие черты поведения всех объектовVCL-библиотеки. Это включает:

• создание, управление и разрушение экземпляра объекта путем выделения емупамяти, инициализации и последующего освобождения выделенной памяти;

• доступ во время выполнения к информации о типе экземпляра объекта и егоpublished-свойствам - RTTI-информация;

• поддержку управления событиями;

• поддержку реализуемых объектами интерфейсов.

Если при создании нового объекта не указан базовый класс, то Delphi автомати-чески использует как предка класс TObject.

Объявление

Объявление нового класса выполняется в секции type. Если после слова classв скобках не указано никакого наследуемого класса, то по умолчанию предпола-гается, что создаваемый класс наследуем от класса TObj ect.

Например:type TMyClass = class // Эти два объявления

type TMyClass = class(TObject) //являются эквивалентными.

Класс TCIassTClasg объявляется в модуле System как тип класс-ссылка (class-reference type).

Тип класса-ссылки иногда также называется метаклассом. Он определяетсяконструкцией вида class of AnyTypeClass.

TCIass определен как type TCIass = class of TObject,-.Класс-ссылка используется для определения типа объекта во время выполнения.Также он позволяет использовать свойства и вызывать методы класса даже в томслучае, если его тип неизвестен во время компиляции.

Пример:

procedure TForml.ButtonlClick[Sender: TObject);var

GlassRef: TCIass; {Класс-ссылка}

5 Зак. 1 1

Page 130: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

130 Глава 5

beginListBoxl.Clear; (Свойство ClassType, доступное по ссылке на класс}

ClassRef := Sender.ClassType;

while ClassRef <> nil do

begin {Цикл поиска всех предков и добавления их в список)ListBoxl.Items.Add(ClassRef.ClassName);

ClassRef := ClassRef.ClassParent;

end;end;

Класс TComponentРасположен в модуле Classes

TComponent является предком всех компонентов VCL-библиотеки.Все потомки данного класса могут быть расположены в палитре компонентов.Как правило, этот класс используется в качестве непосредственного предкатолько для создания невизуальных компонентов, которые можно помещатьв палитру компонентов и настраивать во время проектирования.Для создания визуальных компонентов, как правило, используется классTControl, а для создания окопных объектов - класс TWinControl.

Класс TComponent позволяет определять родительский элемент управления и вла-дельца компонента.Родительским элементом управления называется тот, в который непосредствен-но помещен данный компонент.Владельцем всех компонентов, расположенных в форме, является сама форма.Владельцем всех форм является приложение.Если компонент расположен не непосредственно в форме, а, например, в компо-ненте типа TPanel или TGroupBox, то владелец и родительский элемент управле-ния у него будут различны.

Свойства':

property ComObject: ILJnknown;Определяет ссылку на интерфейс, реализованный компонентом. Используетсятолько для компонентов, поддерживающих СОМ-интерфейс. В противном слу-чае попытка доступа к этому свойству вызывает исключение EComponentError.

property ComponentCount: Integer;Указывает количество компонентов, принадлежащих данному компоненту.Используется для последовательного доступа ко всем компонентам (напри-мер, формы).

В книге приведено описание только наиболее значимых свойств и методов рассматри-ваемы* компонентов. Если класс, в котором объявляются свойство или метод, нерассматривается, то эти свойство и метод могут быть описаны при рассмотрениипроизводного класса.

Page 131: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 31

property Componentlndex: Integer;Указывает индекс компонента в массиве Components владельца данного ком-понента. Первый компонент в списке имеет индекс 0.

property Components[lndex: Integer]: TComponent;Список всех компонентов, принадлежащих данному компоненту. Использу-ется для ссылки на компонент по его индексу или для последовательногодоступа ко всем компонентам, принадлежащим данному компоненту.

property ComponentState: TComponentState;Описывает текущее состояние компонента. Тип TComponentState определяетсякакtype TComponentState = set of (csLoading, csReading, csWriting,csDestroying, csDesigning, csAncescor, csUpdating, csFixups,csFreeNotification, cslnl ine);-

property ComponentStyle: TComponentStyle;type TComponentStyle = set of (cslnheritable, csCheckPropAvail); .Описывает стиль компонента.

property Name: TComponcntName;Указывает имя компонента, используемое в коде программы для доступак его свойствам и методам. При создании компонента Delphi автоматическиназначает ему имя на основе класса компонента. Например: Editl, Label 1,Label2.

property Owner: TComponent;Указывает компонент, владеющий данным компонентом. Компонент всегдаудаляется (освобождается память) при удалении его владельца.

property Tag: Longint;Сохраняет 32-битовое значение. Это свойство может использоваться по ус-мотрению разработчика для сохранения некоторой дополнительной инфор-мации для компонента.

Класс TControlРасположен в модуле Controls

TControl - это базовый класс всех визуальных компонентов - элементов управ-ления (включая и окно формы). Эти компоненты могут быть видимы во времявыполнения. Для них определены такие свойства, как позиция, курсор, всплы-вающая подсказка; методы для рисования йили перемещения элемента управле-ния, события для манипуляций с помощью мыши.

Page 132: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

132 Глава 5

Свойства:

property Action: TBasicAction;Назначает действие (объект action), ассоциируемое с элементом управления. Длясоздания действия следует во время проектирования поместить в форму или мо-дуль данных компонент ActionList, затем выполнить на нем двойной щелчокмышью, вызвав редактор для этого компонента. В редакторе с помощью контек-стного меню можно добавить новые действия. В завершение эти действия мож-но устанавливать как значения свойства Action в инспекторе объектов.

property AutoSize: Boolean;Определяет, будет ли элемент управления автоматически изменять свой раз-мер при изменении его содержимого.

property BoundsRect: TRect;Определяет прямоугольную область, занимаемую элементом управления.Выражение R := Control.BoundsRect; можно записать как четыре следую-щих выражения:

R.Left := Control.Left;R.Top := Control.Top;R.Right ;= Control.Left +• Control .Width;R.Bottom := Control.Top t Control.Height;

type TCaption = string;Определяет строку, отображаемую как заголовок окна или метку. Символ &в заголовке указывает, что следующий за ним символ будет отображатьсяподчеркнутым. Такой символ определяет клавишу-акселератор. При одно-временном нажатии этой клавиши и клавиши Alt происходит перемещениефокуса ввода на данный элемент управления. Для того чтобы показать в заго-ловке сам символ амперсенда, следует ввести два символа &&.Некоторые элементы управления не используют свойство Caption (например,компонент типа TEdit). Как правило, для них определено свойство Text, ко-торое предназначено для отображения содержания элемента управления.

property ClientHeight: Integer;property ClientWidth: Integer;

Эти свойства позволяют определять и изменять высоту и ширину клиентскойобласти элемента управления (в пикселях). Для класса TControl значение этихсвойств совпадает со значениями свойств Height и Width. Однаков производных классах свойства ClientHeight и ClientWidth могут быть пе-реопределены. Например, для компонента типа TFora свойство ClientHeightравно значению свойства Height минус высота строки заголовка и линейкипрокрутки.

Page 133: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 133

property ClientOrigin: TPoint; (только для ЧТЕНИЯ)Определяет экранные координаты верхнего левого угла клиентской областиэлемента управления (в пикселях). Если элемент управления является потом-ком класса TControl и не является потомком класса TWinControl (неоконныйэлемент управления), то для определения его верхнего левого угла следуетдобавить значения свойств Left и Тор к экранным координатам его родитель-ского элемента управления.

property ClientRect: Trect (только для ЧТЕНИЯ)Определяет размер клиентской области элемента управления (в пикселях).Это можно записать как Rect(0, 0, ClientWidth, ClientHeight). ЗначенияТор и Left для определяемой прямоугольной области равны 0.

property ControlStyle: TControlStyle;Определяет стиль элемента управления. Стиль указывается набором установ-ленных флажков. Класс TControlStyle определяется следующим образом:type TControlStyle = set of (csAcceptsControls, csCaptureMouse,csDesignlnteractive, csClickEvents, csFramed, csSetCaption, csOpaque,csDoubleClicks, csFixedWidth, csFixedHeight, csNoDesignVisible,csReplicatable, csMoStdEvents, csDisplayDraglmage, csReflector,csActionClient, csMermEvents) ; .

В следующей таблице приведены значения некоторых флажков для определениястиля.

Флажок

csAcceptsControls

csCaptureMouse

csClickEvents

csFramed

csSetCaption

csOpaque

csDoubleClicks

csFixedWidth

csFixedHeight

csNoDesign Visible

csNoStdEvents

Описание

Становится родительским для любого элемента управления, сброшен-ного на него во время проектирования

При щелчке мышью «захватывает» это событие

Может получать и реагировать на щелчки мышью

Имеет рампу 3D

Значение свойства Caption должно быть равным Name, если свойствоCaption не было установлено непосредственно

Полностью заполняет свою клиентскую область

Может получать и реагировать на двойные щелчки мышью. Если этотфлажок не установлен, то двойной щелчок воспринимается как обыч-ный щелчок мышью

Ширина не может быть изменена

Высота не может быть изменена

Является невидимым во время проектирования

Не реагирует на стандартные сообщения от мыши, от клавиш и от щелч-ков. Это значительно увеличивает скорость выполнения приложения

Page 134: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

134 Глава 5

Первоначально конструктор класса TControl устанавливает для ControlStyle сле-дующие флажки: csCaptureMouse, csClickEvents, csSetCaption,csDoubleClicks.

property Color: TColor;Позволяет определять или изменять фоновый цвет элемента управления. Ес-ли значение свойства ParentColor равно True, то при изменении фона роди-тельского элемента управления происходит и автоматическое изменение фо-на дочернего элемента управления. При изменении значения свойства Colorзначение свойства ParentColor автоматически устанавливается равным False.

Класс TColor используется для определения цвета объекта. Он определяетсяследующим образом:

type TColor = -(COLOR_ENDCOLORS + 1 ) . . S 0 2 F F F F F F ;

Расположен в модуле Graphics. Этот модуль также содержит набор констант, оп-ределяющих цвет.

Тип TColor представляется 4-байтовым шестнадцатеричным числом. Младшие3 байта определяют интенсивность синего, зеленого и красного в RGB-цвете по1 байту на каждую составляющую (например, SOOOOOOFF - это красный). Стар-ший байт определяет используемую цветовую палитру ($00 - системная палитра).

В следующих таблицах приведены константы для некоторых цветов.

Цвета системной палитры

Константа

clAqua

clBlack

ctBlue

clUkGiay

c/Gray

cIGreen

cILime

cILtGray

Цвет

Зеленовато-голубой

Черный

Синий

Темно-серый

Серый

Зеленый

Лимонный

Светло-серый

Константа

cIMaroon

сШзуу

clOlive

cIPurple

cIRed

clSHver

clWhite

clYellow

Цвет

Темно-бордовый

Морской волны

Оливковый

Пурпурный

Красный

Серебристый

Белый

Желтый

Цвета, определяемые на панели управления Windows

Константа

^Background

clActiveCaption

cllnactiveCaption

cIMenu

Описание

Текущий фоновый цвет рабочего стола Windows

Текущий цвет строки заголовка

Текущий цвет строки заголовка

активного окна

неактивного окна

Текущий фоновый цвет меню

Page 135: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 135

Цвета системной палитры

clWindow

clWindowFrame

c/MetwText

clWindowText

cICaptionText

dActiveBortfer

cllnactiveBorder

clAppWorkSpace

clHighlight

clHightlightText

cIStnFace

clBtnShadow

cIGrayText

ctBtnText

cllnactiveCaption Text

clBtnHighlight

cllnfoText

dlnfoBk

Текущим

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

Текущий

фоновый цвет окон Windows

цвет области окна

цвет текста в меню

цвет текста в окнах

цвет текста заголовка активного окна

цвет рамки активного окна

цвет рамки неактивного окна

цвет рабочего пространства приложений

фоновый цвет выделенного текста

цвет выделенного текста

цвет кнопки

цвет для тени от кнопки

цвет недоступного текста (посеревший)

цвет для текста кнопни

цвет текста заголовка неактивного окна

цвет выделения кнопки

Цвет текста в окне подсказки

Фоновый цвет для окна подсказки

Пример:

procedure TForml.ButtonlClick(Sender: TObject};begin

if ColorDialogl.Execute {Отображение стандартного диалога)then Shapel.Color := ColorDialogl.Color; {Свойство Color

объекта ColorDialogl содержитзначение выбранного цвета}

end;

property Cursor: TCursor;Определяет изображение, отображаемое в качестве курсора мыши при распо-ложении указателя мыши над областью, занимаемой элементом управления.Это может быть как пиктограмма устроенного курсора мыши, используемогов Windows, так и пиктограмма курсора мыши, созданная пользователем и до-бавленная в файл ресурсов.Пиктограммы встроенных курсоров выбираются по указываемому индексудля списка курсоров, управляемому посредством глобальной переменнойScreen. Например: Cursor := Screen.Cursors[nlndex];.

Page 136: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

136 Глава 5

Для того чтобы использовать определенную пользователем пиктограмму длякурсора мыши, достаточно добавить ее в список переменной Screen, загрузивданный курсор вызовом метода LoadCursor.

Класс TCursor определяется как type TCursor = -32768..32767; и являетсяиндексом в глобальном списке доступных курсоров переменной Screen.

В Delphi установлены следующие значения констант типа TCursor для предо-пределенных (встроенных) курсоров:

Константа

crfJone

crArrow

crCmss

сг/Веэт

crSizeNESW

crSizeNS

crSizeNWSE

crSizeWE

crUpArrow

crHourGlass

crDrag

crDefault

Значение

-1

-2

-3

-4

-6

-7

-8

-9

-10

-11

-12

0

Пиктограмма

k

Q-

Л

&-•

г%.<Й'

tIV

Константа

crNoDrop

crHSplit

crVSplit

crMultiDrag

с/ -SQL Wait

crfl/o

crAppStart

crHelp

crHandPoint

crSize

crSizeAII

Значение

-13

-14

-15

-16

-17

-18

-19

-20

-21

-22

-22

Пиктограмма

©~

1!*_«

SQL

^

1'

W

U

(для совмести-мости с преды-дущим и вер-сиями)

ФПиктограмма, используемая для ононного класса по умолча-нию (нак правило, crArrow)

Page 137: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 37

Пример:

(Добавление курсора в приложение. Предварительно курсор с именем My_Curl

был создан и добавлен в файл ресурсов. Курсор можно создать при помощи

утилиты linage Editor}

const

myCursorl = 5;

procedure TForml.ForaCreate(Sender: TObject);begin

(Добавление нового курсора в список доступных курсоровприложения:}

Screen.Cursors[myCursorl] := LoadCursor(HInstance, 'My_Curl ') ;Cursor := myCursorl; {Определение текущего курсора для

приложения)end;

property DesktopFont: Boolean;Если это свойство равно True, то при вводе текста будет использоватьсяшрифт Windows, определяемый свойством IconFont глобальной переменнойScreen. И каждый раз при изменении значения IconFont будет автоматическиобновляться значение свойства Font элемента управления.

property Enabled: Boolean;Определяет, доступен ли элемент управления для действия мыши, реакции нанажатие клавиш и на события таймера.

property Floating: Boolean; (только для ЧТЕНИЯ)Указывает, появляется ли встраиваемый элемент управления отдельно в пла-вающем окне или встроенным в родительский элемент управления.

property Font: TFont;Определяет атрибуты текста, такие, как шрифт, начертание, размер, цвети т. п. Эти атрибуты относятся к тексту, как записываемому в элементеуправления, так и отображаемому на элементе управления.

Для определения нового шрифта следует создать объект класса TFont и уста-новить значения его свойств (например, Charset, Color, Height, Name,Pitch, Size, Style).

property Height: Integer;property Width: Integer;

Эти свойства определяют вертикальный и горизонтальный размер элементауправления в пикселях.

property DragCursor: TCursor;Определяет вид указателя мыши при перемещении мышью элемента управления.

Page 138: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

138 Глава 5

property DragKind: TDragKind;Определяет, как перемещается элемент управления: нормально (drag-and-drop) или для встраивания (drag-and-dock).

property DragMode: TDragMode;Определяет, как начинается операция перемещения элемента управлениямышью. Если установлено значение dmManual, то пользователь во время вы-полнения не может выполнить операцию dmAiiloinatic перемещения до вызо-ва в приложении метода BeginDrag. Значение eliiiAuromalic позволяет начатьперемещение непосредственно при щелчке мыши.

property HelpType: THelpType;Определяет, каким образом для элемента управления будет специфицированатема файла справки. Если значение свойства равно litContext, то ГО справкисодержится е свойстве HelpContext. Если значение свойства равно htKeyword,то тему справки определяет свойство HelpKeyword.

property HelpContext: THelpContext;Определяет числовой ID темы справки, отображаемой как контекстнозависи-мая справка. Если ID тем в файле справки определяются ключевыми словами,то следует использовать свойство HelpKeyword Это свойство доступно тольков том случае, если значение свойства HelpType равно lilCotnext. По умолча-нию значение свойства HelpContext равно 0, что означает отсутствие иденти-фикатора отображаемой темы справки.

property HelpKeyword: String;Содержит строку, определяющую ключевое слово темы, отображаемой дляконтекстнозависимой справки. Это свойство доступно только в том случае,если значение свойства HelpType равно htKeyword. По умолчанию значениесвойства HelpKeyword содержит строку нулевой длины, что означает отсут-ствие идентификатора отображаемой темы справки.

property Hint: string;Содержит подсказку, отображаемую при расположении и задержании указа-теля мыши под элементом управления. Одновременно для этого значениесвойства ShowHint должно быть установлено равным True. При перемещениимыши под элементом управления инициируется событие OnHint.

property Left: Integer;Определяет горизонтальную координату элемента управления относительноего родительского элемента.

property Top: Integer;Определяет Y-координату верхнего левого угла элемента управления относи-тельно его родительского элемента.

Page 139: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 39

property LRDockWidth: Integer;Определяет ширину элемента управления при его встраивании с горизон-тальной ориентацией. Это 'значение запоминается таким, каким оно было припредыдущей операции встраивания с горизонтальной ориентацией. Если егоизменить, то оно будет использовано при следующей операции встраивания.

property MouseCapture: Boolean;Указывает, имеет ли элемент управления "захваченное" событие мыши. За-хват события означает, что до того момента, пока пользователь не отпуститнажатую кнопку мыши, все события, инициируемые перемещением мыши,будут направляться данному элементу управления.Это свойство может использоваться для операций перемещения и сбросаобъекта мышью.

property Name: TComponentName;Определяет имя элемента управления, используемое в коде программы.

По умолчанию интегрированная среда разработки IDE назначает объектамимена, используя в качесве префикса название компонента, а в качестве суф-фикса - порядковый номер расположенного в форме компонента данного ти-па. Например, Editl, Edit2 и т. д.Изменять значение данного свойства можно только во время проектирования.При изменении имени следует учитывать, что:

1. Имя должно быть разрешенным идентификатором в Object Pascal.

2. Свойство Caption будет изменено аналогично свойству Name, если оно ра-нее не было установлено непосредственно.

J. Автоматически поддерживается изменение имени только в инспектореобъектов, секции интерфейсов окна кода программы (внутри оператораtype) и в секции реализации в названиях процедур обработчиков событий,

4. Изменение имени в самом коде программы (например, вызов метода обра-ботчика события) автоматически не поддерживается и должно быть вы-полнено программистом в окне редактора кода.

property Parent: TWinControl;Указывает для данного элемента управления родительский элемент управления.

Родительским элементом управления может быть форма, панель, окно груп-пы кнопок и т. п.Для некоторых элементов управления (таких, как ActiveX), расположенных нев VCL-оконных элементах управления, свойство Parent не имеет значения ииспользуется свойство ParentWindow, указывающее не VCL-родительское окно.

property ParentColor: Boolean;

Если это свойство равно True, то элемент управления использует цвет своегородителя. Если False, то для определения цвета используется значение соб-ственного свойства Color.

Page 140: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

140 Глава 5

При изменении значения свойства Color значение для ParentColor автомати-чески устанавливается равным False.

property ParentFont: Boolean;Определяет, будут ли для шрифта использоваться установки родительскогоэлемента управления.

property ParentShowHint: Boolean;Определяет, будут ли для отображения подсказки использоваться значениясвойства ShowHint родительского элемента управления.

property 'PopupMenu: TPopupMenu;Определяет всплывающее меню (контекстное меню), ассоциируемое с даннымэлементом управления. Такое меню появляется при щелчке пользователя правойкнопкой мыши, позиционированной над выделенным элементом управления.

Если свойство AutoPopup объекта типа TPopupMenu равно True, то меню будетотображаться автоматически. Если это свойство равно False, то для отобра-жения всплывающего меню следует в обработчике события OnContextPopupвызвать метод Popup.

property ShowHint: Boolean;Определяет, будет ли для элемента управления отображаться окно всплывающейподсказки при некоторой задержке указателя мыши на элементе управления.При этом для того, чтобы подсказка отображалась, необходимо, чтобыи значение свойства ShowHint объекта приложения также было равно True.

property Text: TCaption;Содержит строку текста, ассоциируемую с элементом управления. ТипTCaption определен как type TCaption = string;.

Для некоторых компонентов значение свойства Text не устанавливается, и онииспользуют только свойство Caption, содержащее заголовок компонента.

Свойство Text отражает содержание компонента и используется для такихэлементов управления, как TEdit, TComboBox, TMemo.

property Visible: Boolean;Определяет, будут ли компоненты появляться на экране. Вызов метода Showотображает компонент и устанавливает значение этого свойства равным True,а вызов метода Hide скрывает компонент и устанавливает значение свойстваравным False.

Методы:

procedure Begin Auto Drag; dynamic;Вызывается при щелчке левой кнопкой мыши над элементом управления, ес-ли значение свойства DragMode равно dwAutomatic. Для указания собственныхдействий в производном классе следует переопределить этот метод.

Page 141: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 141

procedure BeginDrag(lmmediate: Boolean; Threshold: Integer = -1);Начинает операцию перемещения элемента управления.

Приложение вызывает этот метод только в том случае, если значение свойст-ва DragMode равно dmManual.

procedure BringToFront;Располагает оконный элемент управления поверх всех других внутри роди-тельского элемента управления.

Используется для формы или для отображения перекрывающихся элементовуправления внутри формы.

Отметим, что и без вызова этого метода оконные элементы управления(TEdit, TMemo) всегда располагаются поверх неоконных элементов управле-ния (TLabel).

function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; virtual;Определяет, может ли элемент управления автоматически изменять свой раз-мер в зависимости от своего содержимого.

CanAutoSize вызывается автоматически при изменении размера, если значе-ние свойства AutoSize равно True. Это происходит до инициирования после-довательности событий OnCanResize, OnConstrainedResize и OnResize.

Если функция возвращает значение True, то процесс изменения размеров мо-жет быть продолжен. Реализация этого метода в классе TControl всегда воз-вращает значение True.

function CanResize(var NewWidth, NewHeight: Integer): Boolean;Инициирует событие OnCanResize. Этот метод вызывается автоматически припопытке изменения размера элемента управления.

procedure Changed;Посылает элементу управления сообщение CM_CHAHGED.

Используется для того, чтобы сообщить родительскому элементу управленияо факте изменения свойств дочернего элемента управления.

procedure Click; dynamic;Инициирует событие OnClick.

Вызов этой процедуры можно использовать при реализации кода нажатия го-рячей клавиши для кнопки или пункта меню.

function ClientToScreen(const Point: TPoint): TPoint;Преобразовывает координаты точки, указанные относительно клиентской об-ласти, в экранные координаты.

function ScreenToClient(const Point: TPoint): TPoint;Преобразовывает экранные координаты точки в координаты, указываемыеотносительно клиентской области.

Page 142: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

142 Глава 5

Совместное использование функций ScreenToClient и ClientToScreen позво-ляет преобразовать координаты, задаваемые относительно одного элементауправления, в координаты относительно другого элемента управления. На-пример:

Point:=TargetControl.ScreenToClient(SourceControl.ClientToScreen (Point));

преобразовывает координаты точки Point в клиентской областиSourceControl в координаты относительно клиентской области элементауправления TargetControl.

constructor Create(AOwner: TComponent); override;

Создает экземпляр класса TControl и выполняет инициализацию его свойств.При переопределении этого метода всегда сначала нужно вызывать насле-дуемый метод Create.

procedure DblClick; dynamic;

Инициирует событие CnDblClick.

function GetControlsAlignment: TAIignment; dynamic;

Определяет выравнивание текста в элементе управления.

function GetTextLen: Integer;Возвращает длину текста в элементе управления.

procedure Hide;Скрывает элемент управления. При этом значение свойства Visible автома-тически устанавливается равным False.

procedure Invalidate; virtual;Используется для инициализации в Windows перерисовки элемента управления.

function ManualDock(NewDockSite: TWinControI; DropControl: TControl =nil; ControlSide: TAlign = aINone): Boolean;Встраивает элемент управления программным путем. Этот метод извлекает эле-мент управления из текущего положения и встраивает его в новое положение.

function ManualFloat(ScreenPos: TRcct}: Boolean;Извлекает встроенный элемент управления и располагает его указанную па-раметрами прямоугольную область.

procedure Refresh;

Сразу перерисовывает на экране элемент управления, вызывая метод Repaint.

procedure Repaint;

Если значение свойства ControlStyle включает флажок csOpaque, то элементуправления сам сразу перерисовывается.

В противном случае вызывается метод Invalidate, а затем Update для одно-временной перерисовки и нижерасположенных элементов управления.

Page 143: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 143

procedure SendToBack;Помещает оконный элемент управления ниже всех других оконных элемен-тов управления или неоконный элемент управления ниже всех других не-оконных элементов управления.

procedure Show;Делает элемент управления видимым, одновременно устанавливая значениеего свойства Visible равным True.

procedure Update; virtual;Немедленно запускает любые ожидаемые сообщения отрисовки.

Отметим, что Update не устанавливает недостоверности элемента управления,а только форсирует перерисовку всех областей, ранее определенных как не-достоверные.

Для класса TControl предусмотрены следующие обработчики событий:

OnCanResize OnClick OnConstrainedResize

OnContextPopup OnDblClick OnDragDrop

OnDragOver OnEndDock OnEndDrag

OnMouseDown OnMouseMove OnMouseUpOnResize OnStartDock OnStartDrag

Класс TWinControlРасположен в модуле controls

TWinControl является базовым классом всех оконных элементов управления.

Элемент управления является оконным, если:

*_ он может в момент выполнения приложения получать фокус;

* имеет дескриптор окна;

* может (но не обязательно) быть родительским для других элементов управ-ления, т. е. содержать другие элементы управления;

* пользователь может взаимодействовать с ним непосредственно с помощьюклавиатуры (например, вводить или изменять данные, инициировать событияпри щелчке мышью).

Свойства:

property Brush; TBrush; (только для ЧТЕНИЯ)Определяет цвет и палитру, используемые для отображения фона элементауправления. Свойство Brush элемента управления доступно только для чте-ния. А для того чтобы изменить цвет фона или стиль элемента управления,следует установить значения свойств Color и Style объекта TBrush.

Page 144: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

144 Глава 5

Компонент TBrush инкапсулирует объект Windows кисть (HBRUSH) и ис-пользуется для определения фонового цвета фигуры.

property HelpContext: THelpContext;Определяет уникальный номер контекста для отображения окна справки принажатии пользователем клавиши F1. Справочная система Windows ассоции-рует каждую тему файла справки с уникальным номером, называемым номе-ром контекста или ID контекста.Если значение этого свойства равно 0, то будет отображено окно справки, ус-тановленное для его родительского элемента управления. Это позволяет оп-ределять для всех элементов управления, расположенных в форме, единуюсправку и устанавливать номер ее контекста только для формы.Номер контекста определяется как значение типа THelpContext:type THelpContext = -MaxLonglnt..MaxLonglnt;.

property ClientOrigin: TPoint; (только для ЧТЕНИЯ)Указывает экранные координаты (в пикселях) левого верхнего угла клиент-ской области элемента управления.

property ClientRect: TRect; (только для ЧТЕНИЯ)Указывает размер (в пикселях) клиентской области элемента управления.Отметим, что это свойство определяет физический, а не логический размерклиентской области. Так, если элемент управления поддерживает прокрутку,то физические размеры определяют область, доступную в любое время, а невсе прокручиваемое пространство.

property ControlCount: Integer; (только для ЧТЕНИЯ)Указывает количество дочерних элементов управления.

property Controls[lndex: Integer]: TControl; (только для ЧТЕНИЯ)Представляет список всех дочерних элементов управления.Это свойство используется для ссылки на объект по его номеру в массиве до-черних элементов управления, а не по имени. Также это удобно для выполне-ния последовательных действий для каждого дочернего элемента управления.

Пример:

[При щелчке мыши на элементе управления Panell все дочерние }[ элементы управления сдвигаются на 1 пиксель вниз }var I: Integer; ChildControl: TControl;beginfor I:= 0 to Panell.ControlCount -1 dobegin ChildControl := Panell.Controls[I];

ChildControl.Top:= ChildControl.Top+1;end;

end;

Page 145: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 145

Для добавления или удаления дочернего элемента управления программно мож-но использовать методы InsertControl и RemoveControl. Для изменения родите-ля следует установить значение свойства Parent дочернего элемента управле-ния.

property TabOrder: TTabOrder;Указывает номер элемента управления в табулированном порядке родитель-ского элемента управления. Табулированным порядком называют последова-тельность перехода от одного элемента управления к другому при нажатиипользователем клавиши Tab.

Этот номер определяется как type TTabOrder = -1..32767;.

Для элемента управления, имеющего фокус при первом открытии формы,значение этого свойства равно 0.Первоначально значение табулированного порядка устанавливается в поряд-ке добавления элементов в форму: первый добавленный элемент имеет зна-чение, равное 0, второй - 2, и т. д. Если в инспекторе объектов изменить зна-чение этого свойства для одного элемента управления, то это вызовет и изме-нения значений этого свойства для всех других элементов управления данногородителя. Например, если элемент управления переставить со второго места наседьмое в табулированном порядке, то значение этого свойства для элементовуправления, имеющих места с третьего по седьмое, уменьшится на единицу.

Отметим, что в табулированном порядке участвуют только те элементы управле-ния, у которых значение свойства TabStop равно True и которые имеют родителя.Поэтому, чтобы исключить какой-либо элемент из табулированного порядка, длянего достаточно установить значение свойства TabStop равным False. Для элемен-тов управления, не имеющих родителя, значение свойства TabOrder равно -1.

Me толы:

procedure Broadcastfvar Message);Посылает указанное сообщение всем дочерним элементам управления.

procedure MotifyControls(Msg: Word);Посылает сообщение с идентификатором сообщения Ш, передаваемым пара-метром Msg, всем дочерним элементам управления.

function ControlAtPos(const Pos: TPoint; AllowDisabled: Boolean,AllowWinConIrols:BooIean=False): TControl;Возвращает дочерний элемент управления, расположенный в указанной по-зиции. Позиция определяется параметром Pos. Если параметр AllowDisabledравен True, то поиск будет производиться и среди недоступных элементовуправления. Параметр AllowWinControls определяет, следует ли рассматри-вать только потомков класса TWinControl.

Если никакого элемента управления, соответствующего заданным парамет-рам, не найдено, то метод возвращает значение nil.

Page 146: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

146 Глава 5

function CanFocus: Boolean; dynamic;Возвращает значение True, если элемент управления может получить фокусваода. Для этого он сам и все его родители должны иметь значения свойствVisible и Enabled, равные True.

procedure Invalidate; override;Этот метод используется для инициации процесса перерисовки элементауправления.

function GetDeviceContext(var WindovvHandle: HWnd): HOC; override;Обеспечивает доступ к контексту устройства для элемента управления. Этотметод вызывает функцию Windows API GetDC и возвращает дескриптор кон-текста устройства.

procedure PaintTo(DC: HOC; X, Y: Integer);Рисует оконный элемент управления в заданном контексте устройства. Пара-метры X и Y определяют координаты верхнего левого угла отображаемогоэлемента управления.

Например: PageControll.Pages[I].PaintTo(Handle, 10, 1 0 ) ; .

procedure SetFocus; virtual;Устанавливает на элемент управления фокус ввода.

Класс TWinControl определяет следующие обработчики событий:

OnDockDrop OnDockOver OnEnter

OnExit OnGetSitetnfo OnKeyDown

OnKeyPress OnKeyUp OnMouseWheei

OnMouseWheelDown OnMouseWheelUp OnUnDock

Класс TCustomControlКласс TCustomControl является базовым классом всех оконных элементов управ-ления, требующих рамку (Canvas) для своего отображения. Как правило, этоткласс также используется как базовый для создания собственных элементовуправления.

Свойство Canvas позволяет управлять отображением поверхности. Для этого ис-пользуется виртуальный метод Paint, вызываемый для обработки сообщенияWM_PAIHT.

Если создаваемому элементу управления не требуется получать фокус ввода, тоего проще создать как потомка класса TGraphicControl. Перерисовка оконныхэлементов управления выполняется значительно медленнее, чем для графиче-ских элементов управления.

Page 147: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 147

Класс TApplicationРасположен в модуле Forms

Класс TApplication инкапсулирует объект Windows-приложение. Посредствомэтого класса определяется интерфейс между разработчиком и средой Windows.В каждом приложении Delphi всегда автоматически создается переменнаяApplication как экземпляр класса приложения. Для большинства приложений этапеременная является экземпляром класса TApplication, исключая такие приложе-ния, как Web-сервер приложение NT-сервиса и т. п.

Для определения свойств объекта Application на этапе проектирования следуетвыполнить команду меню ProjectjOptions и установить требуемые параметры настраницах Application и Forms.

Компонент TApplication не отображается в палитре компонентов и не имеетпубликуемых свойств. Для того чтобы иметь возможность перехватывать собы-тия для приложения, используя среду разработки IDE, можно добавить в любуюформу проекта компонент TApplicationEvents.

Свойства;

property HelpFile: string;Определяет имя файла справки.

property Hint: string;Определяет текст, появляющийся во всплывающем окне подсказки.

property HintColor: TColor;Определяет цвет прямоугольной области всплывающего окна подсказки.Также для настройки всплывающего окна подсказки можно создать потомкакласса THintWindow и назначить его глобальной переменной HintWindowClass:

var HintWi.ndowCldss: THintWindowClass = THintWindow,-

property Icon: Tlcon;Определяет пиктограмму, отображаемую в строке вместе с именем приложе-ния на панели задач Windows. Например:

Application.Icon.LcadFromFile(OpenPictureDialogl.FileNarae);

property MainForm: TForm; (только для ЧТЕНИЯ)Определяет главную форму приложения. Эта форма действует как главное ок-но приложения. При закрытии этой формы завершается и работа приложения.Устанавливать значение этого свойства следует на этапе проектирования. Дляэтого надо выполнить команду меню Project|0ptions и выбрать страницу Forms.Автоматически при создании приложения главной формой устанавливаетсяпервая созданная на этапе проектирования форма.

Page 148: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

148 Глава 5

property ShowHint: Boolean;Определяет, будут ли отображаться всплывающие окна подсказки. Значениепо умолчанию равно True. Если установить значение равным False, то всплы-вающие окна подсказки не будут отображаться ни для одного элементауправления вне зависимости от значения его собственного свойства ShowHint.

property ShowMainForm: Boolean;Если значение свойства равно True (по умолчанию), то главное окно прило-жения показывается автоматически при запуске приложения.Для того чтобы при запуске приложения главное окно приложения былоскрыто, следует в главном файле проекта до выполнения методаApplication.Run установить значение данного свойства равным False и одно-временно для формы, определенной как главное окно приложения, устано-вить значение свойства Visible равным False.

property Title: string;Определяет заголовок, появляющийся рядом с пиктограммой приложения,которые отображаются на панели задач Windows. По умолчанию значениемэтого свойства устанавливается имя запущенного ЕХЕ- или DLL-файла.На этапе проектирования заголовок приложения можно определить на стра-нице Application, выполнив пункт меню Project|0ptions.

Метолы:

procedure CreateForm(FormClass: TFormClass; var Reference);Создает новую форму во время выполнения. Тип создаваемой формы опреде-ляет параметр FormClass. Параметр Reference определяется как объект ука-занного класса. Владельцем созданной формы становится объектApplication.Напомним, что главным окном приложения становится форма, созданная первой.

procedure Initalize;Позволяет определить код инициализации.Для любого проекта Initialize является первым вызываемым методом, кото-рый в свою очередь вызывает процедуру по указателю InitProc. По умолча-нию указатель InitProc равен ni l и метод Initialize не выполняет, следова-тельно, никаких действий.Для использования этого метода указатель InitProc должен быть предопре-делен. Для этого следует или добавить модуль, в котором определяетсяInitProc (например, модуль OleAuto), или создать процедуру инициализациии присвоить значение указателю InitProc.

Отметим, что, хотя метод Initialize и является первым выполнимым мето-дом приложения, перед ним выполняются все initialization-секции всех пере-численных в проекте модулей.

Page 149: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi —VCL 149

function MessageBox(const Text, Caption: PChar; Flags: Longint): Integer;Показывает диалоговое окно сообщений с указанным набором кнопок и воз-вращает константу, определяющую нажатую пользователем кнопку, или Ов случае отсутствия необходимой памяти.Параметр Text определяет строку сообщения. Параметр Caption определяетзаголовок окна.Параметр Flags указывает комбинацию флажков, определяющих содержаниеи поведение окна сообщения: какие кнопки и пиктограммы будут отображе-ны. В окно сообщения могут быть добавлены следующие пиктограммы, ука-зываемые соответствующими флажками:

О MBJCONHAND и MBJCONSTOP:

в MBJCONQUESTION:

CD MBJCONEXCLAMATION;

О MB JCONASTERISK и MB JCONINFORMATION.

Метод возвращает одну из следующих констант, определяющих идентифика-тор нажатой кнопки:

mrOk

mrAbort

mrlgnore

mrfi/o

1

3

5

7

Кнопка OK

Кнопка Abort

Кнопка Ignore

Кнопка No

mtCancel

mrffetry

mrYes

mrAII 'VIM mrNone

2

4

6

Кнопка Cancel

Кнопка Retry

Кнопка Yes

Пример:

if Application.MessageBoxl 'Текст сообщения','Заголовок окна сообщений',

MB_OKCANCEL + МВ_IСONEXCLAMATION] <> IDOK

then

MessageDlgCЗавершение приложения. ' ,

mtlnformaiicn, [ m b O k j , 0 ) ;

Выполнение вышеприведенного кода отобразит диалог (рис. 5.2), содержащийдве кнопки - ОК и Отмена и изображение восклицательного знака.

Заголовок окна сообщений

/ ?\ Текст сообщен!!• CLl

ок Отмена

Рис. 5.2. Диалог, отображаемый функиией MessageBox

Page 150: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1 SO Глава 5

Для вывода окна сообщения также можно использовать:

* процедуру: procedure ShowMessagetconst Msg: siring);

функцию function MessageDlg(const Msg: string; DlgType: TMsgDlgType; But-tons: TMsgDIgButtons: HelpCtx: Longint): Word;

функцию function MessageDlgPos(consi Msg: string; DigType: TMsgDlgType;Buttons: TMsgDIgButtons; HelpCtx: Longint: X, Y: Integer): Word;

процедуру procedure ShowMessageFmtfconst Msg: string; Params: array of const);.

Более подробно функции для отображения диалогов сообщений рассматривают-ся в главе "Разработка интерфейса пользователя".

procedure Minimize;Метод вызывается для сворачивания главного окна приложения на панель за-дач Windows.

Отметим, что для сворачивания, распахивания или перевода в нормальноепредставление любой формы приложения следует использовать значениесвойства WindowStace для окна формы.

procedure NormalizeAllTopMosts;Отменяет поведение всегда сверху для всех форм, значение свойстваForraStyle которых равно fsStayOnTop. Это также относится и к главному ок-ну приложения.

procedure NormallzeTopMosts;Отменяет поведение всегда сверху для всех форм, значение свойства rormStyleкоторых равно fsStayOnTcp. Это позволяет отобразить окно сообщений илидиалоговое окно, вызываемые функциями Windows API, поверх формы с пове-дением только сверху. Если для отображения окна сообщений использовалисьметоды VCL-библиотеки, то вызывать NormalizeTopMosts не требуется.

Наоборот, для возвращения формам поведения только сверху следует вы-звать метод RestoreTopMosts.

procedure Restore;Возвращает приложение в полноэкранное или нормальное представление в зави-симости от того, каким оно было до сворачивания главного окна приложения.

procedure ShowException(E: Exception);Показывает окно сообщений для исключений, не перехватываемых кодомприложения.

property Title: string;Содержит строку текста, отображаемую рядом с пиктограммой для свернуто-го окна приложения. Это свойство может быть установлено или во время вы-полнения приложения, или через выполнение команды меню ProjectjOptions.

Page 151: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 151

Пример:

procedure TForral.ButtonlClick(Sender: TObject);begin

Editl.Text := Appl icat ion.Tit le; (Отображение имени проектав компоненте Editl}

end;

Класс TApplication определяет слел>'1ощие обработчики событий:OnActionExecute OnActionUpdate OnAclivateOnDeactivate OnException OnHelpOnHint Onldle OnMessageOnMinimize OnReslore OnShortCutOnShowHint

Класс TScreenРасположен в модуле Forms

Каждое приложение Delphi имеет глобальную переменную Screen типа ТЗсгееп-Эта переменная определена как var Screen: TScreen;.Компонент TScreen, так же как и компонент TAppiication, недоступен из ин-спектора объектов. Этот компонент предназначен для обеспечения доступа кустройству вывода - экрану. Его свойства содержат информацию об используе-мом разрешении монитора, курсорах и шрифтах, доступных для приложения,списке форм приложения и активной форме.

Свойства:

property ActiveControl: TWinControl; (только для ЧТЕНИЯ)Определяет элемент управления, имеющий фокус ввода.Для изменения фокуса ввода используется метод SetFocusedControl окна формы.Каждый раз при перемещении фокуса ввода данный компонент получает со-общение OnActiveControlChange.

property ActiveCustomForm: TCustomForm; (только для чтения)Определяет потомка класса TCustcnFcrrr., имеющего в настоящий момент фо-кус ввода. Это позволяет определить, какая форма или страница имеет фокусввода. Если это объект класса TForm, то и значение свойства ActiveCustomFormсовпадает со значением свойства ActiveForm.

property ActiveForm: TForm; (только для ЧТЕНИЯ)Определяет форму, имеющую в настоящий момент фокус. Такая форма назы-вается активной формой.Если приложение в настоящий момент неактивно, то это свойство определяетформу, которая первой получит фокус при активизации приложения.Для изменения активной формы следует вызвать метод SetFocus для формы,на которую устанавливается фокус. Также изменить активную форму можно,

Page 152: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

152 Глава 5

установив фокус ввода на любой ее дочерний элемент управления, вызвавметод SetFocusedConttol.Каждый раз при перемещении фокуса ввода компонент Screen получает со-общение OnActiveFormChange.

property Cursor: TCursor;Определяет вид указателя мыши. Значением этого свойства может быть каклюбая из предопределенных констант для встроенных курсоров Delphi (см.выше раздел "Класс TControl"), так и константа, определенная пользователемдля созданного им изображения указателя мыши.Для того чтобы для каждого элемента управления использовался собствен-ный вид указателя мыши, следует установить значение свойства Cursor рав-ным crDefault. В любом другом случае в качестве указателя мыши для всехэлементов управления приложения будет использоваться тот, который задансвойством Screen.Cursor.

Значение, устанавливаемое для свойства Cursor, должно содержаться в мас-сиве Screen,Cursors.

property Cursors[lndex: Integer]: HCursor;Список доступных в приложении курсоров мыши.Доступ к любому курсору может быть выполнен по его индексу:Screen.Cursors [Index] , Индексы предопределенных в приложении курсоровмыши начинаются с 0 и продолжаются до —22. Первым свободным индексомдля новых курсоров является индекс 1.

Для того чтобы добавить в приложение новое изображение указателя мы-ши, следует:

1. Выполнить команду меню Tools|Image Editor, открывающую окно редакто-ра ресурсов. Создать и сохранить изображение нового указателя мыши.Далее курсор желательно добавить в файл ресурсов приложения {.RES),присвоив ему новое имя.

2. Объявить константу курсора, отличную от любой из предопределенныхконстант для встроенных курсоров Delphi и от констант, объявленных дляуже созданных новых курсоров.

5. Получить дескриптор нового курсора, вызвав функцию Windows APILoadCursor.

4. Занести в массив Cursors значение полученного дескриптора.

Пример:{Добавление в приложение нового вида указателя мыши,}{именуемого в файле ресурсов как MyCur}const crMyCursor = 5; {2}

Page 153: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 153

procedure TFoml.ForiDCreate (Sender: TObject);beginScreen.Cursors[crMyCursor] :=LoadCursor(1, 'MyCur');

Cursor := crMyCursor;end;

property CustomFormCount: Integer; (только для ЧТЕНИЯ)

Определяет количество форм или страниц, отображенных на экране. СвойствоCustomForms содержит список всех отображаемых в настоящий момент форм.

property FormCount: Integer; (только для ЧТЕНИЯ)Определяет количество форм, отображенных на экране.

property Forms[fndex: Integer]: TForm; (только для ЧТЕНИЯ)Список всех форм, отображаемых в настоящий момент на экране.

property Height: Integer; (только для ЧТЕНИЯ)Указывает вертикальный размер экрана в пикселях.

property HintFont: TFont;Определяет шрифт, используемый для отображения текста во всплывающемокне подсказки.

property MenuFont: TFont;Определяет шрифт, используемый для отображения команд меню.

property PixelsPerlnch: Integer; (только для ЧТЕНИЯ)Определяет количество пикселей при данном разрешении экрана на одиндюйм по вертикали.

property Width: Integer; (только для ЧТЕНИЯ)Указывает горизонтальный размер экрана в пикселях..

БАЗОВЫЙ КЛАСС ОКНА ФОРМЫ

Класс TFormРасположен в модуле Forms

TForm является базовым классом для создания окна формы.

По умолчанию каждая новая создаваемая форма реализуется как потомок классаTForm. Форма может быть:

* главным окном приложения;

* диалоговым окном;

* дочерним окном MDI-окиа.

Page 154: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

154 Глава 5

Форма является контейнером и, следовательно, может содержать другие компо-ненты, такие, как TPanel, TButton. TCheckBox, TComboBox и т. п.

Потомки класса TForm классы TLoginDialog и TPasswordDialog позволяют выво-дить диалоговые окна для запроса информации о пользователе и пароле.

Свойства:

property Active: Boolean; (только для ЧТЕНИЯ)Если значение свойства равно True, то форма является активной.

property ActiveControl: TWinControl;Определяет элемент управления формы, имеющий фокус ввода.

Например:

if ActiveControl <> nil thenActiveControl.Left := ActiveControl.Left + 1;

end;

property ActiveMDIChild: TForm; (только для ЧТЕНИЯ!Определяет активное дочернее окно MDI-приложения.

Если данная форма не является родительским MDI-окном (свойствоFormStyle равно fsMDIForm), то значение этого свойства равно nil.

property ActiveOLEControl: TWinControl;

property Borderlcons:TBorderlcons;Определяют пиктограммы, отображаемые в строке заголовка окна формы.Тип TBorderlcons определен как:type TBorderlcon = (biSystemMenu,biMinimize,biMaximize,biHelp);

TBorderlcon = set of TBorderlcon;

Эти свойства могут иметь любую допустимую комбинацию следующих значений:

biSystemMenu - форма имеет кнопку системного меню, располагаемую слевав строке заголовка. Как правило, эта кнопка отображается в виде пиктограм-мы, установленной для свернутого представления окна:

biMinimize - форма имеет кнопку сворачивания окна (Minimize button):

biMaximize - форма имеет кнопку развертывания окна (Maximize button);

biHelp - форма имеет кнопку со знаком вопроса.

Для добавления или удаления кнопок используются операции + и -. Напри-мер: Borderlcons :— Borderlcons - [biMaximize];.

property BorderStyle: TFormBorclerStyle;Определяет внешний вид и поведение рамки окна формы.

Тип TFormBorderStyle определяется какtype TFormBorderStyle = (bsNone, bsSingle, bsSizeable, bsDialog,bsToolWindow, b s S i z e T o o l W i n ) ; TBorderStyle = bsMone..bsSingls;

Page 155: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 55

Свойство BorderStyle можем быть определено как любая допустимая комби-нация следующих значений типа TFormBorderStyle:

bsDialog ~ рамка стандартного диалога без изменения размера;

bsSingle - рамка в виде одинарной линии и без изменения размера;

bsNone — невидимая рамка и без изменения размера;

bsSizeable- стандартная рамка, позволяющая изменять размер окна;

bsToolWindow - аналогично bsSingle. но дополнительно со строкой заголовка;

bsSizeToolWin - аналогично bsSizeable. но дополнительно со строкой заголовка.

property ClientHeight: Integer;Определяет высоту клиентской области окна формы в пикселях.

property ClientRect: TRect;Определяет размер клиентской области окна формы. Значение этого свойстваэквивалентно выражению Rect (0,0,ClientWidth, ClientKeight).

property ClientWidth: Integer;Определяет ширину клиентской области окна формы в пикселях.

property FormState: TFormState; (только для ЧТЕНИЯ)Позволяет определить промежуточное состояние формы при выполнении не-которых действий Windows. Список возможных значений этого свойства оп-ределяется какtype TFormState = set of (fsCreating, f sYis ib le , fsShowing, fsModal,fsCreatedMDIChild, f sAct ivated);

Состояние формы определяется следующими значениями:

fsCreating - выполняется конструктор создания окна формы;

fsVisibte - форма видима;

fsShowing - изменяется значение свойства WindowState;

fsModal - форма создана как модальное окно;

fsCreatedMDIChild - форма является родительским MDI-окном;fsActivated - форма получила сообщение CM_ACT1VATE (вследствие полу-чения фокуса или активизации приложения), но метод Activate для инициали-зации события OnActivate еще не вызван.

property FormStyle: TFormStyle;Определяет с т и л ь формы. Значение свойства определяется какtype TFormStyle =(fsNormal,fsMDIChild,fsMDIForm,fsStayOnTop);

Стиль формы указывается одним из следующих значений:

fsNormal - форма определена как простая SDI-форма и не является ни дочер-ним, ни родительским MDI-окном;

fsMDIChild- форма является дочерним MDI-окном;

fsMDIForm - форма является родительским MDI-окном;

Page 156: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1 56 Глава 5

fsStayOnTop - для формы определено поведение всегда сверху (она остаетсясверху всех других форм проекта, для которых не установлен стильfsStayOnTop}.

Очевидно, что значение этого свойства можно изменять только в режимепрое ктиро ван ия,

property HelpFile: string;Указывает имя файла, используемого для отображения справки (Help) принажатии пользователем клавиши F1 или выполнении им соответствующейкоманды меню.

property Icon: Tlcon;Определяет пиктограмму, отображаемую в заголовке окна формы.

property KeyPreview: Boolean;Определяет, будет ли форма получать события клавиатуры до того, как ихполучит активный элемент управления. По умолчанию значение свойстваравно False и события клавиатуры получает только активный элемент управ-ления. Если KeyPreview равно True, то сначала событие клавиатуры получаетформа, а затем активный элемент управления (указанный свойствомTForm.ActiveControi).Отметим, что клавиши навигации (Tab, - , 4~, *\~. Ф и др.) не инициируютсобытий клавиатуры и, следовательно, на них не влияет значение свойстваKeyPreview.

property MDIChildCount: Integer; (только для ЧТЕНИЯ]Определяет количество открытых дочерних MDI-форм.

property MDIChildren[l: Integer]: TForm;Содержит список всех дочерних MDI-форм. Первоначально дочерние формыдобавляются в список по мере создания. Далее, однако, активная дочерняяMDI-форма всегда перемещается на первое место в списке.

Пример:

{Закрытие всех дочерних MDI-фсры)var Indexl: Integer;begin

with MyForml dofor I := MDIChildCount-1 downtc 0 do

MDIChildren[Indexl].Close;ena;

property Menu: TMainMenu;Определяет главное меню. Во время проектирования меню устанавливаетсяпервым компонентом типа TMainMenu, добавленным в форму.

Page 157: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 157

Пример:

•'Добавление нового меню MyKenu при щелчке}[пользователя по кнопке Buttonl}procedure TForml.ButtonlCUck(Sender: TObject) ;begin

Menu := NewMenu(Self, ' M y M e n u ' , [ N e w l t e r n ( ' П у н к т 1 ' ,TextToShortCutCCtr l+G') , False,True, Actionl.OnExecute, 0, ' I t e m l ' ) ] ;

end;

property ObjectMenultem: TMenuItem;Представляет элемент меню OLE-объекта. Это свойство позволяет получитьили установить элемент меню, который становится доступен при перемеще-нии фокуса на OLE-объект.

property Parent: TWinControl;Определяет родительское окно. Если форма не имеет родителя, то значениесвойства Parent равно n i l . Изменение значения этого свойства позволяетвстроить одну форму в другую (родительскую).

property ParentBiDiMode: Boolean;Определяет, использует ли элемент управления значение родительскогосвойства BiDiMode.

В том случае, если форма не имеет родителя, а свойство ParentBiDiMode рав-но True, то свойство BiDiKode формы устанавливается равным этому свойствуобъекта Application.

Свойство BiDiMode определяет направление ввода/вывода текста: слева на-право или справа налево (как правило, это используется для ближневосточ-ных версий (Middle Easiern) Windows.

property PixelsPerlnch: Integer;Позволяет в режиме выполнения изменить пропорции окна в зависимости отразрешения экрана. По умолчанию это свойство устанавливается автоматиче-ски при создании формы.

Для изменения значения этого свойства следует также установить значениесвойства Scaled равным True.

property Position: TPosition;Указывает размер и местоположение формы. Значение описывается какtype TPosition (poDesigned, poDefault, poDefaultPosOnly,poDefaultSizeOnly, poScreenCenter, poDesktopCenter, poMainFormCenter,poOwnerFormCenter);

Позиция представляется как одно из следующих значений типа TPosition:

poDesigned - форма появляется в той позиции и такого размера, как это былоопределено в режиме проектирования;

Page 158: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

158 Глава 5

poDefault - форма появляется к той позиции и такого размера, как это преду-сматривает Windows;poDefaultPosOnly - форма появляется такого же размера, как это было опре-делено в режиме проектирования, но в позиции, как это предусматриваетWindows;poDefaultSizeOnly - форма появляется в той же позиции, как это было опре-делено в режиме проектирования, по размером,'как это предусматриваетWindows;poScreenCenter - форма появляется такого же размера, как это было опреде-лено в режиме проектирования, и в центре экрана (или монитора для мульти-мониторных приложений);

poDesktopCenter - форма появляется такого же размера, как это было опреде-лено в режиме проектирования, и в центре экрана;

poMainFonnCenter - форма появляется такого же размера, как это было опре-делено в режиме проектирования, и в центре главной формы приложения(для родительской формы этот режим эквивалентен режиму poScreenCenter);

poOwnerFormCenler — форма появляется такого же размера, как это было оп-ределено в режиме проектирования, но в центре формы, указанной свойствомOwner (форма-владелец). Если свойство Owner не ссылается ни на какуюформу, то позиция устанавливается как в режиме poMainFonnCenter.

property PrintScalc: TPrintScalc;Позволяет определить пропорции печатаемой формы: без изменения пропор-ций; в пропорциях, визуально отображаемых на экране (WYSIWYG); в про-порциях экрана, но так, чтобы уместиться в размер печатаемой страницы.

Значение этого свойства определяется какtype TPrintScale = (роЫопе, poProportional, poPrintToFit);

property Scaled: Boolean;Определяет, будет ли форма менять размер в соответствии со значениемсвойства PixelsPerlnch.

property Visible: Boolean;Определяет, является ;ш форма видимой.

property WindowMenu: TMenultem;Определяет меню Window (окно) для родительского MDI-окна. Это стан-дартное меню, содержащее такие пункты, как New, Cascade, Arrange Icons,Tile, список всех открытых окон.

property WindowState: TWindowState;Определяет, в каком виде форма появляется на экране: свернутой, разверну-той или в нормальном представлении. Это свойство описывается как typeTWindowState = [wsNonnai, wsMiniinized, wsMaxinuzed);

Page 159: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 59

Me толы:

procedure Arrangelcons;Упорядочивает пиктограммы свернутых дочерних MDI-форм.

procedure Cascade;Упорядочивает все дочерние MDI-формы, располагая их каскадом.

procedure Next;Делает активной следующую дочернюю форму (в последовательности, какони были открыты).

procedure Previous;Делает активной предыдущую дочернюю форму.

procedure Tile;Упорядочивает все дочерние MDl-формы таким образом, чтобы они все име-ли одинаковый размер и умещались одновременно в клиентской области ро-дительского окна.

Пример:

{Обработчик события для команды меню Windows ! T i le}procedure TForml.TileFormsClick(Sender: TObject);begin

TileMode := tbVertical; Tile;end ;

Класс TForm определяет следующие обработчики событий:

OnActivaie OnClose OnCloseQuery

OnCreate OnDeaciivute OnDestroy

OnHelp OnHide OnPaint

OnShortCut OnShow

КЛАССЫ ДЛЯ СИСТЕМЫ МЕНЮ

Класс TMenuTMenu - это базовый класс для компонентов меню TMainMenu и TPopupMenu. Онпредоставляет свойства и методы для создания меню, определения пунктов ме-ню, определения команд, ассоциированных с пунктами меню, >казание ID кон-текста справки для любого пункта меню.

Page 160: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1 60 Глава 5

Свойства:

property Images: TC ustom Image List;Список изображений, которые могут отображаться слева от заголовка в пунк-те меню.Для определения отображаемого изображения следует установить для пунктаменю значение свойства Imaoelndex, указывающего индекс изображенияв списке Images,

Отметим, что если приложение использует объекты ActionList, то это свой-ство должно быть значением свойства Images объекта ActionList. Это пре-доставит возможность для пунктов и кнопок, выполняющих одинаковые дей-ствия, отображать и одинаковые изображения.

property Items: TMenultem; default; (только для ЧТЕНИЯ)Содержит список пунктов меню. Каждый пункт меню является объектомкласса TMenultem. Для доступа к элементу меню можно записать:Firstltera := Menial. Items [OJ;

property OwnerDraw; Boolean;Определяет, как приложение будет отображать пункт меню. Если значениеэтого свойства равно False, то приложение по умолчанию отображает пунктменю как заголовок и расположенное слева изображение.

Если значение свойства равно True, то приложение будет отображать пунктменю таким образом, как указано в обработчике события OnDrawItem. Такиепункты меню иногда называются самоотображаемыми пунктами меню.

Класс TMainMenuРасположен в модуле menus

Класс TMainMenu инкапсулирует поведение линейки меню {menu bar) и соответст-вующих ниспадающих меню (drop-down menus) для окна формы.

Этот класс определяет свойства и методы, позволяющие соединять ниспадаю-щие меню главного меню с главными меню других форм и помогающие взаимо-действовать с меню для OLE-объектов.

Процесс создания меню формы очень прост. Он состоит из трех этапов:

• добавления в форму компонента класса TMainMenu;

• выполнения на нем двойного щелчка мышью и ввода в открытое далее окнозаголовков всех пунктов линейки меню и пунктов ниспадающих меню;

• определения кода обработчиков событий для каждого пункта меню.

Page 161: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 161

Свойства:

property AutoMerge: Boolean;Определяет возможность слияния меню. Если значение свойства AutoMergeформы равно True, то ее меню будет объединено с меню другой формы. Дляглавной формы главной линейки меню, к которой будут добавляться другиеменю, значение свойства AutoMerge должно быть равно False.То, каким образом меню будут объединяться, зависит от значения свойстваGrouplndex каждого отдельного пункта меню.Для MDI-приложений слияние меню дочерних MDI-форм с родительскимменю выполняется автоматически.

property Handle: HMENU; (только для ЧТЕНИЯ)Обеспечивает доступ к дескриптору меню. Это свойство используется дляфункций Windows API, требующих дескриптора меню.

Пример:

(Выделение первого пункта меню KainMenul формы F1}

HiliteMenuItern(Fl.Handle, MainMenul.Handle, 0,

MF_BYPOSITION+MF_HILITE);

Методы:

procedure GetOle2AcceleratorTable(var AccelTable: HAccel; varAccelCount: Integer; Groups: array of Integer);Возвращает таблицу акселераторов всех элементов меню и значения свойствGrouplndex.

Дескриптор таблицы акселераторов возвращается в параметре АссеГГаЫе.Этот метод используется OLE-контейнером при слиянии меню.

procedure Merge(Menu: TMainMenu);Объединяет главное меню формы с главным меню другой формы для неMDI-приложений.Параметр Menu ссылается на добавляемое меню.В зависимости от значения свойства Grouplndex пункта меню добавляемыйэлемент меню может заменять существующий пункт линейки меню или бытьдобавлен как новый пункт линейки меню.Для автоматического слияния главных меню при отображении несколькихформ следует установить значение свойства AutoMerge равным True для всехформ, чье меню должно добавляться в другое главное меню.

procedure PopulateOle2Menu(SharedMenu: HMenu; Groups: array ofInteger; var Widths: array of Longint);Заполняет OLE-меню, указанное параметром SharedMenu.

6 Зак. 11

Page 162: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1 62 Глава 5

procedure SetOle2MenuHanclle(Handle: HMENU);Ассоциирует дескриптор для OLE-меню с главным меню. Метод использует-ся для временного замещения меню формы на меню, указанное параметромHandle. Для восстановления первоначального меню формы следует вызватьэтот метод с параметром, равным нулю.Этот метод позволяет OLE-контейнеру использовать элементы меню, обеспе-чиваемые OLE-сервером.

procedure Unmerge(Menu: TMainMenu);Позволяет для не MDI-приложения удалить элементы другого меню (указан-ного параметром Menu), добавленные ранее методом Негде.

Класс TMenultemРасположен в модуле menus

Класс TMenultem реализует свойства пунктов меню. Он позволяет определятьсвойства и поведение пункта меню.Контейнером для объектов типа TMenultem может быть компонент типаTMainMenu (линейка главного меню) или компонент типа TPopupMenu (всплы-вающее или контекстное меню).При создании меню на этапе проектирования редактор меню (Menu Designer)автоматически создает объекты меню, пункты для каждой команды меню.Отметим, что если для пункта меню используется объект TAction, то большин-ство его свойств устанавливаются первоначально равными свойствам объектатипа TAction. Некоторые из них затем можно, если необходимо, изменить, ука-зав для объекта пункт меню новое значения свойства. Объект TAction позволяетреализовывать одинаковые действия для соответствующих пунктов меню и кно-пок, а также отображать их идентичным образом.

Свойства:

property Action: TBasicAction;Определяет объект действие (Action), ассоциируемый с пунктом меню.По умолчанию для каждого пункта меню стандартным событием считаетсяOnClick и обработчиком события является процедура, имя которой автомати-чески формируется из имени формы и имени объекта пункт меню, указанныхчерез точку (например. TForml.item31Click). Объект действие позволяет оп-ределить одну процедуру обработки события, которую далее можно будетмногократно использовать для различных объектов при обработке событий.

-у-1 Для определения действия на этапе проектирования следует:

1. Добавить в форму объект типа TActionList.

2. Вызвать редактор объекта действие, выполнив на нем двойной щелчокмышью.

Page 163: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 63

5. Добавить в открывшемся редакторе объекты действие.

4. По двойному щелчку на имени любого объекта действие отображается ре-дактор кода с автоматически добавленным обработчиком события дляданного действия:

procedure IForral.ActioniExecute(Sender: TObject);begin

ST. л;

5. Внутри блока begin end ввести код обработчика события.

6. В завершение определить для объекта пункт меню значение свойстваAction, выбрав в инспекторе объектов из раскрывающегося списка значе-ний свойства Aciion имя созданного объекта действие.

property AutoHotkeys: TMenultemAutoFlag;Определяет, будут ли клавиши-акселераторы для элементов подменю уста-навливаться автоматически. Это свойство определяется значением типа typeTMenultemAutoFlag = (maAutomatic, maManual, maParent);

Если значение свойства равно maAutomatic, то Delphi перед отображениемменю упорядочивает таблицу клавиш-акселераторов таким образом, чтобыисключить совпадение для всех элементов объекта меню, указанных свойст-вом Items.

property Bitmap: TBitmap;Определяет изображение, отображаемое слева от заголовка меню.

Отметим, что если установлено значение свойства Imagelndex и свойствоImages родительского объекта (меню) не пусто, то изображение идентифици-руется свойством Imagelndex, а не Bitmap.

property Break: TMenuBreak;Определяет, будет ли пункт меню располагаться в новом столбце меню. Этопозволяет отображать длинное меню в нескольких столбцах.

Свойство указывается 'значением типа type TMenuBreak = ImbNone, mbBreak,mbBarBreak); . Это константы, определяющие поведение пункта меню сле-дующим образом:

mbNone - разрыв столбца меню не происходит (значение по умолчанию);

mbBarBreak - происходит разрыв меню, данный пункт меню отображаетсяв новом столбце, столбцы отделены друг от друга линией;

mbBreak - происходит разрыв меню, данный пункт меню отображается в но-вом столбце, столбцы отделены друг от друга только визуально и без разгра-ничительной линии.

Page 164: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

164 Глава 5

property Caption: string;Определяет текст пункта меню. Если перед буквой в заголовке пункта менюстоит символ &, то данная буква называется клавишей-акселератором, а вы-бор пункта меню может быть выполнен одновременным нажатием Alt и кла-виши-акселератора.Для автоматического указания значения клавиш и-акселератора таким обра-зом, чтобы она не совпала с уже имеющимися, можно использовать методRethinkHotkeys.Для того чтобы создать разделительную линию между пунктами меню, сле-дует указать значением свойства Caption символ -. Такой пункт меню будетотображен линией, и для него не может быть назначено никаких действий.Отметим, что если пункт меню использует объект TAction, то заголовокпункта меню автоматически определяется значением свойства Caption объ-екта TAction, а не объекта пункта меню. Для изменения заголовка таким об-разом, чтобы он отображал значение свойства Caption объекта пункт меню,это значение следует установить только после того, как будет в свойствеAction указан используемый объект типа TAction.

property Checked: Boolean;Определяет, будет ли маркер переключателя появляться в пункте меню слеваот заголовка. По умолчанию значение свойство равно False (маркер переклю-чателя не отображается).Отметим, что (так же, как и для свойства Caption) если пункт меню использу-ет объект TAction, то значение свойства Checked пункта меню автоматическиопределяется значением свойства Checked объекта TAction, а не объектапункт меню.

property Default: Boolean;Определяет, является ли данный пункт меню пунктом, выполняемым поумолчанию при двойном щелчке мышью на родительском подменю. Пунктменю, выполняемый по умолчанию, отмечается полужирным начертанием.Подменю может иметь только один пункт меню, для которого значение свой-ства Default равно True. Если разработчик устанавливает это значение длявторого пункта подменю, то значение True свойства Default предыдущегопункта меню автоматически изменяется на False.

property Enabled: Boolean;Если значение этого свойство равно True, то при выборе пользователем дан-ного пункта меню вызывается метод Click. В противном случает пункт менюнедоступен и отображается посеревшим.Отметим, что даже в том случае, если значение свойства Enabled равно False,вызов метода Click работает.

Отметим, что если используется объект TAction, то первоначально по умол-чанию устанавливается значение свойства Enabled объекта TAction.

Page 165: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 65

property Grouplndex: Byte;Указывает логическую группу, к которой принадлежит пункт меню.Группы используются для управлении слиянием пунктов меню. Это всегдапроисходит для MDI-приложения: меню активной дочерней формы добавля-ется к меню родительского окна. Это может происходить для приложений,содержащих несколько форм: к меню главного окна приложения могут до-бавляться пункты меню активной формы.По умолчанию все пункты линейки меню имеют одинаковое значение свой-ства Grouplndex. При использовании этого свойства для слияния меню следу-ет установить значение каждого пункта линейки меню равным предыдущемуили большим, чем для него.Если значение свойства Grouplndex добавляемого меню совпадает со значе-нием свойства Grouplndex пункта главного меню, то последний заменяется надобавляемый. Если несколько пунктов меню главного окна имеют одинако-вое значение свойства Grouplndex, то и заменены они могут быть только не-сколькими пунктами добавляемого меню: первый пункт с одинаковым значе-нием заменяется на первый добавляемый пункт с одинаковым значением,второй - на второй и т. д.Если значение свойства Grouplndex добавляемого пункта линейки меню:

• лежит между значениями свойства Grouplndex пунктов линейки менюглавного окна, то добавляемый пункт вставляется между ними;

• больше любого значения свойства Grouplndex пунктов линейки менюглавного окна, то добавляемый пункт становится последним;

• меньше любого значения свойства Grouplndex пунктов линейки менюглавного окна, то добавляемый пункт становится первым.

Если меню создается при активизации OLE-сервера, то сервер может объеди-нять свое меню с меню приложения-контейнера. Свойство Grouplndex ис-пользуется OLE-сервером для замещения основных трех пунктов линейкименю приложения-контейнера на меню OLE-сервера. При этом применяютсяследующие предопределенные значения свойства Grouplndex:

1 - в меню Edit помещаются пункты меню OLE-сервера для редактированияOLE-объекта;

3 - в меню View помещаются пункты меню View OLE-сервера дляOLE-объекта;

5 - в меню Help помещаются пункты меню Help OLE-сервера дляOLE-объекта.

Свойство Grouplndex также позволяет устанавливать для нескольких пунктовменю поведение как в группе радиокнопок. Для этого следует определить длякаждого такого пункта меню одинаковое значение свойства Grouplndex и од-новременно установить для них значение свойства Radioltem равным True.

Page 166: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

166 Глава 5

property HelpContext: THelpContext;Указывает ID контекста справки, отображаемой для пункта меню.

Для этого в используемом приложением файле справки каждая тема должнаиметь свой уникальный ГО контекста справки.Отметим, что если используется объект TAction, то первоначально по умол-чанию устанавливается значение его свойства.

property Hint: string;Определяет текст всплывающего окна подсказки. Это окно отображается, ко-гда пользователь задерживав! указатель мыши на пункте меню, и только в томслучае, если значения свойств ShowHint для приложения и формы равны True.Свойство Hint может содержать два значения подсказки: короткое и длинное,разделенные между собой вертикальной чертойф. Первое используется дляокна Help Hint, а второе - обработчиком события OnHint.

Отметим, что если используется объект TAction, то первоначально по умол-чанию устанавливается значение его свойства.

property Imagelndex: Tlmagelndex;Определяет индекс изображения, отображаемого для пункта меню. Списокизображений, указываемых через индекс, содержится в свойстве Images роди-тельского меню: для пунктов меню верхнего уровня список определяется свой-ством Images объекта типа ТМегш или TPopupMenu, а для пунктов подменю спи-сок определяется свойством Images родительского объекта меню типаTMeniiltem.

Если родительское меню не содержит списка изображений в свойстве Images,то для определения отображаемого изображения будет использовано значе-ние свойства Bitmap пункта меню.

Отметим, что если используется объект TAction, то первоначально по умол-чанию устанавливается значение его свойства.

property ltems[lndex: Integer]: TMenultem; default; [только для ЧТЕНИЯ)

Список пунктов меню в подменю данного пункта меню. Значение параметраIndex -это номер отображаемого пункта подменю минус 1.

Например, если меню Edit содержит три пункта - Copy, Paste и Cut. то выра-жение EditMenu.Iiemsl I ] будет означать ссылку на пункт меню Paste.

property Menulndex: Integer;Указывает индекс пункта меню в родительском меню. Это свойство можноиспользовать для перемещения пункта меню внутри подменю.

property Parent: TMenultem; (только для ЧТЕНИЯ)Определяет для пункта меню его родительское меню.

property Radioltem: Boolean;Для всех пунктов меню, имеющих одинаковые значения свойства Grouplndexи свойства Radioltem. равные True, устанавливается поведение как группы

Page 167: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 167

радиокнопок: только один пункт меню может быть выбран одновременно.Слева от заголовка выбранного пункт;] отображается символ •. Будем назы-вать такие пункты меню яунктами-радиокнопкалш.

Пример реализации такого меню приведен в главе "Разработка интерфейсов".

Отметим, что пункты линейки меню не могут быть радиокнопками.

property Shortcut: TShortCutОпределяет комбинацию клавиш для быстрого выбора пункта меню. Такаякомбинация клавиш иногда называется горячим к.чючом. Значение этогосвойства отображается справа от заголовка пункта меню.

При создании горячего ключа во время проектирования его следует выбратьв инспекторе объектов из списка предлагаемых значений свойства ShortCut.

При создании горячего ключа во время выполнения можно использовать гло-бальные функции ShorlCut или TextToShortCut. Например, чтобы назначитьобъекту пункт меню CopyCommand горячий ключ Ctrl+C, следует записатьв коде программы CopyComraand.ShortCut:=ShortCut(Word( 'C T ) , [ s sCtr l ] ) ; .

Отметим, что если используется объект TAciion, то первоначально по умол-чанию устанавливается значение его свойства.

property SubMenulmages: TCustomlmageList;Определяет список изображений, которые могут появляться внутри пунктовменю из подменю данного элемента меню. Отображаемый элемент спискауказывается значением свойства fmagelndex конкретного пункта подменю.

Отметим, что если используется объект TAciion, то значение свойстваSubMenulmages совпадает со значением свойства Images объекта типаTAction. И это гарантирует для пунктов меню и кнопок, выполняющих оди-наковые действия, отображение одинаковых изображений.

property Visible: Boolean;Определяет, является ли пункт меню видимым.

Метолы:

procedure Add(ltem: TMenultcm); overload;procedure Addfconst Altems: array of TMcnultem); overload;

Добавляют в конец списка Hems один или несколько пунктов меню.

Пример:

var Newltem: TMenuItem; I : integer;

г. -..: - -.\ создадим элемент разделительная линия }

Newltem := TMenuItem.Create(Self);

Newltera.Caption := '-'; {заголовок пункта меню]

{ добавим этот пункт к меню Windows }

Page 168: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

168 Глава 5

Windows.Add(Newltera) ;

{ создадим и добавим пункт меню для каждой формы }for 1 := 0 to Screen.FormCount-1 do

beginNewltem := TMenuItem.Create(Self);Newltem.Caption := Screen.Forms[I].Name;Windows.Add(Newltem);

end;end;

procedure Clear;Удаляет и освобождает все пункты меню, указанные в списке свойства Items.

procedure Click; virtual;Инициирует событие OnClick, но не инициирует сообщение WM_COMMANDокну, ассоциированному с меню.Этот метод может быть переопределен разработчиком для того, чтобы запро-граммировать собственный ответ на выбор пользователем пункта меню.

constructor Create(AOwner: TComponent); override;Создает экземпляр класса TMenuItem. Используется для создания пункта ме-ню во время выполнения. Параметр Component указывает владельца компо-нента, который отвечает за освобождение созданного пункта меню.

procedure De!ete(lndex: Integer);Удаляет из списка свойства Items пункт меню с указанным индексом. Одно-временно удаляются, если есть, и все его подменю.Отметим, что метод Delete только удаляет пункты меню из списка, но не уда-ляет сами объекты. Для одновременного удаления пунктов меню и освобож-дения памяти следует вызывать метод Free.

function lndexOf(ltem: TMenuItem): Integer;Возвращает позицию указанного пункта меню в списке Items. Если указанно-го пункта меню в подменю нет, то функция возвращает значение - 1.

procedure Insert(Jndex: Integer; Item: TMenuItem);Вставляет указанный пункт меню в указанную позицию списка Items.

function InsertNewLineAfteKAltem: TMenuItem): Integer;function lnsertNewLineBefore(Altem: TMenuItem): Integer;

Эти функции вставляют разделительную линию после или до указанногоэлемента меню из списка Items.

function RethinkHotkeys: Boolean;Позволяет выбрать заголовкам подменю клавиши-акселераторы таким обра-зом, чтобы они не дублировали друг друга.

Page 169: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 169

Класс TMenuItemi определяет следующие обработчики событий:

Он AdvancedDrawItem OnCl ick OnDrawItem OnMeasureltem

Класс TPopupMenuРасположен в модуле menus

Класс TPopupMenu инкапсулирует поведение контекстных меню, также назы-ваемых всплывающими или рорир-меню.Он предназначен для создания меню, отображаемых при щелчке пользователяправой кнопкой мыши на элементе управления. Для того чтобы контекстное ме-ню поставить в соответствие конкретному элементу управления, следует уста-новить значение свойства PopupMenu элемента управления равным имени объ-екта TPopupMenu. Для этого в инспекторе объектов следует выбрать значениесвойства PopupMenu из автоматически предлагаемого списка объектов типаTPopupMenu.Базовым классом для TPopupMenu является класс TMenu.

Свойства:

property Alignment: TPopupAlignment;Определяет место появления контекстного меню при щелчке пользователяправой кнопкой мыши: слева, справа или по центру от указателя мыши.По умолчанию установлено значение paLeft.

property AutoPopup: Boolean;Определяет, будет ли контекстное меню появляться автоматически прищелчке пользователя правой кнопкой мыши (или нажатии клавиши контек-стного меню на клавиатуре, спроектированной для Windows 95).Если значение свойства равно True, то автоматически появляется контекстноеменю, указанное свойством PopupMenu. Если значение свойства равно False,то контекстное меню автоматически появляться не будет и для его отображе-ния следует использовать метод Popup.

Пример:(Отображение контекстного меню по щелчку мыши}|на форме FormlJ

procedure Forml.ForroCreate(Sender: TObject);begin PopupMenul.AutoPopup := False; end;

procedure Forml.FonnMouseDown(Sender: TObject;

Button: TMouseButton;

Shift: TShiftState;X, Y: Integer);

begin PopupMenul.Popup(X, Y); end;

Page 170: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1 70 Глава 5

property HelpContext: THelpContext;Определяет ID контекста файла справки контекстного меню.Для того чтобы отображать различные экраны файла справки по разным пунк-там контекстного меню, следует установить значение свойства HelpContext длявсех объектов типа TMenuItem, входящих в контекстное меню.

property MenuAnimation: TMenuAnimation;Определяет способ отображения меню (направление, в котором оно появля-ется на экране).Это свойство указывается значением типа type TMenu Animations -(maLeftToRiglu, maRightToLeft. rnaTopToBottom, maBottomToTop, maNone);Отметим, что это свойство работает только начиная с Windows 98 или NT 5.O.

property PopupComponent: TComponent;Указывает компонент, для которого последним было вызвано контекстное меню.Это свойство позволяет определить элемент управления, использующий раз-деляемое несколькими компонентами одно контекстное меню.Если разделяемое контекстное меню вызывается программно через методPopup, то перед вызовом метода следует установить значение свойстваPop upComponent.

property TrackButton: TTrackButton;Определяет, какая кнопка мыши активизирует контекстное меню, ассоции-руемое с кнопками панели инструментов.Это свойство указывается значением типа Суре TTrackButton = (tbRightButton,ibLeftButton);

Метолы:

constructor Create(AOwner: TComponent); override;Создает экземпляр класса TPopupMenu.Этот метод вызывается для создания контекстного меню программным пу-тем. Если меню было добавлено в форму или модуль данных во время проек-тирования, то объект контекстное меню будет создан автоматически.

procedure DoPopuplSender: TObject); virtual;Инициирует событие OnPopup.

procedure Popup(X, Y: Integer); virtual;Отображает в указанной точке экрана (экранные координаты) контекстноеменю.

Класс TPopupMenu определяет обработчик события OnPopup.

Page 171: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 171

КЛАССЫ КОМАНДНЫХ КНОПОК, ФЛАЖКОВ

И РАДИОКНОПОК

Следующая таблица содержит список классов, инкапсулирующих поведениекомандных кнопок '. флажков и радиокнопок.

-Классы командных кнопок

TButton

TBitBnt

TSpeedButton

TToolButton

Командная кнопка

Кнопка, которая может содержать и заголовок и изображение

Кнопка, которая может оставаться нажатой и содержит только изображение

Кнопка для объекта TToolBar (панель инструментов)

Классы флажков

TCheckBox

TDBCheckBox

Флажок (иногда называется

Флажок, используемый длянина данных

переключателем)

отображения логических значений из источ-

Классы радиокногшк

TRadioButton Радионнопка (иногда называется переключателем)

Классы групп

TGroupBox

TRadioGroup

TDBRadioGroup

Группа - контейнер для компонентов (например, для флажков)

Группа для радиокнопок

Группа радмокнопон, ассоциированных со значением из источника данных

Иерархия классов-предков для кнопок, флажков и радиокнопок представлена наследующей схеме.

TControl

Y

TWinControl

» »

TButtonControl TCu

Y » »

TButton TRadioButton TCust

тTBitBtn v

f

TGraphic Control

¥ *

tomControl TSpeedButton TToolButton

т

urnCheckBox TCu stem Group В ox

Y Y Y

TCheckBox TDBRadioGroup TGroupBox TCustomRadioGroup

TDBRadioGroup TRadioGroup

1 В терминологии Delphi командные кнопки и радиокнопки иногда называются просто

кнопками.

Page 172: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1 72 Глава 5

Как видно из приведенной схемы, все кнопки, за исключением кнопокTSpeedButton и TToolButton, являются оконными элементами управления.

Класс TButtonРасположен в модуле s t d c t r l s

Класс TButton инкапсулирует поведение командной кнопки.

Свойства:

property Cancel: Boolean;Определяет, будет ли выполняться обработчик события OnClick при нажатиипользователем клавиши Escape. Если значение этого свойства равно True, тотакая кнопка реализует команду Отменить (Cancel).Отметим, что если форма содержит более одной кнопки со значением свойст-ва Cancel, равным True, то будет выполнен обработчик события OnClickкнопки, расположенной первой в табулированном порядке.

property Default: Boolean;Определяет, будет ли кнопка являться командной кнопкой по умолчанию,обработчик события OnClick которой выполняется при нажатии пользовате-лем клавиши Enter.Если свойство Default равно True для нескольких кнопок, то выполняться бу-дет обработчик OnClick той кнопки по умолчанию, которая расположена пер-вой в табулированном порядке.Отметим, что любая кнопка, получающая фокус, становится временнои кнопкой по умолчанию.

property ModalResult: TModalResult;Устанавливается для кнопки, закрывающей модальную форму.При этом обработчик события OnClick не используется.

Для каждой кнопки, по щелчку на которой форма может быть закрыта, следуетустановить значение свойства ModalResult, равное коду возврата завершениямодальной формы. Этот код возврата будет установлен как значение свойстваModalResult самой формы, содержащей кнопку. А в том случае, если свойствомодальной формы ModalResult становится отлично от нуля, форма закрываетсяи данное значение является возвращаемым значением функции ShowModal.В следующей таблице приведены возможные значения, которые может при-нимать свойство ModalResult.

Константа

mrNone

mrOk

mrCancel

Значение

0

idQK

idCancel

Описание

Первоначальное значение

Выход по кнопке ПК

Выход по кнопне CANCEL

Page 173: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 173

Константа

mrAbort

mrRetry

mr/gnore

mrYes

ntfNo

mrAII

Значение

idAbort

idRetry

idlgnore

idYes

icINo

mrNo +• 1

Описание

Выход по кнопке ABORT

Выход по кнопке RETRY

Выход по кнопке IGNORE

Выход по кнопке YES

Выход по кнопке N0

Значение последней предопределенной константы

Наслелуеллые свойства':

property TabOrder: TTabOrder;Указывает позицию кнопки в табулированном порядке.

property TabStop: Boolean;Определяет, разрешен ли переход на кнопку по клавише Tab.

property HelpContext: THelpContext;Указывает ID контекста справки, определяющего отображаемую при нажатииклавиши FI тему файла справки.

property Action: TBasicAction;Имя объекта Action, ассоциируемого с данной кнопкой.

property Caption: TCaption;Текст, отображаемый на кнопке.

property Font: TFont;Атрибуты шрифта для отображения заголовка кнопки.

property Name: TComponentName;Имя кнопки, используемое в программе для ссылки на нее.Далее перечислим другие наследуемые свойства объекта типа TButton.Свойства, наследуемые от класса TWinControl:

BrushControlCountDockCHentsHelpContextTabOrder

ClientOriginControlsDoubleBufferedParentWindow

TabStop

ClientRectDockClientCount

HandleShowingVisibleDockClientCount

1 Свойства или методы, описываемые в разделах наследуемых свойств или методови ранее рассмотренные в своем классе, приводятся кратно и только для напоминания.Все соответствующие ссылки можно найти ло предметному указателю.

Page 174: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

174 Глава 5

Свойства, наследуемые от класса TComrol:

Action Al ign AnchorsBoundsReci Caption ClientHeightClientWidth Constraints ControlStateControlStyle Cursor DockOrientationDragCursor DragKind DragModeEnabled Font FloatingFloatingDockSiteClass Height HintHostDockSite Left LRDockWidthName Parent ParentFontParentShowHint PopupMenu ShowHintTBDockHeight Top UndockHeightUndockWidth V i s i b l e WidthWindowProc

Для кнопки типа TButton предусмотрены следующие обработчики событий:OnEnter, OnExit, OnKeyDown. OnKeyPress, OnKeyllp, OnClick, OnContextPopup,OnDragDrop, OnDragOver, OnEndDock, OnEndDrag. OnMouseDown, OnMouseMove,OnMouseUp, OnStartDock, OnStartDrag.

f

Класс TBitBtnРасположен в модуле b u t t o n s

Класс TBitBtn инкапсулирует поведение командной кнопки. В отличие от стан-дартной командной кнопки, реализуемой классом TButton, кнопка типа TBitBtnдополнительно может содержать изображение.Кнопке может быть назначено только одно изображение. Однако само изобра-жение может быть составным: по одной равной части изображения для каждогоположения кнопки (нажата, ненажата, недоступна). Используя свойство Kind,можно создавать предопределенные кнопки, такие, как OK, Cancel, и др.Класс TBitBtn является непосредственным предком класса TButton и соответст-венно наследует все его свойства (подробно описанные в предыдущем разделе).Поэтому рассмотрим только свойства, присущие самому классу TBitBtn.

Свойства:

property Glyph: TBitmap;Ъпределяет изображение (имя BMP-файла), отображаемое на кнопке.В одном файле может содержаться или одно изображение, или четыре после-довательно расположенных по горизонтали изображения одинакового разме-ра. В последнем случае на кнопке в зависимости от ее состояния будет ото-бражаться одно из четырех отображений. Состояния кнопки приведеныв следующей таблице.

Page 175: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 175

Номер Состояниеизображения кнопки

1 Up

2 Disabled

3 Ciicked

4 Down

Описание

Кнопка нажата или в фокусе, аизображений

также если нет других

Кнопка недоступна

Появляется только при щелчкевозвращается изображение 1

мышью по кнопке, а затем

Кнопка остается нажатой после отпускания кнопки мыши

Количество изображений в BMP-файле должно быть указано в свойствеNumGlyphs.

Для того чтобы установить значение этого свойства, достаточно в инспектореобъектов в строке с именем свойства щелкнуть на кнопке ^J и в открывшемсядалее диалоге укачать имя BMP-файла.Для определения значения свойства во время выполнения следует вставитькод Glyph.LoadFromFile( 'HyFile .BMP'); .

Отметим, что самый н и ж н и й левый пиксель изображения зарезервирован подуказание цвета прозрачности. Все пиксели изображения, имеющие указан-ный цвет прозрачности, будут отображаться прозрачными.

property Kind: TBitBtnKind;Позволяет указать тин предопределенной кнопки. В этом случае значениесвойства Glyph устанавливается на указанное предопределенное изображение.

Значение свойства определяется как тип typeTBitBtnKind = (bkCustom, bkOK, bkCancel, bkHelp, bkYes, bkNo, bkClose, bkAbort,

bkRetry, bklgnore, b k A l l j ; .

На рис. 5.3 показаны 10 предопределенных типов кнопок.

,/ OK X Cancel ? Hdo

No

DOS*

Рис. 5.3. Предопределенные кнопки класса TBitBtn

Для всех предопределенных кнопок значение свойства ModalResult устанавли-вается в соответствии со значением свойства Kind (например, Kind=bkOk,a ModalResult=mrOk).

Page 176: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1 76 Глава 5

property Layout: TButtonLayout;Определяет положение изображения на кнопке.Свойство может принимать следующие значения:

blGlyphLeft - изображение появляется слева от заголовка;bldyphRight — изображение появляется справа от заголовка;

blGlyphTop - изображение появляется над заголовком;blGlyphBottom - изображение появляется под заголовком.

property Margin: Integer;Определяет расстояние от угла кнопки до угла изображения {в пикселях).Какой угол кнопки и изображения при этом используется, определяется свой-ством Layout. Так, если изображение выравнено вправо, то расстояние указы-вается от правого края кнопки до правого края изображения.По умолчанию значение свойства равно - 1; изображение и текст выравни-ваются по центру.

property NumGlyphs: TNumGlyphs;Определяет количество изображений в указанном BMP-файле (от 1 до 4).

property Spacing: Integer;Определяет расстояние между текстом и изображением (в пикселях). Еслиуказано значение 0, то между изображением и текстом не будет промежутка.По умолчанию значение свойства равно 4 пикселям.Если значение свойства равно - 1, то текст будет выравнен по центру междуизображением и краем кнопки.

property Style: TButtonStyle;Указывает внешний вид кнопки.Значение свойства определяется как тип type TButtonStyle = (bsAutoDetect,bsWin31, bsNew};.

Для кнопки типа TBitBtn предусмотрены следующие обработчики событий:OnEnter, OnExit, OnKeyDown, OnKeyPress, OnKeyUp, OnClick, OnContextPopup,OnDragDrop, OnDragOver, OnEndDock, OiiEndDrag, OnMouseDown, OnMouseMove,OnMouseUp, OnStartDock, OnStartDrag.

Класс TSpeedButtonРасположен в модуле buttons

Класс TSpeedButton инкапсулирует поведение кнопок, используемых для вы-полнения команд или переключения режимов.Кнопки типа TSpeedButton могут быть объединены в группы.

Page 177: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 77

Свойства:

property Grouplndex: Integer;Позволяет объединять кнопки в группы.Если кнопка не входит ни в какую группу, то значение свойства Grouplndexравно 0 (по умолчанию).Для объединения нескольких кнопок в группу следует всем им проставитьодинаковое значение свойства Grouplndex, отличное от нуля.Если значение свойства Grouplndex равно 0, то при щелчке мышью на кнопкеона становится нажатой, а затем возвращается в первоначальное, ненажатоесостояние.Если кнопка принадлежит к группе, то при щелчке мышью на кнопке онастановится нажатой. По умолчанию в группе может быть одновременно на-жата только одна кнопка (свойство AllowAHUp равно False).На рис. 5.4 кнопка 1 находится в нажатом состоянии.

лГ" Foirn!

Одиночная кнопка типа TSpeedBiittun Группа кнопок, типа TSpeedBulton

1

Рис. 5.4. Кнопки типа TSpeedButton

Для того чтобы одиночную кнопку сделать переключателем - по щелчкумышью переключать режимы нажата и ненажата, следует установить для неезначение свойства Grouplndex, отличное от нуля, но не совпадающее ни с ка-ким другим значением этого свойства для кнопок внутри формы, а значениесвойства Allow AllUp сделать равным True.

property AllowAllUp: Boolean;Если значение свойства равно True, то все кнопки группы типа TSpeedButtonмогут быть ненажаты (up-состояние) одновременно. В противном случае од-на из кнопок группы должна находиться в нажатом состоянии (down-состояние).Отметим, что изменение чначения этого свойства для одной кнопки из груп-пы влечет за собой изменение его и для всех кнопок данной группы.Это свойство не используется, если кнопка не принадлежит ни к какой груп-пе (Groupindex-0).

property Down: Boolean;Определяет, в каком состоянии находится кнопка: нажатом (down-состоянии)или ненажатом (ир-состоянии).Это свойство используется только для кнопок, принадлежащих к группе. Та-ким образом, если значение свойства Grouplndex равно 0, то свойство Downне устанавливается.

Page 178: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

178 Глава 5

property Flat: Boolean;Определяет, имеет ли кнопка рамку 3D.

property Glyph: TBitmap;Указывает BMP-файл, отображаемый на кнопке.

property Layout: TButtonLayout;Определяет, с какой стороны от текста появляется изображение (blGlyphLeft,blGlyphRight, blGlyphTop, blGIypiiBottom).

property Margin: Integer;Определяет расстояние ме/кду краем кнопки и краем изображения или заголовка.

property NumGlyphs:Определяет количество изображений в BMP-файле.

property Spacing: Integer;Определяет расстояние между изображением и заголовком кнопки.

property Transparent: Boolean;Определяет, является ли фон изображения прозрачным (по умолчанию True).

Для кнопки типа TSpeedBuiton предусмотрены следующие обработчики собы-тий: OnClick, OnDblClick, OnMouseDown, OnMouseMove, OnMouseUp.

Класс TCheckBoxРасположен в модуле s t d c t r l s

Класс TCheckBox реализует флажок Windows.

Свойства:

property Alignment: TLeftRight;Определяет позицию заголовка флажка: справа или слева от флажкка (рис. 5.5).

Заголовок расположен оправа Заголовок расположен слева

CheckBoKl !сЬесЙЗс.х2 f?

Рис. 5.5. Компоненты типа TCheckBox

Позиция флажка указывается значением типа type TLeftRighttaLef tJus t i fy . . taRightJus t i fy ; .

property AllowGrayed: Boolean;Определяет, может ли флажок отображать состояние «частичное включение»,которое отображается галочкой на сером фоне.

Page 179: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 79

Если значение свойства равно False (по умолчанию), то флажок может при-нимать только два состояния: «установлен» и «снят» (иногда также эти со-стояния называют «включен» и «выключен»).

Если значение свойства равно True, то флажок может принимать три состоя-ния: частичное включение (cbGrayed), снят (cbUnchecked), установлен(cbChecked).

property Checked: Boolean;Определяет, в каком состоянии (установлен или снят) флажок появляетсяв форме.

property State: TCheckBoxState;Указывает текущее состояние флажка. Оно может быть определено одним изследующих трех значений: cbUnchecked, cbChecked, cbGrayed.

Для того чтобы установить параметры флажка, отображаемые при первомпоявлении окна формы, можно:

• задать значения свойств в инспекторе объектов;

в установить значения свойств программно в обработчике события OnCreateданной формы.

Пример:

procedure TForml.FormCreate(Sender: TObiect);

begin

Checkbox1.State := cbChecked;

CheckBoxl.AllowGrayed := True;

snd;

Наследуемые свойства:

property TabOrder: TTabOrder;Указывает позицию флажка в табулированном порядке.

property TabStop: Boolean;Определяет, разрешен ли переход на флажок по клавише Tab.

property HelpContext: THelpContext;Указывает ID контекста справки, определяющего отображаемую при нажатииклавиши F1 тему файла справки.

property Action: TBasicAction;Имя объекта Action, ассоциируемого с данным флажком.

property Caption: TCaption;Заголовок флажка.

Page 180: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

180 Глава 5

property Font: TFont;Атрибуты шрифта для отображения заголовка флажка.

property Name: TComponentName;Имя флажка, используемое в программе для ссылки на него.

Далее перечислим другие наследуемые свойства объекта типа TCheckBox.

Свойства, наследуемые от класса TWinControI:Brush ClientOriginControlCount ControlsDockClientCount DockCHentsHandle HelpContextParentWindow ShowingTabOrderVisibleDockCHentCouni

Свойства, наследуемые от класса TControl:

ClientRectCtl3DDoubleB ufferedParentCtl 3DTabSlop

ActionBiDiModeClientHeightConstraintsCursorDragKindFloatingHeightLeftParentParentFontShowHintUndockHeightWidth

AlignBoundsRectClientWidthControlStateDockOrientationDragModeFloatingDockSiteClassHintLRDockWidthParentBiDiModeParentShowHintTBDockHeightUndockWidthWindowProc

AnchorsCaptionColorControlStyleDragCursorEnabledFontHostDockSiteNameParentColorPopupMenuTopVisible

Для флажка предусмотрены следующие обработчики событий: OnEnter, OnExit,OnKeyDown, OnKeyPress, OnKeyUp, OnClick. OnContextPopup, OnDragDrop,OnDragOver, OnEndDock. OnEndDrag, OnMouseDown, OnMouseMove, OnMouseUp,OnStartDock, OnStaitDrag.

Класс TRadioButtonКласс TRadioBuuon инкапсулирует поведение радиокнопки Windows.Обычно радиокнопки объединяют в группы. Радиокнопки — это взаимоисклю-чающие опции: в каждой группе одновременно может быть выделена толькоодна радиокнопка.

Page 181: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 181

Как правило, радиокнопки размещают в контейнерах типа TRadioGroup,TGroupBox или TPanel. Все радиокнопки, помещаемые в один контейнер типаTGroupBox или TPanel, автоматически относятся к одной группе.Радиокнопки контейнера типа TRadioGroup создаются непосредственно в немчерез свойство Items.

Свойства:

property Alignment: TLeftRight;Определяет позицию заголовка: справа или слева от радиокнопки. Значениесвойства определяется как тип Суре TLeftRight = taLeftJustify..taRighlJustify;.

property Checked: Boolean;Определяет, выделена ли данная радиокнопка.

Наслелуемые свойства:

property TabOrder: TTabOrder;Указывает позицию радиокнопки в табулированном порядке.

property TabStop: Boolean;Определяет, разрешен ли переход на радиокнопку по клавише Tab.

property HelpContext: THelpContext;Указывает Ю контекста справки, определяющего отображаемую при нажатииклавиши F1 тему файла справки.

property Action: TBasicAction;Имя объекта Action, ассоциируемого с данной радиокнопкой.

property Caption: TCaption;Заголовок радиокнопки.

property Font: TFont;Атрибуты шрифта для отображения заголовка радиокнопки.

property Name: TComponentName;Имя радиокнопки, используемое в программе для ссылки на нее.

Для радиокнопок предусмотрены следующие обработчики событий: OnEnter,OnExit, OnKeyDown, OnKeyPress, OnKeyUp, OnClick, OnContextPopup,OnDragDrop, OnDragOver, OnEndDock, OnEndDrag, OnMouseDown,OnMouseMove, OnMouseUp, OnStartDock, OnStartDrag.

Page 182: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

182 Глава 5

Класс TRadioGroupРасположен в модуле extctr l s

Класс TRadioGroup реализует группу радиокнопок, в которой одновременноможет быть выделена только одна радиокнопка. При щелчке пользователя налюбой радиокнопке в группе она становится выделенной, а все остальные - не-выделенными.Для того чтобы добавить в группу радиокнопку, следует ввести список заголов-ков радиокнопок в свойство Items. Отметим, что независимо созданный компо-нент класса TRadioButton не может быть включен в группу радиокнопок типаTRadioGroup.Текущая выделенная кнопка определяется значением свойства Itemlndex.

Свойство Columns позволяет определить один или несколько столбцов для ото-бражения группы радиокнопок.

Свойства:

property Columns: IntegerОпределяет количество столбцов и группе радиокнопок. По умолчанию зна-чение свойства Columns равно 1.г

property Itemlndex: IntegerОпределяет номер (начиная с 0) радиокнопки, которая является выделеннойв группе. Если первоначально не выделена ни одна кнопка, то значение свой-ства равно- 1.

property Items: TStringsСодержит список заголовков радиокнопок группы. Это свойство определяет-ся через инспектор объектов.

Класс TGroupBoxРасположен в модуле s t d c t r l s

Класс TGroupBox реализует группу Windows.Группа является родительским элементом управления для всех размещенныхв ней компонентов. Если в компонент типа TGroupBox поместить радиокнопки,то они будут образовывать единую группу.

КЛАССЫ ДЛЯ РАБОТЫ С ТЕКСТОМОсновные компоненты Delphi, позволяющие отображать и редактировать текст:

TLabel - нередактируемый текст;

TStaticText - оконный объект нередактируемый текст;

TEdit - однострочное поле редактирования;

Page 183: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 83

TMaskEdit - однострочное поле редактирования, позволяющее отображатьсимволы, не входящие в сам текст;

ТМето - многострочное поле редактирования;

TRichEdit — многострочное поле редактирования, позволяющее вводитьформатирование текста;

TStringGrid - таблица текста.-

Классы TLabel и TStaticTextРасположены в модуле stdctrls

Классы TLabel и TStaticText позволяют создавать объекты нередактируемыйтекст. Их отличие состоит в том, что компонент TStaticText является оконнымобъектом и, следовательно, имеет дескриптор окна и может реагировать на вводс клавиатуры.

Объекты класса TLabel и TStaticText могут содержать ключи-акселераторыи использоваться как надписи для других объектов, позволяющие перемещать наних фокус.

Свойства:

property Alignment: TAhgninent;Управляет выравниванием текста внутри компонента.

property AutoSize: Boolean;Определяет, будет ли размер компонента автоматически устанавливаться дляразмещения в нем всего текста.

property FocusControl: TWinControl;Указывает оконный элемент управления, ассоциируемый с данным компо-нентом типа TLabel или TStaticText.

Если заголовок (свойство Caption) содержит символ &, то следующая букваявляется ключом-акселератором. При нажатии пользователя клавиши Altи ключа-акселератора происходит перемещение фокуса на компонент, ука-занный свойством FocusControl.Для того чтобы назначить ассоциируемый компонент, достаточно в инспек-торе объектов выбрать из списка свойства FocusControl любой из приведен-ных там компонент ов (список всегда содержит все компоненты формы).

property Layout: TTextLayout;Определяет выравнивание текста по вертикали внутри компонента. Свойствоможет принимать следующие значения: tlTop, llCenter, tlBottotn.

Page 184: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

1 84 Глава 5

property Show Accel Char: Boolean;Если значение свойства равно True, то символ, перед которым стоит ампер-сенд (&), отображается подчеркнутым. Для отображения самого амперсендаследует вводить &&, а компонент, указанный свойством FocusControl, будетполучать фокус при нажатии пользователем ключа-акселератора.Если значение свойства равно False, то свойство FocusControl не использует-ся, а символ & появляется как амперсенд.

property Transparent: Boolean;Это свойство имеется только у объектов типа TLabel.Определяет, будет ли фон компонента прозрачным. По умолчанию значениесвойства равно False и компонент «не просвечивает». Если фон прозрачный,то через компонент могут быть видны другие неоконные элементы управле-ния (например, TShape). Напомним, что оконные элементы управления немогут быть прозрачными и всегда располагаются выше любого оконногокомпонента.

property Wordwrap: Boolean;Если значение свойства равно False (по умолчанию), то в случае, когда текстбудет шире, чем размер компонента, этот текст будет усечен.Если значение свойства равно True, то при допустимой высоте компонентатекст может быть отображен в несколько строк.

property BorderStyle: TStaticBorderStyle;Это свойство имеется только у объектов типа TStaticText.Определяет, будет ли вокруг элемента управляемая рамка, и какая.Свойство может принимать следующие значения:sbsNone - без рамки;sbsSingle - простая прямоугольная рамка;sbsSunken - вдавленная рамка.

Наслелуеллые свойства:*

property Caption: TCaption;Отображаемый нередактируемый текст.

property Name: TComponentName;Имя компонента, используемое в программе для ссылки на него.

Класс TEditРасположен в модуле stdctrls

Класс TEdit является оболочкой для элемента управления Windows одностроч-ное поле редактирования.Все публикуемые свойства класса TEdit наследуемы от TCustomEdit.

Page 185: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi —VCL 185

Наслелуемые свойства:

property AutoSelect: Boolean;Определяет, будет ли автоматически выделяться весь текст при получениифокуса элементом управления типа TEdit.

property AutoSize: Boolean;Определяет, будет ли высота компонента автоматически изменяться в соот-ветствии с размером (по высоте) текста.

property BorderStyle: TBorderStyle;Определяет, будет л и компонент иметь рамку (bsSiiigle) или нет (bsNone).

property CanUndo: Boolean; (только для чтения)Указывает, содержит ли компонент изменения, которые можно отменить вы-зовом метода Undo.

property CharCase: TEditCharCase;Определяет регистр отображения текста. Свойство может принимать сле-дующие значения:ecLowerCase - символы текста преобразовываются в строчные буквы (ниж-ний регистр);

ecNormcil - нет преобразования регистра;ecllpperCase - символы текста преобразовываются в прописные буквы.

property HideSelection: Boolean;Если значение свойства равно True (по умолчанию), то при перемещении фо-куса с компонента выделение текста будет сниматься. При значении Falseвыделение текста останется.

property MaxLength: Integer;Определяет максимальное количество символов, которое пользователь можетввести в поле редактирования.-Если ограничение не установлено, то значение свойства равно 0.Отметим, что ограничение длины не усекает уже существующий текст,а только не позволяет редактировать или вводить новый, превышающий ука-занный размер.

property Modified: Boolean;Определяет, был ли текст в поле редактирования обновлен.

property OEMConvert: Boolean;Определяет, следует ли символы текста перед отображением преобразовы-вать из ANSI в OEM, а затем обратно в ANSI.

Page 186: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

186 Глава 5

property PasswordChar: Char;Указывает символ, отображаемый вместо любого вводимого символа. Значе-ние свойства Text при этом будет содержать действительно введенный текст.Это позволяет вводить пароль в скрытом приеме. Если значение свойстваравно #0, то режим пароля не установлен и символы отображаются так же,как и вводятся.

property ReadOnly: Boolean;Определяет, может ли пользователь изменять текст в компоненте TEdit.

property SelLength: Integer;Указывает количество выделенных символов. Если значение свойстваSelLength изменяется, то будет выделено новое количество символов, начи-ная с SelStart.

property SelStart: Integer;Указывает номер {начиная с 0) первого выделенного символа. Если выделен-ного текста нет, то SelStart указывает позицию курсора ввода.Для того чтобы программно выделить фрагмент текста, достаточно указатьего начало (SelSiart) и длину (SelLengih).

property SelText: string;Содержит выделенный фрагмент текста.Для замещения выделенного фрагмента текста или ввода нового текста в ме-сто, указываемое курсором ввода, следует присвоить свойству SelText новоезначение соответственно замещаемого или вводимого текста.

property Text: TCaption;Содержит текст, отображаемый и редактируемый в компоненте.

property TabOrder: TTabOrder;Указывает позицию компонента в табулированном порядке.

property TabStop: Boolean;Определяет, разрешен ли переход па компонент по клавише Tab.

Метолы:

procedure Clear; virtual;Удаляет весь текст и устанавливает значение свойства Text равным пустойстроке.

procedure ClearSelection;Удаляет выделенный фрагмент текста.

•procedure CopyToClipboard;

Копирует выделенный текст в буфер обмена в формате CF_TEXT.

Page 187: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 87

procedure CutToClipboard;Копирует выделенный текст в буфер обмена, удаляя его одновременно изкомпонента.

• •procedure PasteFromClipboard;

Замещает выделенный фрагмент текста или вставляет в место, указываемоекурсором ввода, содержимое буфера обмена.

- "procedure SelectAll;

Выделяет весь текст.

Для выделения фрагмента текста следует использовать свойства SelStartи SelLetigtli.

procedure Undo;Отменяет все изменения, сделанные в тексте после последнего вызова методаClearUndo. Если метод ClearUndo не вызывался, то отменяются все изменения.

Класс T M a s k E d i tРасположен в модуле mask

Класс TMaskEdit инкапсулирует поведение однострочного маскируемого поляредактирования. Такое поле редактирования может отображеть текст, заданныйпо некоторой маске. В маске указывается как место ввода самих символов зна-чения (свойство MaskEdit), так и специальные отображаемые символы (напри-мер, тире и скобки в номере телефона), которые являются нередактируемыми.

Наслелуемые свойства:

property EditMask: string;Определяет маску отображения текста. Маска указывает, какие символыи в какое место могут быть введены, а также содержит отображаемые, но не-редактируемые символы.Маска содержит три поля, разделенные точкой с запятой. Первая часть явля-ется собственно самой маской ввода; вторая часть является символом, опре-деляющим, будут ли специальные нередактируемые символы сохранены какчасть данных; третья часть определяет невводимый символ, указывающийместо ввода редактируемого текста.Первое поле маски может содержать специальные символы, описанныев следующей таблице.

Символ

!

>

Описание

Если в масне появляется символ !, то необязательные символы представляютсяв EditText как лидирующие пробелы, а иначе - как завершающие пробелы

Все символы, следующиеются в прописные буквы

за символом > и до символа < , преобразовыаа-

Page 188: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

188 Глава 5

Символ

<

< >

\

L

I

А

а

С

с

0

9

tt

'•

1

i

~

Описание

Все символы, следующие за символом < и до символа > , преобразовыва-ются в прописные буквы

Если масиэ содержит вместе два символа, то преобразование вводимых сим-волов не выполняется

Символ, следующий за 1, пвпяется литералом. Это используется чтобы вво-дить специальные символы маски как данные

Указывает, что в данную позицию должен быть введен только буквенный сим-вол (А -1, а -z, А -Я, а -я)

Указывает, что в данную позицию может, но необязательно должен быть вве-ден только буквенный символ

Указывает, что в данную позицию должен быть введен только буквенный иличисловой символ (A -Z, а -г, А -Я, а -я, 0 -9)

Указывает, что Е данную позицию может, но необязательно должен быть вве-ден только буквенный или числовой символ

Требует в указанной позиции ввода произвольного символа

Позволяет ввести в умазанную позицию произвольный символ, но не требует этого

Требует ввода в указанную позицию цифрового символа

Позволяет ввести в указанную позицию цифровой символ, но не требует этого

Позволяет ввести в указанную позицию цифру или знак (плюс или минус), ноне требует этого

Используется как разделитель для времени (часы:минуты:сенунды). В попе призтом будет отображен тот символ-разделитель, который определен в системе

используется как разделитель для даты. В поле при этом будет отображен тотсимвол-разделитель, который определен в системе через панель управления

Используется для разделения трех полей маски ввода

Автоматически вставляет в текст пробелы, которые пропускаются при вводев поле данных

Если символ второй части маски ввода равен 1, то специальные нередактируе-мые символы будут сохранены как часть данных в свойстве Text, а если 0, то небудут.

property EditText: string;Текст, отображаемый в поле типа TMaskEdit, включающий форматирование позаданной маске ввода. Это свойство доступно только во время выполнения.Если символы маски включаются в вводимые данные и нет символов, авто-матически заменяемых на пробелы, то значения свойств EditText и Text сов-падают.

Page 189: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 89

property IsMasked: Boolean; (только ддя ЧТЕНИЯ]Определяет, задана ли маска для данного элемента управления.

property MaxLength: Integer;Определяет максимальное количество символов в EditText.

property Text: string;Определяет текст до форматирования его по маске; может содержать симво-лы маски, замененные на те, которыми они будут отображены в поле вводазначения; содержит автоматически добавляемые пробелы.

Наследуешь/в свойства:Класс наследует также ряд свойств от классов TCustomEdit, TWinControl иTControl:

AutoSize BorderStyle CanUndoCharCase Modified PasswordCharReadonly SelLength SelStartSelText Brush ClientOriginClientRect ControlCount ControlsCtl3D DockClientCount DockClientsHandle HelpContext ImeModeImeName ParentCtl3D ParenlWindowShowing TabOrder TabStopVisibleDockCtientCounc

Наиболее важные из этих свойств описаны в разделах этой главы "КлассTControl" и "Класс TEdit".

Метолы:

function GetTextLen: Integer;Возвращает длину неформатированного по маске текста.

Класс TMaskEdit наследует ряд методов, включая методы от класса TCustomEdit:

ClearSelection ClearUndo CopyToClipboard

CutToClipboard GetSelTextBuf PasteFromClipboard

SelectAli SetSelTextBuf

Undo, а также методы от класса TWinControl:

Broadcast CanFocus ContainsControlControlAtPos CreateParented CreateParentedControl

Destroy DisableAlign DockDrop

EnableAlign FindChildControl FlipChildrenFocused GetTabOrderList HandleAllocated

HandleNeeded InsertConirol Invalidate

Page 190: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

90 Глава 5

MouseWheelHandler

RemoveControl

ScrollBy

Update

PaintTo

Repaint

SetBounds

UpdateCoiurol Slate

Realign

ScaleBy

SetFocus

Для класса предусмотрены обработчики следующих событий:

OnChange, OnEnter, OnExit, OnKeyDown, OnKeyPress, OnKeyUp, OnClick,OnDblClick, OnDragDrop, OnDragOver, OnEndDock, OnEndDrag, OnMouseDown,OnMouseMove, OnMouseUp, OnStarlDock, OnStartDrag.

Класс TMemoРасположен в модуле stdctrls

Класс TMemo является оболочкой для многострочного поля редактирования.Компонент типа TMemo позволяет пользователю вводить в оконный элементуправления несколько строк текста. Предками класса TMemo являются классыTCustomMemo (непосредственный предок), TCustomEdit и TWinComrol. Весьтекст, отображаемый компонентом, хранится в свойстве Text (наследуемо откласса TControl). Общее число символов, содержащееся в компоненте, опреде-ляется методом GetTextLen.

Свойства:

property Alignment: TAlignment;Определяет выравнивание текста (taLeftJustify, taCenter, taRightJustify) внутриэлемента управлен ия.

property CaretPos: TPoint; (только для ЧТЕНИЯ)Указывает позицию курсора ввода X.Y (в терминах номера строки и номерасимвола) внутри клиентской области элемента управления.

property Lines: TStrings;Содержит строки текста, отображаемые в многострочном текстовом поле.

property ScrollBars: TScrollStyle;Определяет, имеет ли многострочное текстовое поле линейки прокрутки. Этосвойство может указываться следующими значениями:ssNone - нет линеек прокрутки;ssHorizontat - есть горизонтальная линейка прокрутки;ssVertical- есть вертикальная линейка прокрутки;ssBotk - есть обе линейки прокрутки: горизонтальная и вертикальная.

property WantReturns: Boolean;Определяет, каким образом выполняется вставка в текст символа конца строки.Если значение свойства равно True, то перевод строки происходит по нажа-тии пользователем клавиши Enter.

Page 191: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 191

Если значение свойства равно False, то перевод строки происходит по нажа-тии пользователем клавиш Ctrl+Enter. а нажатие клавиши Enter эквивалентнощелчку по командной кнопке, определенной как кнопка по умолчанию.

property WantTabs: Boolean;Определяет, каким образом выполняется вставка в текст символа табуляции.Если значение свойства равно True, то символ табуляции вставляется при на-жатии клавиши Tab.Если значение свойства равно False, то 'и символу табуляции будет выполнять-ся переход на следующий элемент управления в табулированном порядке.

property Wordwrap: Boolean;Если значение свойства равно True, то выполняется мягкий перевод строки:не умещающаяся справа часть строки переносится на следующую строку.Если значение свойства равно False, то перенос строки происходит тольков месте, указанном символами конца строки. При этом невидимая часть стро-ки может быть просмотрена с помощью л и н е й к и прокрутки.

Класс ТМето наследует от класса TCustomEdh следующие свойства, наиболееважные из которых описаны ранее в этой главе:

CanUndo BorderStyle HideSelection .M,i\Ljn.i:iiModified OEMConvert ReadOnly SelLengthSelStart SelText

Для класса TMemo реализован ряд методов, среди которых:

Clear ClearSelection ClearUndo CopyToClipboardCutToClipboard GetSelTextBuf PasteFromClipboard SelectAll

SetSelTextBuf Undo

Для класса TMemo предусмотрены следующие обработчики событий:OnChange, OnEnter, OnExit, OnKeyDown, OnKeyPress, OnKeyUp, OnClick,OnContextPopup, OnDblClick, OnDragDrop, OnDragOver, OnEndDrag, OnMouseDown,OnMouseMove, OnMouseUp. OnStailDrag.

Пример:

{Замена в memo-поле всех вхождений текста FindText на ReplaceText изстандартного диалога TReplaceDialog)

procedure TForml.ReplaceDialoglRepiace(Sender: TObject); {Обработчиксобытия OnReplace)

varSelPos: Integer;

beginwith TReplaceDialog(Senderl do { TReplaceDialog - стандартный диалог}begin{ Выполняем поиск вхождения текста FindText в Meraol }

Page 192: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

192 Глава 5

SelPos := Роз(FindText, Memol.Lines.Text);

if SelPos > 0 thenbeginMemol.SelStart := SelPos - 1; {Начальная позиция

выделенного текста}Memol.SelLength := Length(FindText); (Количество выделенных

символов}{ Замена выделенного текста на текст, хранимый в свойствеReplaceText объекта TReplaceDialog }

Memol.SelText := ReplaceText;endelse MessageDlg(Concat(He могу найти в поле Meraol текст: "',

FindText),'ratError, [mbOk], 0);end;

end;,,.,

-у Для выполнения этого примера следует:/J

1. Расположить в окне формы компонент TReplaceDialog со страницыDialogs палитры компонентов.

2. Установить значения свойств FindText и ReplaceText объекта ReplaceDialogl.

5. Расположить в окне формы компонент ТМето со страницы Standard па-литры компонентов.

4. Установить значения свойства Lines объекта Memo!. Для этого следуетщелкнуть на кнопке справа от имени свойства и в предложенном диалогеввести текст, отображаемый компонентом.

5. Расположить в окне формы компонент TButton со страницы Standard па-литры компонентов.

6. Создать для объекта Buttonl обработчик события OnClick и ввести в негокод, выполняющий отображение диалога ReplaceDialogl:ReplaceDialogl. Execute;

7. Создать для объекта ReplaceDialog 1 обработчик события OnReplaceи ввести в него код, описанный а данном примере.

Класс TRichEditРасположен в модуле comctrls

Класс TRichEdit является оболочкой элемента управления Windows формати-руемое поле редактирования. Такой компонент может содержать наряду с тек-стом атрибуты шрифта и абзаца.Класс TRichEdit предоставляет ряд свойств и методов для управления редактиро-ванием и форматированием текста. Однако Delphi не предоставляет никаких ком-понентов, реализующих интерфейс форматирования текста в поле типа TRichEdit.Класс TRichEdit является потомком класса TCustornRichEdit.

Page 193: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi —VCL 193

Свойства:

property DefAttributes: TTextAttributes;Описывает параметры шрифта, используемого по умолчанию для отображе-ния текста в элементе управления.Значение свойства доступно только во время выполнения.

property HideScrollBars;Определяет, будет ли отображаться линейка прокрутки.

property HideSelection: Boolean;Определяет, будет ли текст оставаться выделенным при перемещении фокусаввода на другой компонент.

property Lines: TStrings;Содержит строки текста, отображаемые в элементе управления.

property Paragraph: TParaAttributes; (только для ЧТЕНИЯ)Определяет информацию форматирования текущего параграфа.Для управления информацией о форматировании параграфа следует исполь-зовать свойства объекта типа TParaAttributes.

property PlainText: Boolean;Если значение свойства равно True, то при записи в файл коды форма-тирования будут игнорироваться.Если значение свойства равно False, то сохраняемый текст включает кодыформатирования и записывается в формате RTF.

property SelAttributes: TTextAttributes;Описывает параметры форматирования выделенного текста. Установка фор-матирования выполняется через следующие свойства объекта типаTTextAttributes:CharSet- например, ANSI_CHARSET, DEFAULT_CHARSET, OEM_CHARSE;

Color - цвет шрифта (значение типаТСо!ог);Height- высота в пикселях (Height = Size * ScreenPixelsPerlnch/ 72);Name - имя шрифта (property Name: TFontNarne);Pitch - определяет моноширинный или пропорциональный шрифт (typeTFontPitch = (fpDefault, fpVuriable, fpFixed););Protected —текст не может быть изменен пользователем;Size - размер шрифта (Size = Height * 72 / ScreenPixelsPerlnch);Style - стиль, указываемый как множество типа TFontStyle = (fsBold, fsltalic,fsUnderline, fsStrikeOui).Значение свойства доступно только во время выполнения.

7 Зак. 11

Page 194: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

194 Глава 5

Пример:

RichEditl.SelAttributes.Color := clBIue;RichEditl.SelAttributes.Style := [fsBoid, f s l ta l ic];

property SelLength: Integer;Определяет количество выделенных символов.

property SelStart: Integer;Определяет номер первого выделенного символа (начиная с 0).

property SelText: string;Содержит выделенный текст.

Класс ТМето наследует ряд свойств, включая свойства от класса TCustomMemo:

Alignment CaretPos ScrollBars

WantRecurns WantTabs Wordwrap

и от класса TCustomEdit:

BorderStyle CunUndo MaxLength

Modified ReadOnly

Метолы:

function FindText (const SearchStr: string; StartPos, Length: Integer;Options: TSearchTypes}: Integer;Ищет в заданном диапазоне указанную строку.

Тип поиска задается значениями типа type TSearchType = (stWholeWord,stMatchCase); TSearchTypes - set of TSearchType:.

function GetSelTextBuf(Buffer: PChar; BufSlze: Integer): Integer; override;Копирует выделенный текст в буфер размера BufSize и возвращает количест-во скопированных символов. Если выделенного фрагмента нет, то копируетсяпустая строка, а если выделенный фрагмент слишком большой, то копируют-ся первые (BufSize - 1} символы.

procedure Print(const Caption: string); virtual;Форматирует и печатает содержимое форматируемого поля редактирования.Параметр Caption указывает печатаемый заголовок.

Для класса TRichEdit предусмотрены следующие обработчики событий:

OnProtectChange, OnResizeRequest, OnSaveClipboard, OnSelectionChange,OnChange, OnEnter, OnExit, OnKeyDown, OnKeyPress, OnKeyUp, OnMouseWheel,OnMouseWheelDown, OnMouseWheel Up, OnContextPopup, OnDragDrop,OnDragOver. OnEndDock, OnEndDrag, OnMouseDown. OnMouseMove. OMouseUp.OnStartDock, OnStartDrag.

Page 195: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi —VCL 195

КЛАССЫ списковНа рис. 5.6 представлено окно формы, содержащее различные типы списков.

Список типа TTreeView Список типа TListView

Пункт!

. Пцнкт2

3 Пункт21

S Пцнкт22

Список типа TListBciK Список типа TCh

String! >. . . Флалоь!S'rina2 ~ **, Фяажок2

String4 «'•ИВStringS »| _": ФлажокБ

Столбец!П чмкт!Пинкт2ПчнктЗПинк.т4

ickLislBox

Столбец2Пункт! 2

Список типа TCdniboBox

ВариакгЗ _^J

Вариаиг!Вариант 2

Варна иг 4

Рис. 5.6. Компоненты Delphi, реализующие различные типы списков

Класс T L i s t B o xРасположен в модуле stdctrls

Класс TListBox является оболочкой для элемента управления Windows окно списка.Это самый простой вариант списка. Содержание окна списка определяется свойст-вом. Для списка может быть разрешено два типа выбора элемента: выбор толькоодного элемента или выбор нескольких элементов одновременно. Дня программи-рования работы с элементами списка удобно использовать свойства и методы клас-са TList (например. Add. Insert - для добавления элементов в список Items).

Свойства:

property BorderStyle: TBorderStyle;Определяет, имеет ли окно списка рамку. Это свойство может приниматьзначения bsSingle (с рамкой) и bxNone (без рамки).

property Columns: Integer;Определяет количество столбцов в окне списка, которые будут видимы безвыполнения скроллинга.

По умолчанию значение этого свойства равно 0.

property ExtendedSelect: Boolean;Определяет, может ли пользователь, удерживая нажатой клавишу Shift, вы-делять щелчком мыши последовательный диапазон элементов списка. А так-

Page 196: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

196 Глава 5

же выделять или снимать выделение с элемента по щелчку мыши при одно-временном нажатии клавиши Ctrl.Если значение свойства ExtendedSelect равно False, то пользователь не можетвыделить диапазон элементов одним щелчком мыши при нажатой клавише Shift.Отметим, что в любом случае мультивыделение разрешено только при значе-нии свойства MultiSelect, равном True.

property Integral Height: Boolean;Определяет, разрешено ли частичное отображение элемента списка.Если значение этого свойства равно True и значение свойства Style равноIsOwnerDrawFixed, то размер окна списка по высоте всегда будет кратен зна-чению свойства ItemHeight.

Если значение свойства Style равно IbOwerDrawVariable, то свойствоIntegralHeight не учитывается.

property ItemHeight: Integer;Определяет высоту элемента в самоотображаемых (owner-draw) списках.Для списка стандартного стиля (свойство Style равно IbStandart) значениесвойства ItemHeight устанавливается автоматически и не может быть произ-вольно изменено.Также значение свойства ItemHeight игнорируется, если свойство Style рав-но IsOwnerDrawVariable.

property Itemlndex: Integer;Определяет номер выделенного элемента списка (начиная с 0), а при разреше-нии мультивыбора - номер выделенного элемента списка, имеющего фокус.Если выделенных элементов нет, то значение свойства равно - 1.Первоначально по умолчанию для списка с разрешенным единичным выбо-ром значение свойства равно — 1, а с мультивыбором - 0.

property Items: TStrmgs;Содержит строки, отображаемые как элементы окна списка.Добавить элементы списка можно как на этапе проектирования в инспектореобъектов, так и на этапе выполнения, используя методы класса TStrings. На-пример, для добавления в список значения из однострочного поля редактиро-вания следует записать: ListBoxl.Items.Add(EditForList.Text); .

property MultiSelect: Boolean;Определяет, разрешено ли одновременно выделять более одного элементасписка.

property SelCoimt: Integer; (только /v\» ЧТЕНИЯ)Указывает количество одновременно выделенных, элементов списка. Еслимультивыделение не разрешено, то значение этого свойства равно - 1.

Page 197: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 197

property Selected[lndex: Integer]: Boolean;Определяет массив, указывающий, выделен ли каждый элемент списка. Па-раметр Index определяет номер элемента в окне списка (начиная с 0).

Пример:

(Просмотр выделенных элементов списка]for i := 0 to (ListBoxl.Items.Count - 1) do begin

if ListBoxl.Selectedfi] thenMessageDlg('Выбран элемент списка: '+

ListBoxl.Items.Strings[i], mtError, [robOk], 0);end;

property Sorted: Boolean;Определяет, будут ли элементы в окне списка отсортированы в алфавитномпорядке.

property Style: TListBoxStyle;Определяет стиль отображения окна списка. Это свойство может приниматьследующие значения:IbStandard - все элементы; это текстовые строки одинаковой высоты (поумолчанию);IbOwnerDraw Fixed — каждый элемент может быть как текстовой строкой, таки изображением, но все элементы имеют одинаковую высоту, определяемуюсвойством ItemHeight;

IbOwnerDrawVariable - каждый элемент может быть как текстовой строкой,так и изображением, и все элементы могут иметь различную высоту.

Для показа самоотображаемых списков следует ввести код для следующихобработчиков событий:OnDrawItem -для списка стиля IbOwnerDrawFixed;

OnMeasureltem и OnDntwItem -для списка стиля IbOwnerDrawVariable.

property Toplndex: Integer;Номер элемента списка, отображаемого первым в окне списка.

Класс TListBox наследует ряд свойств, включая свойства от класса TWinControli

Brush ControlCount Controls

QI3D DockClientCount DockClients

HelpContext ParentWindow Showing

TabOrder TabStop VisibleDockClientCount

и свойства от класса TControl:Action Align BoundsRect

ClientHeight ClientWidth ColorControlState ControlStyle Cursor

DockOrientation DragCursor DragKind

Page 198: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

198 Глава 5

DnigModeFontLeftParentColorPopupMenuVisible

EnabledHeightNameParentFomShowHintWidth

FloatingHintParentParentShowHinlTop

Методы:

function ItemAtPosfPos: TPoint; Existing: Boolean): Integer;Возвращает номер элемента, указанного координатой TPoint. Получить зна-чение координаты при нажатии клавиши мыши можно, например, в обработ-чике события OnMouseUp.

function ItemRectdtem: Integer): TRect;Возвращает координаты прямоугольной области, в которой расположен ука-занный параметром Item элемент списка.

procedure Invalidate; override;Сообщает Windows о необходимости перерисовки элемента управления.

Для класса TListBox предусмотрены следующие обработчики событий:

OnDrawItem, OnMeasureliem. OnEnter, OnEx.it, OnKeyDown, OnKeyPress,OnKeyUp, OnClick, OnConlextPopup, OnDblClick, OnDragDrop, OnDragOver,OnEndDock, OnEndDrag. OnMouseDown, OnMouseMove, OnMouseUp,OnStartDock, OnStartDrag.

Класс TComboBoxРасположен в модуле stdctr ls

Класс TComboBox реализует поведение комбинированного списка, состоящегоиз поля редактирования и прокручиваемого списка. Визуально список присты-ковывается к полю редактирования и в зависимости от выбранного стиля можетотображаться как ниспадающий ^drop-down) список или постоянно видимый.Выбранный элемент списка немедленно отображается в поле редактирования.Пользователь может иметь возможность модифицировать текущий элемент не-посредственно в поле редактирования или, используя методы работы с объекта-ми типа TList, добавлять новые элементы.

Свойства:

property CharCase: TEditCharCase;Определяет, будет ли текст преобразовываться в строчные или прописныебуквы. Данное свойство определяется как типtype TEditCharCase=(ecNormal,ecUpperCase,ecLowerCase);и может принимать следующие значения:

Page 199: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 1 99

ecLowerCase- преобразование в строчные буквы;ecNormul - преобразования нет (по умолчанию);ecUpperCase - преобразование к прописные буквы.

property DropDownCount: Integer;Определяет максимальное количество элементов, отображаемых в ниспа-дающем списке. Если элементов в списке больше, чем указано в данномсвойстве, то ниспадающий список будет содержать горизонтальную линейкупрокрутки

property DroppedDown: Boolean;Указывает, отображаем ли в данный момент ниспадающий список. Это свой-ство не имеет смысла для списка стиля csSimple (всегда видим).

property ItemHeight: Integer;Определяет высоту (в пикселях) элементов списка.

property Itemlndex: Integer;Указывает номер выделенного элемента списка. Если выделенного элементапет, то значение свойства равно — 1.

property Items: TStrings;Содержит массив элементов списка - отображаемых строк текста.

property MaxLength: Integer;Определяет максимальное количество символов, которые пользователь мо-жет ввести в поле редактирования комбинированного списка. Если значениесвойства равно 0, то длина строки не ограничена.

property SelLength: Integer;Указывает количество символов в выделенном фрагменте текста внутри поляредактирования комбинированного списка.

property SelStart: Integer;Указывает номер первого символа (начиная с 0) выделенного фрагмента тек-ста внутри поля редактирования комбинированного списка.

property SelText: string;Содержит выделенный фрагмент текста.

property Sorted: Boolean;Определяет, будут ли элементы списка отсортированы в алфавитном порядке.Если список сортируемый, то добавляемые элементы будут также вставлять-ся соответственно отсортированному порядку.

Page 200: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

200 Глава 5

property Style: TComboBoxStyle;Определяет стиль отображения комбинированного списка. Свойство можетуказываться следующими значениями:csDropDown - все элементы являются строками одинаковой высоты, в полередактирования можно модифицировать выделенный элемент списка;csSimple — поле редактирования и список постоянно видимы, высота комби-нированного списка определяется свойством Height, в поле редактированияможно вводить новые значения (но заносить в список их следует в обработ-чике события), все элементы являются строками одинаковой высоты;csDropDownList - все элементы являются строками одинаковой высоты, в по-ле редактирования нельзя модифицировать выделенный элемент списка;csOwnerDrawFixed - самоотображаемый ниспадающий список, в поле редак-тирования можно вводить текст, высота каждого элемента списка определя-ется свойством ItemHeight;csOwnerDrawVariable - самоотображаемый ниспадающий список, в поле ре-дактирования можно вводить текст, высота каждого элемента списка можетбыть различна.Отметим, что для самоотображаемых списков следует ввести код для обра-ботчиков событий OnDrawItem и/или OnMeasureltem.

Для класса TComboBox предусмотрены следующие обработчики событий:OnChange, OnDrawItem, OnDropDown, OnMeasureltem, OnEnter, OnExit,OnKeyDown, OnKeyPress, OnKeyUp, OnEndDock, OnClick, OnContextPopup,OnDblClick, OnDragDrop, OnDragOver, OnEndDrag, OnStartDock, OnStartDrag.

Класс T C h e c k L i s t B o xРасположен в модуле checklst

Класс TCheckListBox инкапсулирует поведение списка, элементами которогоявляются флажки.

Свойства:

property AIlowGrayed: Boolean;Определяет, может ли флажок отображать состояние «частичное включение»,которое отображается галочкой на сером фоне.Если значение свойства равно False (по умолчанию), то каждый флажок (эле-мент списка) может принимать только два состояния: установлен и снят(иногда также эти состояния называют включен и выключен).Если значение свойства равно True, то любой флажок может принимать трисостояния: частичное включение (cbGrayed), снят (cbUnchecked), установлен(cbChecked).

property Checked[lndex: Integer]: Boolean;Определяет состояние каждого флажка списка.

Page 201: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 201

property Stateflndex: Integer]: TCheckBoxState;Указывает состояние каждого флажка списка. Оно может быть определеноодним из следующих трех, значений: cbUnchecked, cbChecked, cbGrayed.

property Flat: Boolean;Определяет, будет ли компонент типа TCheckBox появляться объемным илиплоским.

property ltemEnabled[Index: Integer]: Boolean;Указывает, доступен или нет каждый элемент списка.

property HelpContext: THelpContext;Указывает ID контекста справки, определяющего отображаемую при нажатииклавиши F1 тему файла справки.

property Action: TBasicAction;Имя объекта Action, ассоциируемого с данным элементом управления.

Для списка типа TCheckListBox используются те же методы, что и для спискатипа TListBox. .

Класс TreeViewРасположен в модуле comctrls

Класс TTreeView реализует окно списка, отображающее иерархический списокэлементов. Это может быть дерево каталогов и файлов, содержание документаили иерархический предметный указатель.

Список представляется как иерархия узлов (node). Каждый узел дерева состоитиз метки и номера изображения (необязательного). Каждый узел может содер-жать ассоциируемый с ним список подузлов. По щелчку мыши пользовательможет разворачивать или сворачивать список подузлов.

Свойства:

property AutoExpand: Boolean;Определяет, будут ли узлы автоматически сворачиваться или развора-чиваться при выделении.

property BorderStyle: TBorderStyleTBorderStyle;Определяет стиль рамки вокруг элемента управления (bsNone, bsSingle).

property DragMode: TDragMode;Определяет, разрешен ли режим автоматического переноса и сброса узловсписка. Свойство может задаваться следующими значениями: dmAutomatic,dmManual.

Page 202: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

202 Глава 5

property Images: TCustomlmageList;Определяет список изображений, ассоциируемый с компонентом типаTTreeView. Изображения показываются слева от метки узла.

Для того чтобы npoipa.MMHO добавить в список изображения, можно исполь-зовать функцию function Add(Image, Mask : TBi tmap) : Integer;.

property Items: TTreeNodes;Содержит список узлов компонента типа TTreeView.

Каждый отдельный узел - это объект типа TTreeMode.

Для того чтобы указать третий элемент списка, можно записать кодMyTreeNode := T r e e V i e w l . I t e m s [ 2 ] ; .

Во время проектирования узлы создаются в инспекторе объектов редактиро-ванием значения свойства Items. Во время выполнения работа с узлами вы-полняется следующими методами класса TTreeNodes: AddChildFirst,AddChild, AddChildQbjectFirst , AddChildObject, AddFirst, Add,AddObjectFirst, AddObject и Insert.

property Selected: TTrccNode;Указывает текущий выделенный узел. Если выделенного узла нет, то зна-чение свойства равно n i l .

Класс TComboBoxExНа странице Win32 палитры компонентов расположен класс TComboBoxEx. реали-зующий ниспадающий список с более широкой функциональностью, включаю-щей отображение пиктограмм в содержании списка.

j Для того чтобы использовать компонент класса TcomboBoxEx, выполните'• слеДующие действия:

1. Расположите в окне формы компонент TComboBoxEx.

2. Расположите в окне формы компонент TImageList. Этот компонент будетсодержать список пиктограмм, отображаемых в списке ComboBoxExl.

5. Вызовите редактор компонента TlraageList. Для этого выполните для негокоманду контекстного меню ImageList Editor. Добавьте в этом редакторенужное число пиктограмм.

4. Свяжите компонент ComboBoxExl со списком изображений ImageList 1.Для этого установите значение свойства Images объекта ComboBoxExlравным ImageList 1, выбрав это значение из предлагаемого списка.

5. Добавьте элементы списка. Для этого щелкните на кнопке справа от свой-ства LineEx (рис. 5.7). Для добавления элемента списка достаточно щелк-нуть по кнопке Add New панели инструментов диалога EditingComboBoxExl.ItemsEx. Добавленный элемент сразу отображается в окне де-рева объектов.

Page 203: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 203

Adftoul VAi32|s«teni1 DalaAc»i!J DaaCcrtiolsl dbE.Bess] DataSnao] BDE | AUO ] IntaBaie 1 WebSwvicss! InteinttExDfet:'~

= 3 Соп*нВш£<1

«5 0- Строка!. «1 1 - TComtoEnltera:-ilJ 2-TComboExlleni

ImageLJstl

I Ctxnbt£o*EKl 3 „j

Imagalnds.Indent i-1

AJvhown

^ SysUtils, Variants,

i Dialogs, StdCtrls, ContCcrla, ImgList;

type

(TForffl)

31 1 'MtuMied Jniat

Рис, 5,7. Диалог Editing для добавления элементов списка компонентаTComboBoxEx

6. Для добавленного элемента списка надо задать текст заголовка - значениесвойства Caption и выбрать отображаемую пиктограмму — значение свой-ства Imagelndex. Свойство Imagelndex будет отображать список пикто-грамм, добавленных для объекта ImageListl, связанного с объектом нис-падающий список ComboBoxExl.

Свойства:

property DropDownCount: Integer;Устанавливает максимальное число строк списка, одновременно отображае-мых в ниспадающем списке. Если общее число элементов списка больше, чемуказано в данном свойстве, то остальные элементы будут доступны при по-мощи линейки прокрутки.

property Images: TCustomlmageUst;Устанавливает связь с объектом, содержащим список изображений, исполь-зуемый элементами списка. Каждый элемент списка связывается с отдельнымизображением через его индекс. Индекс изображения указывается свойствомImagelndex элемента списка.

property SelText: string;Содержит выделенный фрагмент текста в поле редактирования ниспадающе-го списка.

Page 204: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

204 Глава 5

property Style: TComboBoxExStyle;Определяет стиль ниспадающего списка. Свойство Style может приниматьследующие значения:CsExDropDown - ниспадающий список имеет поле редактирования (поле дляввода текста);CsExSimpie - создастся список с полем редактирования фиксированного раз-мера;csExDropDownList - ниспадающий список без поля редактирования.

Класс TValueListEditorРасположен в модуле ValEdi t

Класс ValueListEditor расположен на странице Additional палитры компонен-тов и реализует окно списка, содержащее пары имя/значение. Визуально компо-нент ValueListEditcr состоит из двух столбцов: в первом содержатся имена, аво втором - соответствующие им значения. При этом каждое значение второгостолбца может быть представлено как одним значением в отдельной ячейке, таки значением выбираемым, из ниспадающего списка значений.

Свойства:

property CelIs[ACol, ARow: Integer]: string;Список строк для каждой ячейки компонента ValueListEditor.

Параметры ACol и ARow указывают номер столбца и строки ячейки (начинаяс 0). Для доступа к элементам столбца с названиями элементов можно ис-пользовать свойство Keys. Для доступа к элементам столбца со значениямиэлементов можно использовать свойство Values.

property TitleCaptions: TStrings;Свойство TitleCaptions содержит две строки, используемые как заголовкистолбцов: первая строка — это заголовок первого столбца, вторая строка — заго-ловок второго столбца. По умолчанию заголовок первого столбца - Key,а второго - Value. Используя составное свойство DisplayOptions, можно управ-лять отображением строки заголовков компонента ValueListEditor: вложенноесвойство doColumnTitles определяет, будет ли отображена строка заголовков.

property Strings: TStrings;Содержание элементов списка ValueListEditor. Для того чтобы ввести значе-ния в список, выполните двойной щелчок мышью на кнопке [ГГ.], расположен-ной слева от значения свойства Strings в инспекторе объектов. Первую парузначений можно ввести непосредственнно в диалоге Value List editor (рис. 5.8).Для дальнейшего редактирования следует перейти в окно редактора, выпол-нив щелчок на кнопке Code Editor. Пары значений указываются в отдельныхстроках как:значение_первого столбца_Кеуз=значение_второго столбца.,values (рис. 5.9).

Page 205: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 205

7 value list editor

key 1 strng 1|

'

OK Cancel

Рис. 5.8. Диалог Value List editor для определения пар значении

Закрыть окно редактора свойства String можно, как и любой другой откры-тый документ, выполнением команды контекстного меню Close Page.

Ё Forml.ValueUsteditorl .Strings- • xl

-" 1 llMhUFM

-!n[x|Fotml.ValueListEditoiT. Strings ^ , nf -

key l=s t ring 1

key 2 =stt:ing 2

kevj 3 «string 3.

_iLI3: 4 Modifie

A

-

TJ

j Insert

Рис. 5.9. Окно редактора со страниией редактора свойства String

property KeyOptions: TKeyOptions;Это составное свойство, позволяющее определить, какие действия можновыполнять над значениями первого столбца (Key).Составное свойство KeyOptions включает четыре вложенных свойства, опре-деляемых следующим шпом:Туре

TKeyOption = (keyEd.it, keyAdd, keyDelete, keyUnique) ;TKeyOptions = set of TDisplayOption;

Если значение свойства keyEdit установлено равным True, то названиев столбце Key можно редактировать. Для того чтобы иметь возможность до-бавлять или удалять значения в столбце Key, следует установить равным Trueзначение свойств keyAdd или keyDelete соответственно.

Page 206: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

206 Глава 5

property ltemProps[const KeyOrlndex: Variant]: TltemProp;Определяет ограничения на то. как пользователь может вводить значение длякаждого элемента списка.

Свойство ItemProps позволяет для каждого элемента указать следующие ог-раничения:

• можно ли редактировать элемент;

« максимальная длина строки для вводимого пользователем значения;

•- маска ввода, ограничивающая вид вводимого значения;

• разрешен ли выбор значения из ниспадающего списка или отображение диа-лога для ввода значения;

• фиксированный набор значений для элемента, использующего ниспадающийсписок для выбора значения.

Для того чтобы значение элемента списка компонента ValueListEditor мож-но было выбирать из предлагаемого ниспадающего списка значений, следуетустановить соответствующий режим каждому элементу списка: свойствоEditStyle элемента списка должно быть равным esPickList. Если установ-лен режим esPickList, то в поле значения элемента будет отображатьсястрелка для открытия окна ниспадающего списка.

Пример:

procedure TForml.FormCreate(Sender: TObject);begin

{Режим ниспадающего списка устанавливается для второгоэлемента списка}

ValueListEditorl. ItemProps [1].EditStyle:=esPickLisL,-{Список значиний элемента в ниспадающем списке}

ValueListEditor l . I temProps[I] .PickList .add( '10 ' ) ;ValueListEditorl .ItemProps[1].PickList .add[ '20');ValueListEditor l .I temProps[1] .PickList .add( '30 ' I ;end;

Свойство ItemProps позволяет ссылаться на элементы списка и определять ре-жим работы с ними (элементы списка индексируются, начиная с 0). СвойствоEditStyle класса TltemProp устанавливает режим редактирования значения эле-мента списка ValueListEditor.

Свойство PickList класса TltemProp содержит список предлагаемых значенийкак значение типа TStrings. Для того чтобы добавить элемент в такой списокиспользуется метод add.

property Row: Longint;Определяет индекс строки, содержащей текущий элемент. Это свойствонаследовано от класса TCustomGrid.

Page 207: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi —VCL 207

Для того чтобы записать в компонент типа TEdit выбранное значение теку-щего элемента списка, следует в обработчике события OnClick получить зна-чение элемента и преобразовать его в строку.Если редактирование значений столба Key компонента ValueListEditor неразрешено, то событие OnClick будет возникать только при щелчке пользова-теля на значении элемента списка. Событие OnClick является стандартнымсобытием для данного компонента, и, следовательно, обработчик событиясоздается по двойному щелчку мышью на компоненте.

property Keysflndex: Integer]: string;Содержит массив названий элементов списка.

property Values[const Key: string]: string;Содержит массив значений элементов списка.

Пример:

procedure TForml.ValueListEditorlClick(Sender: TObject);begin

{Номер текущего элемента списка}Editl .Text:=IntToStr(ValueListEditorl.Row) ;(Название текущего элемента списка}Edit2.Text:= ValueListEditorl.Keys[ValueListEditorl.Row] ;(Значение текущего элемента списка)Edit3.Text:=ValueListEditorl.Values(ValueListEditorl.Keys[ValueListEditorl.Row]];end;

На рис. 5.10 приведена форма, содержащая компонент TValueLisiEditor и три поляввода, значения которых формируются как показано в предыдущем примере.

х]

Ksy

и •key 2

Kty 3

Value

string 1

20

ttiing 3Jd

[20

Рис. 5.10. Использование компонента TValueListEditor

Page 208: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

208 Глава 5

КЛАССЫ ПАНЕЛЕЙ ИНСТРУМЕНТОВСтраница Win32 палитры компонентов содержит два класса, позволяющих соз-давать панели инструментов: TToolBar и TCoolBar.

Класс T T o o l B a rРасположен в модуле comctrls

Класс TToolBar реализует стандартную панель инструментов, содержащую кноп-ки. Такая панель может быть встроена в окно формы или перемещаться как са-мостоятельное окно.Очень часто создают панели инструментов с кнопками, соответствующими ко-мандам меню. Для того чтобы обеспечить выполнение кнопками панели инст-рументов тех же действий, что и командами меню, достаточно установить зна-чение свойства Menultem, выбрав из предлагаемого списка соответствующийидентификатор компонента типа TMenuItem (пункт меню).

Класс TToolBar - это контейнер, в котором могут быть расположены как обыч-ные компоненты Delphi, так и специально предназначенные для данного кон-тейнера кнопки типа TToolButton.

Все кнопки панели инструментов TToolButton автоматически создаются одина-кового размера. Для того чтобы добавить на панель новую кнопку или раздели-тель, достаточно вызвать контекстное меню панели инструментов и выполнитьсоответственно команды New Button или New Separator.Для того чтобы на кнопках были отображены пиктограммы, можно использо-вать объект типа TImageList (список изображений), разместив его на форме.Этот компонент находится на странице Win32 палитры компонентов. Двойнымщелчком мыши на компоненте TImageList следует вызвать редактор списка изо-бражений (рис. 5.11).

огпИ ImogeLisll ImageList

" Selected 1 mage •IiorispdierilCului,

I'j JL jclFuchsia

1 *Lr^ I' 1 , - _-J

г Image*—

О» в ttf

6 [61 4

4| ' i

Add.. | Delete | Clear1

в. fit

Options urv

P DSP CancelSire с ,

f~ Cflntei 1 Acply

НЫр

EHport... .

Рис. 5.11. Редактор списка изображении компонента TImageList

Page 209: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 209

Затем добавить в нем пиктограммы для каждой кнопки в порядке их расположе-ния в списке свойства Buttons (в порядке первоначального расположения на па-нели инструментов).

На нижней панели редактора списка изображений с помощью «перетаскивания»пиктограмм мышью можно изменять порядок изображений в списке.Имя объекта TImageList будет доступно в списке значений свойства Image ком-понента TToolBar.

На рис. 5.12 приведен внешний вид'окна формы, содержащего панель инстру-ментов и компонент TImageList.

Панель инструментов имеет восемь кнопок и два компонента (TListBox и TEdit).В списке изображений TImageList указано семь пиктограмм, которые и отобра-жаются на кнопках.

g-Forml

шэИ"; С:;мЬ:.Во>:1 J^j!^'1

Рис. 5.12. Форма с компонентами TToolBar и TImageList

Свойства:

(только для ЧТЕНИЯ!property ButtonCount: Integer;Указывает количество кнопок в контейнере TToolBar.

property Buttons[lndex: Integer]: TToolButton;Содержит список кнопок контейнера TToolBar.

(только для ЧТЕНИЯ)

property Disabledlmages: TCustomlmageList;Содержит список изображений, которые будут появляться на недоступныхкнопках. Если это свойство не определено, то недоступная кнопка будет ото-бражаться посеревшей.

property Hotlmages: TCustomlmageList;Содержит список изображений, которые будут появляться на кнопках припозиционировании на них курсора мыши.

property Images: TCustomlmageList;Содержит список изображений, отображаемых на кнопках.

property Indent: Integer;Определяет размер отступа для расположения первой кнопки панели инст-рументов.

Page 210: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

210 Глава 5

property Flat: Boolean;Определяет, будут ли кнопки отображаться без рамок и плоскими. В этомрежиме кнопка становится объемной и с рамкой только при позиционирова-нии над ней курсора мыши. Все панели инструментов Delphi функционируютв данном режиме.

property ShowCaptions: Boolean;Определяет, будут ли одновременно с пиктограммами отображаться заголов-ки кнопок, содержащиеся в свойстве Caption каждой кнопки. По умолчаниюзначение свойства равно False - заголовки не отображать.

property Wrapable: Boolean;Позволяет кнопкам панели инструментов автоматически располагаться в не-сколько рядов, если они не умещаются в один ряд окна формы.

Класс TToolButtonРасположен в модуле c o m c t r l s

Класс TToolButton реализует кнопки панели инструментов TToolBar.

Свойства: 1

property AHowAllUp: Boolean;Определяет, могут ли все кнопки группы быть одновременно ненажаты.

property DropdownMenu: TPopupMenu;Определяет для кнопки контекстное меню - объект типа TPopupMenu (рис. 5.13).

Файл Выход

Печать в Файл

Печать на сетевой принтер

Печать на локальный принтер

Рис. 5.1 3. Контекстное меню для кнопки Печать панели инструментов

property Grouped: Boolean;Позволяет объединять неразделенную последовательность кнопок в группу.Если для кнопок группы, имеющих стиль tbsCheck. установить значениесвойства Grouped, равное True, то эти кнопки будут взаимно исключающими:одновременно может быть нажата только одна кнопка группы.В качестве разделителя для группы может служить:

• любая кнопка со значением свойства Grouped, равным False;

Page 211: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 211

* кнопка со значением свойства Style, неравным tbsCheck;

* кнопки-разделители: tpsSeparator и tbsDivider;

* другие элементы управления, расположенные на панели инструментов.

property Imagelndex: Tlmagelndex;Определяет номер изображения (начиная с 0) из списка свойства Image пане-ли инструментов. Если кнопка не содержит изображения, то значение свойст-ва Iraagelndex равно - 1.

property Index: Integer; (только для ЧТЕНИЯ}Определяет номер кнопки в свойстве Buttons панели инструментов.

property Marked: Boolean;Определяет, отмечена ли кнопка. Отмеченные кнопки имеют синеватое зате-нение.

property Menultem: TMcnultem;Указывает пункт меню, соответствующий кнопке.

property Style: TToolButtonStyle;Определяет стиль кнопки. Значение свойства Style выбирается из предлагае-мого списка, содержащего следующие константы:

ibsBiitton - кнопка функционирует аналогично кнопке типа TSpeedButton;

tbsCheck — кнопка имеет два состояния: нажата и ненажата;

tbsDropDown - кнопка содержит изображение стрелки вниз, при щелчкена которой может быть распахнуто меню, указанное в свойстве Menultem;

rbsSeparmor - кнопка играет роль разделителя и отображается пустымпромежутком;

rbsDivider - кнопка играет роль разделителя и отображается вертикальнойлинией.

Класс T C o o l B a rКласс TCoolBar позволяет создавать наборы панелей инструментов. Внутри на-бора панели можно перемещать, а также сворачивать и разворачивать.

Компонент типа TCoolBar является контейнером объектов типа TCoolBand (па-нель). В каждом таком объекте в свою очередь могут быть размещены другиекомпоненты из палитры инструментов. Наиболее частым вариантом размещае-мого компонента выступает объект типа TToolBar, который в свою очередь так-же содержит кнопки и компоненты.iffff-f,

Процесс создания набора панелей состоит из следующих шагов:

I. Расположить в форме компонент типа TCoolBar.

Page 212: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

212 Глава 5

2. Двойным щелчком мыши или через контекстное меню вызвать редакторпанелей (рис. 5.14) и добавить в нем объекты типа TCoolBand (панели).

Г Editing CoolBari .Bands

сзО-TCoolBand1 • TCoolBand2-TCoolBand

Рис. 5.14. Редактор панелей

5. Расположить в форме компоненты, которые будут размещены на этих па-нелях: по одному компоненту на панель. Размещаемый компонент выби-рается из предлагаемого списка свойства Control.

4. Выбрать в редакторе панелей имя редактируемой панели н настроить еесвойства в инспекторе объектов (рис. 5.15). Отметим, что при закрытом ре-дакторе панелей объекты типа TCoolBand в инспекторе объектов недоступны.

Object Inspector

Coo!Bar1.Bands[2]

Properties j Events]

Bitmap

В order Style

Break

Color

Control

FixedBackgroundFixedSIze

Horizontal Only

ImageindexMinH eight

MinWidlhParentB itmap

ParentColor

Text

Visible

Width

All shown

21

J

(None)

bsNone

TrueDclBtnFsce

1ЛТП1ЛЛ11 J-J

TrueFalse

False

-125

0True

True

True

792

A

Рис. 5Л5.Инспектор обьектовдля компонента TCoolBand

Свойство Bands содержит список всех дочерних панелей компонента ТСооШаг.

Page 213: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 213

Класс TControlBarРасположен в модуле Extctr ls

Класс TControlBar предназначен для управления расположением панелей. Этовстроенный в форму контейнер, в который могут быть помещены различныедочерние компоненты. Однако в основном это объекты типа TToolBar.

Компонент TControlBar называется менеджером компоновки и находится настранице Additional палитры инструментов.

На рис. 5.16 показана форма, содержащая панель типа TControlBar, на которойрасположены четыре дочерние панели: два объекта типа TEdit, объект типаTToolBar и объект типа TComboBox.

Файл Выход

EdilS Edill

: ComboBoxl

Рис. 5.16. Форма, содержашая компонент типа TControlBar

КЛАССЫ ДЛЯ ТАБЛИЧНОГО ОТОБРАЖЕНИЯ

ДАННЫХСтраница Additional палитры инструментов содержит два класса для табличногоотображения данных: TStringGrid и TDrawGrid.

Класс TStringGridРасположен в модуле grids

Класс TStringGrid реализует объект таблица, состоящий из строк (рядов)и столбцов. Он предоставляет множество свойств и методов для управлениявнешним видом таблицы и ее функционирования, а также реализует ряд обра-ботчиков событий, специфичных для компонента таблица.

Компонент TStringGrid позволяет отображать и редактировать строки текстав отдельных ячейках. С каждой ячейкой может быть связана строка и назначен-ный для нее объект.

На рис. 5.11 показана форма, содержащая компонент типа TStringGrid.

Page 214: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

214 Глава 5

В Form!

Столбец!

Название!

Название2

Столбец2 Столбеи.3 Столбец4

Кш1 1234 12-12-33

Рис. 5.1 7. Форма с компонентом типа TStringGrid

Свойства:

property Cells[ACol, ARow: Integer]: string;Содержит список строк для всех ячеек таблицы.Свойство Cells реализуется массивом строк, первая размерность которогосоответствует номеру столбца (начиная с 0), а вторая размерность — номерустроки (начиная с 0).Количество столбцов и строк определяются в свойствах ColCount и RowCount.

Для того чтобы иметь доступ к объектам, ассоциируемым со строкамив массиве Cells, следует использовать свойство Objects.

Пример:

{Цикл для заполнения элементов таблицы индексами элементов массива)

procedure TForml.ButtonlClick(Sender: TObject);

varI, J: Integer;

begin

with StringGridl do

begin{Заполнение первой строки!for I := 0 to ColCount - 1 do

Cells[I,0] := 'Столбец Ч IntToStr(I);(Заполнение элементов массива, начиная со

второй строки второго столбца}

for I := 1 to ColCount - 1 do

for J:= 1 to RowCount - 1 dobegin

Cells[I,J] := IntToStr(I)-r ' , ' +

IntToStr(J);end;

end;end;

Page 215: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 215

Результат выполнения приведенной выше процедуры обработки события OnClick,заполняющей строковыми значениями ячейки таблицы, приведен на рис. 5.18.

1. Г Form! ИНЕП

Столбец 0

iLJЗаполнить т

Столбец 1 Ст

1.1 \2,

1.2 2,

1.3 2,

1,4 2,

абшцу

элбец 2 Столбец 3

1 3,1

2 3.2

3 3.3

4 3.4

Столбец 4 *

4.1

4 , 2

4 , 3

4,4 Н

Рис. 5.1 8. Таблица типа TStringGrkf, заполненная индексами элементовмассива Cells

property Cols[lndex: Integer]: TStrings;Содержит для каждого столбца таблицы список строк и ассоциированных имобъектов.

property Rows[lndex: Integer]: TStrings;Содержит для каждого ряда таблицы список строк и ассоциированных имобъектов.Для того чтобы заполнить компонент типа TListBox элементами из текущегоряда таблицы, можно, например, записать следующий код:

ListBoxl.Items := StringGridl.Rows[StringGridl.Row];(Или, что абсолютно эквивалентно:)for I := 0 tc StringGridl.ColCount-1 do

ListBoxl.Items[I] :=StringGridl.Rows[StringGridl.Row].Strings[I];

В результате список ListBoxJ будет содержать количество элементовColCount-1 и каждый элемент будет равен содержимому ячейки текущейстроки таблицы (рис. 5.19).

StringGridl.Row содержит номер текущей строки, а свойство Strings позво-ляет отображаться конкретным строкам из массива Rows.

property Objects [ACol, ARow: Integer]: TObject;Содержит массив объектов, ассоциированных с каждой ячейкой таблицы.Первоначально этот массив для каждой ячейки содержит значение nil.Это свойство можно использовать, чтобы назначить ячейкам таблицы ассо-циированные объекты, которые будут существовать и после разрушения са-мого объекта TStringGrid.

Page 216: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

216 Глава 5

^ •>f'Foiral

Столбец 0 Столбец 1

1 ,1

1 ,2

1 ,3

1 ,4

Заполнить таблицу

Столбец 2 Столбец 3 Столбец 4 Список ListBox!

Щ|||3.1 4,1

3,2 4 , 2 ЩШНННН2,3 3 , 3 4.3 1,1

2 , 4 3 , 4 4 , 4

Рис. 5.19. Таблииа типа TStringGrid

Далее опишем свойства, наследуемые от класса TCustomGrid и являющиеся об-щими и для класса TstringGrid, и для класса TDrawGrid.

property BorderStyle: TBorderStyle;Может принимать значения bsSingle или bsNone и определяет, будет ли таб-лица заключена в рамку.

property Col: Longint;property Row: Longint;

Эти свойства определяют номер столбца и номер строки, в которых располо-жена выделенная ячейка таблицы.Для перемещения фокуса между ячейками таблицы достаточно изменитьзначение этих свойств.

property ColCount: Longint;property RowCount: Longint;

Эти свойства указывают количество столбцов и строк в таблице.

property ColWidths[lndex: Longint]: Integer;Содержит массив значений, определяющих ширину (в пикселях) каждогостолбца таблицы. Первоначально по умолчанию для всех столбцов использу-ется значение ширины, определяемое свойством DefaultColWidth.Количество элементов массива ColWidihs равно ColCount-1.

property RowHeights[lndex: Longint]: Integer;Содержит массив значений, определяющих высоту (в пикселях) каждой стро-ки таблицы. Первоначально но умолчанию для всех строк используется зна-чение высоть(, определяемое свойством DefauItRowHeight.

property EditorMode: Boolean;Определяет, можно ли редактировать текущую ячейку таблицы.Отметим, что это не влияет на значение свойства Options.

Page 217: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 21 7

property FixedCols: Integer;Определяет количество столбцов, расположенных слева в таблице, которыевходят в непрокручиваемую область таблицы.Это свойство позволяет указать столбцы таблицы, которые всегда будут ви-димыми.Отметим, что таблица должна включать по крайней мере один непрокручи-ваемый столбец.

property FixedRows: Integer;Определяет количество строк, расположенных в таблице сверху, которыевходят в непрокручиваемую область таблицы.Отметим, что таблица должна включать по крайней мере одну непрокручи-ваемую строку (например, для заголовков столбцов).

property FixedColor: TColor;Определяет цвет фона для непрокручиваемой области таблицы.Отметим, что цвет фона прокручиваемой области таблицы определяетсясвойством Color.

property Options: TGridOptions;Определяет внешний вид и режим функционирования таблицы.Это свойство является составным. Для него могут быть установлены равны-ми True или False следующие вложенные свойства:goFixedVertLine - отображать вертикальные линии, разделяющие непрокру-чиваемую область таблицы;goFixedHoreLine - отображать горизонтальные линии, разделяющие непро-кручиваемую область таблицы:goVertLine - отображать вертикальные л и н и и для прокручиваемой областитаблицы;goHorzLine - отображать горизонтальные л и н и и для прокручиваемой облас-ти таблицы;goRangeSelect — разрешено одновременное выделение диапазона ячеек, ноигнорируется, если значение свойства goEditing равно True;goDrawFocusSelected - ячейка, имеющая фокус ввода, отображается специ-альным цветом выделения; если значение свойства равно False, то ячейка,имеющая фокус ввода, выделяется прямоугольной рамкой;goRowSizing - разрешено изменение размеров прокручиваемых строк;goColSizing - разрешено изменение размеров прокручиваемых столбцов;goRowMoving - разрешено перемещение строк мышью;goColMoving - разрешено перемещение столбцов мышью;goEditing - разрешено редактирование ячеек таблицы;goTabs -для перемещения между ячейками пользователь может употреблятьклавиши Tab и Shift+Tab;

Page 218: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

218 Глава 5

goRowSelect - выполняется выделение всего ряда;

goAlwaysShowEditor - таблица функционирует в режиме редактирования, ес-ли установлено свойство goEditing;

goThumbTracking - обновление таблицы с изображениями выполняется впроцессе ее прокрутки; если значение этого свойства равно False, то обнов-ление будет выполняться только но завершении прокрутки.

property ScrolIBars: TScrollStyle;Определяет, будет ли таблица иметь горизонтальную и вертикальную линей-ки прокрутки.

property Selection: TGridRect;Определяет границы текущего выделения или устанавливает новое выделение.

Тип TGridRect определяется как

type TGridRect = recordcase Integer of

0: (Left, Top, Right, Bottom: Longint);1: (TopLeft, BoUomRight: TGridCoord) ;

end;

Пример:

(Выделение диапазона: столбцы 2-3, а строки 1-5}

var myRectl: TGridRect;

begin

myRectl.Left := 2; {Номер столбца}myRectl.Top := 1; {Номер строки}myRectl .Right := 3;myRectl.Bottom := 5;

{Или, что эквивалентно:}myRect l .TopLeft .X := 2;myRectl .TopLeft .Y:=1 ;myRectl. BottomRight.X :=3;myRectl. BottomRight.Y :=5;

{Выполняем вьщеление:1StringGridl.Selection := myRectl;

end;

property TopRow: Longint;Определяет номер первой видимой строки таблицы.

Для класса TStringGrid предусмотрены следующие обработчики событий:

OnColumnMoved OnDruwCell OnGetEditMask

OnGetEditText OnRowMoved OnSelectCell

OnSetEditText OnTopLeftChanged OnEnter

Page 219: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL

КЛАСС СТРОКИ состояния

219

OnExit

OnKeyUp

OnDblClick

OnEndDrag

OnMouseUp

On Key Down

OnClick

OnDragDrop

OnMouseDown

OnStariDrag

OnKeyPress

OnCoruextPopup

OnDragOver

OnMouseMove

Класс TStatusBarРасположен в модуле comctrls

Класс TStatusBar реализует строку состояния формата, используемого в Windows.

Этот компонент обычно размещается внизу окна формы. Панель состояния - этоконтейнер, содержащий отдельные панели, реализуемые компонентами типаTStatusPanel.

Для того чтобы добавить дочерние панели, следует из контекстного меню ком-понента (или по двойному щелчку мыши на компоненте) вызвать редактор па-нелей Editing Panels (рис. 5.20).

Редактор панелей позволяет не только добавлять новые панели, но и изменятьих свойства в инспекторе объектов, так как при закрытом редакторе панелей до-черние объекты компонента TStatusBar в инспекторе объектов недоступны.

После создания отдельных панелей можно определить, как они будут размеше-ны в строке состояния и что в них будет отображаться.

IjrEdilingSlalusBarl.Panels

П - TSlatusPanel1 -TStalLisPanel

Рис. 5.20. Редактор панелей для компонента типа TStatusBar

Для того чтобы программно создать строку состояния, можно ввести следую-щий код:

with TStatusBar.Create(Self) dcbegin

// Определение свойств строки состояния

Parent := Self;

SimplePanel := True;

Page 220: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

220 Глава 5

Свойства:

property AutoHinf: Boolean;Определяет, будет ли автоматически в строке состояния отображаться тексттекущей подсказки.

property Panels: TStatusPanels;Содержит список всех дочерних панелей TSiatusPanel для строки состояния.Например, для того чтобы определить текст, отображаемый на первой пане-ли, можно записать следующий код:

StatusBarl.Panels[0].Text:='Text for panel 1;

property SimplePanel: Boolean;Определяет, будет ли строка состояния функционировать в режиме простойпанели или в режиме набора панелей. Если значение свойства равно True, тодочерние панели не используются и строка состояния отображает текст,указанный свойством SimpleTexi.

Отметим, что режим функционирования строки состояния можно переклю-чать во время выполнения.

property SimpleText: string;Содержит строку, отображаемую в компоненте TStatusBar, если значениесвойства SimplePanei равно True.

"КЛАССЫ СТАНДАРТНЫХ ДИАЛОГОВСтраница Dialogs палитры компонентов содержит ряд компонентов, предназна-ченных для реализации различных стандартных диалогов. Это диалоги для от-крытия файла, сохранения файла, выбора цвета или шрифта, открытия или со-хранения графического файла. Более подробно все диалоги страницы Dialogsбыли описаны в главе "Объекты и компоненты".Для вызова любого размещенного в форме диалога используется функцияExecute. Если она возвращает значение True, то можно, используя свойства ком-понентов, определить сделанный пользователем выбор (например, полное имяфайла).

Пример:

var F: TextFile; S: string;begin

if OpenDialogl.Execute then {Показать диалог Open}begin

AssignFile(F, OpenDialogl.FileName]; {Назначить

файловей-леременной имя выбранного файла!Reset(F);

Page 221: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 221

Readin(F, S) ; {Прочитать первую строку файла}Editl.Text := S; (Поместить строку в компонент TEdit]CloseFi le(F); (Закрыть файл)

end;end;

ОБРАБОТКА СОБЫТИЙВсе приложения под Windows управляются через события. Для каждого компо-нента Delphi предусмотрены обработчики событий - методы, вызываемые дляреакции приложения на конкретное событие.

Delphi автоматически формирует имя обработчика события из имени объектаи названия события (без префикса On).

Список всех доступных для объекта событий отображается на вкладке Eventsинспектора объектов.

Напомним, что для того чтобы создать в окне кода программы новый обработ-чик события или перейти в уже существующий, достаточно выполнить двойнойщелчок мышью в поле имени обработчика события, справа от названия события.

На странице Events инспектора объектов отображаются имена всех обработчиковсобытия для конкретного объекта, в которые был введен какой-либо код.

Delphi автоматически вставляет пустую процедуру обработки события при соз-дании нового обработчика события.

При создании нового обработчика события OnChange из инспектора объектов(или при двойном щелчке на компоненте типа TEdit) в модуль будет добавленследующий код:

procedure TForml.Edit2 (Sender: TObject) ;.-:;:.. •

end;

Программисту требуется только записать код программы для обработки данногособытия внутри блока begin end.

Некоторые обработчики события предусматривают параметры, передаваемыев метод обработки события. В этом случае автоматически формируемая проце-дура обработки события будет содержать список этих параметров и их тип.

Отметим, что одни и те же события могут для различных компонентов реализо-вываться обработчиками событий с различными параметрами.Для того чтобы определить, какой компонент или компонент какого класса ини-циировал событие, можно использовать одну из следующих конструкций:

if Sender is TEdit {Определение класса компонента}then with (Sender as TEdit) do begin

end

Page 222: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

222 Глава 5

if ActiveControl is TEdit (Сравнение с классом

компонента}

if Sender=MenuIteml then ... {Сравнение с именем

else if Sender=MenuItem2 ihen ... компонента)

События от клавиатурыVCL-библиотека реализует три обработчика события, предназначаемых для кон-троля за вводом пользователя с клавиатуры:OnKeyDownOnKeyPress

OnKeyUp.

Эти события позволяют программировать последовательность действий, зави-сящую от нажатия любых клавиш или их комбинаций.

Пример:

procedure TForml.FormKeyDown[Sender: TObject;

var Key: Herd; Shift: TShiftStatel;

begin

{Проверка нажатия клавиш Alt+Ctrl]

if (shift - ([ssAlt, ssCtrl])) then forml.color := clAqua;

end;"

Каждое нажатие клавиши инициирует событие OnKeyDown, а затем OnKeyUp. Дляклавиш, имеющих ASCII-код (буквы, цифры и символы), также инициируетсясобытие OnKeyPress.

События от мышиВ VCL-библиотеке предопределено три обработчика события для действийс мышью:OnMouseDown - произошло нажатие кнопки мыши;

OnMouseMove — кнопка м ы ш и отпущена;

OnMouseUp- выполняется перемещение мыши.

Процедуры обработки этих событий используют следующие параметры:Sender-объект, для которого выполняются действия мыши;

Button - указывает нажатую кнопку мыши: mbLeft. mbMiddle или mbRight;Shift-указывает, были ли нажаты клавиши Alt, Ctrl и Shift;X. У - координаты точки, в которой произошло событие.

Пример:

(Отображение строки текста в том месте формы, в котором была нажата

кнопка мыши}

procedure TForml.ForrrMouseDown(Sender: TObjecr;

Page 223: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi - \ CI 223

Button: TMouseButton; S h i f t : TShiftState; X, Y: Integer);begin

Canvas.TextOut(X, Y, ' Т е к с т ' ) ;end;

В VCL-библпотеке предопределено два обработчика события для щелчков мы-шью:OnClick;OnDblClick.

Пример:

procedure TEditl.Click (Sender: TObject)

begin

[Определение компонента, инициировавшего событие)

if ActiveControl is TEdit then

TEdit(ActiveControl).SelectAll;

end;procedure TEdit2.Click (Sender: TObject)

begin

end;

События перемещения и сброса объектовОперации перемещения и сброса позволяют перемещать целые компоненты илиотдельные их элементы из одного компонента в другой.В VCL-библ и отеке предопределено четыре события для операций перемещенияи сброса объектов;

OnDragOver - перетаскиваемым объект находится над элементом управления, длякоторого инициировано событие;

OnDragDrop - выполнен сброс объекта: отпущена кнопка мыши;

OnStartDrag - начат процесс перемещения объекта: пользователь нажал и удер-живает левую кнопку мыши;

OnEndDrag - процесс перемещения и сброса объекта завершен.

Для того чтобы с помощью мыши можно было перемещать компонент, значениесвойства DtagMode должно быть равно dmAutoniaiic. В противном случае для за-пуска процесса перемещения объекта должен быть вызван метод BeginDrag(True).

Перемещение объектов мышью может быть выполнено только в том случае, ес-ли значение свойства DragKind равно dkDrag.

Компонент может принять сбрасываемый на него объект, только если в обра-ботчике события OnDragDrop > становлено Accept: =True;.

Page 224: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

224 Глава 5

Пример:{Создадим форму, содержащую три компонента типа TLabel. Разрешим для нихоперацию перемещения и сброса, установив значение свойства DragModeравным dmAtJto/natic. Назначим каждому их этих компонентов различныезначения свойства Font.

Создадим компонент типа TListBox, в который будет производиться сбрособъекта, инициирующий событие OnDragDrop.)procedure TForml.ListBoxlDragOver(Sender, Source: TObject;

X, Y: Integer; State: TDragState; var Accept: Boolean);beginAccept := Source is; {Разрешен сброс только для объекта

типа TLabel }end;procedure TForml.ListBoxlDragDrop(Sender, Source: TObject;

X, Y: Integer);begin

if (Sender is TListBox) and (Source is TLabel) thenbegin

with Sender as TListBox dobegin (Изменение свойств объекта ListBoxl]

Font := (Source as TLabel).Font;Color := (Source as TLabel).Color;

end;end;

end;

Форма, содержащая три компонента типа TLabel и компонент типа TListBox, накоторый выполняется сброс объекта, приведена на рис. 5.21.

iJFFoiml

Label!Labet2

текста B^fgtfт менятьсвои шрифт и фонпри перемещении и сбросеодного из конпонентовтипа TTabei

Рис. 5.21. Форма, реагируюшая на события OnDragOver и OnDragDrop

События, инициируемые для компонентовVCL-библиотека содержит ряд предопределенных обработчиков событий, кото-рые должны вызываться при перемещении фокуса ввода, редактировании значе-ния объекта, создании или активизации объекта, изменении его размеров.

Page 225: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Библиотека компонентов Delphi — VCL 225

Большинство общих обработчиков событий наследуются компонентами от клас-сов TControl, TWinControl. К ним относятся обработчики событий от клавиатурыи от мыши. Но некоторые из этих обработчиков событий переопределяются дляконкретного компонента. В этом случае их отличие, как правило, состоит в ко-личестве и типе передаваемых параметров.Существует ряд обработчиков событий, которые предопределены только дляконкретных компонентов. .В следующей таблице приведено описание наиболее часто используемых обра-ботчиков событий.

Обработчик

события

OnChange

OnEnter

OnExit

OnActivate

OnDeactivate

OnException

OnHelp

OnMiniroize

OnRestore

Onldle

OnHint

OnCreate

OnPaint

Какими компонентамииспользуется

TEdit. TDBEdit, TBitmap,TBrush, TCarwas,TComboBox, TFonl, TMemo,TPen, TScrollBar, TStringList,TTabContro! и др.

Все оконныеэлементы управления

Все оконныеэлементы управления

TForm, TApplication

TForm, TApplication

TApplication

TForm, TApplication

TApplication

TApplication

TApptication

TApplication

TForm

TForm

Описание

Происходит изменение значения объекта.Для объекта TEdit зто изменение свойстваText; длн обьекта ТРеп - свойств Width,Color, Mode; для объекта TComboBox -изменение в поле ввода

Компонент получил фокус ввода

Компонент потерял фокус ввода

Приложение или форма становятсяактивными

Выполняется переключение на другоеприложение или другую форму

Произошла исключительная ситуация

Нажата клавиша F1

Выполняется сворачивание окна приложения

Выполняется распахивание ранее сверну-того приложения

Пока параметр равен True, могут выпол-няться другие приложения. Зто событиеинициируется периодически для приложе-ния, находящегося в режиме ожидания

Может вызываться при позиционированиикурсора мыши на компоненте

Вызывается при создании формы

Вызывается при перерисовке формы

8 Зак I !

Page 226: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

226 Глава 5

Обработчик

события

OhClose

OnCloseQuery

OnTimer

Какими компонентамииспользуется

TForm

TForm

TTimer

Описание

Вызывается при закрытии формы(например, при вызове метода Close)

Вызывается перед закрытием формы. Есливторой параметр (CanClosej возвращаетзначение False, то форма не будет закрыта

Вызывается через указанный промежутоквремени

События, обрабатываемые приложением

1 Обработчик событий для приложения не создается по двойному щелчку| мыши в нужном месте. Для того чтобы такой обработчик добавить в при-•' ложение. можно выполнить следующие действия:

1. В обработчике события QnCreate для формы указать имя процедуры, кото-рая должна будет вызываться для определяемого обработчика событияобъекта Application. Например:

Application. OnHif!t:=ProcedureForAppOnHir.t;

'2. Создать процедуру с указанным именем и ввести код этой процедуры. На-пример:

procedure Forml.ProcedureForAppOnEint (Sender: TObject);begin

StatusBarl . SimpleText : Application . Hint;end;

В этом случае при возникновении такого события для приложения будет вызва-на созданная процедура.

"

'

Page 227: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 6

СОЗДАНИЕ ПРИЛОЖЕНИЙВ СРЕДЕ DELPHI

В этой главе подробно рассмотрен порядок действий разработчика для созданияконкретных приложений и для реализации наиболее общих элементов интер-фейса пользователя.

ПЕРВЫЕ ШАГИ

Управление свойствами визуальныхкомпонентов

Начинать разработку нового приложения всегда следует с создания нового проек-та. Затем в него можно добавлять уже готовые модули или создавать новые.

;i| Первыми шагами при разработке любого нового приложения на базе окна' >' формы должны быть:

1. Создание нового проекта. Для этого можно выполнить команду менюFile |New[ Application.

2. Сохранение проекта в отдельном каталоге. При этом сохраняется как файлпроекта и файл модуля (Unii l) , так и для вспомогательных файлов.

Первоначально создаваемый проект состоит из одной формы. На эту формуможно помещать различные компоненты из палитры компонентов.Настраивать свойства компонентов можно как в инспекторе объектов, таки программным способом.Рассмотрим пример простого приложения, состоящего из одной формы Forml.Расположим на форме несколько компонентов, определив их свойства, как опи-сано в следующей таблице.

Типкомпонента

TLabel

TListBox

ЗначениесвойстваName

Label!

ListBoxl

Свойства,устанавливаемыев инспекторе объектов

Caption(изменение цвета формы)

items [красный, желтый;синий, белый). Hint,ShowHint

Свойство,устанавливаемоепрограммно

Программируемыйобработчиксобытий

ListBoxl Click

Page 228: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

228 Глава 6

Типкомпонента

TForm

TLabeS

TComboBox

TLabe2

Значение

свойства

Name

Forml

Labe3

ComboBoxl

Label2

Свойства,

устанавливаемыев инспекторе объектов

Caption

Caption(список шрифтов)

Hint, ShowHint

Caption, Font

Свойство,

устанавливаемоепрограммно

Forml. Color

ComboBoxl. /tow

Label2.FontJVa/7W

Программируемыйобработчиксобытий

FormCreate

ComboBoxl Click

Выбирая значения из списка ListBoxl, будем изменять цвет формы (свойствоColor), а выбирая значения из списка ComboBoxl, будем изменять параметрышрифта компонента Label2. Элементы списка ListBoxl определим в инспектореобъектов. Элементы списка ComboBoxl установим во время выполнения при соз-дании формы, определив значение свойства Items как список экранных шрифтов.

Для отображения всплывающих подсказок при позиционировании курсорамыши на компонентах ListBoxl и ComboBoxl установим значения следую-щих свойств:

1. Hint, указав строку текста, которая будет отображаться как всплывающаяподсказка;

2. ShowHint, которое должно быть равным True.

Для программного изменения цвета формы выполним следующие действия:

Создадим обработчик события OnClick (процедуру ListBoxl Click) двой-ным щелчком мыши на элементе управления или выбрав его на страницеEvents инспектора объектов.

Изменение цвета формы будет выполняться каждый раз при выборе эле-мента списка ListBox 1. Для этого введем следующий код в обработчик со-бытия OnClick:

procedure TForml.ListBoxlClick(Sender: TObject);begin

if (ListBoxl.Itemlndex>=0) and(ListBoxl.Itemlndex< ListBoxl.Items.Count) then

case ListBoxl.Itemlndex of0: Forml.Color:=clRed ;1: Forml.Color:=clYellow ;2: Forml.Color:=clBlue ;

Forml.Color:=clWhite ;3:end;

end;

Page 229: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Создание приложений в среде Delphi 229

rrr-[] Для программного изменения шрифта, которым отображается компонент-у || TLabel2, выполним следующие действия:

1. Заполним список ComboBoxl названиями экранных шрифтов. Выполнимэто в обработчике события OnCreate для формы:procedure TForml.FonnCreate{Sender: T C b j e c t l ;begin,ComboBoxl.Items := Screen.Fonts;

end;

2. Создадим обработчик события OnClick для компонента ComboBoxl и вве-дем в него следующий код:procedure TForml.ComboBoxlClickfSender: TObject);beginForml.Label2.Font.Name := ComboBoxl.Items[ComboBoxl.Itemlndexj;

end;

В результате описанных действий будет создана форма, приведенная на рис. 6.1.

швяяяяяяяяящ

- Изменение цвета формы - Список шрифтов-

- красный • jCombaBox!. желтый

синийбелый Изменяемый компонент типа TLabel

^"Управление свойствами визуальных компонентов НВЕ

Рис. 6.1. Форма для управления свойствами Color и Font

В модуле Unitl будет автоматически сформировано следующее объявлениекласса TForml:type

TForml = class(TForm)ListBoxl: TListBox;Labell: TLabel;Label2: TLabel;ComboBoxl: TComboBox;LabelS: TLabel;procedure ListBoxlClicklSender: TObject);procedure FormCreate(Sender: TObjectl;procedure ComboBoxlClick(Sender: TObject);

private( Private declarations }

public{ Public declarations }

end;

Page 230: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

230 Глава 6

Проектирование SDI- и MDI-приложенийДля того чтобы создать шаблон приложения, поддерживающий SDI- или MDI-интерфейс, можно выполнить команду меню File|NewJOther и на странице Projectвыбрать требуемый тип приложения. В главе "Интегрированная среда разработ-ки IDE" был подробно описан процесс создания шаблона SDI-приложения.Основное отличие автоматически формируемого шаблона MDI-приложения отшаблона SDI-приложения заключается в поддержке одновременной работыс несколькими документами. Каждый новый документ открывается в создавае-мом дочернем окне.Дополнительно шаблон MDI-приложепия содержит кнопки для изменения распо-ложения окон, а в меню Windows добавляются имена всех открытых документов.На рис. 6.2 представлен шаблон формы для MDI-приложения.

te Приложение с HDI-ннтерФвйсомFile Edit. Window Help

Рис. 6.2. Форма для MDI-приложения

Проект (.рис. 6.3) состоит из трех модулей - main.pas, childwin.pas, about.pas -и главного файла приложения.

Для главной формы приложения свойство FormStyle должно быть установленоравным fsMDJform, а для дочерней формы - fsMDIChild.

Класс главной формы приложения определяется следующим кодом:

typeTMainForm = class(TForm)

MainMenul: TMainMeilu; {Компонент главного меню)Filel: TMenuItem; {Компоненты элементов меню}FileNewItem: TMenuItem;

FileOpenltem: TMenuItem;

FileClcselTiem: TMenuItem;

Page 231: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Создание приложений в среде Delphi 231

Windowl: TMenuItem;Helpl: TMenuItem;N1: TMenuItem;FileExitltem: TMenuItem;WindowCascadeltem: TMenuItem;WindowTileltem: TMenuItem;WindowArrangeltera: TMenuItera;

HelpAboutltem: TMenuItem;OpenDialog: TOpenDialog;FileSaveltem: TMenuItera;FileSaveAsItem: TMenuItem;Editl: TMenuItem;Cutltem: TMenuItem;Copyltem: TMenuItem;Pasteltem: TMenuItera;WindowMinimizeltera: TMenuItem;StatusBar: TStatusBar;

ActionListl: TActionList;

EditCutl: TEditCut;

(Компонент именованного действия)

{Компонент строки состояния){Компонент для определениясписка именованных действий}{Компонент для копированияв буфер обмена)

EditCopyl: TEditCopy;

EditPastel: TEditPaste;FileNewl: TAction;FileSavel: TAction; FileExitl: TAction;FileOpenl: TAction; FileSaveAsl: TAction;WindowCascadel: TWindowCascade;WindowTileHorizontall: TWindowTileHorizontal;

WindowArrangeAlll: TWindowArrange;IfJindowMinimizeAlll: TWindowMinimizeAll;HelpAboutl: TAction;FileClosel: TWindowClose;WindowTileVerticall: TWindowTileVertical;

WindowTilelteraZ: TMenuItem;TooIBar2: TToolBar;ToolButtonl: TToolButton;ToolButton2:' TToolButton;ToolButtonS: TToolButton;ToolButton4: TToolButton;ToolButtonS: TToolButton;ToolButton6: TToolButton;ToolButton9: TToolButton;ToolButton7: TToolButton;ToolButtonS: TToolButton;

{Панель инструментов}{Кнопки панели инструментов)

Page 232: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

232 Глава 6

ToolButtonlO: TIoolButton;ToolButtonll: TToolButton;IraageListl: TlmageList;procedure FileNewlExecute[Sender: TObject};procedure FileOpenlExecute(Sender: TObject);procedure HeIpAboutlExecute(Sender: TObject) ;procedure FileExitlExecute(Sender: TObject);

end;

В коде модуля MAIN.PAS должно быть указано использование двух других мо-дулей приложения; uses Chi ldWin, About; .

Project Manager

JMDIAPP.exe

Files:^ ШЗЕИЗЕЕЭШНмр MDIAPP.exe

Ё Щ] about

гЮ a be ut. pas:- 3 AboufBox

El |=p CHILDWIN|- tX] CHILDWIN.;-2l MDIChild

B-g MAIN- И] MAIN.PAS

~l MainForrn

В

New Remove "• Activate

; Path

E:\Delphi6\Pmjects

E:SDelphiG\PiojectsEADelphi6\Pio[ects

EADelphiGXProjectsEADelphiGSPiojects

EADelphi6\Projects

.. EADelphiG\Piojects

EADelphiGSPioiects

EADelphi6\Prajects

EADelphiGXPiojeclsEADelphiGXProiects

Рис. 6.З. Менеджер проекта

Процедура создания нового документа или открытия существующего реализо-вана следующим кодом:

{Создать новый документ}procedure TMainForm.FileNewlExecute(Sender: TObject);begin

{Создание дочернего окна с новым именем}

CreateHDIChildCNONAME' + IntToStr(MDIChildCount +1));end;{Открыть документ}

procedure TMainForm.FileOpenlExecute(Sender: TObject);begin

if OpenDialog.Execute then (Выбор имени документа}CreateMDIChildlOpenDialog.FileName); {Создание окна}

end;

Page 233: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Создание приложений в среде Delphi 233

procedure TMainForm.CreateMDIChild(const Name: string);var

Child: TMDIChild;begin

{ Класс TMDIChild определен в модуле CHILDWIN.PAS JChild := TMDIChild.Create(Application); (Создание окна}

Child.Caption := Name; (Заголовком окна будет имя файла)if FileExists(Name) then Child.Memol.Lines.LoadFromFile(Name);

(Загрузка текстового файла]end;

Для завершения приложения выполняется следующая процедура:

procedure TMainFcrm.FileExitlExecute(Sender: TObjec t ) ;begin Close; end;

В модуле CHILDWIN.PAS находится код дочерней формы

typeTMDIChild = class(TForm)

Memol: TMemo; {Поле для отображения текста)procedure FormClose(Sender: TObject;

var Action: TCloseAction];end;implementationprocedure TMDIChild.FormClose(Sender: TObject;

var Action: TCloseAction);begin Action := caFree; end;end.

Главная форма приложения описывается следующими свойствами (полужирнымшрифтом и курсивом выделены свойства, значения которых не могут быть дру-гими):

object MainForm: TMainFormCaption = 'Приложение с MDI-интерфейсом1

FormStyle = fsMDIFormMenu = MainMenulWindowMenu = Windowlobject StatusBar: TStatusBar

AutoHint = TruePanels = оSimplePanel = True

endobject ToolBar2: TToolBar

Images = ImageListl

object ToolButton9: TToolButtonAction = FileNewl (Именованное действие,

которое будет выполнено при щелчке на кнопке)

Page 234: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

234 Глава 6

endobject ToolButtonl: TToolButton

Action = FileOpenlend{Кнопки панели инструментов}

endobject MainMenul: TMainMenuImages = ImageListlobject Filel: TMenuItemCaption = 'SFile'object FileNewItem: TMenuItem

Action = FileNewlendobject FileOpenltem: TMenuItemAction = FileOpenl

endobject FileCloseltem: TMenuItem

Action = FileCloselend

object FileExitltem: TMenuItemAction = FileExitl

endendobject Editl: TMenuItem

endobject Window!: TMenuItem

endendobject OpenDialog: TOpenDialogFilter = 'All files (*.*)j*.*'

endobject ActionListl: TActionListobject FileNewl: TAction

Category = 'File'Caption = '&New'OnExecufce = FileNewlExecuie

endobject FileOpenl: TActionCategory = 'File

1

Caption = 'sOpen'

(Диалог Open)

Page 235: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Создание приложений в среде Delphi 235

QnExecute = FileOpenlExecuteend

endend

Дочерняя форма фактически является обычной формой, в которую помещенодин объект типа ТМето (многострочное поле редактирования). Она описываетсяследующими свойствами:

object MDIChild: TMDIChildFormStyle = fsMDIChild

• Position = poDefaultr

Visible = TrueOnCiose = ForraCloseobject Memol: TMemo

Wordwrap = Falseend

end

После того как шаблон приложения будет создан, его можно изменять, добавляяновые команды меню и компоненты типа TAction для реализации именованныхдействий.

В проект можно добавлять новые формы, выполняя команду меню File|New, илиуже существующие формы, выполняя ProjectjAdd To Project.

Для того чтобы открыть вновь созданную форму, для нее следует выполнитьметод Application. CreateForm.

Для закрытия формы достаточно вызвать метод Close.

ПРОЕКТИРОВАНИЕ МЕНЮ ОКНА ФОРМЫСоздание главного меню

Любое окно формы можег иметь меню.(iw*P

!! Для того чтобы создать меню окна формы, следует:

1. Поместить в форму компонент типа TMainMenu;

2. Выполнить на нем двойной щелчок мышью и затем в открывшемся окнеопределения заголовков линейки меню и ниспадающих меню (рис. 6.4)ввести названия пунктов (команд) меню.

Вводимые заголовки будут отображаться как значения свойства Caption в инспек-торе объектов. При этом для каждого нового пункта меню автоматически будутсоздаваться и отображаться в инспекторе объектов объекты класса THenuItem(именуемые по умолчанию как N1, N2, N3 и т. д.).

Page 236: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

236 Глава 6

if' Foirn! MainMenul

Файл Редактировать Справка Выход [.

Вырезать

Скопировать

. Удалить

Рис. 6.4. Окно определения пунктов меню

Объект класса TMainMenu будет являться контейнером всех создаваемых для негопунктов меню класса TMenuItem.После определения всех заголовков меню окно редактирования меню можнозакрыть.В окне формы после выполнения этих действий будет отображена вновь создан-ная линейка меню.1/77*

Для того чтобы определить обработчики событий для каждого созданного--' пункта меню, следует:

1. Выполнить в окне формы двойной щелчок мышью на пункте созданногоменю. При этом в окне кода программы автоматически будет добавленапустая процедура - обработчик события для указанного пункта меню (на-пример, procedure rForml.N2Click(Sender: TObject) ;) .

2. Ввести код обработки события, который будет выполняться при щелчкепользователя на данном пункте меню.

СОЗДАНИЕ и ИСПОЛЬЗОВАНИЕDLL-БИБЛИОТЕК

Создание DLL-библиотекиDLL-библиотека позволяет объединить в одно целое повторно используемыйкод. Функции из DLL-библиотеки могут подключаться динамически во времявыполнения, в отличие от функций из пакетов Delphi, линкуемых статически наэтапе компиляции приложения.

Для того чтобы создать DLL-библиотеку, выполните следующие действия:

Выполните команду меню File|New|Other и выберите на странице New диа-лога New Item элемент DLL Wizard (рис. 6.5).

Page 237: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Создание приложений в среде Delphi 237

f. New Hems

WebServices Business V/ebSnap Web Documents Corba

New I ActiveX | Muldfei | Ptoiectl j Forms | Dialogs | Projects | Data Modules j IntraWeb

Application Balch File CLX Component Console Control Panel Control Panel Data ModuleApplication Application Application Module

Form Frame Package PtojectGroup Report Resource DLL ServiceWizard

Service Texl ThreadObiect Unit Webserver XMLDalaApplication Application Binding

.Г Сер;- Г lrrhe.it Г Ц»

OK Cancel Help

Рис. 6.5. Диалог New Item для создания DLL-библиотеки

Мастер DLL Wizard автоматически создаст пустой шаблон для DLL-библиотеки.

В отличие от обычного модуля, начинающегося с ключевого слова unit, модульDLL-библиотеки начинается с ключевого слова library.

Секция uses модуля DLL-библиотеки требует подключения только двух паке-тов: SysUtils и Classes.

Создание DLL-функции состоит из нескольких этапов:

1. Сначала в секции реализации модуля следует ввести сигнатуру функциии запрограммировать код, выполняемый функцией.

2. Далее в сигнатуре функции надо определить, каким образом будет проис-ходить вызов параметров.

J. В заключение функцию, которую предполагается использовать не тольковнутри модуля, но и вызывать из других приложений, следует объявитькак экспортируемую в секции exports.

Функции из DLL-библиотеки могут вызываться как из приложений, разработан-ных в Delphi, так и из приложений, написанных на других языках программиро-вания, таких, как C++.Порядок выделения памяти под параметры и освобождения ее различен для раз-ных языков программирования. Для того чтобы не возникла ошибка времени вы-полнения, объявление функции в DLL-библиотеке и ее объявление в приложениидолжны использовать одинаковый механизм передачи параметров.

Page 238: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

238 Глава 6

При объявлении процедуры или функции может быть указан один из следу-ющих механизмов передачи параметров:

• register,• pascal,• cdecl,• stdcall,• safecall.

.Способ передачи параметров указывается через точку с запятой после описанияфункции. Например: function F1 (X, Y, Z: Real]: Real; stdcall;.Различные способы передачи параметров определяют порядок передачи пара-метров (слева направо или справа налево), а также указывают, кто будет осво-бождать память стека (вызываемая или вызывающая процедура).При использовании DLL-библиотек в качестве компонентов, вызываемых изприложений на других языках программирования, следует использовать соот-ветствующий модификатор вызова. Для приложений на C++ применяется мо-дификатор вызова stdcall1.Для того чтобы функцию, описанную в DLL-библиотеке, можно было вызватьиз другого приложения, эту функцию следует экспортировать. Список всех экс-портируемых функций указывается в секции exports через запятуюи завершается символом точка с запятой.Экспорт функций может выполняться тремя способами:

• по имени функции, используемому в DLL-библиотеке;• по имени функции, заданному как имя экспорта;• по присвоенному функции индексу.

Для того чтобы присвоить функции некоторый индекс, его следует указатьв секции exports после имени функции с ключевым словом index.Для того чтобы экспортируемая функция вызывалась по имени, отличном от име-ни, используемого в DLL-библиотеке, в секции exports после имени функцииследует указать ключевое слово name и новое имя экспорта для данной функции.DLL - библиотека не является выполняемым модулем. Для получения ее кодадостаточно произвести компиляцию проекта. Это можно сделать, выполнивкоманду меню Рго}ес1|СотрНе<имя_проекта> или нажав клавиши Ctrl+F9.

Пример:

library Projectl;uses

SysUtils, Classes;f£R *.res}function F1(X, Y: Integer): Integer; stdcall;begin F1:=X+Y; end;

Технология COM, реализующая серверы в процессе как DLL-библиотеки, предполагаетиспользование модификатора вызова stdcall для любых создаваемых компонентов.

Page 239: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Создание приложений в среде Delphi 239

function F2(X, У: Integer): Integer; stdcall;

begin F2:=X*Y; end;.

exports

Fl , {Функция будут доступна по имени F1) , -

F2 index 2 ; {Функция будут доступна по индексу 2)end.

Статическое подключение DLL-библиотекиDLL-библиотека может подключаться или статически, или динамически. Приподключении DLL-библиотеки она загружается в память приложения.При статическом подключении DLL-библиотека загружается один раз при за-пуске приложения.На всем протяжении выполнения приложения имя функции, импортируемой изDLL-библиотеки, которая была подключена статически, указывает на одну и туже функцию (точку входа в DLL) в одной и той же DLL.Все функции из DLL-библиотеки, которые будут использоваться в приложениипервоначально, должны быть объявлены как внешние. При этом следует ука-зать, если требуется, модификатор вызова. Если функция вызывается по индек-су, то для нее следует задать имя, используемое в приложении, и индекс функ-ции в DLL-библиотеке.Объявления внешних функций выполняется в секции implementation до исполь-зования этих функций.Объявление внешней функции с ключевым словом external определяет, что бу-дет использовано статическое связывание.

"Пример:

unit Unit l ;interfaceuses

Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms, Dialogs, StdCtrls;

typeTForml = class(TForm)

Editl: TEdit; [Поле для ввода первого значения}Edit2: TEdit; (Поле для ввода второго значения}Edit3: TEdit; (Поле для отображения результата

выполнения функции из DLL-библиотеки}Buttonl: TButton; {Выполняется вызов функции, используемой по имени)Button2: TButton; [Выполняется вызов функции, используемой по индексу}procedure ButtonlClickfSender: TObjec t ) ;procedure Button2Click(Sender: TObject) ;

private{ Private declarations }

public

Page 240: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

240 Глава 6

( Public declarations }end;

varForml: TForml;

implementation

{$R *.dfm)

(Объявление экспортируемых функций}function Fl (i: Integer; j:Integer): Integer; stdcall;

external 'Projectl.dll';

function F2 (i: Integer; j:Integer): Integer; stdcall;

external 'Projectl.dll1 index 2;

procedure TForml.ButtonlClick(Sender: TObject);

{Вызов экспортируемой функции}

begin

Edit3.Text:=IntToStr(Fl(StrToInt(Editl.Text),StrToInt{Edit2.Text)));end;procedure TForml.Button2Click(Sender: TObject);

beginEdit3.Text:=JntToStr(F2(StrToInt(Editl.Text),StrToInt(Edit2.Text)));

end;end.

Динамическое подключение DLL-библиотекиВ отличие от статического подключения DLL-библиотеки, выполняемогов момент загрузки приложения, динамическое подключение DLL-библиотекиможет быть выполнено в любой точке выполнения программы. После вызовафункции из DLL-библиотеки ее можно отключить. При одновременном исполь-зовании нескольких DLL-библиотек это дает ощутимую экономию памяти.Для динамического подключения DLL-библиотеки используются функцииWindows API. Windows API - это набор стандартных функций, используемыйдля реализации взаимодействия с операционной системой.При вызове функции из динамически подключаемой DLL-библиотеки вместоопределения имени функции как external в случае статического связыванияследует определить новый тип, соответствующий типу вызываемой функции,и создать переменную данного типа. Определение типа функции или процедурыописывается как:9овда_тип=£ипс^1оп(список_параметров):тип_функции;ыодификатор_доступа;или:Новый_тип=ргосв(Й1Гв'(сиисок_параметров)/модификатор доступа;

:] Для того чтобы выполнить вызов функции из динамически подключаемой! jf } DLL-библиотеки, выполните следующие действия:

1. Создайте новый тип. соответствующий типу вызываемой функции (имянового типа можно ввести после секции type).

Page 241: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Создание приложений в среде Delphi 241

Например:TMyFl=function( i , j :Integer)^Integer; stdcall;

2. В секции var interface-секции модуля создайте переменную созданноготипа функции. Например: HyFl : TMyFl;

5. Перед загрузкой DLL-библиотеки объявите переменную типа Integer, ко-торая будет содержать дескриптор подключаемой библиотеки.

4. Вызовите метод LoadLibracy, выполняющий подключениеDLL-библиотеки. Например; h:=LoadLibrary ( 'Pro ject l .d l l ' ) ;

5. Проверьте, успешно ли выполнено подключение библиотеки. Если имяDLL-библиотеки указано неверно или библиотека не найдена, то функцияLoadLibrary вернет значение 0.

6. В случае успешного подключения DLL-библиотеки далее следует полу-чить адрес функции. Для этого используется функция Windows APIGetProcAddress, в качестве параметров которой указывается дескрипторDLL-библиотеки и имя подключаемой функции.Например: @MyFl: =GetProcAddress (h, ' F l ' ) ,-

7. Если адрес функции получен, то значение адреса (в нашем примере@MyFl) не должно быть равно n i l .

8. На этом этапе можно выполнять вызов функции из динамически подклю-ченной DLL-библиотеки.

9. Для освобождения и соответственно выгрузки DLL-библиотеки вызовитеметод FreeLibrary, выполняющий отключение DLL-библиотеки.

Пример:

unit Unitl;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls;typeTForml = class(TForm)iditl: TEdit;Edit2: TEdit;Edit3: TEdit;Button3: TButton;procedure Button3Click[Sender: TObject);

private{ Private declarations }

public{ Public declarations }

Page 242: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

242 Глава 6

end;TMyFl=function( i,j:Integer):Integer; stdcall; {Создание типа

функции)var

Forml: TForml;

MyFl : TMyFl; (Объявление переменной типа функции]

implementation{SR *.dfm}procedure TForral.Button3Click(Sender: TObject);varh: Integer;

begin

h:=LoadLibrary('Projectl.dll');if h <> 0 thenbeginSMyFl:=GetProcAddress(h,'Fl');

if @HyFl <> nil then

Edit3.Text:=IntToStг(MyFl(StrToInt{Editl.Text),

StrToInt(Edit2.Text)));

FreeLibrary(h);

end;end;end.

Использование DLL-библиотеки АЛЯ вызоваобщих модальных диалогов

Результатом выполнения процедуры из DLL-библиотеки может быть отображе-ние некоторого модального диалога. Для этого следует в экспортируемом мето-де создать объект форма, отобразить ее как модальный диалог, а затем удалитьобъект форма. При этом в самой форме следует предусмотреть вызов методаClose для завершения диалога.

Для создания формы используется метод Create, в качестве параметра которомупередается указатель на родительскую форму - форму вызывающего приложе-ния. Этот параметр передается вызываемой DLL-функции.Далее приведен пример DLL-библиотеки, содержащей функцию, используемуюдля отображения модальной формы и возврата введенного в нее значения.

Пример:library Projectl;usesSysUtils,Classes,

Page 243: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Создание приложений в среде Delphi 243

Unitl_DLL in 'Uni t l_DLL.pas ' { F o r m l l ;{SR '.res]procedure HyModalForm (var Z:Integer ;F :TForml); stdcall;begin

Forml:=TForml.Create(F);(Параметр F передается при вызове процедуры и содержит указательна родительскую форму - форму вызывающего приложения}

Forml.ShowModal();(Первый параметр используется для возвращаемого значения}Z:=StrToInt(Form!.Sdit l .Text);

Forml.Free;end;exportsHyModalForm;end.

Для того чтобы использовать данную DLL-библиотеку g целью вызова создан-ного модального диалога, можно применять как динамическое, таки статическое связывание. Следующий пример иллюстрирует вызов функции изDLL-библиотеки, отображающей модальный диалог.

Пример:

unit Unitl;interfaceuses

Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls, Forms,Dialogs, StdCtris;

type

TForml = class(TFormlButton4: TButton;Edit4: TEdit;procedure Button4Click(Sender: T O b j e c t ) ;

privatepublicend;TMyModalFora=procedure(var Z:Integer ; F :TForml); stdcall;

varForml: TForml;MyModalForm : TMyHodalForm ; (Переменная типа

вызываемой процедуры]implementation{$R *.dfmlprocedure TForml.Button4Click(Sender: TObject);var

Page 244: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

244 Глава 6

h: Integer;

ii: Integer; {Для сохранения возвращаемого значения)begin

ii:=0;h:=LoadLibrary('Projectl.dll'} ;if h о 0 thenbegin@MyModalForm:=GetProcAddress(h,'HyModalForm');if @MyModalForm о nil then

MyModalForm(ii,Forml) ;FreeLibrary(h);

end;Edit4.Text;= IntToStr(ii); {Отображение значения, возвращаемого

функцией MyModalForm из DLL-библиотеки)end;end.

Page 245: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 7

РАБОТА С БАЗАМИ ДАННЫХ

В этой главе рассматриваются компоненты VCL-библистеки, обеспечивающиедоступ к различным источникам данных, и элементы управления, позволяющиеотображать и редактировать информацию из таблиц баз данных.

РЕЛЯиИОННЫЕ БАЗЫ ДАННЫХ

Основные понятияСуществуют различные модели баз данных. Наибольшее распространение полу-чила реляционная модель '. Она лежит в основе таких БД (СУБД), как Paradox,FoxPro, Access. InterBase. Oracle, и многих других.Реляционная база данных представляет собой совокупность таблиц (отношений),содержащих данные.Основными преимуществами реляционных баз данных являются:

• ссылочная целостность - контроль за изменением, удалением или вводомзависимых данных;

• различные типы индексов - для обеспечения более быстрого доступа и кон-троля вводимых данных;

• первичный и вторичный ключи - для реализации отношений между таблицами;

• связь таблиц один-к-одному - одна запись одной таблицы, называемой роди-тельской или основной, связывается с одной записью другой таблицы, назы-ваемой дочерней;

• связь таблиц одип-ко-многим - одна запись родительской таблицы связыва-ется с несколькими записями дочерней таблицы;

• объединение таблиц - работа с несколькими таблицами как с одной объеди-ненной таблицей;

• отсутствие избыточное/ни данных - использование нормализованногопредставления данных гарантирует, что таблица не будет содержать повто-ряющиеся записи или повторяющиеся части записи.

Отметим, что реляционная СУБД только предоставляет разработчику наборсредств для построения реляционной модели. Проектирование конкретной мо-дели данных, обладающей ссылочной целостностью и отсутствием избыточно-сти, полностью лежит на разработчике.

1 В последнее время быстро развивается объектно-ориентированная модель баз данных,

также поддерживаемая компонентами Delphi.

Page 246: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

246 Глава 7

ТаблицыТаблица представляет собой двумерный набор строк, называемых также запися-ми, и столбцов, называемых полями или атрибутами.Поле содержит информацию об одной категории данных и имеет тип и имя.

Индексы и ключиИндексы используются для ускорения доступа к данным, усиления ограничений,а также для упорядочения записей.В различных СУБД могут применяться разные виды индексов.Однако, как бы эти индексы ни назывались, любая реляционная СУБД поддер-живает следующие типы индексов:

• первичный индекс - таблица может иметь только один первичный индекс,значения первичного индекса должны быть уникальны;

• вторичный уникальный индекс - таблица может иметь несколько таких ин-дексов, значения индекса должны быть уникальны. Как правило, вторичныйуникальный индекс используется для упорядочения записей;

• простой вторичный индекс - таблица может иметь несколько таких индек-сов, значения индекса не должны быть уникальны.

Любой индекс может быть как простым, так и составным. Простой индексстроится на основе одного поля, а составной - на основе нескольких полей.Физически любой индекс представляет записи в упорядоченном виде и реализу-ется как таблица ссылок на реальное местоположение записей.Ключи используются для связывания данных. Существуют первичный и вто-ричный (внешний) ключи: первичный ключ родительской таблицы связываетсясо вторичным ключом дочерней таблицы.Отметим, что для большинства СУБД ключ может быть установлен только наиндексированное поле. Поэтому понятия индекса и ключа очень часто путают.Следует помнить, что, говоря о связи таблиц, мы всегда имеем в виду ключ,а говоря об упорядочении записей или их уникальности, - индекс.

Сеансы д а н н ы хДля любого приложения баз данных автоматически создается сеанс данных поумолчанию, именуемый Sessions. Сеанс позволяет управлять соединениямис базой данных. Сеанс BDE управляет соединениями с БД, курсорами, запроса-ми и т, п. Компоненты TSession и TSessionList используются для управления се-ансами BDE.Для каждого сеанса данных создается свой объект типа TSession.Использование в приложении нескольких сеансов необходимо в том случае, если:

• требуется для каждой формы иметь свой сеанс данных;

• к одной базе данных а многопотоковом приложении выполняются парал-лельные запросы.

Page 247: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 247

ТранзакцииТранзакцией называется интервал, в течение которого любые изменения данныхмогут быть полностью отменены и по завершении которого все выполненныеизменения фиксируются. Откатам транзакции называется отмена всех выпол-ненных в течение транзакции изменений. Фиксацией трст-защии или коммитомназывается процедура внесения всех выполненных изменений в базу данных.Транзакции используются для обеспечения целостности данных.Транзакция может объединять действия, выполняемые над несколькими табли-цами базы данных. Если хотя бы одна из выполняемых операций внутри тран-закции дала сбой, то происходит откат всей транзакции.Машина баз данных BDE обеспечивает неявную транзакцию на уровне записи.Однако при обработке набора записей это несколько перегружает сетевой тра-фик и замедляет работу. Этого можно избежать, определив явную транзакцию.Для явного управления транзакцией в приложениях, использующих машину базданных BDE, можно:

* использовать методы и свойства компонента TDatabase такие, какStartTransaction, Commit. Rollback, InTransaciion, Translsolation;

* использовать режим SQLPASSTHRU для компонентов типа TQuery,TStoredProc или TUpduieSQL, передавая SQL-операторы управления транзак-цией непосредственно на удаленный сервер.

БАЗЫ ДАННЫХ в DELPHIНе все базы данных содержат все свои таблицы в одном файле. Поэтому для та-ких БД любой каталог, содержащий таблицы, рассматривается к Delphi как еди-ная база данных. Это в первую очередь относится к таким популярным базамданных, как Paradox (DB-файлы) или dBase (DBF-файлы). Все таблицы базыданных InterBase располагаются в одном файле (GDB-файле).Как правило, любая современная база данных кроме таблиц также содержити словарь данных, включающий информацию об индексах, хранимых процеду-рах, триггерах, правах доступа и т. п.Delphi позволяет работать как с локальными БД, расположенными на том жекомпьютере, что и выполняемое приложение, так и с удаленными БД, располо-женными на другом компьютере или на сервере БД.Базы данных, работа с которыми возможна через структурированный язык за-просов SQL, иногда называются SQL-серверами.

При этом для удаленных БД может быть реализована:

* архитектура клиент/сервер - двухзвенная архитектура;

* архитектура клиент/сервер приложений/сервер БД - трехзвенная архитектура;

* многозвенная архитектура.

Page 248: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

248 Глава 7

При этом первоначальную отладку приложения с архитектурой клиент/серверможно выполнять на локальном SQL-сервере, а затем уже простой заменой рас-положения источника данных использовать удаленный SQL-сервер,Основными механизмами доступа к данным, поддерживаемым в Delphi, являются:

• ODBC - доступ через ODBC-драйверы БД или BDE-драйверы;

• OLE OB - доступ с использованием провайдеров данных (OLE DB - это методдоступа к любым данным через стандартный СОМ-интерфейс);

• средства dbExpress, ,использующие легковесные драйверы БД (lightweightdatabase drivers);

• средства доступа к распределенным наборам данных в многозвенной архи-тектуре.

Источники данныхБудем называть любую базу данных, таблицу или плоский файл источником данных.Delphi предоставляет широкий набор средств, позволяющий быстро и эффек-тивно разрабатывать различные приложения баз данных.Эти средства можно условно разделить на следующие группы:

• компоненты для доступа к данным, включающие:

• доступ через машину баз данных BDE, предоставляющую доступ черезODBC-драйверы или через внутренние драйверы машины баз данных BDE(компоненты страницы BDE палитры инструментов);

• доступ через ADO-объекты (ActiveX Data Objects), в основе которого ле-жит применение технологии OLE DB (компоненты страницы ADO);

• доступ к локальному или удаленному SQL-серверу InterBase (компонентыстраницы InterBase);

• доступ посредством легковесных драйверов dbExpress;

• доступ к БД при многозвенной архитектуре (компоненты страницыDataSnap);

• визуальные компоненты, реализующие интерфейс пользователя:

• элементы управления для работы с полями баз данных1 {компонентыстраницы DataControl);

• компоненты для связи источников данных с визуальными компонентами,предоставляющими интерфейс пользователя;

• компоненты для визуального проектирования отчетов (компоненты стра-ницы QReport).

1 В этой главе компоненты страницы DataControl, являющиеся элементами управления дляработы с полями источников данных, будем для краткости называть просто элементамиуправления. Все они являются аналогами обычных элементов управления, расположенныхна страницах Standard и Additional.

Page 249: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 249

Машина баз данных BDEDelphi при работе с базами данных как промежуточное звено между приложениеми источником данных может использовать машину баз данных BDE (BorlandDatabase Engine). Интерфейс BDE с приложением называется ГОАР1-интерфейсом(Integrated Database Application Programming Interface).

Источником данных может выступать как локальная база данных, так и удален-ная база данных.

Доступ к данным через BDE может быть реализован двумя способами:

• как доступ к таблицам и их полям, указываемым непосредственно;

« как доступ к наборам данных, получаемым при выполнении SQL-операторов.

BDE может реализовывать доступ как через свои внутренние драйверы, таки через ODBC (Open DataBase Connectivity).

BDE позволяет легко и быстро получить доступ к таким БД, как Paradox или dBase.

Для просмотра списка всех внутренних и ODBC-драйверов, предоставляемыхBDE, следует вызвать приложение BDE Administrator (рис. 7.1).

На странице Configuration можно просмотреть список всех установленных драй-веров, а на странице Databases - список всех баз данных, для которых определе-ны псевдонимы.

ПсевдонимыДля более гибкого доступа к базам данных целесообразно при разработке при-ложения указывать не непосредственно имя файла и драйвер, а псевдоним.

Псевдоним' содержит имя базы данных и набор параметров, используемые длядоступа к удаленной базе данных. Хотя для работы с локальными базами данныхпсевдоним не требуется, он позволяет реализовывать при разработке приложенийбыстрый переход от локальной БД к удаленной. Для этого достаточно только из-менить местоположение источника данных, на который ссылается псевдоним.

Псевдоним можно создать в администраторе BDE.

Для того чтобы создать псевдоним, следует:

1. Вызвать приложение BDE Administrator и выбрать страницу Databases.

2. Выполнить команду меню Object)New и в открывшемся диалоге (рис. 7.2)выбрать имя используемого драйвера.

}. Ввести на левой панели имя псевдонима.

4. Определить, путь доступа к базе данных на правой панели в поле PATH илиSERVER NAME.

1 В терминологии, используемой в Delphi, понятие псевдонима эквивалентно источнику

данных DSN (Data Source Name), определяемому с помощью приложения ODBC с панели

управления Windows,

Page 250: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

250 Глава 7

*BDE Administrator D-.VProgram HtesSCommon FJIes\Borlaiul §,(iared\BOE • - 1 OJ * j

Object Edit View Cations Kelp

£ X ooD/ivet: and System Definition of ORACLE

Databases Contiguation | Definition j

1- Q) Configuration _^_

e'^ DriversEl-Q) Native

© PARADOX© DBASE

© FOXPRO© MSACCESE

© DB2© INFORMIX

© INTRBASE

© MSSQL

®SBD© SYBAfE

i-\ Q ODBC© SQLServei© MicrosoftAccftssDjivej |'.mdb[

© MicrosoflText Driver (".Ы;"© MicrosoflE«elDnverr.xli]

© Microsolt dBase Driver f.dbl]© iMicrasolt Paradon Driva [".db

© Microvolt Visual FoxPro Driver

© Microsolt FonPtoVFP Driver [-.© Microsoft dBase VFP Drivel ('.d

© Micro5cft Access-Tleibei ("mdb© Microsoft Т ftnl-Tisiba С Ы;

© MicrasoftEncel-TreibaC.nlsJ© Microsoti dBawTreber (• dbl)

© Microsotl Parades- Т reiber I'.db© MiciosoitVisudFbxPro-Traber j-J

VERSION

TYPEDLL32VENDOR INIT

DRIVER FLAGS

TRACE MODEBATCH COUNT

BLOB SIZEBLOBS TO CACHE

ENABLE BCDENABLE INTEGERS

ENABLE SCHEMA CACHELAN GO RIVER

LIST SYNONYMS

MAX ROWS

MET PROTOCOLOBJECT MODEOPEN MODE

ROWS ET SEESCHEMA CACHE DIR

SCHEMA CACHE SIZESCHEMA CACHE TIME

SERVER NAME

SQLPAESTHRUMQDESQLQRYMQDE

USER NAME

40SERVERSOLORA8.DLL

OO.DLL

02003264FALSE

FALSEFALSE

NONE•1THETRUE

READ/WRITE

20

8-1ORA.SERVERSHARED AUTOCOMMIT

MYNAME

0 items in ORACLE. • " %

Рис. 7.1. BDE Administrator

New Database Alias

Г Database Driver Name"

Microsoft Text Dnver

Cancel Help

Рис. 7.2. Диалог определения драйвера для доступа к базе данных

Зашита доступа к БЛДоступ к информации, хранимой в базах данных, часто требуется ограничиватьили санкционировать. Для этих целей используются пароли и права доступа.Права доступа могут устанавливаться для действий над таблицами и полями или

Page 251: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 251

определять полномочия пользователей. Предоставляемые средства защиты дос-тупа зависят от конкретной базы данных.Доступ к информации баз данных в общем случае может предусматриватьследующие уровни защиты:

* защита таблицы по паролю;

• аутентификация пользователя для доступа к определенным таблицам и полямтаблицы;

• имя базы данных, имя пользователя и пароль, указываемые при подключе-нии. В дальнейшем эти параметры определяют полномочия доступа к табли-цам и полномочия для выполнения определенных операций над ними.

На этапе проектирования приложения следует учитывать уровень защиты, кото-рый имеет используемый источник данных. Для большинства SQL-серверов за-щита, как правило, реализуется на уровне имени пользователя и пароля. Во вре-мя проектирования при попытке первого подключения к источнику данных,требующему имя пользователя и пароль, отображается стандартный диалог.Для идентификации пользователя во время выполнения можно:

• отображать стандартный диалог Login, установив для этого значение свойст-ва LoginPrompt равным True;

* программно определять имя пользователя и пароль:

е присвоив значения параметрам USER NAME и PASSWORD свойства Paramsкомпонента типа TDatabase и установив значение свойства LoginPromptравным False;

« присвоив значения свойству ConnectionString (строка описания провай-дера) компонента типа TADOConnection (для ADO-объектов) и установивзначение свойства LoginPrompt равным False;

* использовать .обработчик события OnLogin, установив для этого значениесвойства LoginPrompt равным False.

Пример:

{Определение свойства Params для объекта типа TDatabase}

jB БД InterBase для доступа к demo-файлам следует указать пользователя

SYSDBA и пароль mastetkey}

with Database! do begin

Params.Values['USER NAME'] := 'SYSDBA1;

Params.Values['PASSWORD'] := 'masterkey';

LoginPrompt := False;- Connected := True;

end;(Определение свойства ConnectionString для объекта типа TADOConnection}

'with ADOConnectionl do begin

Page 252: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

252 Глава 7

"Close;LoginPrompt := False;Connect!onString := 'Provider=NameQfYourProvider;' +

'Remote Server=NameOfYourServer;' +'User Name=Userl;Password=PasswordUserl';

{Строка ConnectionString может содержать или полное описание провайдераи пользователя, или только описание провайдера с одновременным указаниемпользователя при вызове метода Open:ConnectionString := '?rovider=HameOfYourProvider;Ч

'Remote Server=NameOfYourServer' ;Open( 'User l ' , 'PasswordUserl 1 ); )

Connected := True;end;

Огметим, что пароли, хранимый в ЕХЕ-файле, может быть «прочитан» и, следо-вательно, не обеспечивает полной защиты.

Более надежным считается создание собственного обработчика событияOnLogin.

Пример:

procedure TFonnl.DatabaselLogin(Database: TDatabase;LoginParams: TStrings);

begin{Расшифровка значений UserNameVar к PasswordVar.]LoginParams.Values[ 'USER NAME'] := UserNameVar;LoginParams.Values! 'PASSWORD 1 ] := PasswordVar;

end;

При ошибке программного подключения к источнику данных инициируется ис-ключение EOleException.

SQL ExplorerДля просмотра таблиц и баз данных можно использовать инструмент SQLExplorer, расположенный в группе Borland Delphi 7 панели задач Windows.

Окно SQL Explorer (рис. 7.3) состоит из двух панелей: левая - для выбора базыданных или таблицы, а правая - для просмотра параметров, редактирования таб-лиц или ввода и выполнения SQL-операторов.

На странице Data правой панели автоматически отображаются все записи табли-цы, выделенной на левой панели.

Страница Text правой панели отображает информацию в зависимости от типаобъекта, выделенного палевой панели:

• для секции Tables приводится список SQL-операторов CREATE TABLE, исполь-зуемый для создания каждой таблицы базы данных;

• для конкретной таблицы приводится SQL-оператор создания данной табли-цы CREATE TABLE;

Page 253: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 253

• для конкретного поля таблицы приводится та часть SQL-оператора CREATETABLE, которая относится к созданию данного поля.

Страница Enter SQL позволяет ввести SQL-оператор и выполнить его, щелкнувмышью на расположенной справа кнопке Execute Query. Если введенныйSQL-оператор не содержит ошибок, то внизу на правой панели будет отображе-на таблица с результатом выполненного запроса. Эта страница может использо-ваться для предварительной отладки применяемых SQL-операторов.

7 SOI fHplorei

2bje« Cdonacy Edt Веч оеюгн н*

Ь JC *•'"> ~» и ^ -7- H ч *-

-IDI*

H f- r- .' •

Л1 Dalabase ASase; Execute SOL querie: in djltoiie IBLocal

Databases j Diclionay |

- .Jfi IBLocai

>_ gj Tables

i. Ш COUNTRY'£ B! OJSTOIHER- mi fflljHnESiIi

Ь ^Э Coluriris*' И ОЕРТ NO.- BSD DEPARTMENT

5 Щ HEAD OEPT

;•; ШП MNGR.MOHI И BUDGET

'* H LOCATIOM

:• И PHONE.NO*• Ш 'ndeet

». Ц Re(«ent«lCor attaint;.-. |3 Unique Constiai-its[fi Й1 Cbeck Constraints

[-. & Tfigge«&

• ffll EMPLOYEE J

Oefimtion Teri [Data ErteSQLJ

j£DEPT NQ|DEPARTMEMTooo

5 100

~ 115lie120121123125131HO180

" 600620621

LiU

Cojporale Headquailjrs

Sale: and Maketngо r o- u

Field I чее . аза ,

Field Office. Sngapoie

E uopean H eadquailers

Field Oflce. 5«tierlenl

",= с Office Fiance

Field Oflee Italy

Field Qir.ce. East Coast

Feld Office Canada

Marketing

Engineering

Eollwse Products Div.

SoltwareDevelopinenl

HEAD DEPT|MNGR no-'.-:

DOO 85

110 113

110100 36

120 141

120 134

120 121

100 11

100 72

100

000 2

600

его

BUDGET (LOCATION i j1000СШ Мошнеу

2000000 SanFtanceco

500000 Tokyo

300000 Sngapore

700000 London

500000 Zjfh ,

400000 Cannet — '

400000 Mian

500000 Boson

500000 Toronto

15QCODO San Franc ico

1100000 Morteny

1200000 MonWoy

400000 Monterey _^J

±J

3 rows were aff ected ,;

Рис. 7.З. SQL Explorer

В комплект Delphi входит инструмент Database Desktop, предоставляющий про-стой графический инструментарий, не требующий знания языка SQL, для созда-ния новых таблиц, изменения структуры уже существующих таблиц и вводазначений.

КОМПОНЕНТЫ для ДОСТУПАК ИСТОЧНИКАМ ДАННЫХDelphi позволяет реализовывать различные механизмы манипулирования дан-ными. Самый простой механизм управления данными может быть реализован последующей схеме.

Page 254: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

254 Глава 7

В модуль данных (или в форму) добавляется компонент набора данных (по-томок класса TDataSet). Через него устанавливается связь с источником данных(свойство DatabaseHame). Связь может быть указана одним из трех способов - поимени базы данных, каталогу или псевдониму (способ указания связи можетбыть ограничен типом источника данных).

Список всех псевдонимов доступен на этапе проектирования.

В модуль данных (или в форму) добавляется компонент источника данных(TDataSourse), выполняющий связь между набором данных и элементами управ-ления, отображающими эти данные. Для него устанавливается значение свойстваDaraSet, указывающее на набор данных (например, на компонент типа ТТаЫе).

Если компоненты набора данных и источника данных расположены в модуледанных, то их следует добавить в проект {команда меню File | Use unit).В форму добавляются элементы управления для работы с данными. Дляних определяется используемый источник данных (свойства DataSource, Data-Field).

Графически схему работы с базами данных для двухзвснных архитектур в средеDelphi можно представить следующим образом:

r r u flU

Провайдеры OLE Dli Машина бач данныхBDE

1 Database[необязательный]

Связующие KOMTDutaSwirce

r r uВизуальные компоненты для работы сланными

TDBGrid. TDBEdit, TDBTcxt. TDBMemo, TDBNavigetor и др.

Page 255: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 255

Наборы данныхПредком всех классов наборов данных является класс TDataSet. Он определяетоснову структуры всех наборов данных - массив компонент типа TField (каж-дый элемент массива соответствует столбцу таблицы).Набор данных - это упорядоченная последовательность строк, извлеченных изисточника данных. Каждая строка набора данных состоит из полей, указываемыхв свойствах класса. Иногда набор данных также называется результирующим па-бором. Наборы данных типа ТТаЫе, TQuery и TClientDataSet можно рассматри-вать как некоторый кеш памяти, отводимой на клиенте под результаты запроса.В зависимости от архитектуры, используемой приложением, базовыми классаминабора данных являются:TDataSet - для однозвенной архитектуры (использующей плоские файлы);

TClientDataSet - для многозвенной архитектуры (использующей распределен-ный доступ). TCtientDataSet - потомок класса TDataSet;TADODataSet - для приложений, использующих ADO-объекты. TADODataSet -потомок класса TDataSet;ТТаЫе, TQuery, TStoredProc - для однозвенных или двухзвениых приложений,использующих машину баз данных BDE;TBDEDataSet, TDBDataSet, TQuery, TStoredProc, ТТаЫе - для создаваемых компо-нентов наборов данных, использующих машину баз данных BDE непосредст-венно в клиентском приложении.TSQLDataSet - для доступа к базе данных посредством dbExpress. Этот классреализует направленный набор данных, (unidirectional dataset), функционирую-щий по принципу курсора. Для такого набора данных не создается кеш памятина клиенте и среди методов доступа возможны только методы Next и First. Ре-дактирование записей в направленном наборе данных возможно только явнымвыполнением SQL-оператора UPDATE или при установке соединения с клиент-ским набором данных через провайдера;TSQLTable и TSQLQuery - для доступа к базе данных посредством dbExpress.Иерархия классов наборов данных приведена на рис. 7.4.Наборы данных указываются различными свойствами, в зависимости от классанабора данных. Для того чтобы приложение знало, откуда брать данные, следуетопределить:

* для класса ТТаЫе - значения свойств DataSourse и ТаЫеКате;

* для класса TQuery - значение свойства SQL.

Для того чтобы читать данные из таблиц или записывать их в таблицы, наборданных предварительно должен быть открыт.Открыть набор данных можно двумя способами:

* установить значение свойства Active набора данных равным True во времявыполнения или в инспекторе объектов (например, Tablel.Active := True;);

* вызвать метод Open (например, Tablel . Open;).

Page 256: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

256 Глава 7

TDaiaSet

jstornADODataSei TBDEDalaSet TChenlDataSet

TADOCommand

TADODataSei

TADOQuery

TNestedTable

TDBDataSet

TADOStoredProc

TTable

TQuery

TSloredProc

Рис. 7.4. Потомки класса TDataSet

Аналогично закрыть набор данных можно вызовом метода Close или установивзначение свойства Active равным False.Активная запись определяет текущую позицию открытого набора данных, накоторую указывает курсор.

Класс TDataSetРасположен в модуле db

Класс TDataSet инкапсулирует множество независимых от БД свойств, событийи методов для работы с данными.Большинство из методов класса TDataSet являются абстрактными (отмеченыключевым словом abstract и не имеют реализации) или виртуальными. Абст-рактные методы не могут быть вызваны как методы класса TDataSet. И абст-рактные и виртуальные методы переопределены с учетом конкретных наборовданных в классах-потомках, таких, как TClientDataSet, TBDEDataSet, TDBDataSet,TQuery, TStoredProc, TTable.

Для того чтобы лучше понять, за что отвечают компоненты набора данных, рас-смотрим некоторые наиболее общие их свойства и методы.

СВОЙСТВА:

property Active: Boolean;Определяет, открыт ли набор данных.Открытие набора данных влечет за собой:

• выполнение обработчиком событий BeforeOpen и AfterOpen;

Page 257: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 257

* установку состояния набора данных в dsBrowse;

ш открытие курсора для набора данных.

Отметим, что если в момент открытия набора данных произошла ошибка, тосостояние набора данных устанавливается в dslnactive, а курсор закрывается.

property ActiveRecord: Integer; [только для чтения)Указывает номер активной записи во внутреннем кеше записей.Записи набора данных, отображаемые в элементах управления, находятся вовнутреннем кеше записей.

property CurrentRecord: Integer;Указывает номер текущей записи во внутреннем кеше записей.

Номер текущей и номер активной записи иногда могут не совпадать. Так кактекущая запись - это запись, используемая в данный момент набором дан-ных, то, например, при отображении элемента управления таблица текущаязапись цикличедки изменяется на каждую видимую запись, а номер активнойзаписи при этом не изменяется.

property DataSource: TDataSource;Определяет источник данных или другой набор данных, на основе которыхформируется текущий набор данных.

Это свойство переопределяется для производных классов с учетом особенно-стей формируемых наборов данных.

Значение свойства DataSource всегда должно быть установлено разработчиком.

property Bof: Boolean; (только для ЧТЕНИЯ)Определяет, находится ли курсор на первой записи набора данных.

property Eof: Boolean; (только для ЧТЕНИЯ)Определяет, находится ли курсор на последней записи набора данных.

Отметим, что если одновременно значение свойств Bof и Eof равны True, тонабор данных пуст.

property Bookmark: TBookmarkStr;Определяет текущую закладку в наборе данных {как значение типа typeTBookmarkStr: siring;). Закладка отмечает позицию в наборе данных (за-пись). Используя методы TDataSet.GetBookmark и TDataSet.GotoBookmark,приложение может запоминать и быстро переходить на нужную позициюв наборе данных.

property FieldCount: Integer;Указывает количество компонентов полей, ассоциированных с набором данных.Для постоянных полей значение этого свойства не изменяется при открытиинабора данных, а для динамически создаваемых полей может быть различным.

9 Зак. 11

Page 258: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

258 Глава 7

property FieldList: TFieldList;Содержит список компонентов полей (имена полей) в наборе данных.

property Fields: TFields;Содержит список всех неагрегированных компонентов полей в наборе данных.Это свойство используется для доступа к компонентам-полям.Если значение свойства ObjectView равно True, то поля хранятся в массивеTFields.Fields иерархически. Если значение свойства ObjectView равноFalse, то дочерние поля хранятся последовательно.Свойство Fields позволяет выполнять последовательные итерации над всемиполями набора данных. Это свойство также применяется для доступа к дина-мически создаваемым столбцам.

Для того чтобы прочитать значение символьного поля в элемент управления ти-па TEdit, можно выполнить, например, следующий код:

EditI.Text := Tablel.Fields.Fields[6].AsString;Наоборот, для того чтобы присвоить значение, отображаемое в элементе управ-ления поле, можно выполнить одно из трех следующих действий:

Tablel.Edit;Tablel .Fields.Fields[6].AsStr ing := Edit1.Text;Tablel.Post;

Свойство Fields позволяет:

* получить имя поля в текущей структуре записи. Например:

var S: String;beginS := Fields[0].FieldName; [Имя первого поля)S := Fields[0].FieldName; (Имя второго поля}. . . "*end;

* записать в переменную значение поля. Например:

var S: String; I: Integer; F:Double; DT: TDateTime;L: Boolean;

S := Fields[0].AsString;I := Fields[OJ.AsInteger;F : = Fie lds[0] .AsFloat;DT := Fields[0].AsDate;L := Fields[0].AsBoolean;

Вместо Fields[n] можно использовать функцию FieldsByName('имя_поля') .Так, следующие две строки кода эквивалентны:

S := Fields[OJ.AsString;S := FieldsByName('Fieldl ') .AsString;

Page 259: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 259

property Filter: string;Определяет текст текущего фильтра для набора данных.Фильтр определяет условие, которому должны удовлетворять доступныезаписи.

Определение фильтра должно удовлетворять следующим правилам:

« фильтр состоит из условии для полей набора данных, объединенных логиче-скими операциями and и or. Например: Fieldl <> 'ААА' or Fieldl = NULL;

* если имя поля содержит пробелы, то оно должно быть заключено в квадрат-ные скобки. Например: [Field Hamel] > 100;

• фильтр может содержать сравнение полей для всех SQL-таблиц, за исключе-нием некоторых локальных таблиц (Paradox, dBASE, Access, FoxPro). Напри-мер: Fieidl <> Field2.

На установление фильтра также влияет значение свойства FilterOptions.

property Found: Boolean; (только для ЧТЕНИЯ)Определяет, успешно ли выполнен поиск для методов FindFitst, FiridLast,FindNext или FindPrior.

property Modified: Boolean; (только для ЧТЕНИЯ)Определяет, была ли изменена активная запись.

property RecordCount: Integer; (только для ЧТЕНИЯ)Указывает общее число записей в наборе данных.

property State: TDataSetState; (только для ЧТЕНИЯ)Указывает текущее состояние набора данных.

Это свойство может принимать следующие значения:dslnactive - набор данных закрыт;dsBrowse - первоначальное состояние при открытии набора данных, данныеможно только просматривать;dsEdit- можно изменять активную запись;dslnsert - активной записью является новая запись, пока не сохраненная;dsSetKey - просмотр ограниченного множества записей (SetRange) или поискзаписи. Состояние доступно только для компонентов типа ТТаЫе илиTCHentDataSei;dsCalcFiehis - выполняется обработчик события OnCalcFields. Нельзя редакти-ровать невычисляемые поля и вставлять новые записи;dsFilter- выполняется обработчик события OnFilterRecord;dsOpening - набор данных находится в процессе открытия.

Page 260: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

260 Глава 7

Процедуры и функиии для добавления, удаленияили изменения записей

procedure CheckBrowseMode;Автоматически вызывается приложением для передачи сделанной модифи-кации данных в базу данных или отмены ее при изменении активной записинабора данных.Этот метод вызывается, если набор данных находится в состоянии dsEdit,dslnsert или dsSetKey.Если набор данных находится в состоянии els Edit или dslnsert, тоCheckBrowseMode вызывает метод UpdateRecord и в том случае, если значениесвойства набора данных Modified равно True, вызывает затем метод Post.Если значение свойства набора данных Modified равно False, то вызываетсяметод Cancel.Если значение свойства State набора данных равно dsSetKey, то вызываетсяметод Post.Если значение свойства State набора данных равно dslnaciive, то иницииру-ется исключение.

procedure Append;Добавляет в конец набора данных новую пустую запись и делает ее активной.Далее эта запись может быть добавлена в таблицу вызовом методов Post илиApplyUpdates.Отметим, что ее физическое расположение в таблице зависит от используемогоисточника данных и того, проиндексирована ли данная таблица.

procedure Delete;Удаляет активную запись из базы данных и перемещает курсор на следующуюзапись.Если в момент удаления набор данных неактивен, то инициируется исключение.При удалении записи выполняются обработчики событий BeforeDeleteи AfterDelete.

procedure Edit;Разрешает редактирование активной записи набора данных.Лри этом если набор записей пуст, то вызывается метод Insert.Перед редактированием записи вызывается CheckBrowseMode для обработкиизменений, выполненных над предыдущей записью, а затем выполняется об-работчик события BefbreEdit. После завершения редактирования выполняетсяобработчик события AlterEdit.

procedure Insert;Вставляет в набор данных новую пустую запись и делает ее активной.

Page 261: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 261

procedure InsertRecortKconst Values: array of const);Вставляет в набор данных новую запись, заполненную указанными значе-ниями, и передает ее базе данных.Например:

CustTabl.InsertRecord ( [Editl.Text, Edit2.Text, Edit3.Text,Hull, Null, Edit4.Texc] ) ?

procedure Post; virtual;Виртуальный метод, реализуемый всеми потомками класса TDataSet, для за-писи измененных записей в базу данных.

procedure Refresh;Извлекает данные из базы данных для обновления набора данных.

procedure SetFields(const Values: array of const);Устанавливает значения всем полям записи, используя порядок полейв таблице. Значениями полей могут быть литералы, переменные, NULL или nil.

procedure ClearFields;Удаляет содержание всех нолей активной записи.

function FieldByName(const FieldName: string): IField;Определяет поле по его имени.Если указанного имени не существует, то инициируется исключениеEDaiabaseError,

Например:

if Tablel.FieldByName('NameFl').Calculated thenMessageDlg(Format( 'Is это вычисляемое поле',

[ ' N a m e F l ' ] ) , mtInformation, [mbOK], 0 ) ;

Для того чтобы записать значение в поле таблицы базы данных, достаточноуказать следующий код:

Tablel.FieldByName('NameFl1).Aslnteger :=StrToInt(Editl .Text);

function FindField(const FieldName: string): TField;Выполняет поиск поля, заданного по имени.Эта функция может использоваться для доступа к полю. Например:

FindField ( 'NameFl M.AsSt r ing := 'ABCDE 1 ;

Если поле 'NameFl' является первым нолем в наборе данных, то для доступак этому полю можно использовать свойство Fields. Однако это менее надеж-ный путь.

Например: Fields [0] .AsString := '1234' ; .

Page 262: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

262 Глава 7

procedure Cancel; virtual;Отменяет изменения, сделанные в активной записи и еще не внесенные в базуданных.

procedure Close;Закрывает набор данных.

Процедуры и функции для навигации по набору данных

procedure First;Устанавливает курсор на первую запись набора данных и делает ее активной,одновременно устанавливая значение свойства Bof равным True.

procedure Last;Устанавливает курсор па последнюю запись набора данных и делает ее ак-тивной, одновременно устанавливая значение свойства Eof равным True.

procedure Next;Перемещает курсор на следующую запись набора данных и делает эту записьактивной.

procedure Prior;Перемещает курсор на предыдущую запись набора данных и делает эту за-пись активной.

Класс TDataSourceРасположен в модуле db

Класс TDataSource обеспечивает интерфейс между компонентом набора данныхи элементом управления.Любой набор данных, отображаемый или редактируемый элементами управле-ния, должен быть ассоциирован с компонентом источником данных. Аналогич-но и любой элемент управления должен быть ассоциирован с компонентом ис-точником данных для управления получением и манипулированием данными.При построении отношений между таблицами родительская-дочерняя компо-нент источник данных служит для связывания наборов данных.

Свойства:

property AutoEdit: Boolean;Определяет, будет ли автоматически вызываться метод Edit набора данныхпри получении фокуса элементом управления, ассоциированного с источни-ком данных.По умолчанию значение свойства равно True - разрешено изменение данных.

property DataSet: TDataSet;Определяет ассоциируемый набор данных.

Page 263: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 263

Набор данных может быть указан компонентами типа TTable, TQuery,TStoredProc,Изменяя значение свойства DataSet во время выполнения, можно эффективнопереключаться на работу с различными наборами данных в одних и тех жеэлементах управления.Например: DataSource,DataSet := Table!;.

Напомним, что источник данных может быть расположен как на форме, таки в модуле данных. В последнем случае для добавления модуля данныхв проект следует выполнить команду меню File | Use unit.

property Enabled: Boolean;Если значение свойства равно True (по умолчанию), то элемент управлениябудет отображать ассоциированные с ним данные. В противном случае эле-мент управления будет пустым.

Класс ТТаЫеРасположен в модуле dbtables

Компонент типа ТТаЫе используется для доступа к базам данных через BDE. Онпозволяет работать с таблицами Paradox, dBASE, Access, FoxPro, ODBC-источниками данных, а также с SQL-серверами, расположенными на удаленномкомпьютере, такими, как InterBase, Oracle, Sybase, MS-SQL Server, Informix и DB2.Компоненты класса TTable поддерживают следующие операции над наборомданных:

* навигация по записям;

* модификация, добавление и удаление записей;

* установка и использование фильтра;

* использование индексов;

* отображение упорядоченных данных.

Во время проектирования, используя контекстное меню компонента типаТТаЫе, можно:

* вызвать Fields Editor для определения списка доступных полей;

* удалить или переименовать выбранную таблицу базы данных;

* вызвать SQL Explorer для просмотра структуры и содержимого полей табли-цы, просмотра и редактирования элементов словаря данных, а также для вы-полнения SQL-операторов.

Если просматриваемая таблица принадлежит SQL-серверной базе данных, то настранице Text правой панели SQL Explorer (рис. 7.5) показывается SQL-опера-тор, выполняемый для создания таблицы, индексов, первичного и вторичногоключей, триггеров, в зависимости от выбранного на левой панели элемента сло-варя данных.

Page 264: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

264 Глава 7

7: SQL ExplorerQbject Dictionary Edit Options Це1р

& /^ О С""

All Database Aliases

Databases j Dictionary

3 qg Databasesffi S& DBDEMOS!+l Sg DefaultDD3 i'n> IBLocal

^ ^ . и - ^ w r| ТЫ of CUSTOMER

DetWion Text j Data j Enter SQL j

*

: R Ш Domaini1 а Ш fables

Ш ШВ COUNTRY — JS ID CUSTOMER

й-Й: i+ HJ

+' iffH. к [щ|

+. fflЛ 1Й1Hjjj

Tolumnsndices

p - i.

^eierer.tial Constraints

Jnlque Constiaints

Theck Constiaints

T/iggeis _rj

C R E A T E TABLE CUSTOMER (CUSTJJ0 CITSTHO HOT HULL,CUSTCHER VARCHAE(ZS> HOT HULL,COHTACT_FIfcST FIPSTHAHE,

C011IACT_LA3T LASTHAHB,PHONE MO PHOUEHUMEEE,

ADDRESS ЫЫЕ1 ADDBESSLIME,APHRESS LI1JE2 ADDRESSLIHE,CITY UARCHAHtZS),STATE PROVIUCE V A R C H A C U E J ,CDUHTRY COUHTRYHAMB,POSTAL CODE UARCHARI12),OW_HOLD CHARU) DEFAULT HULL

'1

^J .iT7 items in CUSTOMER. . ^

Рис. 7.5. SQL Explorer с таблицей локальной InterBase

Для того чтобы лучше понять, какие действия может выполнять пользовательнад набором данных типа ТТаЫе, рассмотрим некоторые наиболее общие свой-ства и методы этого класса, за исключением тех, которые являются общими длявсех наборов данных и были описаны выше в разделе "Класс TDataSet".

Свойства:

property DatabaseName: String;Определяет имя базы данных, используемое для компонента набора данных.Для определения значения свойства DatabaseName можно использовать пред-лагаемый список всех доступных псевдонимов баз данных. Имя таблицы сле-дует устанавливать только после определения имени базы данных, выбираяего из предлагаемого списка.

property CanModify: Boolean; [только для ЧТЕНИЯ)Определяет, может ли приложение выполнять вставку, редактированиеи удаление записей в таблице.

На значение этого свойства влияет свойство Readonly и имеющиеся привиле-гии доступа.

Page 265: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 265

property Defaultlndex: Boolean;Указывает, должны ли данные в таблице быть упорядочены при ее открытии.Если значение свойства равно True (по умолчанию), то при открытии табли-цы на SQL-сервере BDE использует фразу ORDER BY. Упорядочение вы-полняется по первичному ключу или уникальному индексу.

property Exclusive: Boolean;Определяет режим доступа к таблице. Значение этого свойства должно бытьопределено до открытия таблицы. Также таблица должна быть закрыта доизменения значения этого свойства.Если во время проектирования для таблицы установлено свойство Activeравным True, то исключительный доступ к таблице невозможен, так как IDEуже имеет доступ к этой таблице. При попытке исключительного доступа бу-дет инициировано исключение.

Режим блокировки доступа на уровне таблицы возможен только в том случае, ес-ли используемая база данных или SQL-сервер поддерживает такую блокировку.

property IndexDefs: TlndexDefs;Содержит информацию об установленных для таблицы индексах.Количество индексов указывается как Tablel .IndexDefs.Count, а доступк конкретному индексу из массива индексов как

Tablel.TndexName := Tablel.IndexDefs.Iterns[i].Name;

Для того чтобы найти индекс для конкретного поля, можно организоватьцикл по всем индексам и ввести код:

if Tablel .IndexDefs.Items[i] .Fields = 'CustNo;OrderNo' then.

При выборе значения свойства IndexDefs открывается диалог редактор индексов(рис. 7.6), в котором можно добавить новые индексы или удалить существующие.

If Editing Table2.lndexDeIs i

D-<PrimariJ>

1 -CuslNo

Рис. 7.6. Редактор индексов

Для того чтобы получить список индексов, доступный для данной таблицы,свойство IndexDefs следует заполнить значениями. Это выполняется вызовомметода Update (например, Tablel.IndexDefs.Update).

Пример:

{Свойство IndexName используется для сортировки записей в таблице по

полям CustNo и QrderNo)

Page 266: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

266 Глава 7

Tablel.Active := False; {Закрытие набора данных)Table!.Exclusive := True,- {Доступ в исключительном режиме)Tablel.IndexDefs.Update; [ Получение доступных индексов. Объект

класса TIndexDefs содержит список доступных индексов длятаблицы. Метод Update класса TIndexDefs выполняетобновление определений индекса в свойстве Items безпредварительного открытия набора данных.}

{ Поиск составного индекса на базе полей CustNo и OrderNo:]for i := 0 to Tablel.IndexDefs.Count - 1 do

if Tablel.IndexDefs.Iterns[i].Fields = 'CustNo;OrderNo' {СвойствоItems содержит список описаний индексов. Для полученияимени поля, по которому создан индекс, используетсясвойство Fields объекта типа TlndexDef.}

then{ Установка найденного индекса как текущего для таблицы }Tablel.IndexName := Tablel.IndexDefs.Iterns[i].Name;

Tablel.Exclusive := False;Tablel.Active := True; (Получение набора данных на основе

выбранного индекса!

property IndexFieldCount: Integer; (только для ЧТЕНИЯ)Указывает количество полей, образующих текущий индекс. Если индекс по-строен на базе одного поля, то значение этого свойства равно 1.

property IndexFieldNames: String;Содержит список столбцов, которые используются как индексы таблицыи служат для упорядочения значений в указанных столбцах. Имена полейв списке разделяются точкой с запятой.

Для таблиц Paradox и dBASE любые имена полей, указываемыев IndexFieldNames, предварительно должны быть проиндексированы. Длятаблиц SQL-баз данных предварительная индексация не требуется.Отметим, что свойства IndexFieldNames и IndexName являются взаимоис-ключающими: определение одного свойства очищает значение другого.

property IndexFields: [Index: Integer]: TField;Содержит список полей для текущего индекса.

property IndexName: String;Определяет вторичный индекс таблицы. Если значение IndexName пусто, топорядок сортировки записей основывается на индексе, используемом поумолчанию. А для таблиц dBASE используется физический порядок записей.Если значение свойства IndexName установить равным значениюTablel.IndexDefs.Items[IJ.Name, а затем открыть набор данных, то он будетотсортирован по выбранному индексу.

Page 267: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 267

Пример:

{Форма содержит три кнопки, используемые для изменения порядка сортировкинабора данных, отображаемого компонентом DBGridl}unit Unitl;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls,Forms, Dialogs, DB, Grids, DBGrids, DBTables, StdCtrls;

typeTForml = class(TForra)

Tablel: T-Tabie; (Набор данных]DBGridl: TDBGrid; {Таблица для отображения набора данных}DataSourcel: TDataSource; {Источник данных)TablelEMP_NO: TSmallintField; {Поля набора данных}TablelFIRSTJIAME: TStringField;TablelLAST_NAME: TStringField;Table1DEPT_NO: TStringField;TablelJOB_CODE: TStringField;TablelJOB_GRADE: TSmallintField;Table1JOB_COUNTRY: TStringField;Buttonl: TButton;Button2: TButton;ButtonS: TButton;procedure ButtonlClick(Sender: TObject);procedure Button2Click(Sender: TObject);procedure Button3Click(Sender: TObject);

private( Private declarations }

public{ Public declarations }

end;varForml: TForml;

implementation($R '.dfm|procedure TForml.ButtonlClick(Sender: TObject);

beginTablel.Active := False;Tablel.IndexDefs.Update;Tablel.IndexName := Tablel.IndexDe£s.Items[l].Name;Tablel.Active := True;end;procedure TForml.Button2Click(Sender: TObject);begin

Page 268: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

268 Глава 7

Tablet.Active := False;Tablel.IndexDefs.Update;

Tablel.IndexName := Tablel.IndexDefs.Items[2].Name;Tablel.Active := True;

end;

procedure TFonnl.EuttonSClick(Sender: TObject);beginTablel.Active := False;

Tablel.IndexDefs.Update;Tablel.IndexName := Tablel.IndexDefs.Items[3].Name;Tablel.Active := True;

end;end.

property MasterFields: String;Определяет одно или несколько полей из родительской таблицы, служащихдля связи с соответствующими полями данной дочерней таблицы. Это опре-деляет отношение между родительской и дочерней таблицами. Поля в спискеразделяются точкой с запятой.Отметим, что предварительно следует установить источник данных роди-тельской таблицы в свойстве MasterSource.

При двойном щелчке мышью в поле значения свойства MasterFields (илипри щелчке на кнопке J, расположенной справа от значения свойства) от-кроется диалог Field Link Designer {рис. 7.7).

-ield Link Designer

Available Indexes | Primary

Detail Fields

Рис. 7.7. Диалог Field Link Designer

Page 269: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 269

В этом диалоге следует указать, какое поле дочерней таблицы будет связанос полем родительской таблицы. Указанное поле станет значением свойстваMasterFields.

property MasterSource: TDataSource;Определяет имя компонента источника данных родительской таблицы дляустановления отношения между таблицами родительская-дочерняя. Наборданных, ассоциированный с указываемым источником данных, становитсяродительской таблицей, а текущая таблица - дочерней.

Значение свойства MasterSource можно выбрать из предлагаемого спискавсех доступных источников данных.

property ReadOnly: Boolean;Позволяет установить для таблицы режим доступа только для чтения.

property TableName: TFileName;Указывает имя таблицы базы данных.

property SessionName: String;Определяет имя компонента сеанса данных, ассоциируемого с набором дан-ных. Если значение этого свойства пусто, то набор данных автоматически ас-социируется с сеансом данных по умолчанию Session.

property Filter: String;Определяет текущий фильтр (условие) для набора данных.

При назначении фильтра будут доступны только те записи, которые удовле-творяют установленному фильтру.

Примеры:

Tablel. Fi l ter :='CustNc>10' and 'CustNo<10QQ';Tablel. Fi l ter :='Si ty='C* ' ;

property Filtered: Boolean;Определяет, будут ли доступны только отфильтрованные записи набора дан-ных или все записи.

Пример:

{Поле Editl содержит значение устанавливаемого фильтра. Кнопка Buttonl

используется для установки нового значения фильтра}

procedure TFormI.ButtonlClick(Sender: TObject);

beginTablel. Filter:=Editl.Text;Tablel.Filtered:=True; (Определяет, что фильтр будет использован)

end;

Page 270: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

270 Глава 7

property RecNo: Longint;Указывает номер текущей записи набора данных.

Процедуры и функции:

function FindKey(const KeyValues: array of const): Boolean;Выполняет поиск значения или значений, перечисленных в списке, для клю-чевого поля. Количество значений в списке должно соответствовать количе-ству полей, на которых базируется индекс (ключевое поле).

procedure EmptyTable;Удаляет из таблицы все записи.

procedure FindNearestfconst KeyValues: array of const);Перемещает курсор на запись, наиболее близкую к указанному значениюключевого поля (индекса). Массив, передаваемый методу FindNearest как па-раметр, должен содержать столько значений, сколько полей определено в со-ставном индексе. Если число значений, указываемое через запятую, меньшеколичества полей составного индекса, то оставшиеся значения будут принятыравными NULL. Для индекса по одному полю указывается одно искомое зна-чение (например, Tablel. FindNearest ( [ ' Forest ' ] ) / ' ! •

Пример:

(Изменение значения в компоненте Editl будет автоматически перемещатьпозицию курсора в наборе данных Tablel}procedure TForml.FormActivate(Sender: TObject);begin

Tablel.DatabaseName := 'DBDemos 1 ;Tablel.TableHarae := 'Customer.db ' ;Tablel .Active := True;Tablel.IndexName := 'ByCompany'; (Ключевое поле)

end;(Обработчик события OnChange для компонента Editl}procedure TForml.EditlChange(Sender: TObject);begin

Tablel.FindNearest([Editl.Text]); {Выполнение поиска]end;

procedure GotoCurrent(Table: ТТаЫе);Устанавливает текущей записью набора данных текущую запись для набораданных, указанного параметром. Это возможно для наборов данных, исполь-зующих разные источники данных, но ссылающихся на одну и ту же таблицубазы данных: значения свойств DatabaseName и TableHame для синхронизи-руемых наборов данных должны совпадать.

Page 271: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 271

procedure SetKey;Метод обнуляет буфер значений, используемый для поиска, и переводит на-бор данных в режим dsSetKey. Для того чтобы выполнить поиск, следует оп-ределить новый набор искомых значений, используя метод FieldByName.

Пример:

with Tablel do

beginSetKey;

FieldByName('State1).AsString := 'C

1;

FieldByName('City').AsString := 'London';GotoNearest;

end;

function GotoKey: Boolean;Перемещает курсор H;I запись, указанную для текущего ключа, и при успеш-ном поиске возвращает значение True.

Пример:

with Tablel dobeginEditKey; {Вызывается, чтобы не изменять текущие

значения ключевых полей)

FieldByNamef'State') .AsString := 'С';

FieldByNajne('City').AsString := 'Moscow';

GotoKey;

end;

procedure SetRange(const StartValues, EndValues: array of const);Устанавливает начальное и конечное значение ранга доступных записей. Па-раметр StartValues указывает значение поля, даваемое первой записи в ранге,а параметр EndValttes - последней записи в ранге.Процедура SetRange заменяет отдельное выполнение трех процедурSetRangeStart, SetRangeEnd и AppIyRange.

После выполнения SetRange:

• набор данных переводится в состояние dsSetKey;

• отменяются ранее установленные границы ранга записей;

• устанавливаются новые начальное и конечное значения для ранга;

• выполняется назначение ранга набору данных.

Page 272: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

272 Глава 7

Отметим, что если для параметров указано меньше значений, чем полей, накоторых базируется текуиши индекс, то недостающие значения устанавлива-ются равными NULL.

Для баз данных Paradox и dBASE процедура SetRange работает только дляиндексированных полей. Для SQL-баз данных SetRange может работатьс полями, укачанными в списке IndexFieldNaraes.

Пример:

{При каждом щелчке на кнопке Buttonl выполняется попеременно то установкаранга, то его отмена, в зависимости от значения поля Caption }procedure TForml.ButtonlClick(Sender: TObjec t ) ;begin

Tablel.DatabaseNarae := 'DBDemos'; (Имя БД}Tablel.TableName := 'Customer.db'; {Имя таблицы)Tablel.Active := True;Tablet.IndexHame := 'ByCompany'; {Текущий индекс}if Buttonl.Caption = 'Установить ранг 1 then

beginTable l .SetRange([Edit l .Text] , [Edit2 .Text]) ;Buttonl-Caption := 'Отменить ранг 1 ; {Новый заголовок}

endelse

beginTablel,CancelRange;Tablel.Refresh;Buttonl.Caption := 'Установить ранг';

end;end;

function Locate(const KeyFields: String; const KeyValues: Variant; Options:TLocateOptions): Boolean;Выполняет для указанных полей KeyFields поиск первой записи, содержащейзначения KeyVaiues, и при успешном завершении делает эту запись текущей.

Поля в списке полей KeyFields разделяются символом ;.

Для того чтобы определить вариант для поиска, используется процедураVarArrayOf.Например:

with Tablel doLocate( 'Corapany;Sity ', V a r A r r a y O f ( [ ' A B C 1 , ' M o s c o w ' ] ) .

[ioPartialKey]);

Options определяет параметры поиска.

procedure Post; override;Записывает измененную запись в базу данных.

Page 273: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных

Для класса ТТаЫе предусмотрены следующие обработчики событий:

OnUpdateError

AfterClose

Afterlnsert

AfterRefresh

BeforeClose

Beforelnsert

BeforeRefreshOnDeleteError

OnNewRecord

OnUpdateRecord

AfterDelete

AfterOpen

AfterScroll

BeforeDelete

BeforeOpen

BeforeScroliOnEditError

OnPost-Error

AfterCancel

AfterEdit

AfterPost

BeforeCancel

BeforeEdit

BeforePost

OnCalcFields

GnFilterRecord

Класс TQueryРасположен в модуле dbtables

Компонент типа TQuery реализует доступ к базам данных через BDE, используядля формирования набора данных SQL-оператор. Он позволяет работать с таб-лицами Paradox, dBASE. Access. FoxPro, ODBC-источниками данных, а такжес SQL-серверами, расположенными на удаленном компьютере, такими, какInterBase, Oracle, Sybase. MS-SQL Server, Informix и DB2.Наборы данных, извлеченные из таблиц базы данных с помощью SQL-оператора,называются результирующими наборами.В отличие от класса ТТаЫе класс TQuery позволяет создавать наборы данных изнескольких таблиц, а также ограничивать получаемый набор данных определен-ными условиями. Это позволяет избегать необходимости извлечения всех запи-сей таблицы в набор данных, что в свою очередь экономит память, сокращаетсетевой трафик для удаленных баз данных и уменьшает время доступа.Для определения набора данных TQuery следует установить значение свойствDatabaseHame и SQL.

Класс TQuery можно использовать для разработки масштабируемых приложенийбаз данных. Он позволяет абстрагироваться от типа базы данных и ее располо-жения, а также от конкретной структуры таблиц.Основным препятствием в использовании класса TQuery может стать недоста-точное знание структурированного языка запросов SQL. Поэтому кратко рас-смотрим основы синтаксиса операторов управления данными SELECT, INSERT,DELETE и UPDATE.

Оператор SELECTОператор SELECT определяет, какие поля из каких таблиц должны образоватьновую временную таблицу - набор данных — и какие записи, удовлетворяющиеусловию WHERE, должны быть добавлены в этот набор данных.

Оператор SELECT описывается следующим синтаксисом:

SELECT список_столбцовFROM имя таблицы! [A3 имя синонима!]

Page 274: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

274 Глава 7

[, имя таблицы? [AS кмя_синонима2] . . . ]iWHERE предикат]

BORDER BY имя_столбца]

Список столбцов в операторе SELECT можно указывать через запятую, квалифи-цируя при необходимости имя каждого поля именем синонима. Для того чтобывключить в набор данных все поля из указанных таблиц во фразе FROM, доста-точно вместо списка полей ввести символ *.

Фраза FROM специфицирует имена таблиц для включаемых в запрос полей илидля определения условия.

Фраза WHERE позволяет задать условие, содержащее параметры, называемыеиногда переменными связи. 11еред именем переменной связи всегда следует ука-зывать символ :.

Запрос, содержащий параметры, иногда называют параметризироканным запро-сом. Преимуществом такого запроса является то. что его достаточно один разоткомпилировать, а затем его можно выполнять с различными значениями пе-ременных связи без перекомпиляции. Компонент типа TQuery может быть на-строен таким образом, что будет динамически реагировать на любые измененияпеременных связи.Для того чтобы открыть набор данных, достаточно установить значение свойст-ва Active равным True или вызвать метод Open.

Оператор INSERTОператор INSERT добавляет запись в таблицу, указывая, в какие поля ввести ка-кие значения.

Оператор INS5RT описывается следующим синтаксисом:

INSERT INTO жч_таблицы[(имя_поля1, имя_поля2, . . . ) ]VALUES (значение!, значение2, . . . ]выражение_запроса_значений j конструктор_значений

] [DEFAULT VALUES}

Имя таблицы специфицирует, в какую таблицу будет добавлена запись (илизаписи). Список имен полей указывается в круглых скобках и определяет поря-док указываемых значений во фразе VALUES. Если имени поля нет в списке, то внего будет записано значение по умолчанию.

Пример:

INSERT INTO Order (OrderNo,CustNo) VALUES (1190, 2334)

Оператор UPDATEОператор UPDATE изменяет значения одного или нескольких полей таблицыи описывается следующим синтаксисом:

UPDATE имя_таблицы

SET имя псля!= выражение! HULL DEFAULT

Page 275: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 275

[, имч_псля2= выражение2 | NULL DEFAULT . . . ]WHERE предикат WHERE CURRENT OF шя_курсора

Фраза WHERE определяет условия, которым должны удовлетворять обновляемыезаписи. Другой вариант для определения обновляемой записи — фраза WHERECURRENT OF - может быть использован только для курсора, открытого операто-ром OPEN CURSOR, и для записи, позиционированной оператором FETCH.

Оператор DELETEОператор DELETE удаляет из таблицы одну или несколько записей и описываетсяследующим синтаксисом:

DELETE FROM галя_та5лицы! WHERE предикат [ WHERE CURRENT OF имя_курсора ]

Теперь мы можем перейти к рассмотрению наиболее существенных свойстви методов класса TQuery.

Свойства:

property Constrained: Boolean;Определяет, разрешено ли для наборов данных, получаемых из таблицParadox или dBASE, выполнять операции вставки или редактирования, в ко-торых получаемая запись не будет удовлетворять условию фразы WHERESQL-оператора SELECT.

По умолчанию значение свойства равно False и диапазон вводимых значенийне регламентируется оператором SELECT.

property DataSource: TDataSource;Это свойство используется только в том случае, если необходимо указать насвязь с другим источником данных, из которого будут автоматически выби-раться значения переменных связи для фразы WHERE.

Например, если свойство SQL содержит значение 'SELECT * FROM Orders 0WHERE (O.CustNo = : C u s t N o ) ', то значение переменной связи :CustNo будетопределяться из источника данных, указанного свойством DataSource.

property ParamCheck: Boolean;Определяет, следует ли регенерировать список параметров при изменениизначения свойства SQL во время выполнения.

property Params[lndex: Word]TParams;Содержит список параметров для SQL-оператора.

При определении этого списка во время проектирования можно автоматиче-ски создавать объекты Query.Params[i] из редактора параметров, одновре-менно редактируя их свойства в инспекторе объектов.Наиболее просто получить или установить значение параметра можно, ис-пользуя метод ParamByName,

Page 276: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

276 Глава 7

Пример:[Выполнение оператора INSERT для таблицы ADDRESS:Обнуление свойства SQLФормирование оператора INSERTОпределение значений параметровВыполнение SQL-оператора, содержащегося в свойстве SQL}Query3. SQL. Clear;Query3. SQL. Add ( ' INSERT INTO ADDRESS (NAME, S I T Y ) ' ) ;Query3. SQL. Add Г VALUES ( :Name, : S i t y ) ' ) ;Query3.Params[0] .AsStrir.g := 'Смирнов 1;Query3 . Params [ 1 ] .AsString := 'Москва' ;Queryj.ExecSQL;

Для того чтобы использовать параметры (переменные связи), можно вместосвойства Params использовать свойство DataSource, определяя источник дан-ных для извлечения значений параметров.

property RequestLive: Boolean;Определяет, будет ли BDE пытаться получить модифицируемый результи-рующий набор или только для чтения.

Любой набор данных, извлекаемый из нескольких таблиц, всегда создаетсяв режиме только для чтения.

Возможность получения модифицируемого результирующего набора зависитот используемого SQL-сервера.

property SQL: TStrings;

Содержит текст SQL-оператора, который может:

* открыть результирующий набор вызовом метода Open (или при значениисвойства Active равным True);

* быть выполнен вызовом метода ExecSQL.

Синтаксис SQL -оператора ограничивается используемым источником дан-ных и определяется следующим образом:

* для таблиц Paradox и dBASE используется локальный SQL, являющийсяподмножеством стандарта SQL-92;

* для баз данных на Local InterBase Server используются SQL-92 и расшире-ния SQL для InterBase;

* для баз данных на удаленном сервере, использующих драйверы SQL Linksили ODBC, применяется стандарт SQL. ограниченный или расширенныйконкретным сервером.

Для автоматического формирования SQL-оператора можно вызвать из контек-стного меню компонента TQuery диалог SQL Builder (рис. 7.8).

Page 277: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 277

• SQL Builder

D liable [customer .at, Database D60EMOS

SHPToContact(A20)

SMpToAddrl (A30)

ShipToAddr2 (A30)

ShpToCily [A15)

SNpToSlate CA2DJ

CltV CA! 5)

Г Slate СА2ЩГ 2р(А10)Г Сош1гуСА20)

•5QL Buoy Text Enti*Edil Qusry

JDBDEMOS

Dileria j Seladiun j Oroi.fiin3 j Group Criet'ia I Soring Joins

SELECT O.OrdgrNo,Q.SaleDale.O.ShipDfcte,O.CustNo, Customer CustNoFROM Orders 0, " customer db"CustomerWHERE OCjslNo-Customer.CuslMo

JALL _*joflhe following ederiaere met

,-! :

FlelO or Value 'Cotrpare

O.CuilMc.

=

Ficlrf o: Value

GJJ si orner. CustNo *•!

Рис. 7.8. Диалог SQL Builder для формирования запроса

Из списка Table следует выбрать все таблицы, поля которых должны участвоватьв запросе. Выбранные таблицы автоматически будут отображены в отдельныхокнах на верхней панели диалога SQL Builder. Для каждой таблицы следует отме-

тить поля, включаемые в запрос. Далее на вкладке Criteria можно определить ус-

ловие WHERE.

Выбрав команду меню Query|Show SQL, можно посмотреть текст сформированно-го SQL-оператора. Для того чтобы выполнить созданный SQL-оператор и про-смотреть полученный результат в отдельном окне, следует выбрать команду ме-ню Query|Run Query.

Свойство SQL можно изменять и программно. Для этого сначала следует вызвать

метод Clear, а затем метод Add. Чтобы выполнить вновь созданный оператор,следует вызвать метод ExecSQL.

Пример:

Queryl.Close;Queryl.SQL.Clear;

Queryl.SQL.Add['Delete from Order where OderMo = 111Г);

Queryl.ExecSQL;

property Database Name: String;

Имя подключаемой базы данных.

Page 278: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

278 Глава 7

Дополнительно компонент TQuery может использовать наследуемые свойства.Среди них: DBSession, SessionName, CanModify, Filter, Filtered, FilterOp-tions, RecNo, RecordCount, Bof и др.

Процедуры и ф у н к ц и и :

procedure ExecSQL;Выполняет SQL-оператор, записанный в свойство SQL.

Эту процедуру не следует вызывать для оператора SELECT, создающего ре-зультирующий набор. Для пего вызывается метод Open.

ExecSQL можно вызывать для таких SQL-операторов, как INSERT, UPDATE,DELETE, CREATE TABLE И Т. П.

Если перед вызовом ExecSQL не был вызван метод Prepare, то SQL-операторбудет одновременно откомпилирован и выполнен.

procedure Prepare;Выполняет компиляцию SQL-оператора на сервере. Вызов этого метода пе-ред ExecSQL увеличивает скорость выполнения запроса. Особенно важно все-гда вызывать Prepare перед многократным повторением вызовов ExecSQL дляодного и того же оператора (например, параметризированного запроса). Этопозволит только один раз откомпилировать SQL-оператор, а затем много-кратно его выполнять. В противном случае компиляция будет выполнятьсяповторно при каждом вызове ExecSQL.

Для компонента TQuery также можно применять методы для поиска записейи для извлечения значений полей, аналогичные компоненту ТТаЫе.

Класс T S Q L T a b l eРасположен в модуле SqlExpr

Класс TSQLTable представляет таблицу базы данных, доступную на клиенте какнаправленный набор данных. Такой набор данных содержит все записи для по-лей, определенных в компоненте TSQLTable. Для использования компонентаTSQLTable он должен быть сопоставлен компоненту TSQLConnection, определяю-щему соединение с базой данных. Для отображения такого набора данных нель-зя использовать таблицу, так как на клиенте отсутствует кеш памяти для набораданных. Значение полей таблицы можно отображать компонентами TDBText илиTDBEdit. Для навигации но набору записей доступны только методы First и Next.

(##£*!]- ; | После размещении в модуле данных или на форме компонента надо выпол-

jf .; нить следующие действия:

1. Установить значение свойства SQLConnection компонента TSQLTable, выбравдобавленный ранее компонент типа TSQLConnection из предлагаемого списка.

2. Определить имя таблицы базы данных, используемой для построения на-бора данных, определив свойство TableName компонента TSQLTable.

Page 279: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 279

КЛАССЫ, РЕАЛИЗУЮЩИЕ СОЕДИНЕНИЕС БАЗОЙ ДАННЫХПри работе с компонентами наборов даншлх можно обойтись без явного исполь-зования компонентов, реализующих соединение с базой данных. Однако некото-рые возможности, такие, как управление транзакциями, кешированные обновле-ния, невозможны без компонентов типа TDatabase или TADOConnection. Компо-нент база данных. TDatabase применяется для соединения с источником данныхчерез драйверы BDE или напрямую через внешние ODBC-драйверы. КомпонентTADOConnection используется для создания объекта соединение при доступе черезOLE DB, который инкапсулируется посредством ADO-объектов VCL-библиотеки.

Класс TDatabaseРасположен в модуле dbtables

Класс TDatabase (база данных) предоставляет средства контроля над соединени-ем с одной базой данных.

Компонент типа TDatabase позволяет управлять транзакциями, использовать на-страиваемое подключение к серверу (login), определять в приложении свои псев-донимы для базы данных.На самом деле, в любом приложении, использующем компоненты для работыс базами данных, во время выполнения создается временный объект TDatabaseс установленными по умолчанию значениями свойств. И разработчик может несоздавать в приложении своего объекта база данных. Помещать компонентTDatabase в форму (или модуль данных) следует только в тех случаях, когдатребуются более широкие возможности контроля за соединением. В первуюочередь это относится к управлению транзакциями.Транзакция гарантирует, что заключенная в ней последовательность действийбудет полностью выполнена или при возникновении какой-либо ошибки полно-стью отменена.

Для того чтобы открыть транзакцию, следует вызвать метод Star transaction.После этого можно выполнять любые действия, составляющие транзакцию (на-пример, изменение полей в нескольких таблицах). Для успешного завершениятранзакции следует вызвать метод Commit. В случае, если произошла какая-либоошибка, следует выполнить откат транзакции, вызвав метод Rollback, а затемповторно получить набор данных.

Для работы с компонентом TDatabase необходимо установить значение свойствAliasNaree и DatabaseName.

Если значением свойства AliasName указан существующий псевдоним, то разра-ботчик может сам определить любой внутренний (для приложения) псевдонимбазы данных и задать его в свойстве DatabaseName.

В этом случае любой набор данных (например, ТТаЫе или TQuery) будет в спи-ске значений свойства DatabaseName отображать наряду со всеми доступнымипсевдонимами BDE и внутренний псевдоним, заданный свойством DatabaseNaroeкомпонента TDatabase,

Page 280: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

280 Глава 7

В том случае, если псевдоним базы данных не определен, то свойствоDatabaseName должно содержать полное имя файла базы данных, а свойствоDriverName-указывать используемый BDE-драйвер.

Настроить необходимые свойства компонента TDatabase можно, выполнив нанем двойной щелчок мышью (или непосредственно в инспекторе объектов).В открывшемся затем диалоге Form I. Data base I Database (рис. 7.9) следует вы-брать из списка Alias name имя псевдонима, а в поле Name ввести внутреннийпсевдоним базы данных.

Form I.Database! Database

• Database"'1 Ыагпе: name; Driver name:

[MyDB

Parameter overrides:

DBDEMOS

PAT H=DAPro gram FlesSCommon FilesSBorland SharedVDataENABLE BCD=FALSEDEFAULT DRIVER=PARADOX

- П— tupoons

Login prompt

Keep inactive connection

OK Cancel Help

Рис. 7.9. Диалог для настройки свойств компонента TDatabase

Свойства:

property AliasName: String;Указывает псевдоним базы данных, устанавливаемый в BDE Administrator, ко-торый используется для определения подключаемой базы данных.

Отметим, что если значение этого свойства установлено, то любое ранее оп-ределенное значение свойства DriverName будет удалено.

Попытка изменить значение свойства AliasName при активном соединении,когда значение свойства Connected равно True, инициирует исключение.

property Connected: Boolean;Определяет, является ли созданное соединение с базой данных активным.Если соединение не является активным, то перед использованием базы дан-ных набор данных должен быть открыт.

Page 281: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 281

property DatabaseName: string;Определяет внутренний псевдоним (если установлено свойство AliasName)или полное имя базы данных.

property DataSets[Index: Integer]: TDBDataSet; (только для ЧТЕНИЯ)Содержит список всех активных наборов данных для компонента база данных.

Пример:

{Выполнение указанных действий над каждым открытым набором данных}var I: Integer;begin

with Database! dofor I := 0 to DataSetCount - 1 do

if DataSets[I] is TTable then.DataSets[I].CachedUpdates := True;

end;

property DriverName: String;Определяет имя используемого BDE-драйвера (например, STANDARD,ORACLE, SYBASE. INTERBASE).

property Exclusive: Boolean;Позволяет приложению получить исключительный доступ к базе данных.

Если значение этого свойства равно True, то после открытия базы данных ни-какие другие приложения не могут получить к ней доступ.

Отметим, что нельзя одновременно устанавливать значения свойствExclusive и Connected равными True во время проектирования. Так как средаIDE использует базу данных (при значении Connected, равном True), то такаяустановка вызовет исключительную ситуацию.

Для SQL-серверов полностью исключительный доступ может быть реализо-ван только в том случае, если используемый SQL-сервер его поддерживает.Некоторые серверы не обеспечивают исключительной блокировки или по-зволяют при установленной блокировке другим приложениям иметь доступна чтение данных.

Iproperty InTransaction: Boolean; (только для ЧТЕНИЯ}

Определяется, был ли выполнен для базы данных вызов StartTransaction.

property IsSQLBased: Boolean;Определяет, использует ли компонент базы данных драйвер BDE SQL Linksдрайвер, сокет BDE" ODBC или драйверы STANDARD, Paradox, dBASE,ASCII и другие внутренние BDE-драйверы.Если значения свойства равно True, то используется SQL Links драйвер или со-кет BDE (для взаимодействия с ODBC-драйверами сторонних производителей).

Page 282: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

282 Глава 7

property KeepConnection: Boolean;Определяет, будет ли соединение оставаться открытым при закрытии всехнаборов данных.

Это значение свойства должно быть установлено равным True, если разра-ботчик не хочет, чтобы пользователь каждый раз заново подключался к базеданных при закрытии и повторном открытии набора данных.Это свойство влияет на сетевой трафик, позволяя его уменьшить, и соответ-ственно на скорость выполнения приложения.

property Params: TStrings;Содержит параметры для укачанного псевдонима BDE, такие, как путь к базеданных, название сервера, имя пользователя, пароль, и др. Название исполь-зуемых параметров зависит от драйвера базы данных.

Параметры, устанавливаемые по умолчанию, можно посмотреть в диалоге,открываемом по двойному щелчку м ы ш и на компоненте TDatabase.

property Session: TSession; (только для ЧТЕНИЯ)Указывает компонент TSession (сеанс данных), который ассоциирован с ба-зой данных.

ч

Добавление в приложение сеанса данных позволяет управлять базой данныхв многопотоковом приложении.

По умолчанию используется сеанс данных, создаваемый временно при вы-полнении приложения.

property SessionAlias: Boolean; (только для ЧТЕНИЯ)Определяет, использует ли компонент база данных псевдоним сеанса данных.

Псевдоним сеанса данных создается автоматически в том случае, если:

• вместо свойства AiiasName используются свойства DriverMame и Params,содержащие какие-либо параметры;

• значение Params. установленное в соответствии с указанным AiiasName,переопределено.

property SessionName: String;Определяет и м я сеанса данных, используемого компонентом база данных.Если значение этого свойства не установлено, то используется сеанс данныхпо умолчанию, именуемый в коде программы Session.

Во время проектирования значение этого свойства можно выбрать из предлагае-мого списка (размещенных в форме или модуле данных компонентов TSession).

property ReadOnly: Boolean;Определяет, установлен ли для соединения базы данных доступ только начтение.

Это свойство должно быть задано до открытия базы данных.

Page 283: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 283

Если значение этого свойства равно False, то приложение не может ни изме-нять поля таблиц, ни создавать новые таблицы или индексы.Отметим, что для SQL-баз данных одновременно с установкой Readonly ком-понента база данных равным True следует установить и Readonly набора дан-ных (ТГаЫе или TQuery) также равным True.

property Translsolatton: TTransisolation;Определяет уровень изоляции для управления транзакциями посредством BDE.

Уровень изоляции определяет, как данная транзакция будет взаимодейство-вать с другими транзакциями, работающими с одними и теми же таблицами.Альтернативным способом управления уровнем изоляции для приложений,использующим для набора данных режим SQL PASS THRU, является непосредст-венное выполнение SQL-оператор;!, устанавливающего уровень изоляции.

Свойство Translsolation может быть указано одним из следующих значе-ний:tiDirtyRead - транзакция может читать данные, которые были изменены дру-гой транзакцией, но для которых не был выполнен вызов Commit (фиксацияизменений);tiReadCommitted — позволяет в одной транзакции читать фиксированные из-менения, сделанные в базе данных другой транзакцией;tiRepeatableRead - истинность данных гарантируется на все время чтения,и транзакция не видит никаких изменений, сделанных другой транзакцией.Прочитанная запись остается одинаковой, пока в ней не будут сделаны изме-нения внутри самой транзакции.

Однако разные SQL-серверы поддерживают различные уровни изоляциитранзакций. Если в приложении будет выбран уровень изоляции, не поддержи-ваемый конкретным сервером базы данных, то BDE определит более высокийи наиболее соответствующий уровень транзакции.В следующей таблице приведены уровни изоляции, поддерживаемые серверамии узнаваемые BDE.

SQL-серверы

Oracle

Sybase, MS-SOL

DB2

Указанные уровни изоляции

tiDinyReadliReadComrnittedtiRepeaiableRead

tiDirtyReadtiReadCommittedtiRepeatableRead

tiDirtyReaeftiReadCommittedtiRepeatableRead

Действительные уровни изоляции

tiReadCommittedtiReadCommittedtiRepeatableRead (READONLY)

tiReadCommittedtiReadCommittedHe поддерживается

tiDirtyReadtiReadCommittedtiRepeatableRead

Page 284: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

284 Глава 7

SQL-серверы

Informix

InterBase

Paradox,dBASE.Access,FoxPro

Указанные уровни изоляции

tiOirtyReadtiReadCommittedtiRepeatableRead

tiDirtyReadtiReadCommittedtiRepeatableRead

tiDirtyReadtiReadCommittedtiRepeatabieRead

Действительные уровни

tiDirtyReadtiReadCommittedtiRepeatableRead

tiReadCommittedtiReadCommittedtiRepeatableRead

ИЗОЛЯЦИИ

tiDirtvReadHe поддерживаетсяHe поддерживается

Отметим, что для локальной транзакции в Paradox или dBASE свойствоTranslsolation должно быть равно liDirtyRead. В противном случае будет ини-циировано исключение.

property DataSetCount: Integer; (только для ЧТЕНИЯ)Указывает количество активных наборов данных, ассоциированных с компо-нентом.

property LoginPrompt: Boolean;Определяет, будет ли перед открытием нового соединения появляться диалогlogin для ввода имени пользователя и пароля.

Для программного определения имени пользователя и пароля можно в свойствеPararas компонента TDat abase, указать параметры USER NAME и PASSWORD.

Забегая вперед, отметим, что для компонента типа TADOConnection имя пользо-вателя и пароль могут быть указаны в свойстве ConnectionString.

•Процедуры и функиии

procedure ApplyUpdates(const DataSets: array of TDBDataSet);Применяет все кешированные обновления, сделанные с момента последнейпопытки обновления записей или с момента \становления значения свойстваCachedUpdates указанного набора данных равным True.

Параметр DetmSels указывает список наборов данных, для которых кеширо-ванные обновлении посылаются в базу данных. При этом для каждого набораданных вызываются методы Applyllpdates и CoramitUpdates.

Кешированные обновления позволяют обновлять несколько записей из набораданных. По умолчанию если режим кешированного обновления не установлен,то изменения посылаются в базу данных при переходе от одной записи к другой.Это значительно увеличивает сетевой трафик.

При вызове метода ApplyUpdates выполняются следующие действия:

1. Для компонента база данных начинается транзакция.

Page 285: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 285

2. В базу данных записываются кешнрованные обновления.

J. При успешном окончании процесса обновления выполняется фиксация базыданных и завершение транзакции.

4. Кешированные обновления фиксируются, и очищается внутренний буферкеша.

5. При возникновении каких-либо ошибок при записи в базу данных выполня-ется откат транзакции без фиксации базы данных и очистки буфера кеширо-ванных обновлений.

Пример:

{Обработчик события EeforeClose для дочерней таблицы)orocedure TForml.DetailBeforeClose(DataSet: TDataSet) ;begin

if Master.UpdatesPending or Detail.UpdatesPending thenif Master.UpdateStatus = uslnserted then

Database!.ApplyUpdates([Master, Detail]),else

Databasel.ApplyUpdates([Detail, Mas ter ] ( ;end;

procedure CloseDatasets;Закрывает все наборы данных, ассоциированные с компонентом база данных,без отсоединения от сервера базы данных.Вызов метода Close одновременно с закрытием набора данных закрываети соединение.

procedure Commit;Выполняет фиксацию изменений базы данных и завершает текущую транзакцию.Текущей транзакцией является транзакция, открытая последним вызовом ме-тода StartTransaction.

Пример:(Запись в базу данных кешкрованных обновлений вызовом метода ApplyUpdates

для набора данных}procedure TForml.ApplyUpdateButtonClick (Sender: TObject);begin

with Tablel do {Набор данных}beginDatabasel. StartTransaction; {Начало транзакции}

ApplyUpdates; (Запись изменений в базу данных}Databasel .Commit; {Фиксация транзакции}

except

Page 286: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

286 Глава 7

Databasel.Rollback; {Откат транзакции);raise; {Инициация исключения для предотвращения вызова

CommitUpdates]end;

CommitUpdates; (Очищение буфера кеша}end;

end;

function Execute(const SQL: string; Params: TParams = nil; Cache: Boolean= False; Cursor: phDBICur = nil): Integer;Выполняет SQL-оператор, указанный параметром SQL.

Параметр Params содержит, если есть, список параметров SQl-оператора.Порядок параметров в Params должен соответствовать порядку параметровв SQL-операторе.

Для каждого параметра создается один объект TParam вызовом методов объ-екта TParams. Указание AsString для объекта TParam позволяет присвоитьзначение каждому параметру.

Параметры могут использоваться в так называемых параметризированпыхзапросах -запросах с фразой WHERE.

Параметр - Cache определяет, будет ли компилируемый SQL-оператор кеши-роваться для повторного использования в текущей транзакции. Этот режимзначительно увеличивает скорость выполнения повторного запроса.

Параметр Cursor используется только для SQL-оператора, возвращающегорезультирующий набор (оператор SELECT). Этот параметр позволяет примногократном выполнении запроса присваивать его результат компонентунабора данных (ТТаЫе или TQuery).

Функция возвращает количество записей, обработанных SQL-оператором.

Пример:

{Выполнение SQL-оператора и назначение полученного им набора данных

компоненту ТТаЫе ]

procedure TDataForm.UseParamBtnClick(Sender: TObject);

varSQLstmt: String;

stmtParams: TParams;

Cursor: hDBICur;

begin

stmtParams := TParams.Create; {Создание объекта TParams}

try

(Открытие соединения TDatabase)

Databasel.Connected := True;

{Создание объекта TParam для MyParaml}

stmtParams.CreateParamfftString, 'MyParaml1, ptlnput);

{Присвоение значения параметру MyParaml]

Page 287: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 287

stmtParams[0].AsString := 'Москва 1 ;(Определение SQL-оператора}

SQLstmt := 'SELECT Company, City FROM Customer ' +'WHERE (City = :MyParaml) ' +'ORDER BY State, Company';

(Вызов метода Execute}Database!..ExecutetSQLstrot, stmtParams, False, @CursorJ;(Закрываем любой курсор, открытый ранее для компонентаТТаЫе (

Tablel. Close,-{Присваиваем дескриптор курсора ВОЕ дескриптору ТТаЫе}

TDBDataSet(Tablel).Handle := Cursor;f inal ly

(Удаляем динамически созданный объект для TParams)stmtParams.Free;

end;end;

procedure Rollback;Выполняет откат текущей транзакции.

Отметим, что если метод Rollback вызывается в момент, когда нет открытойтранзакции, то инициируется исключение.

procedure StartTransaction;Начинает новую транзакцию.

procedure ValidateName(const Name: String);Если указанная база данных уже открыта в активной сессии, то метод ини-циирует исключение EQatabaseSrrcr.

Параметр Name содержит имя базы данных.

Этот метод вызывается приложением каждый раз при попытке открыть базуданных.

procedure Close;Закрывает соединение.

Вызов этого метода эквивалентен установке значения свойства Connectedравным False.

Если ранее закрытое соединение будет повторно открыто, то должны бытьповторно открыты и ассоциированные ему наборы данных (автоматическинаборы данных не открываются).

procedure Open;Открывает соединение.

Вызов этого метода эквивалентен установке значения свойства Connectedравным True.

Page 288: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

288 Глава 7

Для класса TDatabase предусмотрены следующие обработчики событий:OnLogin, AfterConnect, AfterDisconnect, BeforeConnect, BeforeDisconnect.

Класс TADOConnectionРасположен в модуле ADOdb

Класс TADOConnecticn обеспечивает соединении с данными, доступ к которымреализуется через ADO-объекты.ADO-объекты позволяют работать с различными хранилищами данных, которыемогут и не быть SQL-серверами. Доступ, предоставляемый объектомTADOConnection, использует провайдеры OLE DB,

Компонент TADOConnection может быть разделен одновременно несколькимикомпонентами TADOCoiranand и TADGDataSet. которые ссылаются на негов свойстве Connection.

Дня идентификации соединения необходимо определить значение свойстваConnect!onString {строка соединения).

Для автоматического формирования строки соединения во время проектирова-ния можно выполнить двойной щелчок мышью па расположенном в форме (илимодуле данных) компоненте TADOConnection. В диалоге Forml.AdoConnectionl(рис. 7.10) следует выбрать один из следующих способов подключения к источ-нику данных:

• Use Data Link File - использование datalink-файла;

* Use Connection String - использование строки соединения.

Forml.AQDCpnnettnnt Connect icnStung

SomcecJ Connection

Г Use DalaLii*. File

(• Use Connection Stma

Build.

Рис. 7.10. Диалог Forml.AdoConnectionl

При выборе опции Use Connection String строку соединения можно сформиро-вать, щелкнув по кнопке Build. В диалогах (рис. 7.11 и 7.12) следует выбратьпровайдера OLE DB и указать строку соединения или источник данных, опреде-ляющих местоположение базы данных.

Для проверки правильности введенных параметров в диалоге Data Link Propertiesможно протестировать создаваемое подключение, щелкнув мышью по кнопкеTest Connection.

Page 289: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 289

В результате будет автоматически сформирована строка соединения. Например,для доступа к файлам dBASE строка будет выглядеть так:

Provider=MSDASQL.l; Persist Security Info=False; Data Source=dBASE Files.

Щ Data Link Properties

Provide! | Connection | Advanced j All

Select the data you want to connect io:

_QLE DB_PrayidejM

Microsoft Jet 4.0 OLE DB ProviderMicrosoft OLE DB Provider for Indexing ServiceMicmsotl OLE DB Provider for Internet PublishingMicrosoft OLE OB Provider for ODBC DirveisMicrosoft OLE DB Provider for OLAP ServicesMicrosoft OLE DB Provider lor OracleMicrosoft OLE DE Provider lor SQL ServerMicrosoft OLE DB Simple ProviderMSDataShapeOLE DB Provider ior Microsoft Directory ServicesVSEE Versioning Enlistment Manager PIOK^ Dais Source

Next»

OK Cancel Help

Рис. 7.11. Диалог для выбора провайдера OLE DB

Для того чтобы программно определить строку соединения, можно записатьследующий код:

ADOConnectionl.ConnectionString :='Provider=ProviderRef;Remote Server=ServerRef';

В строке соединения можно указать параметры:

* Provider - имя провайдера;

* File name - имя файла, содержащего информацию о соединении;

* Remote Provider - имя провайдера, используемого клиентом для соединения;

* Remote Server - полный путь для сервера, к которому выполняется под-ключение.

* Дополнительно строка соединения может также содержать имя пользователяи пароль.

10 Зак. 1 1

Page 290: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

290 Глава 7

Provide! Connection j Advanced | All

Specif}1 the following to connect to ODBC data:

1. Specify the source of data1

f* Use data source name

|Файпы dEASE

Use connection string

_ : . ' . . Й

2. Enter information to log on lo the server

User name: |

Password. |

I Blank password Г" Allow saving password

3. Enter the initial catalog to use:

Г• lesi Connection

Cancel Halp

Рис. 7.1 2. Диалог для определения источника данных

КОМПОНЕНТЫ УПРАВЛЕНИЯ ДАННЫМИКомпоненты управления данными расположены на странице Data Controls палит-ры компонентов. Многие из этих компонентов аналогичны элементам управле-ния страницы Standard с тем л и ш ь отличием, что связаны через источник данных(компонент типа TDataSource) с определенным полем (или полями) из набораданных (компонентов типа ТТаЫе или TQuery).

Класс TDBGridКласс TDBGrid позволяет отображать записи набора данных в виде таблицыи управлять этими записями. Таблица состоит из строк и столбцов.

На рис. 7.13 покачана форма, содержащая два невизуальных компонента ТТаЫеи TDateSource и компонент типа TDBGrid. Компонент ТТаЫе указывает, откудабрать данные и ч га будет представлять собой набор данных. КомпонентTDateSource определяет связь между набором данных и компонентами управле-ния данными. Компонент TDBGrid ссылается на конкретный компонентTDateSource.

Page 291: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 291

ЕЯ9МН

. . . ,-».... \,: . .

iiffii —

7

ErnpNo

34

36

37

44

45

46

jJ — I

LaslName JFirstNarne jPhoneExt

Baldwin Janet 2

Reeves Roger 6

Stansbuy Willie 7

Phong Lirilic 216

Ranianathan Ashok ."'fi1'1

Steadrnan Waller 210

-

... j D^

HieOate (±\

21 031Э91

25.04.1531

25Ж1ЭЭ1 _J

03.06.1931

01.03.1991

09.03.1331 .ZJ

".,!

'4

Рис. 7.1 3. Форма с компонентом типа TDBGrid

Отметим, что на один компонент TDateSource, связанный с одним и тем же ком-понентом ТТаЫе или TQuery, могут ссылаться несколько компонентов управле-ния данными.

Для того чтобы можно было работать с набором данных, его следует открыть.Если он открывается посредством указания 'значения свойства Active компонен-та ТТаЫе (или TQuery), равного True, то имена полей и значения отображаютсяв компоненте TDBGrid и во время проектирования. Однако таблица TDBGrid ви-дит только те поля из набора данных, которые были добавлены в редакторе по-лей компонента ТТаЫе.

Свойство Active, используемое для открытия набора данных, можно уста-новить как непосредственно для компонента ТТаЫе, так и как вложенноесвойство Act ive свойства DataSet компонента TDataSource.

Для того чтобы иметь возможность редактировать в инспекторе объектов свой-ства отдельных столбцов таблицы и определять для них обработчики событий,следует создать объекты типа TColuran для каждого столбца таблицы. Это вы-полняется в редакторе столбцов (Columns Editor) компонента TDBGrid: для каж-дого добавляемого столбца создается новый объект типа TColuran; инспекторобъектов отображает страницы свойств и событий текущего столбца (рис. 7.14).Редактор столбцов можно вызвать из контекстного меню компонента TDBGridили редактируя значение его свойства Columns.

Отметим, что, когда редактор столбцов не является активным окном, в спискеобъектов инспектора объектов компоненты типа TColumn не видны.

Для перехода на страницу свойств любого столбца таблицы наиболее удоб-но использовать окно дерева объектов (рис. 7.15)

Перемещаться менаду записями в таблице TDBGrid можно с помощью верти-кальной линейки прокрутки. Но для того чтобы иметь возможность добавлятьновые записи, вносить сделанные в таблице изменения в базу данных или уда-

Page 292: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

292 Глава 7

лять записи, удобно использовать компонент типа TDBNavigator, называемыйиногда навигатором.

Object InspectorJDBGfid1.Columns[0] TColumn

Properties I Events j

Alignment

ButtonSlyjeColor

DropDownRowsExpanded

itaRighUustifycbsAuto

.dclWindowl?False

• FieldName

'EForit-jmeMode

ImeName

PickList

limDontCare

TSIririgs)Popup Menu

ReadOnl^

В Title

Visible

False(TColumnTitle)

TrueWidih ;64

All shown

Рис. 7.14. Инспектор обьектов для столбца таблииы

Рассмотрим наиболее важные свойства класса TDBGrid.

Свойства:'

property Columns: TDBCridColumns;Описывает атрибуты столбцов и имена полей, с которыми эти столбцы связаны.Для управления атрибутами столбцов следует использовать свойства объек-тов типа TColumn. Эти объекты могут быть добавлены как во время проекти-рования, так и программно.

Например, для получения имени поля, с которым связан объект, первый столбецтаблицы следует указать так: DBGrid.Colurans[0] .FieldName, а для измененияатрибутов шрифта или цвета указать соответственно

DBGridl .Columns[0] .Font .Sty le :=[f sI ta l ic , f sBold] ;

или DBGridl.Columns[0].Color:=clBlue;.

Для объекта TColumn можно устанавливать значения следующих свойств:Alignment- выравнивание;

Page 293: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 293

Object TreeView

Forml

Columns

*•* 1 • LaslNarne

•4 2 - FirslName

; *i 3-PhoneExt

. t-5 4-HireDate

tf, 5 -Salary[>S Delaull (Session!>. UQ DBDEMOSl^lias)

B1 *t> emplojiee.db {Table!}

D alsS uurce!

FieldDets0-EmpNo1 • LastName

2 - FirstName

3 - PhoneExt

4-HireDale5 • Salary

IndexDek

Рис. 7.15. Окно Object TreeView

ButtonStyle- стиль кнопки при редактировании:• сЬзАи/о - в ячейке отображается компонент типа ниспадающий список, со-

держащий значения, установленные свойством PickList;• cbsEllipsis - ячейка содержит кнопку Д при щелчке на которой иницииру-

ется событие OnEditButtonClick;• cbsNone - пользователь не имеет возможности выбирать значение из предла-

гаемого списка;

Color - цвет столбца;DropDownRows - количество отображаемых элементов в раскрывающемся списке;Expanded ~ используется только для потомков класса TObjectField и позволяетотображать дочерние поля как отдельные столбцы с возможностью редактиро-вания их значений или как нередактируемую строку, содержащую разделенныйчерез запятую список значений;FieldName - имя поля набора данных;Font- параметры шрифта;PickList— массив элементов, отображаемый как комбинированный список приредактировании ячейки столбца;РорирМепи - контекстное меню;

Page 294: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

294 Глава 7

ReadOnly - доступность для редактирования;Title - заголовок столбца;Visible - отображение столбца в таблице;Width - ширина столбца.

property DataSource: TDataSource;Указывает на источник данных, связанный с набором данных, который ис-пользуется компонентом.

TDBGridOptions = set of TDBGriclOption;Определяет параметры отображения и поведения таблицы. Значение этогосвойства может быть указано допустимой комбинацией следующих констант(флажков):

dgEditing - пользователь может редактировать поля таблицы, если не уста-новлен флажок dgRowSelect',dgAlwaysShowEditor - таблица находится в режиме редактирования, что нетребует от пользователя нажимать клавиши F2 или Enter для редактированияячейки (по умолчанию равно False), установка не действует, если установленфлажок dgRowSelect;dgTttles - отображаются заголовки столбцов;dglndicotor ~ в первом (служебном) столбце, иногда называемом головнымстолбцом, появляется индикатор текущей строки;dgColumnResize - можно перемещать столбцы и изменять их размер;dgColLins - столбцы отделяются друг от друга горизонтальными линиями;dgRowLines - строки отделяются друг от друга вертикальными линиями;dgTabs - для перемещения внутри таблицы можно использовать клавиши Tabи Shift+Tab;dgRowSelect - разрешается выделение строки таблицы (по умолчанию равноFalse);dgAlwaysShowSelection - при потере таблицей фокуса остается выделение те-кущей ячейки (по умолчанию равно False);dgConflrmDelete - при удалении строки нажатием клавиш Ctrl+Delete отобра-жается диалог для подтверждения операции удаления;dgCancelOnExit - вставленные пустые строки, в которых не сделано ни одно-го изменения, не записываются в базу данных;dgMultiSelect - одновременно может быть выделено больше одной строки (поумолчанию равно False).

property ReadOnly: Boolean;Определяет, разрешено ли редактировать данные в таблице.

property Selected Index: Integer;Определяет номер текущего столбца в массиве Columns.

Page 295: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 295

Это свойство позволяет перемещать фокус ввода на столбец с указаннымномером. Если нет выделенного столбца (выделенной ячейки), то значениесвойства равно - 1.

Для того чтобы изменить атрибуты текущего столбца, можно, например, запи-сать следующий код:

DBGridl.Columns[DBGridl.Selectedlndex].Font.Style:=[fsltal ic,fsBold];

property SelectedField: TFielci;Определяет компонент поле для текущей выделенной ячейки таблицы; еслинет выделенной ячейки, то значение свойства равно nil.

Например, для того чтобы изменить заголовок текущего столбца, можно в обра-ботчике события OnColEnter ввести код

with DBGridl.SelectedField do {Изменение заголовка столбца)DisplayLabel : = ' + ' + DisplayLabel;

При переходе на другую ячейку заголовок столбца можно восстановить в обра-ботчике события OnColExit, указав

with DBGridl.SelectedField do {Изменение заголовка столбца]DisplayLabel := FieldName;

.

property TitleFont: TFont;Определяет параметры шрифта для заголовков столбцов.

Для класса TDBGrid предусмотрены следующие обработчики событий:

OnCellClick

OnColumnMoved

OnEditButtonClick

OnExit

OnKeyUpOnDragOver

OnMouseDowr.

OnStartDock

OnColEnterOnDrawColumnCell

OnTitleClick

OnKeyDown

OnDblClick

OnEndDock

OnMouseHoveOnStartDrag

Класс TDBGrid является контейнером, содержащим объекты типа ТСо1тжп. Длядоступа к отдельному столбцу таблицы можно использовать свойство Itemsкласса TCclumn.

В следующей таблице приведен синтаксис получения некоторых полезных зна-чений объекта типа TDBGrid.

OnColExit

OnDrawDataCellOnEnter

OnKeyPress

OnDragDrop

OnEndDrag

Or.MouseUp

Значение

DBGridl . Columns .Items [ i ]

DBGridl . Columns . Items [ 1 ] . Title

Описание

Доступ и (-столбцу объекта DBGridl

Доступ н объекту типа TColumnTitle. Для дан-нога объекта можно устанавливать следующиесвойства:

Page 296: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

296 Глава 7

Значение

DBGridl . Columns . Items [1 ] . Title . Caption : ='Новый заголовок';

DBGridl . Columns . Items [ 1 ] . Title. Font . Color:= clGreen;

DBGridl .Columns .Items [DBGridl .Selectedlnd•-'•'- .

Tablel.FieldByNameCLAST NAME') .Visible:= False;

ОписаниеAlignment

Caption

Color

Column

Font

Определение для первого столбца (нумерациистолбцов начинается с 0) нового заголовка

Определение цвета символов в заголовке столбца

Доступ к текущему столицу

Свойство Visible объекта типа TField позволяетскрыть столбец в отображаемой таблице. Этогожв эффекта можно добиться, используя свой- "ство Visible объекта типа TColumn

Пример:

В обработчике события QnDrawColumnCell объекта типа TDBGrid следуетустановить новый цвет фона, а затем вызвать метод DefaultDrawDataCell,выполняющий отображение данных.}procedure TForml.DBGridlDrawColumnCell (Sender: TObject;

const Rect: TRect; DataCol: Integer;Column: TColumn; State: TGridDrawState) ;

beginDBGridl . Canvas . Brush . Color : =c IGreen ; { Цвет фона }

DBGridl. Canvas. FillRect (Rect) ; (Закрашивание ячейки]

DBGridl .DefaultDrawDataCell (Rect, DBGridl . Fields [DataCol] , State) ;

end;

Класс T D B N a v i g a t o rРасположен в модуле dbctr ls

Компонент типа TDBNavigator (навигатор по записям базы данных) является на-бором кнопок (рис. 7.16), с помощью которых пользователь может перемещать-ся между записями набора данных, выполнять операции вставки н удаления за-писей, вносить сделанные изменения в базу данных или отменять их.

Рис. 7.16. Компонент типа TDBNavigator

Для того чтобы указать, с каким набором данных связан компонент типаTDBNavigator, следует установить значение свойства DataSource.

Page 297: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 297

Этот компонент может показывать не все представленные в нем кнопки. Всекнопки, которые должны быть отображены пользователю, указываются в свой-стве Visible-Buttons.Для того чтобы программно инициировать действие, выполняемое по щелчку накнопке навигатора, следует вызвать метод BtnClick. Например:DBNavigatorl .BtnClick(nbNext]; .

Компонент TDBNavigator может отображать следующие кнопки:

First ~ переход к первой записи;Prior— переход к предыдущей записи;Next - переход к следующей записи;Last- переход к последней записи;Insert - вставка перед текущей записью новой записи и переход на нее;Delete - удаление текущей записи;Edit- переход в режим редактирования текущей записи;Post- внесение изменений текущей записи в базу данных;Cancel - отмена изменений, сделанных в текущей записи;Refresh - повторное считывание значений полей из источника данных.

При использовании набора данных типа TQuery или ТТаЫе, отображаемогов таблице типа TDBGrid или в полях типа TDBEdit. переход от текущей запи-си к другой записи вызывает неявный автокоммит. КомпонентTDBNavigator может отменять или вносить изменения в базу данных толькодля текущей записи. Для того чтобы использовать транзакции, следует до-бавить в форму или модуль данных компонент типа TDatabase.

Свойства:

property DataSource: TDataSource;Указывает используемый источник данных.

Пример:

[Использование одного компонента TDBNavigator для двух источников данных)

procedure TForml.DBEditlEnter(Sender: TObject); (При переходе накомпонент DBEditl изменяется текущий источник данных}

beginif Sender = DBEditl then (Какой объект инициировал событие}

DBNavigatorl.DataSource := DBEditl.DataSource (Установить другойисточник данных, используемый объектом,

инициировавшим событие}

elseDBNavigatcrl.DataSource := DBEdit2.DataSource; {На вкладке Events

определить для объекта DBEdit2 обработчик события

Page 298: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

298 Глава 7

OnEnter, введя DBEditlEnter (использование одногообработчика события OnEnter для двух разных объектов)}

Tablel.First;end;

property VisibleButtons: TButtonSet;Определяет, какие кнопки будут отображены в навигаторе.Свойство VisibleButtons определяется как множество из следующих значе-ний: nbFirst, nbPrior, nbNext, nbLast, nblnsert, nbDelete, nbEdit,nbPost, nbCancel, nbRefresh.

Компонент TDBHavigator может быть настроен как во время проектирования, таки программным путем. Для того чтобы во время выполнения сделать какую-либо кнопку навигатора невидимой следует задать для нее значение свойстваVisibleButtons равным False.

Пример:

{Сделать KHonKHnbFirst и nbLast объекта DBNavigatorl невидимыми:}DBNavigatorl.VisibleButtons:=

DBNavigatorl.VisibleButtons-[nbFirst ,nbLast];{Сделать кнопку nbFirst объекта DBNavigatorl видимой:}DBNavigatorl.VisibleButtons:=DBNavigatorl.VisibleButtons-Ь [nbFirst];

Кроме наследуемых обработчиков событий в классе TDBHavigator реализованодва обработчика событий:

* BeforeAction - вызывается перед выполнением действий по кнопке;

• OnClick- вызывается при щелчке на кнопке.

Пример:{При щелчке на кнопке выдается сообщение с именем этой кнопки. Второй

параметр в обработчике события OnClick для навигатора задается значением,

идентифицирующим кнопку. }

procedure TForml.DBNavigatorlClick(Cer.der: TObject; Button: TNavigateBtn);

var BtnName: string;

begincase Button of

nbFirstnbPriornbNextnbLastnb InsertnbDeletenbEdit

BtnNameBtnNameBtnNameBtnHaraeBtnNameBtnNameBtnHar.e

= 'nbFirst ' ;= 'nbPrior ' ;= 'nbNext 1 ;= 'nbLast ' ;= 'nblnsert '= 'nbDelete'= 'nbEdi t ' ;

Page 299: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 299

nbPost : BtnName := 'nbPost ' ;nbCancel : BtnName := 'nbCar.cel 1 ;nbRefresh: BtnName := ' r .bRefresh ' ;

end;ShowMessagel 'Нажата кнопка Ч BtnName);

end;

Г Для каждой кнопки компонента TDBHavigator можно отображать всплы-

/• вающую подсказку. Для этого достаточно выполнить следующие действия;J

1. Установить значение свойства ShowHint компонента TDBHavigator равнымTrue.

2. Двойным щелчком м ы ш и на по.че справа от свойства Hints (или щелчкомна кнопке [7TJ) вызвать диалог String List Editor.

5. Ввести в отображаемом диалоге текст всплывающей подсказки для каж-дой кнопки на отдельной строке.

Класс T D B T e x tРасположен в модуле dbctrls

Компонент TDBText аналогичен компонент)' TLabel, но в отличие от него позволя-ет в качестве надписи отображать значение поля текущей записи набора данных.

Для того чтобы связать этот компонент с полем набора данных, следует установитьзначения свойств: DataSource - для указания источника данных, DataField- дляопределения имени поля набора данных.

Отметим, что если значение свойства DataSource определено и указанный ис-точник данных ссылается на компонент набора данных, то свойство DataFieldустанавливается из автоматически предлагаемого списка полей набора данных.

Класс TDBText не реализует собственных обработчиков событий, а наследует ихот класса TControi.

Класс T D B E d i tР а с п о л о ж е н в модуле dbct r l s

Класс TDBEdit реализует однострочное поле редактирования, в котором можноотображать и изменять значение поля набора данных.

Связь с полем набора данных указывается свойствами DataSource и DataField.Значение поля содержится в свойстве Text.

Для того чтобы использовать маску ввода, следует применять свойства класса TFieldи его потомков, такие, как TField. : :EditMask, TDateTimeField.: :DisplayForinat,TNumericField.::DisplayFormat.

Класс TDBEdit не реализует собственных обработчиков событий, а наследует ихот классов TCustoraEdit, TWin.Control и TControi.

Page 300: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

300 Глава 7

Для полей, используемых в качестве счетчиков, увеличение значения можно по-лучать, используя метод Inc (1пс(значение[,инкремент|);).

Класс TDBMemoРасположен в модуле dbctrls

Класс TDBMemo реализует многострочное поле редактирования, в котором можноотображать и изменять значение поля набора данных.

Связь с полем набора данных указывается свойствами DataSource и DataField.Значение поля содержится в свойстве Text.

Класс TDBImageРасположен в модуле dbctrls

Класс TDBImage реализует объект рисунок, в котором можно отображать и изме-нять значение поля набора данных формата BLOB,

В объект типа TDBImage может быть скопировано любое изображение.

Для того чтобы вырезать, скопировать или вставить изображение в объект рису-нок, можно использовать клавиши Ctrl+X, Ctrl+C, Ctrl+V или программно вызватьметоды CutToClipboard. CopyToClipboard. PasteFroraClipboard.

Связь с полем набора данных указывается свойствами DataSource и DataField.Объект типа TPicture, определяющий изображение, указывается в свойствеPicture. Для того чтобы программно изменить содержание объекта типаTDSIraage, можно ввести следующий код:

DBImagel.Picture.Assign(Intagel.Picture);..

Класс TDBRadioGroupКласс TDBRadioGroup реализует группу радиокпопок, связанных с полем базыданных. Применение такого объекта предоставляет пользователю удобную воз-можность устанавливать значение поля базы данных, выбирая его из предлагае-мых опций. При отображении записи компонент типа TDBRadioGroup показываетвключенной ту радиокнопку, которая соответствует значению поля в текущейзаписи. Фактически компонент TDBRadioGroup отображает список всех возмож-ных значений для связанного с ним поля базы данных.

Значение свойства Readonly определяет, можно ли использовать данный компо-нент для изменения значения поля.

'"• Для того чтобы создать группу радиокнопок, предназначаемую для отобра-- j j жения или ввода значений в какое-либо поле базы данных, необходимо вы-

полнить следующие действия:

1. Установить значения свойств DataSource и DataField компонента типаTDBRadioGroup.

Page 301: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 301

2. Определить метку каждой радиокнопки. Количество меток будет соответст-вовать числу радиокнопок в группе. Для этого следует выполнить двойнойщелчок мышью па поле справа от свойства Items (или щелкнуть мышью накнопке J7j), вызвав диалог String List Editor. Ввести в отображаемом диалогедля каждой радиокнопки на отдельной строке ее метку.

5. Определить список возможных значений. Для этого следует выполнить двой-ной щелчок мыши на поле справа от свойства Values (или щелкнуть мышью

на кнопке П). вызвав диалог String List Editor. Ввести в отображаемом диало-ге для каждой радиокнопки на отдельной строке значение, при котором дан-ная кнопка будет показана включенной. В текущей записи это значение такжебудет устанавливаться для поля, связанного сданным компонентом.

При изменении значения поля (щелчке пользователя по радиокнопке) для ком-понента TDBRadioGroup инициируется событие OnChange.

Класс TDBCheckBoxКласс TDBCheckBcx реализует компонент флажок, связываемый с полем базы дан-ных.

Свойства:

property DataField: String;Определяет поле базы данных, связываемое с данным компонентом.

property DataSource: TDataSource;Определяет источник данных. Для того чтобы установить значение данногосвойства во время проектирования, следует предварительно расположить наформе или в модуле данных компонент типа TDataSource и связать его с ком-понентом набора данных. Для изменения значения свойства во время выпол-нения можно записать: DBCheckBoxl.DataSource := DataSourcel;

property Readonly: Boolean;Определяет может ли пользователь изменять значение поля.

property ValueChecked: String;Определяет значение поля, соответствующее установленному состояниюфлажка. Свойство ValueChecked - это строка, содержащая одно или несколь-ко значений, разделенных точкой с запятой. Если отображаемое поле содер-жит одно из значений, указанных свойством ValueChecked, то флажокDBCheckBox отображается установленным. При изменении значения поля по-средством компонента DBCheckBox в качестве записываемого в базу данныхзначения выбирается первое, указанное в списке свойства ValueChecked.

Для изменения значения свойства можно записать:DBCheckBoxl.ValueChecked := ' f ia;Yes;On';

Page 302: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

302 Глава 7

property ValueUnchecked: String;Определяет значение поля, соответствующее снятому состоянию флажка.Свойство ValueUnchecked - это строка, содержащая одно или несколько зна-чений, разделенных точкой с запятой. Если отображаемое поле содержит од-но из значений, указанное свойством ValueUnchecked, то флажок DBCheckBoxотображается неустановленным.

Если свойство DataField компонента DBCheckBox указывает на поле, имеющеелогический тип, то свойства ValueChecked и ValueUnchecked не используются.Для таких полей флажок будет иметь установленное состояние для значения по-ля равного True и снятое состояние - для значения поля равного False.

Если значение поля, связанного с компонентом DBCheckBox, не соответствует ниодному из значений в списках ValueChecked и ValueUnchecked, то флажок будетотображен "посеревшим".

Классы TDBListBox и TDBComboBoxРасположены в модуле dbctrls

Классы TDBListBox и TDBCoraboBox реализуют списки, аналогичные спискамTListBox и TComboBox, с тем лишь отличием, что они используются для выборазначения поля набора данных.

Связь с полем набора данных указывается свойствами DataSource и DataField.Значения, отображаемые в списке, содержатся в свойстве Items. Элементы мас-сива Items можно добавлять как в инспекторе объектов, так. и программно.

Пример:{Заполнение списка типа TDBListBox значениями поля Company набора данных}

procedure TForml.FormCreate(Sender: TObject);

beginwhile not Tablel.Eof do beginDBListBoxl. Items .Add (Tablel. FieldByName ( 'Страну ' ) .AsStr ing) ;

Tablel.Next;end;end;

Если создать список, связанный с конкретным полем, и заполнить его значения-ми данного поля, то затем его можно будет использовать для выбора значенияполя текущей записи.

На рис. 7.17 показаны форма, содержащая таблицу TDBGrid, и список TDBListBox,связанный с полем Company набора данных. При выборе значения поля Companyв списке оно автоматически отображается в таблице в столбце Company текушейзаписи. При переходе к следующей записи изменения вносятся в базу данных.

Page 303: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 303

*f Form")

CustNo Company Addrl

CN 6582

CM 6312

CN 9341

The Diving Company PO Box 6535

Nowesl'er SOJBA Lmled PO Box 6334

The Diving Company 7865 NE Berber Ct.

|POBox129

-1JJ

"I-I v x

Kauai Dive ShoppeUniscoSighl DiverCayman Divers World Unli т Iт r- r\' ' f i ••• '

Рис. 7.17. Компоненты типл TDBGrid, TDBListBox и TDBNavigator.

Класс T D B L o o k u p L i s t B o xРасположен в модуле dbctrls

Компонент TDBLookupListBox позволяет выполнять просмотр списка, заполнен-ного значениями полей из другого набора данных.

•Свойства:

property DataField: String;Определяет поле набора данных, значения которого могут быть выбраны изданного списка.

property DataSource: TDataSource;Указывает источник данных, содержащий поле, заданное свойствомDataField.

property KeyField: String;Определяет поле из источника данных, указанного свойством ListSource, ко-торое должно соответствовать значению поля DataField.

property ListField: String;Определяет поле или несколько полей, значения которых отображаютсяв списке. Если указывается несколько полей, то их идентификаторы разделя-ются символом ;.

До определения свойства ListField следует определить связь между двумянаборами данных, указав значение свойства KeyField.Если свойство ListField не определять, то по умолчанию будут показанызначения поля, указанного свойством KeyField.

Page 304: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

304 Глава 7

property ListFieldlndex: Integer;Если в свойстве LisiField определено больше одного поля, то ListFieldlndexопределяет, какое иоле используется для поиска. Для компонента типаTDBLockupComboBox это свойство также определяет, какое поле будетредактироваться.

property ListSource: TDataSource;Определяет источник данных для полей, отображаемых в списке.

Значения свойсгв KeyField и ListField указываются для этого источника дан-ных.

Класс TDBCtrlGridРасположен в модуле dbcgrids

Компонент типа TDBCtrlGrid позволяет отображать записи набора данныхв любых элементах управления.

Это особый вид таблицы, в которой каждая запись отображается на отдельнойпанели. Количество панелей в компоненте указывается значением свойстваRowCount. Поля записи могут отображаться и редактироваться в различныхэлементах управления. Так, на одной панели можно редактировать текстовыеполя; поля, содержащие изображения; поля, представляющие логические значе-ния; выбирать значения полей из списков.

i Для того чтобы настроить компонент типа TDBCtrlGrid, следует:

1. Указать источник данных в свойстве DataSource.

2. Определить размер каждой панели, установив значения свойствPanelHeight и PanelWidth.

J. Расположить на первой панели все элементы управления данными для ра-боты с полями одной записи.

4. Настроить каждый элемент управления, указав имя поля в свойствеDataField. Имя источника данных при этом будет устанавливаться авто-матически.

На рис. 7.18 показана форма, содержащая компонент типа TDBCtrlGrid. Этоткомпонент состоит из трех панелей, на каждой из которых отображаются поляодной записи. Каждая запись представлена двумя компонентами типа TDBEditи одним компонентом TDBImage.

Линейка прокрутки компонента TDBCtrlGrid позволяет перемещаться междузаписями набора данных.

Для вставки новых записей, внесения изменений в базу данных или удалениязаписей совместно с компонентом TDBCtrlGrid можно использовать компонентTDBNavigator, связанный с тем же источником данных.

Page 305: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 305

iFTo.ml

Рис. 7.1 8. Форма с компонентом типа TDBCtrlGrid

ДОПОЛНИТЕЛЬНЫЕ КЛАССЫ,ПРЕДНАЗНАЧЕННЫЕ ЛЛЯ РАБОТЫС ДАННЫМИ

Класс TSessionОбъект типа TSession автоматически создается для каждого Delphi-приложенияработы с базой данных. Этот компонент используется только для многопоточ-ных приложений баз данных: для каждого потока баз данных своя собственнаясессия.

Свойства:

property Active: Boolean;Определяет, открыт ли сеанс данных.

property SessionName: String;Определяет имя сеанса данных, используемое для связи с ним.

Page 306: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

306 Глава 7

М е толы:

function OpenDatabase(const DatabaseName: String): TDatabase;Открывает существующую базу данных или создает временный объект базаданных и открывает его.

procedure CloseDatabase(Database: TDatabase);Закрывает соединение с базой данных.

procedure Open;Открывает сеанс данных и делает его текущим.

procedure Close;Отсоединяется от всех баз данных и закрывает текущий сеанс.

Класс TBatchMoveОбъект типа TBatchMove предназначен для выполнения действий над группойзаписей или всей таблицей. Он позволяет добавлять или удалять записи из таб-лицы, копировать набор данных для создания новой таблицы.

Свойства:

property Source: TBDEDataSet;Определяет набор данных, используемый в качестве источника для получе-ния записей.

property Destination: TTable;Определяет объект TTable, который является целевым для выполняемой опе-рации. Это свойство указывает таблицу, куда будут скопированы или откудабудут удалены записи.

property Mode: TBatchMode;Определяет действие, выполняемое компонентом TBatchMove при вызоае ме-тода Execute. Это действие может определяться следующими константами:batAppend, bat Update. batAppendUpdate, butCopy или batDelete.При изменении или удалении записей целевая таблица должна иметь индекс,используемый для определения соответствия записей.

М е толы:

procedure Execute;Выполняет для целевой таблицы операцию, предусмотренную свойством Mode.

Page 307: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 307

Класс TUpdateSQLОбъект типа TUpdateSQL позволяет для наборов данных, созданных с доступомтолько для чтения, поддерживать возможность их обновления посредствомSQL-операторов.

Свойства:

property DeleteSQL: TStrings;Определяет SQL-оператор DELETE.

property InsertSQL: TStrings;Определяет SQL-оператор INSERT.

property ModifySQL: TStrings;Определяет SQL-оператор UPDATE.

Метолы:

procedure £xecSQL(UpdateKind: TUpdatcKind);Выполняет один и-j заданных SQL-операторов в 'зависимости от значения па-раметра, которое может быть указано следующими константами: ukDelete,uklnsert или ukModify.

КЛАССЫ, ПРЕДНАЗНАЧАЕМЫЕ ДЛЯ

СОЗДАНИЯ ОТЧЕТОВДля создания отчетов в Delphi 7 предназначаются компоненты страницы Rave.

Наряду с этим сохраняется возможность построения отчетов с использованиемкомпонентов страницы QReport 1, которые позволяют выполнять визуальное про-ектирование быстрых отчетов (Quick Report). Такой отчет может быть сформи-рован на основе любого источника данных DataSource, включая ТТаЫе, TQuery,списки или массивы. В отчет могут быть включены различные общепринятыеэлементы отчетных форм, такие, как заголовки отчета, заголовки страниц, верх-ние и нижние колонтитулы, группы, суммирование полей и счетчики.

Класс TQuickRepЭто визуальный компонент, определяющий прямоугольную область текущеговыбранного размера страницы. На основе этой базисной формы строятся все от-четы. Для создания отчета следует сбросить на данный компонент компонентытипа TQRBand (по одному для каждой полосы) и все печатаемые компоненты, со-

Дпя использования страницы QRepori первоначально следует выполнить команду менюComponenl|lns1all Packages и подключить соответствующий пакет.

Page 308: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

308 Глава 7

единив их с набором данных. Добавить в отчет полосы типа TQRBand можно,и установив значение вложенных свойств свойства Bands равными True.

Свойства:

property Dataset: TDatasetОпределяет связь с набором данных.

property Bands : TQuickRcpBnndsЭто составное свойство, используемое для определения того, какие полосыдолжны присутствовать в отчете. Каждая полоса соответствует определеннойобласти в отчете.

На рис. 7.19 показано окно инспектора, содержащее составное свойство Bandsдля компонента типа TQuickRep, расположенного на форме.

9 : Г? 1 ' ' '" •" • Ф : t"T&'he\ WobSwviMi] Irit-ft.ws \ Пяпо . VnrtiroDl Dtcmr, Ci4K ! D'4i«H i WnJl I 5нип4н| Adr^X] Rev? DFteoM ilixJiCii-L- "" *^-^" '— /I,' " . n ± t 4 £ i - 5 l - x l ! f t ? = J B « « < V V < *iJ * *i SiiJ *l. =i *i *rt -i'-i

Рис. 7.19. Компонент TQuickRep, используемый для формирования отчета

Класс TQRSubDetailКласс TQRSubDetail позволяет добавлять в отчет дополнительные наборы дан-ных. Обычно для этого между компонентами таблица или запрос устанавлива-ются отношения родительская-дочерня я (master/detail). Отношение создаетсяпосредством компонента TQRSubDetail.

Page 309: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 309

Свойства:

property Dataset: TDatasetОпределяет связь с набором данных.

property Bands : TQuickRepBandsЭто составное свойство, используемое для определения того, какие полосыдолжны быть на полосе Sub Detail.

property Master : TComponent

Используется для определения отношения между таблицами дочер-няя/род ител ьская.

Класс TQRStringsBandКомпонент размещает в отчете полосу Strings Band, которая может содержатьстроки формируемого отчета.

ttrt: i j Для того чтобы показать в форме отчета содержимое текстового файла, вы-

j ii полните следующие действия:

т 111

1. Создайте отчет, используя класс TQuickRep (в принципе можно использо-вать и класс TQuickAbstractRep: класс TQuickAbstractRep предназначендля создания отчетов, не использующих добавления в отчет компонентов,связанных с набором данных).

2. Добавьте в контейнер TQuickRep компонент типа TQRStringsBand,реализующий полосу для данных.

J. Добавьте в контейнер TQRStringsBand компонент TQRExpr и установите длянего значение свойства Aittosize равным False, значение свойстваAutoStretch равным True, значение свойства Expression - имя полосы (на-пример, QRSmngsBandl).

4. Выполните загрузку текстового файла как значение свойства Items. Дляэтого введите в соответствующий обработчик события (например, событиеOnClick для кнопки, используемой для отображения отчета) следующийкод:QRStringsBandl.Items.LoadFromFile('MyFile.txt');

5. Для отображения отчета выполните метод Print или Preview для компо-нента типа TQuickAbstractRep.

Класс TQRBandКомпонент типа TQRBand размещает полосу в контейнере TQuickRep. Для оп-ределения поведения полосы во время генерации отчета используется свойствоBandType.

Page 310: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

310 Глава/

Класс TQRChildBabdКласс TQRChildBabd применяется для размещения одних компонентов под други-ми, атакже при слишком длинных полосах протяженностью в несколько страниц.

Свойства;-

property LinkBand : TQRCustomBandПозволяет указать печать двух полос обязательно на одной странице.

property HasChild : BooleanОпределяет полосу, которая будет являться дочерней.

property ParentBand : TQRCustomBandУказывает родительскую полосу. Это свойство автоматически устанавлива-ется при изменении значения свойства HasChild.

Класс TQRGroupКласс TQRGroup позволяет группировать полосы и обеспечивает управление за-головками и колонтитулами.

Свойства;

property Expression: StringСодержит выражение, определяющее условие формирования групп: при из-менении значения данного свойства начинается новая группа.

Класс T Q R L a b e lКласс TQRLabel позволяет отображать любой статический текст не из источникаданных. Отображаемый текст определяется свойством Caption. Текст можетрасполагаться как на нескольких строках, так и на нескольких страницах.

Свойства:

property Caption : StringСодержит текст, отображаемый в отчете данным компонентом.

Класс TQRDBTextКласс TQRDBText позволяет отображать значение поля из источника данных. Этомогут быть строковые или числовые поля, поля даты и memo-поля. Текст можетрасполагаться как на нескольких строках, так и на нескольких страницах. Ис-точник данных и поле данных определяется свойствами DataSource и DataField.

Page 311: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 311

Свойства:

property Dataset : TDatasetОпределяет связь с набором данных.

property DataField : StringОпределяет поле набора данных, отображаемое компонентом.

Класс TQRExprПечатает значение поля из источника данных или выражения, включающегозначения полей. Печатаемое значение определяется свойством Expression.

Свойства:

property Expression ; StringОпределяет выражение, отображаемое компонентом. Данное выражение можетбыть создано при помощи диалога Expression Wizard (рис. 7.20), вызываемого-при двойном щелчке мышью па значении свойства Expression в окне инспекто-ра.

Enlei espies sian:

xl^J

Table!.Salary "2C(

Insert at cursor position -

Database Ibid Function Variable

< > < > < - > • Hat And Or

Clear j Validate.

Рис. 7.20. Диалог Expression Wizard для построения выражения

Создаваемое выражение может включать идентификаторы переменных, ме-тоды и поля набора данных.

Класс TQRSysDataКласс TQRSysData позволяет отображать в отчете системную информацию: заго-ловок отчета, номер текущей страницы и т.п. отображаемые данные определя-ются свойством Data, а предшествующий текст- свойством Text.

Page 312: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

312 Глава 7

Класс TQRMemoКласс TQRMemo предназначен для вывода большого фрагмента текста, но не изисточника данных.

Свойства:

property Lines : TStringsСодержит текст, отображаемый компонентом.

Класс TQRExprMemoЭтот компонент является гибридом компонента TQRExpr и компонента TQRMemoи позволяет отображать memo-текст со встроенными выражениями.

Свойства:

property Lines : TStringsСодержит текст, отображаемый компонентом. Встраиваемые в текст выраже-ния заключаются в круглые скобки.

Класс TQRRichTextПозволяет встраивать в отчет форматированный текст.

Свойства:

property Lines : TStringsСодержит текст, отображаемый компонентом.

property ParentRichEdit : TRichEditУказывает элемент управления, содержащий отображаемый текст.

Класс TQRDBRichTextПредоставляет отчету возможность иметь доступ к полю данных DBRichText.

Свойства:

property Dataset : TDatasetОпределяет связь с набором данных.

property Data Field : StringОпределяет поле набора данных, отображаемое компонентом.

Класс TQRShapeКласс TQRShape позволяет отображать в отчете простые фигуры, такие, какпрямоугольник, линия или круг.

Page 313: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 31 3

Свойства:

property Shape : TQRShapeTypeОпределяет тип отображаемой фигуры. Класс TQRShapeType определен сле-дующим образом: суре TQRShapeType = (grsRectangle, qrsCircle,qrsVertLine, qrsHorLine, qrsTopAndBottom, qrsRightAndLeft).

property Brush : TBrushОпределяет свойства объекта типа TBrush (кисть), используемого для заданияцвета фигуры.

property Pen : TPenОпределяет свойства объекта типа ТРел (ручка), используемого для заданияпараметров контура, ограничивающего фигуру.

Класс TQRImageКласс TQRImage предназначен для отображения в отчете рисунка. Может бытьиспользован любой из графических форматов, поддерживаемых классомTPicture.

Класс TQRDBImageКласс TQRDBImage позволяет отображать в отчете рисунок, хранимый в двоичномполе (BLOB) данных.

Свойства:

property Dataset : TDatasetОпределяет связь с набором данных.

property DataField : StringОпределяет поле набора данных, отображаемое компонентом.

property Stretch : BooleanОпределяет, каким образом изображение будет отображаться в элементеуправления. Если значение свойства равно True, то изображение будет вы-ровнено по размеру элемента управления. Если значение свойства равноFalse, то размер изображения не будет изменен.

Классы TQRTextFilter, TQRCSVFilterи TQRHTMLFilter

Классы TQRTextFilter, TQRCSVFilter и TQRHTMLFilter предназначены для экс-порта содержимого отчета:

• класс TQRTextFilter позволяет экспортировать содержание отчетав текстовый формат;

Page 314: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

314 Глава 7

• класс TQRCSVFilter позволяет экспортировать в текстовый файл содержаниеотчета в формате, использующем запятые как разделители;

• класс TQRHTMLFilter позволяет экспортировать содержание отчета в HTML-файл.

Для того чтобы экспортировать содержание отчета в файл, следует расположитьна форме компонент, реализующий фильтр, затем вызвать метод Create для соз-дания файла и выполнить экспорт отчета вызовом метода ExportToFilter.

Пример:

(Экспорт содержимого отчета в HTML-файл}

procedure TForml.ButtonlClick(Sender: TObject);

varAExportFilter : TQRHTMLDocumentFilter; {Используемый фильтр]

begin

AExportFilter :=

TQRHTMLDocumentFilter.CreateCFroraReport.HTM1]; {Создание файла}

try

QuickRepl.ExportToFilter{AExportFilter) {Запись отчета в файл}

finally

AExportFilter.Free;

end;end;

Класс TQRChartКласс TQRChart позволяет использовать в отчете компоненты типа TQRDBChart.После размещения на полосе отчета компонента типа TQRChart следует выпол-нить на нем двойной щелчок мышью для вызова диалога, используемого длянастройки компонента типа TQRChart. Первым делом следует создать серии(объекты типа TSeries). отображаемые на графике. Далее надо связать сериюс полем источника данных.

Такие объекты можно располагать на полосах типа GroupHeader для полученияотдельного графика для каждой группы отчета.

Класс TRvPro jec tКласс TRvProject предназначен для отображения и печати отчетов, созданныхпри помощи утилиты Rave Reports.

Создаваемый в Rave Reports проект может содержать как один, так и несколькоотчетов. Список всех отчетов помещается в секцию Report Library окна проекта.В список Data View Dictionary окна проекта следует добавить все источники дан-ных, используемые для отчетов данного проекта. Проект отчетов сохраняется вфайле с расширением RAV. Для использования какого-либо шаблона отчета изпроекта отчетов первоначально надо вызвать метод Open класса TRvProject, a

Page 315: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 315

затем выбрать текущий отчет вызовом метода SelectReport. Отображение отче-та инициируется методом Execute. В завершение следует закрыть проект отчета,вызвав метод Close класса TRvProject.

Свойства:

property Active: Boolean;Свойство Active позволяет открыть или закрыть проект отчетов. При уста-новке значения свойства равным True проект отчетов открывается. Это ана-логично вызову метода Open. Изменение значения свойства на False анало-гично вызову метода Close.

property Engine: TRpComponent;Это свойство позволяет указать машину выполнения отчета, которая будетиспользоваться при отображении или печати отчета, определенного компо-нентом TRvProject. В том случае, если значение этого свойства не установ-лено, то по умолчанию будет использоваться компонентTRvSystem.Машина выполнения отчета может быть указана как компонент классаTRvNDRWritor или класса TRvSyslcm.

property ProjectFile: string;Имя файла RAV-проекта. используемое при вызове метода Open или опреде-лении значения свойства Active равным True.

property ReportDesc: string; (только для ЧТЕНИЯ)Содержит описание текущего проекта.

property ReportFullName: string; (только для ЧТЕНИЯ)Содержит полное имя текущего проекта.

property ReportName: string; (только для ЧТЕНИЯ)

Содержит имя текущего проекта (без пробелов и специальных символов).

Методы;

procedure Open;Метод открывает проект отчетов, указанный свойством ProjectFile, и делаетего доступным для печати или изменения.

function SelectReport(ReportNatne: string; FullName: boolean): boolean;Если отчет, заданный параметром ReportName, найден в открытом проектеотчетов, то функция возвращает значение True. Если параметр FullName ра-вен True, то будет выполняться поиск по полному имени отчета.

procedure GetReportList(ReportList: TStrings;FullName: boolean);Заносит в параметр Report List список всех отчетов из открытого проекта от-четов.

Page 316: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

316 Глава/

procedure ReportDescToMemo{Memo: TCustomMemo);Заносит в многострочное текстовое поле, указанное параметром Memo, крат-кое описание текущего отчета.

procedure Close;Закрывает проект отчетов и освобождает память.

procedure Execute;Начинает выполнение текущего отчета.

procedure ExecuteReport(ReportName: string);Начинает выполнение отчета, указанного параметром.

СОБЫТИЯ, ИНИиИИРУЕМЫЕ ПРИ РАБОТЕ

С БАЗАМИ ДАННЫХКласс TDataSet является базовым классом всех наборов данных. Далее приведенсписок наиболее часто используемых обработчиков событий, наследуемых по-томками класса TDataSet.

AfterCancelПроисходит после отмены в приложении всех изменений, сделанных для теку-щей записи.

AfterCloseПроисходит после закрытия набора данных и перевода базы данных в состояниеdslnactive.

AfterDeleteИнициируется после удаления приложением текущей записи, перевода набораданных в состояние dsBrowse и перемещения позиции курсора на предыдущуюзапись.

Пример:

procedure TForml.TablelAfterDelete (DataSet: TDataSet);begin

StatusBarl.SimpleText := Format(В таблице всего Id записей1,

[DataSet.RecordCount]);

end;

AfterEdit

Происходит после начала редактирования приложением текущей записи.

AfterlnsertПроисходит после того, как приложение вставит новую запись.

Page 317: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 31 7

AfterOpenПроисходит после того, как приложение откроет набор данных, но до того, каккакие-либо доступные данные будут отображены.

Пример:

procedure TForml.TablelAfterOpen(DataSet: TDataSet);begin

Таблица открыта, и доступны значения ее свойств.Выполняется обновление строки состояния. .

StatusBarl.SimpleText := 'Запись ' + Ir.tToStr(Tablel.RecNo) + 'из '+ IntToStr(Tablel.RecordCount);

end;

AfterPostПроисходит после завершения переноса значений активной записи в базу данных.

-

AfterRefreshПроисходит после обновления набора данных.

AfterScrol!Происходит после перемещения позиции курсора на другую запись.

BeforeCancelПроисходит перед отменой в приложении всех изменений, сделанных для теку-щей записи. Этот обработчик события может содержать код, заносящий отме-няемые изменения в undo-буфер.

BeforeCloseПроисходит перед закрытием набора данных и перевода базы данныхв состояние dslnactive.

Before Del etcИнициируется перед удалением приложением текущей записи, перевода набораданных в состояние dsBrowse и перемещения позиции курсора на предыдущуюзапись.В обработчике этого события можно предусмотреть отображение уведомляю-щего диалога с требованием подтвердить удаление записи.

BeforeEditПроисходит перед переходом приложения в режим редактирования активнойзаписи.

BeforelnsertПроисходит перед тем, как приложение вставит новую запись.

Page 318: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

318 Глава 7

Пример:

procedure TForml.TablelBeforeInsert(DataSet: TDataSet);

begin

try(Проверка на возможность преобразования введенного

значения в целочисленное. Если введено ошибочное значение,

то будет брошено исключение, при обработке которого полю

присваивается нулевое значение }

StrToInttEditl.Text!;

except

Editl.Text := '0' ;

end;end;

BeforeOpenПроисходит перед тем, как приложение откроет набор данных.

BeforePostПроисходит перед передачей изменений для активной записи в базу данных илив кеш.

Пример:

procedure TFormi.TablelBeforePostlDataSet: TDataSet);beginif DBEditl.Text = " then

Abort; {Если значение не введено,то прервать передачу записи)

end;

Before RefreshПроисходит перед обновлением набора данных,

BeforeScrollПроисходит перед перемещением позиции курсора на другую запись.

OnCalcFieldsПроисходит при открытии набора данных, переводе его в состояние dsEdit, пе-ремещении фокуса ввода от одного компонента к другому или от одного столб-ца к другому, при изменениях записи или извлечении записи из базы данных, нотолько в том случае, если значение свойства AutoCalcFields равно True.

OnDeleteErrorИнициируется, если при попытке удаления строки произошла ошибка — былоброшено исключение.

Page 319: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 31 9

Параметры обработчика событияprocedure TForml.StoredProclDeleteError(DaUaSet: TDataSet; E: EDatabaseError;var Action: TDataAction)определяют набор данных, для которого было брошено исключение, указательна исключение EDatabaseError и действия, которые следует выполнить. Припервом вызове параметр Action всегда равен daFa'tl. Если ошибка может бытьустранена, то следует установить значение Action равным daRetry: это иниции-рует приложение выполнить повторную попытку удаления.

Если ошибка не устранена, то можно:

• отобразить сообщение об ошибке: для этого не следует изменять значениепараметра Action;

* подавить сообщение об ошибке: для этого параметр Action должен быть рав-ным daAbon.

OnEditErrorИнициируется, если при попытке изменения или вставки записи произошлаошибка - было брошено исключение.

Этот обработчик события имеет те же параметры, что и OnDeleteError.

OnFilterRecordПроисходит при изменении активной записи и только в том случае, если свойст-во State набора данных установлено равным dsFilter, а свойство Filtered равноTrue.

Этот обработчик события используется в качестве фильтра в том случае, еслиусловие фильтрации нельзя указать в свойстне Filter набора данных.

Для того чтобы запись была включена в отфильтрованный набор данных, длянее следует установить параметр Accept ранным True. Если задать Accept рав-ным False, то запись будет исключена из отфильтрованного набора данных.

Пример:

procedure TForml.TablelFilterRecord(DataSet: TDataSet;г

var Accept: Boolean);begin

Accept := DataSet [ 'SAL 1 ] > 900;end;

OnNewRecordПроисходит при вставке или добавлении новой записи.

OnPostErrorИнициируется, если при попытке передать изменение или вставку новой записипроисходит ошибка - бросается исключение.

Page 320: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 8

РАЗРАБОТКА ПРИЛОЖЕНИЙБАЗ ДАННЫХ

СОЗДАНИЕ ФОРМЫ для РАБОТЫ с БАЗОЙДАННЫХ ЧЕРЕЗ ВОЕСамый простой способ создания формы для работы с базами данных черезBDE - это использование мастера Form Wizard. Этот мастер позволяет создаватьшаблоны формы полностью работающего приложения для:

* просмотра и редактирования одной таблицы базы данных;

* просмотра и редактирования двух таблиц, соединенных отношениемродительская-дочерняя.

Этот мастер создает одну форму для работы с таблицей. Если в приложениитребуется иметь несколько форм для работы с различными таблицами, то требу-ется запустить мастера Form Wizard несколько раз.

Для того чтобы создать шаблон приложения, работающего с таблицей (илидвумя таблицами), следует:

1. Создать новый проект.

2. Запустить мастера Form Wizard, выполнив команду меню Database|FormWizard.

J. Выбрать в первом открывшемся диалоге Database Form Wizard (рис. 8.1) типсоздаваемой формы:

* Simple database - форма одной таблицы;

* Master/detail - форма для просмотра и редактирования двух таблиц,связанных отношением родительская-дочерняя.

4. Выбрать тип объекта набора данных: ТТаЫе или TQuery. В нашем примеревыберем тип объекта набора данных ТТаЫе.

5. После определения всех параметров надо перейти к следующему шагу,щелкнув на кнопке Next>.

6. Выбрать во втором открывшемся диалоге Database Form Wizard (рис. 8.2)каталог расположения базы данных и таблицу (в случае для двух таблиц -родительскую таблицу).

Page 321: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 321

Database Form Wizard

What type of form do you ' anl the wizard to create?

• Form Options •

t* [Cteate a simple foirrj

С Create a masterAtetail form

- DataSet Options -

f* Create a foim usinc TTable objects

Create a Form usini? Tflueiy objects

Help Next> Cancel

Рис. 8.1. Диалог Database Form Wizard - 1-й шаг

D al abase Foi m Wizard

Choose a table to use with the form.

Table Name:

customer, db

Directories:

еЛ... \bofland shared\data

Ш clients.dbl

Щ country.db

Щ eustoly.db

-aa customer.db

Ш employee, db

Щ events db

List Fifes

i DelphiS

Borland Shaied

Drive or Alias name:

All Table! [ DBF DEi| " В

Help < Back. Newt > Cancel

Рис. 8.2. Диалог Database Form Wizard - 2-й шаг

7. В третьем открывшемся диалоге Database Form Wizard (рис. 8.3} выделитьна левой панели список полей, которые следует поместить в создаваемую

Пак II

Page 322: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

322 Глава 7

форму, и щелкнуть на кнопке >. Для того чтобы добавить в форму все по-ля таблицы, следует щелкнуть на кнопке ».

Database Form Wizard

То add lields to the loim. click each one In IheAvailable Fields list and then click the ">" button.To choose all fields, click Ihe "»" button.

Available Fields: Ordered Selected Fields:

CustNoCompanyAddilAddr2CityStaleZiD

JJ_LJ

Help < Back Next > Cancel

Рис. 8.3. Диалог Database Form Wizard - 3-й шаг

8. С помощью кнопок JJ и ft, расположенных под правой панелью, опреде-лить порядок размещения полей на форме.

9. В четвертом диалоге Database Form Wizard (рис. 8.4) определить порядокследования полей в таблице: горизонтально одно за другим, вертикальноодно под другим.

Ю.В пятом диалоге Database Form Wizard (рис. 8.5) указать, является ли созда-ваемая форма главной формой приложения.

11.Выбрать место расположения невизуальных компонентов: набора данных(ТТаЫе или TQuery) и источника данных (TDataSourse). Они могут бытьрасположены на форме или в отдельном модуле данных. Во втором случаеэтот модуль данных может быть использован для нескольких форм.

Page 323: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 323

Database Foim Wizard

How do you want the field: arranged on ihe form?

(* Horizontally

Place each field side-by-side starling at the left cornerworking towards Ihe bollorri right.

Г Vertically

Place each field directly below the previous one

working from Ihe top down lo Ihe bottom.

С In a gridPlace each field wilhin iis own column inside a grid objectworking from left Io right.

Help Nexl> Cancel

Рис. 8.4. Диалог Database Form Wizard - 4-й шаг

Database Form Wizard

You have new completed Ihe form design. Clickthe Finish button to generate the геи form.

[• Generate a main Form

Form Generation"""

(• Form Only

Г Form and DalaModule

Help < Buck Finish Cancel

Рис. 8.5. Диалог Database Form Wizard - 5-и шаг

Page 324: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

324 Глава 7

Форма для одной таблицы, используюшаякомпонент типа ТТаЫе

После щелчка на кнопке Finish интегрированная среда разработки Delphi автомати-чески создаст форму (рис. 8.6), на которой в нашем примере будут расположены:

• компонент типа DBNavigator для перемещения по записям набора данных;

• компонент набора данных типа ТТаЫе;

• компонент источника данных типа TDataSource;

» компоненты типа TLabel и TDBEdit для названий полей и полей редактирова-ния.

r f c Foiml

lill ГТ>|

lustNo Company

EdilCustNa JEdilComparij'

Addr2

EditAddr2

Zip

Cily

|EditGty

lountr^ Phone

EdilZip jEditCountiy EditPh

TanRate Contact Lastlnv

EditTaxRdte

' Addrl >

EdiiAddr

State

EditS tale

РЖ

, ,.

re |EditM<

.irsH its

Ё ditCoritact 1 E drtLastl nvoiceD ale

Компонент TOateSourse

Компонент ТТаЫе

Компонент D В Navigator

Рис. 8.6. Автоматически созданная форма для работы с полями таблицы

Код для этой формы будет автоматически сформирован в Pascal-модуле Unitl.Кроме объявления класса TFonnl, содержащего расположенные на форме визу-альные и невизуальные компоненты, implemeniation-секция модуля будет со-держать только один обработчик событий, в котором выполняется открытие на-бора данных:

procedure TForml.FormCreate(Sender: TObject) ;begin

Tablel.Open;end;

Одновременно для всех созданных компонентов будет выполнена настройка ихсвойств. Напомним, что информацию о свойствах можно получить, посмотревв инспекторе объектов или открыв файл с расширением DFM. В этом файлеописаны все объекты и все их свойства. Рассмотрим наиболее важные свойстваи отметим жирным шрифтом и курсивом те из них, которые всегда необходимоустанавливать.

Page 325: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 325

Файл свойств формы:

[После object указывается имя объекта модуля формы; описание объектазавершается no end.Данная форма содержит вложенные объекты:объект Forml содержит два объекта: Panell - для навигатора - и Рапе12 -для области прокручивания, в которой располагаются поля ввода; объектDataSoursel и объект Tablel, содержащий поля таблицы, - объекты типапотомков класса TField.)object Forml: TFormlActiveControl = PanellCaption = 'Forml

1

object Panell: TPanelLeft = 0Top = 0Align = alTopTabCrtier = 0object DBNavigator: TDBNavigatorLeft = 8Top = 4DaiaSource = DataSourcel [Указывает объект

источника данных}TabOrder = О

endendobject Panel2: TPanel

Left = 0Top = 33Width =428Height = 174Align = alClientBevelOuter = bvNoneBorderWidth = 4Capticn = '?ane!2

r

TabOrder = 1(Создание прокручиваемой области ScrollEox на панели Panel? дляразмещения компонентов типа TLabel и TDEEdit}

object ScrollBox: TScrollBoxLeft = 4Top - 4Width = 420Height =166HorzScrollBar.Margin = £HorzScrollBar.Range = 419VertScrollBar.Margin = 6VertScrollBar.Range = 160

Page 326: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

326 Глава 7

Align = alClientAutoScroll = FalseBorderStyle = bsNoneTabOrder = 0

{О&ъекгы типа TLabel для каждого поля таблицы}object Labell: TLabelCaption = 'CustNo

1

FocusControl - EditCustNo {Назначает оконный компонент,ассоциируемый с данной меткой}

endobject Label2: TLabelCaption = 'Company

1

FocusControl = EditCompany

end

{Объекты типа TDBEdit для каждого поля таблицы}object EditCustNo: TDBEdit

Left = 6Top = 21Width = 65Height = 21DataField = 'CustNo

1

DataSource = DataSourcelTabOrder = 0

endobject EditCompany: TDBEditLeft - 11Top = 21Width - 165Height - 21DataField = 'Company'DataSource = DataSourcelTabOrder = 1

endobject EditAddr: TDBEditLeft = 248Top = 21Width - 165Height =21DataField = 'Addrl'DataSource = DataSourcelTabOrder = 2

end

end (Конец объекта ScrollBox }end (Конец объекта Рапе12}

Page 327: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 327

object DataSourcel: TDataSourceDataSec = Tablel [Ссылка на набор данных!

endobject Tablel: TTable

DatabaseName = 'C:\Program Files \Сошюп Files\Borland SharedVData' (Имя базы данных)

TableName = 'customer.db ' (Имя таблицы}Left = 361Top = 3

(Объекты - поля данных типа TFloatField,TStringField и т. п.]object TablelCustNo: TFloatField

Fi'eldWame = 'CustNo' [Имя поля}endobject TablelCcmpany: TStringField

FieldName = 'Company'Size = 30

endobject TablelAddrl: TStringField

FieldName = 'Addrl 1

Size = 30end

object TablelLastlnvoiceDate: TDateTimeFieldFieldWarae = 'LastlnvoiceDate'

endend {Конец объекта Tablel }

end [Конец объекта Forml}

В завершение для выполнения созданного приложения достаточно нажать наклавишу F9. На рис. 8.7 показан внешний вид работающего приложения.

LfForml ИВЕ

CustNo

| 1330

Addr2

j Suite 310

Zip

[33776

TaxRate

7,1 01

H + - A

Company

|6lue Jack Aqua Centei

City

^0-Addrl

1 23733 Paddington Lane

Stale

IWaipahu JHI

Country

[LTT

Contact

jEinest Batratl

^hor'ie FAX

401-609-7623 ]401-609-9403

.astlnvoiceDate

03.11.3423.22:03

Рис. 8.7. Выполняемая форма

Page 328: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

328 Глава 7

Форма для двух таблиц, используюшаякомпонент типа TQuery

Для создания формы для двух таблиц, связанных отношением родительская-дочерняя и использующих компонент типа TQuery, следует выбрать соответст-вующие опции на 1-м шаге мастера Form Wizard.

В этом случае мастер Form Wizard предложит два дополнительных диалога, пер-вый из которых аналогичен диалогу, открываемому на 2-м шаге. В нем следуетвыбрать имя дочерней таблицы. Второй диалог (рис. 8.8) предназначен для оп-ределения поля, по которому будет устанавливаться связь между таблицами.Выберите на панели Detail Field поле дочерней таблицы (внешний ключ), а напанели Master Field - поле родительской таблицы (первичный ключ), а затемщелкните на кнопке Add.

Database Form Wizard

Select a pair of lields from the field lists that will join thetwo queries. Use the add button to odd the selected pailto the list.

Detail Fields Maslei FieldsOideiNoSaleDateShipDateErnpHo

Joined Fields

A ]HI

CompanyAddrlAddr2

*|13

QjslNo-> CustNo

Help < Back Cancel

Рис. 8.8. Диалог Database Form Wizard - для определения связи таблии

В результате в создаваемой форме будут отображаться только те записи из до-черней таблицы, в которых значение выбранного в качестве ключа поля совпа-дает со значением поля из родительской таблицы в активной записи.

Автоматически созданная форма (рис. 8.9) будет отображать дочернюю таблицув компоненте типа TDBGrid.

В данном примере нами на последнем шаге была выбрана опция, определяющаясоздание отдельно модуля формы и модуля данных.

В этом случае в модуль данных будут помещены четыре невизуальных компо-нента: два источника данных и два набора данных.

Page 329: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 329

• JrFormZ

1 Г \ " \ r-1

CustNo .

JEdilCuUNo

Addi2

JEdilAddi2

Zip

[EdilZp

TaxRale

JEditTaxRate

|

Г

HI-IB

' j2il£J '• iCcirnpany Addrl —

|EdCompany JEdit^ddj

Cily Stale

JEdiOy JEditSiate

Country ' Phone FAX

JEdilCountiy (EdilPhone JEditFAX

Contact LasllnvoiceDale

lEdiiConSact ]EdilLastinvoiceDa!e • ..T.I

Рис. 8.9. Автоматически созданная форма для двух связанных таблии

Листинг модуля данных:

unit Unitl;interfaceusesSysUtils, Windows, Classes, Graphics, Controls,Forms, Dialogs, DB, DBTables;

typeTDataModulel = class(TDataModule)QuerylCustNo: TFloatField; {Поля из наборов данных)

QuerylCompany: TStringField;QuerylAddrl: TStringField;

QuerylLastlnvoiceDate: TDateTimeField;Query20rderNo: TFloatField;Query2CustNo: TFloatField;Query2SaleDate: TDateTiraeField;Query2ShipDate: TDateTimeField;Query2EnpHo: TIntegerField;

Query2A.iiountPaid: TCurrencyField;DataSourcel: TDataSource;Queryl: TQuery;Query2: TQuery;

DataSource2: TDataSource;

Page 330: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

330 Глава 7

procedure DataModuleCreatefSender: TObject);end;var DataModulel: TDataModulel;implementation{SR ' .DFM}procedure TDataModulel.DataModuleCreate(Sender: TObject);begin

Queryl.Open; Query2.0pen; (Открытие наборов данных}end;end.

Одновременно для этих четырех созданных компонентов модуля данных будетвыполнена настройка их свойств. Рассмотрим наиболее важные свойства и от-метим полужирным шрифтом и курсивом те из них, которые всегда необходимоустанавливать.

Ф а й л с в о й с т в модуля д а н н ы х :object DataModulel: TDataModulel

OldCreateOrder = TrueOnCreate = DataModuleCreate

object Queryl: TQuerySQL.Strings = ( {SQL-оператор для родительской таблицы)

'Select customer."CustNo",customer."Company",

customer."LastlnvoiceDate"From "C:\ \Data\customer.db" As customer')

object QuerylCustNo: TFloatField

FieldName = 'CustNo'endobject QuerylCompany: TStringField

FieldName = 'Company'Size = 30

end

endobject Query2: TQuery

DataSource = DataSourcelSQL.Strings = ( {SQL-оператор для дочерней таблицы}

'Select orders."OrderNo", orders."CustNo", orders."SaleDate",

From "C:\Data\crders.db" As ordersWhere [Условие связи}

С:\Data\orders.db"."CustNo" =:"CustNo"')ParamData = <

item

DataType = ftFloat

Page 331: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 331

Name = 'CustNo'ParamType = ptUnknown

end>object Query20rderNo: TFloatField {Объект создается)

FieldName - 'OrderHo1 (автоматически)

endobject Query2CustNo: TFloatFieldFieidName = 'CustNo

1

endobject Query2SaleDate: TDateTimeFieldFieldName = 'SaleDate

1

end

object Query2AmountPaid: TCurrencyFieldFieldName = 'AmountPaid'

endendobject DataSourcel: TDataSourceDataSet = Queryl

endobject DataSource2: TDataSourceDataSet = Query2

endend

Листинг формы:

unit Unit2;interfaceusesWindows, Messages, Classes, SysUtils, Graphics, Controls, StdCtrls,

forms, Dialogs, DBCtrls, DB, DBGrids, Grids, Mask, ExtCtrls;typeTForm2 = class(TForm)ScrollBox: TScrollBox;Label1: TLabel;EditCustNo: TDBEdit;Label2: TLabel;EditCompany: TDBEdit;

Labell3: TLabel;EditLastlnvoiceDate: TDBEdit;DBGridl: TDBGrid;DBNavigator: TDENavigator;Panell: TPanel;Panel2: TPanel;

Page 332: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

332 Глава 7

Panel3: TPanel;end;

таг Form2: TForm2;implementation{SR * .DFM)uses Unitl; {Использование модуля данных}end.

Файл свойств формы:

object Form2: TForm2object Panell: TPanelobject DBNavigator: TDBNavigatorDataSource = DataModulel.DataSourcel

endendobject Panel2: TPanelobject ScrollBox: TScrollBoxAutoScroli = FalseBorderStyle = bsNorieobject Labell: TLabel

Captior. = 'CustSo'FocusControl = EditCustNo

endobject Label2: TLafcel

Caption = ' C o m p a n y 1

FocusControl = EditCompanyend

object EditCustNo: TDBEditDataField = 'CustHo'DataSource = DataModulel.DataSourcel

endobject EditCompany: TDBEditDataField = 'Company

1

DataSource = DaUModulel. DataSourcelend

end {Конец объекта ScrollBox }end {Конец объекта РапеШobject Panel3: TPanelobject DBGridl: TDBGrid (Для дочерней таблицы}

DataScurcs = Datatbdulel.DataSource2endend

end

Page 333: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 333

На рис. 8.10 показан внешний вид работающего приложения - формы, отобра-жающей поля из двух таблиц, связанных отношением родительская-дочерняя.

.|Тогт2

"

H -4 >-.

~uslNo

1356

Udr2

!ip

JOOS2D

_.

<

0

CusiNo

1356

135Б

1356

1356

1356

1356

1356

1356

JJ .

M ^ F-

Companji

,- ~ '"f - ' Г< С

Addr! .±j

|Tom Sawyer Diving Centie |632-1 Thild Frydenhoi

City Slate

Country

iChrisliansled 1st. Doix

Phone FA><

[US Viigln Islands

Contact

504-7ЭЗ-3022 [504-798-7772

„as Unvoice Date

IChris Thomas |20 03.92 9:35:40 _lJ

OrderNo

1005

1059

1072

1080

1105

1180

12GG

1280

SaleDale

20.04.86

24.02.89

11.04.83

05.05.89

21,07.92

06.08.94

15.12.34

26.12.94

{ShipDate EmpNo Ship;*

21.01.6312:00:00 110

25.02.89 109

12.04.8Э 29

06.05.ВЭ 45

21.07.92 23

06.03.94 144

15.12.94 Л

25.12.94 118 ,j

Рис. 8.10. Форма, отображающая поля из двух таблии

Использование страницы Diagram для работыс базами данных

Страница Diagram окна редактора кода позволяет представлять в графическойформе взаимоотношения компонентов.

Объекты, отображаемые на странице Diagram окна редактора кода, могутбыть ту да помешены из окна Object TreeView.

Для того чтобы посмотреть, какие связи установлены между источниками дан-ных в текущем проекте, поместите на страницу Diagram элементы {Alias}и{ТаЫе1) и {Tuble2J из окна дерева объектов. Рисунок 8.11 иллюстрируетсвязь между двумя таблицами дочерняя (Customer) - родительская (Order) пополю CustNo.Для отображения связи между источником данных, полями данныхи компонентами отображения полей базы данных все эти объекты следует по-местить на страницу Diagram (рис. 8.12).

Page 334: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

334 Глава 7

Сопрогчп! йу-k-t-.t Toott

| Svfflml DH ol BDE

a sal * *

ii Fts^f-wwpn Fi

f, Л ™*"e.» (TaUeJI-' •& odd!.* (I Ml)

= О"1— о-; П soa

r : . : .•

3 ttkSieDie3 £*5hnIiAll

77О

I N,™

Altfo^n

яякяетяяетяейч1- -mi ч

Рис. 8.11. Странииа Diagram окна редактора кода

Рис. 8.1 2. Странииа Diagram - связь между наборами данныхи источниками данных

Связь между объектами может быть установлена или в инспекторе объектов,или на странице Diagram.

Page 335: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 335

Например, для того чтобы графически установить связь между компонентомDBNavigatorl и объектом DataSourcel, следует па панели инструментов страни-цы Diagram выбрать инструмент Property connector, а затем при нажатой кнопкемыши провести линию от объекта DBNavigator! к объекту DataSourcel. Приустановлении связи автоматически будет определено свойство, используемоедля указания этой связи.Используя этот прием, при наличии нескольких источников данных связь ком-понента доступа к данным с некоторым источником данных можно менять гра-фически непосредствен [to на странице Diagram, не меняя вручную значение со-ответствующего свойства.

ОСНОВНЫЕ ШАГИ ПРИ СОЗДАНИИПРИЛОЖЕНИЙ, РАБОТАЮЩИХС ТАБЛИПАМИВ предыдущих разделах был подробно рассмотрен процесс разработки прило-жений баз данных с использованием мастера Form Wizard.В большинстве случаев для облегчения настройки взаимосвязанных компонен-тов использование мастера Form Wizard - это самый лучший выход.Далее в уже готовое приложение можно добавлять линейку меню и увязыватьвзаимодействие автоматически созданных форм.

-y-ij Для того чтобы создать приложение баз данных с нуля, следует:£

1. Создать новый проект.

2. Расположить в форме (или в модуле данных) компонент типа TDateSource.

5. Расположить в форме (или в модуле данных) компонент типа ТТаЫе (илиTQuery).

4. Установить значение свойства DataSet компонента TDateSource (напри-мер, DateSourcel.DataSet = Tablel;).

5. При использовании компонента ТТаЫе установить значение его свойствDatabaseHame и ТаЫеНате. Если для базы данных создан псевдоним, то зна-чение свойства DatabaseName может быть выбрано из предложенного списка.

При использовании компонента TQuery установить значение его свойстваSQL. Значением этого свойства является строка, содержащая SQL-операторSELECT. На рис. 8.13 показан диалог String List Editor, открывающийсядля ввода SQL-оператора.

6. Определить режим использования таблицы; общий или исключительный,установив значение свойства Exclusive компонента типа ТТаЫе. Отметим,что если во время проектирования для таблицы установлено свойство

Page 336: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

336 Глава 7

Active, то свойство Exclusive можно устанавливать только программно,так как таблица уже используется интегрированной средой проектирова-ния IDE и, следовательно, исключительный доступ к ней невозможен.

Suing List editoi

10 lines

Selectcustomer. "CustNo".с us t о mer." С omp any".customer. "Add!",customer. "Add r2",customer. "City",customer. "Slate",customer. "LastlnvoiceD ate"

From "CAProgram Files'\Common Files\Eotland SharedM}ataScuslomer.db"As customei

Code Editoi... OK Cancel Help

Рис. 8ЛЗ. Диалог String List Editor для ввода SQL-оператора

7. Выполнив двойной щелчок мышью на пиктограмме компонента ТТаЫе(или TQuery), открыть редактор полей (рис. 8.14).

For ml. Tab el

Addi2CityZipPhone

SAdd Fields

"Available fields

CompanySlateCountry

Tab-RateContactLas tin voice Date

i

OK Cancel

ЗЭЕШП

Help

1

Рис. 8.14. Редактор полей и диалог Add Fields

Page 337: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 337

8. Вызвать в редакторе полей контекстное меню, позволяющее создавать но-вые поля или добавлять уже существующие поля. На рис. 8.14 приведендиалог Add Fields, в котором отображен список всех доступных полей таб-лицы (для набора данных Tablel).

9. Выполнить в контекстном меню команду Add Fields, добавив все требуе-мые поля. Автоматически для каждого добавляемого поля будет созда-ваться свой объект. Тип объекта будет зависеть от типа поля.

Необязательно все указанные в SQL-операторе или имеющиеся в таблице по-ля должны быть визуально отображены. Некоторые из них могут быть ис-пользованы в вычислениях. Однако если поле не указано в SQL-операторе, тоего не будет и в наборе данных.

Если необходимо, то можно выполнить в контекстном меню редактораполей команду New Fields, добавив новые поля (рис. 8.15). Новое поле мо-жет быть создано для работы'с данными как вычисляемое или только дляпросмотра.

Hew Field

~ Field properties"

Name: NewField Component: TablelflewField

| Type. [String _*] Size:

! _ -_ ___

Field type; Г Г Lookup

- Lookup definition"

I J

:

OK Cancel Help

Рис. 8.1 5. Диалог для создания нового поля

Ю.Распо;южнть в форме компонент типа TDBHavigator.

11.Связать его с источником данных, определив значение свойства DataSource(например,DBNavigator.DataSource=DataSoursel;).

12. Рас положить в форме компоненты типа TDBEdit для отображения полей

таблицы.

15.Установить значения свойств DataField (имя поля) и DataSource (источ-ник данных) для каждого компонента типа TDBEdit.

14.Если требуется, то расположить в форме компоненты типа TLabel для ка-ждого компонента типа TDBEdit.

Page 338: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

338 Глава 7

15.Установить значения свойств FocusControl компонентов TLabel. Этосвойство указывает имя компонента типа TDBEdit, к которому относитсякомпонент TLabel.

16.Добавить обработчик события OnCreate для формы и ввести в него код,открывающий набор данных (например, Tablel.Open; или Query I. Open;).

НАСТРОЙКА CTOABUOB ТАБАИУЫ ТИПАTDBGRIDНапомним, что после того как в форму добавлен компонент набора данных,ссылающийся на конкретную таблицу базы данных, для него следует:

1. Вызвать редактор полей (.Fields Editor).

2. Добавить поля таблицы, которые требуются в приложении.

J. Если надо, то создать новые поля.

Имя компонента набора данных указывается п источнике данных, являющемсясвязующим звеном между таблицей базы данных и элементами управления,отображающими эти данные.

На странице Data Controls палитры компонентов расположены элементы управ-ления, предназначенные для работы с полями таблиц баз данных.

Для табличного представления данных удобно использовать компонент типаTDBGrid.f fff

\ ~~~~—у-\ Для того чтобы настроить компонент типа TDBGrid. следует:

1. Вызвать по двойному щелчку на компоненте или из контекстного менюкомпонента редактор столбцов (Columns Editor).

2. Добавить имена полей, которые должны отображаться в столбцах таблицы.

Инспектор объектов всегда отображает свойства столбца таблицы, выделенногов редакторе столбцов (рис. 8.16).

По умолчанию ячейка таблицы ведет себя как обычное поле редактирования.Для того чтобы изменить режим работы с ячейкой, надо изменить значения со-ответствующих свойств объекта DBGrid.Columns[i].

:| Для того чтобы получить доступ к свойствам столбца компонента типа} TDBGrid, следует:

1. Вызвать редактор столбцов.

2. Выбрать в нем имя поля и перейти в инспектор объекгов для изменениязначения свойств данного столбца.

Page 339: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 339

Object Inspector

JDBGrid1.Columns[1]: T Column _^_

Properties Events

Alignment . ;tal_eftJustily_H»

ButlonStyle icbsAuto

Color [~1 с [Window

DropDownRw. 7

Expanded False

FieldName " _ " • CUSTOMER

fTFontj

ImeMode 'imDontCaie

ImeHarrve

PickList | (T Strings]

PopupMenu

FleadOnly False

E Title ;[tCoiumnTitie)'~

Visibje 'True "

All shown

CUST NC CUSTOMER CONTACT : -•

tEditing DUtiudl.... £

O - C U S T WO1 -CUSTOMER2 - COHTACT_FIRST3 • CQNTACT_UST4-PHONEJJO5-ADDRESSJJNE1E-ADDRESS_LINE2

Рис. 8.1 6. Редактор столбиов и инспектор объектов со свойствамивыделенного столоиа

-\\ Для того чтобы установить режим работы ячейки столбца при редактирова-jf [j ним как комбинированное окно списка (рис. 8.17), следует:

1. Определить значение свойства PickList этого столбца. Свойство PickListдолжно содержать список элементов и может быть определено как во вре-мя проектирования, так и динамически во время выполнения.

2. Установить значение свойства Expanded: True разрешает ввод значений не изсписка, False ограничивает выбор только значениями из предлагаемого списка.

jBTorml

CUST NO

lots100Э

101D

1011

1012

1013

1014

1015

CUSTOMER

Anini Vacation Rentals

Man

MF'M Corpoiolion

Dynamic Intel ligence С

3D -Pad Corp.

Lorenzi Export, Ltd

Dyno Consulting

GeoTechlnc.

COUNTRY j^J

USA

Fiii

Japan

Switzerland

Fiance

ItaljJ

АнглияРоссияФранцияСША

|

zJ

Рис. 8.1 7. Столбец Country редактируется как комбинированный список

Page 340: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

340 Глава 7

ФОРМА С ДИАГРАММОЙ ДЛЯ НАБОРА

ДАННЫХЗаписи набора данных можно отображать с помощью различных элементовуправления, расположенных на странице Data Controls палитры инструментов.Числовые данные можно использовать для построения диаграмм.

Для того чтобы создать форму, отображающую на диаграмме значения по-лей набора данных, следует:

Определить используемый набор данных. Для этого расположить в формекомпонент типа ТТаЫе {или TQuery).

Установить значения свойств DetabaseName и TableName компонентаТТаЫе (или SQL компонента TQuery).

Выполнив двойной щелчок мышью па компоненте, вызвать редактор по-лей. Выбрать команду контекстного меню Add Fields и добавить поля, зна-чения из которых будут использоваться.

Расположить в форме компонент типа TDBChart. Выполнить на нем двойнойщелчок мышью для вызова диалога Editing DBChart (рис. 8-18). Этот диалог по-зволяет полностью в графическом режиме настроить параметры диаграммы.

Editing DBChaill

1.

2.

J.

4.

i Chart I Series

>enes General] Axis ] Titles | Legend] Panel ] Paging] Walls ] 3D

| Series Title

i Series!

g Seiies2

Ц Series3

Help.:

Рис. 8.18. Диалог Editing DBChart

Page 341: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 341

5. На странице Chart щелкнуть па кнопке Add для добавления серии значений.11ри этом будет открыт диалог TeeChart Galary (рис. 8.19). В нем можно вы-брать свой тип диаграммы для каждой серии.

SPTeeCharlGalleij.

Standard Functions

Horiz. Bat Area

Shstpe

Gantt Arrow Er.. bie

Cancel [7 3D

Рис. 8.19. Диалог TeeChart Galary

6. Вернувшись на страницу Chart диалога Editing DBChart, создать требуемоечисло серии. Для каждой серии автоматически будут созданы объекты ти-па TBarSeries. TLineSeries, TAreaSeries. в зависимости от выбранноготипа диаграммы.

7. Перейти на страницу Series диалоги Editing DBChart (рис. 8.20) и выбратьдалее страницу Data Source.

8. На странице Data Source для каждой серии укачать тип источника данныхDatasei. иыорать имя компонента набора данных (например, Table 1)и определить имя поля.

9. Установить значение свойства Active набора данных равным True иливвести код для вызова метода Open.

Ю.Для запуска созданного приложения нажать на клавишу F9,

Page 342: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

342 Глава 7

Editing DBChaitl

Charl Series j

Format] Gerieial j Marks Data Source |

Dalaset: Table!

Labels: |llemNc

X: I V j " DaleTime

т Г DaleTime

Help- Close

Рис. 8.20. Страница Series диалога Editing DBChart

Отметим, что для отображения диаграммы нам даже не понадобился компоненттипа TDataSource. Созданная диаграмма будет показывать текущие значениявыбранных полей таблицы базы данных- При изменении значений полей это ав-томатически будет отображаться на диаграмме,

J Для того чтобы предоставить пользователю возможность изменять значения; J? || полей в той же форме, где расположена диаграмма, следует:

1. Расположить в форме компонент типа TDataSource.

2. Связать этот компонент с набором данных, определив значение свойстваDataSet.

J. Расположить в форме компонент типа TDBGrid (или TDBEdit для каждогополя и TDBHavigator для навигации по набору данных).

4. Связать расположенный элемент управления TDBGrid с источником дан-ных, выбрав его из списка значении свойства DataSource (для компонентаTBSEdit определить свойства DataSource и DataField, выбрав значения изпредлагаемого списка).

На рис. 8.21 приведена полученная в результате этих действий форма,

Page 343: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 343

I Series'!I Serie$20 SeriesS1 Senes4

IDNs

llLJ

I J'a 1 Description Val2 Vai3 Val4 •• '•

1

2

3

20 1

50 2

90 3

40

70

ЭО

50

50

50

Рис. 8.21. Форма с диаграммой и таблицей для работы с полями набораданных

ВЫПОЛНЕНИЕ SQL-ОПЕРАТОРОВИ ХРАНИМЫХ ПРОУЕАУР

Создание генераторов значений для БД InterBaseВ различных СУБД средства автоматической генерации последовательностиуникальных номеров создаются не всегда одинаково. В СУБД InretBase такиезначения называются генераторами и создаются при помощи SQL-оператораCREATE GENERATOR.В некоторых СУБД, таких, как Oracle, автоматически генерируемые значенияназываются последовательностями.

Для того чтобы разработать приложение, выполняющее создание генера-I; тори значений для СУБД InretBase, выполните следующие действия:

1. Создайте новый проект и разместите на форме компонент типа TQuery.

2. Установите для компонента Queryl значение свойства DatabaseName рав-ным IBLocul, выбрав это значение из списка.

Page 344: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

344 Глава 7

J. Компонент TQuery позволяет выполнять за один вызов метода ExecSQLтолько один SQL-оператор. Создание генератора выполняется двумя опе-раторами:1. CREATE GENERATOR иия_генератора

2. SET GENERATOR имя_гекератора ТО начальное_значениеПоэтому метод ExecSQL следует вызвать дважды с разными значениямисвойства SQL.Вызовите редактор SQL-оператора, выполнив двойной щелчок мышьюв поле значения свойства SQL или на расположенной справа кнопке [Т] .

4. Введите в редакторе свойства SQL следующий SQL-оператор:CREATE GENERATOR CUST_1_GEN

5. Расположите на форме компонент командная кнопка и в обработчике со-бытия OnClick для этой кнопки введите код, инициирующий выполнениесозданного SQL-оператора:Queryl.ExecSQL;

6. Далее в созданный обработчик события следует добавить код, изменяю-щий значение свойства SQL. Это реализуется следующими строками:Queryl.SQL.Clear;Queryl.SQL.Add('SET GENERATOR CUST_1_GEN TO 270 '} ;

7. И в завершение следует добавить код, выполняющий второй созданныйSQL-оператор:Queryl.ExecSQL;

Для проверки правильности выполнения используемых SQL-операторов можноиспользовать утилиту SQL Explorer. Вызвать SQLExplorer можно посредствомкоманды меню Database] Explore. Далее следует открыть базу данных IBLocal, вве-дя в диалоге Database Login пароль masterkey. После открытия секции Generatorsбазы данных IBLocal на вкладке Summary правой панели SQLExplorer будетотображен список всех генераторов базы данных. Текст SQL-оператора, исполь-зованный для создания данного генератора, можно просмотреть на вкладке Textправой панели SQLExplorer.

Создание триггеровТриггером называется программа, хранимая в базе данных и выполняемая настороне сервера СУБД. Триггеры позволяют перенести выполнение части дей-ствий от клиента - приложения, на сервер - СУБД. Более того, триггеры позво-ляют унифицировать действия над таблицей для нескольких приложений.

Триггер - это действие, запускаемое для таблицы при выполнении SQL-оператораязыка обработки данных.

Сокращенно синтаксис оператора создания триггера можно представить сле-дующим образом:

CREATE TRIGGER имя триггера FOR нме.таблнцы BEFORE | AFTER

INSERT I DELETE I UPDATE

Page 345: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 345

AS BEGIN

код_триггсраEND

Фраза BEFORE или AFTER определяет, когда будет выполнятся триггер: доили после SQL-оператора, для которого он запускается.

Фраза INSERT, DELETE или UPDATE определяет, для какого SQL-оператораязыка обработки данных запускается данный триггер.

Для обращения к новому значению поля в коде триггера используется операторnew. Так new.localion определяет повое значение поля location.

,Цля обращения к старому значению поля в коде триггера используется оператор old.

?} Для того чтобы разработать приложение, создающее триггер, выполняющий:: перед записью в базу данных преобразование значения символьного поля

в верхний регистр, выполните следующие действия:

1. Установите значение свойства SQL компонента TQuery, введя следующиестроки:

CREATE TRIGGER DEPTJLOC FOR DEPARTMENT BEFORE INSERT POSITION 0 asbeginnew.location=uppet(new.location);end

2. Расположите на форме компонент командная кнопка и в обработчике со-бытия ОпОк^для этой кнопки введите код, инициирующий выполнениесозданного SQL-оператора:Query I.ExecSQL;

Создание н в ы п о л н е н и е х р а н и м ы х процедурХранимые процедуры могут быть двух типов:• процедура, возвращающая результирующий набор, подобно оператору

SELECT;• процедура, выполняющая обработку данных и не возвращающая результи-

рующий набор.

Выполнение хранимой процедуры может быть реализовано с помощью следую-щих компонентов:• TQucry;• TStorcdProt.

Сокращенно синтаксис оператора создания хранимой процедуры можно пред-ставить следующим образом:CREATE PROCEDURE iiMii_iipi>iuuypbi [( спнсок_нараметров) ]

Е RETURNS (возвратаем ое_знячение}]ASDECLARE VARIABLE локалы1:ш_персмсиная тнп_персм(;нной;

Page 346: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

346 Глава 7

[DECLARE VARIABLE локалыиш^псрсмспшш тнп__переменной ; ...]BEGIN

код_процедур1>1ENDСоздать хранимую процедуру можно двумя способами:• выполнить SQL-оператор, содержащий текст хранимой процедуры в свойст-

ве SQL компонента типа TQuery (Query l.ExecSQL);

• в утилите SQL Explorer ввести текст SQL-оператора, создающего хранимуюпроцедуру, и выполнить этот оператор.

Пример:

[ Эта хранимая процедура будет добавлять новую строку в таблицу DEPARTMENT.

При этом значение поля dept_no будет формироваться на основе генератора,а значения полей department и location будут браться из параметров хранимой

процедуры.

Функция GENJED выполняет в InterBase автоматическую генерацию уникальныхзначений. Первым параметром функции указывается генератор базы данных, а

вторым - на сколько это значение будет увеличено. При каждом вызове функции с

приращением, равным 1, будет формироваться значение на 1 большее предыдущего.]

CREATE PROCEDURE DEPT_INIdep VARCHAR(25), loc VARCHAR(15))

RETURNS (dno INTEGERi

ASBEGIN

SELECT GEN_ID(CUST_1_GEN,1] FROM department

where dept_no=333 INTO :dno;

INSERT INTO DEPARTMENT (dept_no,department, location)

VALUES (:dno, :dep, :loc) ;

SUSPEND;END

:! Для того чтобы выполнить хранимую процедуру, сделайте следующие дей-ствия:

1. Расположите на форме компонент типа TStoredProc.

2. Свяжите компонент StoredProc 1 с базой данных, указав значение его свой-ства DatabaseName равным IBLoctil.

5. Выберите имя хранимой процедуры DEPT_1N из списка значений свойст-ва StoredProcName. предвари!ельио введя по запросу Delphi парольmasicrkey.

4. Откройте редактор параметров компонента StoredProc I. выполнив двой-ной щелчок мышью на значении свойства Params.

Page 347: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 347

5. Для каждого параметра процедуры и для возвращаемого значения следуетуказать их тип, а для параметров также определить передаваемые храни-мой процедуре значения.Сначала выделите в редакторе параметров параметр DEP, а затем в ин-спекторе объектов введите для этого параметра значение свойства Valueравным !333. Delphi автоматически определит тип параметра, указывае-мый свойством Туре как String, а значение свойства ParamType какрг/ирыг.Свойство ParamType определяет является ли параметр значением переда-ваемым в процедуру или возвращаемым значением. Delphi пытается уста-новить это свойство самостоятельно исходя из кода хранимой процедуры.

6. Далее выделите в редакторе параметров параметр LOC и в инспектореобъектов введите значение его свойства Value равным 333. Выделитев рсдакчоре параметров параметр DNO, используемый как возвращаемоезначение, и в инспекторе объектов выберите значение его свойства Туреравным Integer.

7. Для выполнения хранимой процедуры надо ввести в соответствующий об-работчик события следующий код:

StoredPtocl.ExecProc;

ShowMessage('Создана запись с emp_no ' +

StoredFrocl. ParaniByName ( 'DNO 1 } .AsStr ing ) ;

Это обеспечит выполнение хранимой процедуры и отображение сообщения созначением поля emp_no созданной записи.

Пример:

(База данных содержит следующую процедуру:CREATE PROCEDURE GET_EMP (EMPJIO INTEGER)

RETURNS (E_NAME CHAR(10})

AS

BEGIN

FOR SELECT ENAME FROM EMP

WHERE EMPJJO = :EMP_HO

INTO :E_NAME

DO

SUSPEND;END){Для создания параметров и выполнения данной хранимой процедуры можноввести следующий код:}

varPI, P2: ТРагага;

begin

with StoretiProcl do begin

Page 348: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

348 Глава 7

StotedProcName := 'GET_EMP';

Params.Clear;

[Создание параметров}

PI := TParam.Create(Params, ptlnput);

P2 := T?ara^.Create(Params, ptOutput);

tryParajisfO] .Name := 'EMP_HO';

Params[1].Name := 'EJIAME';

ParamByname('EMP_NO').AsInteger := 10;

ExecProc; {Выполнение хранимой процедуры)

Editl.Text : = ParamByName('E_N.4-E').AsString;

finallyPI.Free; [Освобождение памяти]

P2.Free;

end;end;

end ;

Delphi позволяет выполнять перегружаемые хранимые процедуры (например, дляСУБД Oracle). Для этого следует установить значение свойства Overload компо-нента TStoredProc равным порядковому номеру перегружаемой процедуры.

|i Для того чтобы выполнить хранимую процедуру, используя компонентTQuery, следует:

1 . Расположить в форме компонент TQuery.

2. Связать его с базой данных Oracle, указав значение свойства DatabaseName.

3. Определить значение свойства SQL, указав оператор SELECT в том случае,если есть возврат результирующего набора.Например:SELECT * FROM GET_EMP(4)Значения параметров следует указывать через запятую в скобках послеи м е н и хранимой процедуры.

4. L'c:in хранимая процедура не возвращает значений, то определить значе-ние свойства SQL как SQL-оператор EXECUTE с именем выполняемой хра-нимой процедуры.

5. Для выполнения хранимой процедуры следует установить для объектаTQuery значение свойства Active ранным TRUE или вызвать метод Open.

Page 349: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с блзами данных 349

ОБРАБОТКА ДАННЫХ для МНОГОЗВЕННОЙАРХИТЕКТУРЫ

Применение многозвенных архитектурПрименение многозвенной архитектуры позволяет вынести бизнес-логику рабо-ты с данными в приложение-сервер.При многозвенной архитектуре приложение разбивается на ряд компонентов,которые могут выполняться на различных компьютерах.

Трехзвенная архитектура обозначается как:

приложение-клиент <^> прпложсннс-ссриср с=> база данных.

Такая архитектора позволяет реализовывать доступ к серверу БД из приложе-ния-сервера, не имея на клиентских машинах никаких драйверов доступа к базеданных.

Большое преимущество использования такой архитектуры заключается такжев возможности изменения серверной части без необходимости перетрансляцииклиентского приложения.Приложение-сервер получает набор данных стандартным способом: через одиниз компонентов набора данных, таких, как ТТаЫе или Tquery. и пересылает егос помощью компонента TDataSetProvider компоненту TClientDataSet в прило-жении-клиенте. Для подключения к удаленному приложению-серверу в прило-жении-клиенте используется компонент TRemoteServer.

Приложение-сервер реализуется как удаленный модуль данных, представляю-щий собой СОМ-объект. Доступ к такому компоненту может быть выполненпосредством DCOM с любого удаленного компьютера.

Создание сервера и клиента для доступа к данным

Начинать следует с создания приложения-сервера. Дня этого надо выпол-f , нить следующие действия:

1. Создайте новое приложение, выполнив команду Fi le |New|Appl icat ion.

2. Далее выполните команду меню F i L e j N e w | O t h e r и выберите на страницеMultitier создание удаленного модуля данных Remote Data Module. В ответна это Delphi отобразит диалог (рис. 8.22). в котором следует ввести на-звание класса.

?. Далее поместите в созданный модуль компонент ТТаЫе. Установите значениеего свойства Name (в нашем примере определим имя компонента TableEmp).

4. Укажите для компонента ТТаЫе, определяющего набор данных, свойстваDatabaseKame и TableName. В пашем примере следует выбрать псевдоним,определяющий местоположение базы данных Oracle (предварительно та-кой псевдоним должен быть создан), и таблицы.

Page 350: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

350 Глава 7

.2<j

CoClassName; (TestMidas

Instancing: Multiple Instance

Threading Model: Apartment

OK Cancel Help

Рис. 8.22. Диалог для создания удаленного модуля данных

5. Вызовите редактор полей Fields Editor компонента ТТаЫе. Затем в открыв-шемся диалоге редактора поле!! выполните команду контекстного менюAdd АИ Fields, по которой в модуле данных будут созданы объекты для ка-ждого столбца таблицы.

6. Поместите в удаленный модуль данных компонент TDataSetProvider(страница Data Access). Определите значение его свойства Нате (в нашемпримере имя провайдера будет ProviderEmp).

7. Определите для провайдера связываемый с ним набор данных. Для этогоустановите значение его свойства DataSet указывающим на компонентТТаЫе. Значение выбирается из предлагаемого списка (в нашем примереимя выбираемого набора данных TableEmp).На рис. 8.23 отображен созданный в результате описанных действий мо-дуль данных.

8. Выполните команду меню File |Use Unit для добавления в приложение соз-данного удаленного модуля данных.

9. Выполните это приложение для регистрации созданного сервера.

При создании приложения-сервера для него будет создана библиотека типа(рис. 8.24).После того как сервер создан, его можно разместить на локальном или на уда-ленном компьютере. Далее можно переходить к созданию клиента.

.. Для создания клиента нужно выполнить следующие действия:

ев\. Создайте повое приложение.

2. Разместите в форме компонент TDCOHConnection со страницы DataSnap па-литры компонентов.

J. Установите значение свойства ProgID (имя сервера в реестре Windows)компонента TDCOMConnection. выбран его из предложенного списка. (В

Page 351: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 351

нашем примере это Projectl.TestMidas.) Так как мы уже зарегистрировалисервер, то свойство ServerGUID, определяющее уникальный идентифика-тор класса сервера в реестре Windows, будет установлено автоматически.

If TeilMidas

TestMidas

>*, Default {Session!

Е- tft РОЫе Has}3-fc^ EMPUableEmp}

••i Constraints

Components | Data Diagram j

DataSetProvideil

FieldDefs

Fields

»4 D-EMPNO {TableEmpEMPNO}

*', 1 -ENAME {ТэЫеЕгтрЕНАМЕ}

>'_, 2-JQB{TobleEmpJOB}

»' 3-MGR{TableErnpMGR}

^ 4 - HIREDATE {TableEmpHIREDATE}

>* 5-SAL{TsbleEmpSALl

( 6 - COMM {TableEmpCDMM}

»'_, 7-DEPTNO{TableEmpDEPTNO}

IndexDels

TableEmp Do(a?elProviderl

Рис. 8.23. Модуль данных для приложения-сервера

4. Для того чтобы автоматически запустить сервер, следует установить зна-чение свойства Connected компонента TDCCMConnection равным True. За-пуск сервера можно выполнить и потом из обработчика какого-либо собы-тия.

?. Разместите в форме компонент TClientDataSet. Установите значение егосвойства RemoteServer. выбрав его из предложенного списка. (В нашемпримере это DCOMConnectionl.) Установите также значение свойстваProviderName.

6. Установите значение свойства Active компонента TClientDataSet равнымTrue. На этой стадии у вас будет запрошено имя пользователя и пароль дляподключения к базе данных.

7. Добавьте в форму компонент TDataSourse и свяжите его с набором данныхCHentDataSetl, определив значение его свойства DataSet.

8. На этом шаге построение доступа к базе данных с использованием трех-звенноП .архитектуры завершено. Остается только добавить в форму эле-менты управления, используемые для отображения значений столбцовтаблицы.

Page 352: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

352 Глава 7

gg Project 1. lib-»

*><>$ A A^'-] & PjoiecM

^ ITeslMfifes^ r-:.r •.-::

Hodifud

»

=- 1R Ез

>*'*^. ; а^ о-

Allribules Uses | Flaas ТЫ

[ uuldt3E30EBEO-Oe9B-IlI>2-E013-BAlAF7074SEC), ^version (1.0! ,helpstrinB ( "Project! Library")

-•l ibrary Project !

impocclib ( " S T D O L E 2 . T L E " ) ;

version ( 1 . 0 ) ,halpstcingC'Dispaict i interlace £oc TestMidaa Ob_

] 1incetriace ITestHifias; lAppServer

i;

ve r s ion t l -O) ,Lelpscriiig ("Tescllidas Objecc"]

j

^LJ - 2Г1

A

Рис. 8.24. Диалог для просмотра библиотеки типа

На рис. 8.25 приведен внешний вид разработанной формы приложения-клиента.

IS* Доступ к Oracle в тр виз вен ной архитектуре

Таблица ЕМР из базы данных Oracle .:EMPNO MGR H1REDATE SAL COMM PEPTWO

ГЗЗЭ KING PRESIDE!! 1711.В1 500Д О

Рис. 8.25. Приложение-клиент для доступа к БД в трехзвеннои архитектуре

СОЗДАНИЕ ОТЧЕТОВ в RAVE REPORTSСоздании отчета при помощи средств Ritvc Designer состоит из двух этапов.

I. На первом шаге is Rave Reports создается RAV-файл проекта отчетов. Этотфайл может содержать несколько шаблонов отчетов.

Page 353: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 353

2. Далее для печати или просмотра отчета используется компонент TRvProject,для которого могут быть выполнены следующие четыре действия:

» открытие проекта отчетов методом Open;

в выбор текущего шаблона отчета методом SeiectReport;

* выполнение отчета методом Execute;

* закрытие проекта отчета методом Close.

«НИДля того чтобы создать проект отчетов, выполните следующие действия:

1. Откроите утилиту Rave Reports, выполнив команду меню Tools|RaveDesigner.

2. Создайте в Rave Reports новый отчет, выполнив команду меню FiLeJNew.

5. Добавьте н создаваемый проект отчетов информацию обо всех используе-мых источниках данных. Для этого выполните команду меню FiLeJNew DataObject. В диалоге Data Connections (рис. 8.26) выберите элемент спискаDatabase Connection.

Dais Object Type

Data Lookup Se;,irit/ Cc.r,::o;!a

Direct Data View

Driver Data View

Simple Security Controller

Next >: snc-el

4.

5.

6.

7.

Рис. 8.26. Диалог Data Connections

В следующем диалоге следует выбрать тип соединения с базой данных(ADO, BDE, DBX).

Далее в диалоге Database Connection Parameters определите имя подклю-чаемого источника данных (рис. S.27).

В секцию Data View Dictionary на правой панели окна Rave Reports будетпомещен элемент Database!, указывающий соединение с базой данных.

Далее опять выполните команду меню F i l e j N e w Data Object и в диалоге DataConnections выберите элемент списка Driver Data View.

Page 354: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

354 Глава 7

ii Database Connection Раг

Ok

Рис. 8.27. Диалог Database Connection Parameters

8. Укажите имя подключенной ранее базы данных (в данном примереDatabasel).

9. Далее в диалоге QueryAdvanced Designer (рис. 8.28) выберите таблицы базыданных, которые будут использоваться в отчетах.

Layout Sorting Ь Graupirig j

customer. lib | M] j«j

Is/] CompanyA Addrl2 Addr2

Ш State_' ZipI_! CountryG Phone

"..I Contact

Ed tor

zl

ddeis.db [T2] _X

> OrderNo ~"-/ : '~ "'."Т"Т."w, SJeDatey: ShipDate•</j EmpMoy] ShipTcContactГ' SliipTcAddrlH ShipToAddr2.."; ShipToCitvП ShipToSlale

J ShipToZip" EfeToCourilrv Л I

Table:animals dbf •••

,' biollte.dbclients, dbfcountry, db

' custolji dbcustomer, db

; employee dbevents, dbholdings, dbfindustry. db(items.db

', master dbf; neKlcust dbneKlitem.db

'pa/is.dbreservat db

.vendois.db ~j

OK Cancel

Рис. 8.28. Диалог QueryAdvanced Designer

Ю.Теперь для формирования простого шаблона можно выполнить командуме шо Tools | Report Wizards] Sam pie Table.

Page 355: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 355

11 ,В диалоге Simple Table следует выбрать элемент Data View, определяющийдоступные поля таблиц базы данных. И далее на втором шаге диалога SimpleTable указать поля, которые следует включить в шаблон отчета (рис. 8.29).

WzSelect The Fields you wish 1o use for this repurt

NoneA

•j '..-.- :

Day

Cudl'-loJnStJeDeteHShipOate~;EmpMo

CShipToContact

Mext»

Рис. 8.29. Диалог Simple Table

12. В результате выполненных действий будет сформирован шаблон диалога.

На рис. S.30 представлено окно утилиты Rave Reports, отображающее созданныйшаблон диалога.Окно утилиты Rave Reports содержит строку меню, панель инструментов и трипанели: панель свойств (текущего выделенного объекта), панель шаблона отчетаи панель проекта.Панель проекта отображает всю информацию о проекте в виде древовиднойструктуры. Секция Report Library содержит имена шаблонов отчетов. Секция DataView Dictionary содержит информацию об используемых источниках данных.

Страница Page Designer панели шаблона отчета служит для формирования внеш-него вида отчета. Поля отчета отображаются па полосе данных — компонентыDataBand. Для компонента DataBand устанавливается значение свойства DataView,связывающее его с источником данных.Компонент DataBand можно расположить на странице отчета, выбрав его настранице Report палитры компонентов. Для отображения значений полей можноиспользовать компонент DataText со страницы Report палитры компонентов.После завершения формирования шаблонов отчета проект отчетов следует со-хранить (по умолчанию он сохраняется в файле с расширением RAV).Далее созданный проект отчетов можно использовать в приложениях.

Page 356: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

356 Глава 7

.infxi

t-sa. FainB**£l*

LotMbMOnQ ьCmmMiind ....

Д^^ДДЩ^Щ '|F«B

F35

С Кбririlcr» 'к-

"Fata

I

properly

ol ih* dalaviH, Mild Ihtreives e Iwh recc-d 01

. — -, . .

!,,,!,,,,I I....I.M.1 1.11 1» I... I I ..и

Simple Table Report

Ord?lNQIM.tier 1 I |

<> С «* =

3 ' 1: = -'

G О Dirv

DataCamau^L О X-OD15Y.Q(IK

Рис. 8-30. Окно утилиты Rnve Reports

Пример:

{Использование проекта отчетов}unit MyReports;interfaceuses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, RpRave, RpDefine, RpBase, RpSystem;type

TForml = class(TForm)RvSysteml: TRvSystem;Listl: TListBox; (Окно списка для отображения имен

шаблонов отчетов)Memol: TMemo;Buttonl: TButton;RvProject: TRvProject;procedure FormCreate(Sender: TObject);procedure ListlClick(Sender: TObject);procedure FormDestroytSender: TObject);procedure ButtonlClickfSender: TObject);procedure FormShowfSender: TObject);

end;varForml: TForml;

Page 357: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Работа с базами данных 357

implementation{SRprocedure TForml.FormCreate (Sender: TObject);beginRvProject.Open; (Открываем проект отчетов}

RvProject.GetReportList (Listl. I terns, true) ; {Заполняем окносписка Listl именами шаблонов отчета)end;

procedure TForml.ListlClick(Sender: TObject] ;begin(Выбираем шаблон как текущий элемент списка:}RvProject.SelectReportfReportLB. Items [ReportLB.ItemlndeK] , true);

(Отображаем Е поле ткпа TMemo информацию о текущем шаблоне:}RvPro ject . ReportDescToMemo (Memol | ;

end;procedure TForml.ButtonlClick (Sender: TObject) ;

beginRvPrcject. Execute; {Выполняем текушй отчет}

end;procedure TForral.FormDestroy (Sender: TObject);

beginRvPtoject. Close; (Закрываем проект отчетов}

end;procedure TForml.FormShow (Sender: TObject);begin

Listl. Itemlndex := 0;ListlClick(nil);

end;end.

Page 358: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 9

РАЗРАБОТКАРАСПРЕДЕЛЕННЫХПРИЛОЖЕНИИ

В этой главе подробно рассмотрен порядок действий разработчика для созданияраспределенных приложений на основе технологий СОМ и CORBA.

МОДЕЛЬ КОМПОНЕНТНЫХ ОБЪЕКТОВ СОММодель компонентных объектов COM (Component Object Model) позволяет пред-ставлять единое монолитное приложение как набор взаимосвязанных небольшихкомпонентов и определяет унифицироапппый способ взаимодействия между та-кими компонентами.Основная цель СОМ — создавать такие компоненты, которые могут вызываться изприложений, написанных на различных языках программирования и располо-женных на разных компьютерах в сети.

СОМ - это также спецификация, определяющая, как надо создавать компонен-ты, чтобы их можно было одинаковым образом выполнять как DLL-библиотеки,какЕХЕ-кОмпопенты или как удаленные компоненты.

Взаимодействие с СОМ-компонентом происходит через интерфейс.

ИнтерфейсыИнтерфейс можно рассматривать как набор виртуальных абстрактных общедос-тупных методов для управления объектом. Интерфейсы не могут содержатьданных.

Интерфейс - это тип языка Object Pascal, который определяется следующим об-разом:

typeимя_кнтерфейса =interfасе(предок!

[ ' { G U I D } ' ]список_членов;

end;

Указывать предка для интерфейса и его GU1D необязательно. GUID представля-ет собой уникальный 128-разряднын идентификатор (например, '{00000002-0000-0000-СООО-000000000046П, который можно присвоить каждому интер-фейсу, компоненту или каждой категории. Технология создания GUID гаранти-рует, что нигде не может быть получено два одинаковых GUID.Интерфейс не реализуется самостоятельно, а создается как часть класса.

Page 359: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложении 359

Интерфейс создается с целью описания методов, которые впоследствии можнобудет вызывать клиенту компонента, реализующего данный интерфейс.Спецификация СОМ требует, чтобы любой компонент наследовал интерфейсlUnknown. Если компонент не наследует этот интерфейс, то он не являетсяСОМ-компонентом. В языке Object Pascal по определению любой создаваемыйинтерфейс всегда наследует интерфейсу lUnknown.

Интерфейс lUnknown определяет три метода: Querylnterface, AddRef и Release.Метод Querylnterface должен возвращать указатель на интерфейс, используе-мый затем для вызова функций интерфейса. Методы AddRef и Release предна-значены для подсчета количества обращений к интерфейсу.

Если объект объявляется полностью состоящим из виртуальных методов, какинтерфейс, то при компиляции создается таблица виртуальных методов, назы-ваемая vtbl. Эта таблица содержит массив указателей на реализации виртуаль-ных функций. Структура таблицы виртуальных методов одинакова для интер-фейса lUnknown вне зависимости от языка программирования.

Определяя интерфейс, мы фактически определяем структуру некоторого блокапамяти.

Первые три элемента таблицы vtbl всегда одинаковы для всех СОМ-компонентови содержат указатели на функции интерфейса lUnknown.

И

- : | Для того чтобы создать интерфейс, выполните следующие действия:

1. Создайте простой модуль, выполняющий реализацию интерфейса, выпол-нив команду меню File |New Unit.

2. Введите в секцию interface определение создаваемого интерфейса.Например:

typeIMylnterface = interface

[Интерфейс определяет один метод - GetUserName)function GetUserName: string;

end;

5. Далее следует создать класс, реализующий этот интерфейс. Для этого соз-дадим класс, наследуемый от класса TInterfacedObject и от создаваемогонами интерфейса ГМуInterface. После объявления интерфейса следует за-писать объявление класса:

TMyClass =class (TInterfacedObject,IMylnterface)function GetUserHame: string;

end;

4. В завершение в секции implementation надо реализовать методы интерфей-са уже как методы класса, наследующего данный интерфейс. Объявлен-ный класс обязательно должен реализовывать все методы, объявленныев наследуемом им интерфейсе.В нашем примере класс TMyClass объявляет метод GetUserName.

Page 360: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

360 Глава 9

В секции implementation введите код реализации функции GetUserName.Например:

function TMyClass. GetUserName: string;begin

Result:='Bbi3BaH метод интерфейса' ;end;

На этом реализация интерфейса завершена.

Класс TInterfacedObject - это класс языка Object Pascal, наследуемый от ин-терфейса lUnknown и реализующий его.

Для того чтобы создать любой СОМ-компонент, следует или самостоятельнореализовать методы интерфейса lUnknown, или наследовать класс, который реа-лизует эти методы.

Класс TInterfacedObject объявляется следующим образом:

typeTlnterfacedObject = class (TObject, lUnknown)

private

FRef Count : Integer;

protected

function Querylnterf ace (const IID: TGUID; out Obj): Integer; stdcall;

function _AddRef: Integer; stdcall;

function _Release: Integer; stdcall;

public

property RefCount: Integer read FRefCount;

end

Вызов методов интерфейса через реализующий его классВызов методов интерфейса можно выполнить различными способами.

j j Для того чтобы произвести вызов метода интерфейса через реализующийего класс, выполните следующие действия:

1. Перейдите в модуль, в котором будет производиться вызов интерфейса{в нашем примере — Unitl).

2. Выполните подключение модуля, содержащего реализацию интерфейса(в нашем примере - Unit2), к модулю Unit ! . Для этого выполните командуменю File|Use Unit и выберите модуль Unit2.В результате этого действия в секцию implementation будет вставлен код

uses Unil2;

J. Создайте код, выполняющий вызов метода интерфейса.Например:

varMyClass: TMyClass;

Page 361: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 361

begir;

MyClass:=TMyClass.Create; {Создание экземпляра класса]

ShowKessage(MyClass.GetUserName); (Вызов метода интерфейса,

реализованного классомMyClass)

MyClass.Free; [Удаление объекта, используемого

для вызова метода!end;

На этом процесс вызова метода объекта завершен.

Вызов метода интерфейса через ссылку на интерфейсГ f Л '

|]Дпя того чтооы выполнить вызов метода интерфейса через ссылку на ин-терфейс, выполните следующие действия:

1. В методе, в котором производится вызов метода интерфейса, объявите пе-ременную типа класса, реализующего интерфейс.Например:varMyClass: TMyClass;

2. Далее объявите переменную типа интерфейса:

Mylnterface :IMyInterface;

5. Введите в тело метода код, выполняющий создание экземпляра класса.Например:

MyClass:=TMyClass.Create;

4. Создайте ссылку на интерфейс путем присваивания ему ссылки на класс:

Mylnterface:= MyClass;

5. В завершение введите код, выполняющий вызов метода интерфейса черезссылку на интерфейс:

ShowMessage(Mylnterface.GetUserName);

Вызов метода интерфейса ч е р е з ссылку на создаваемыйобъект, р е а л и з у ю щ и й д а н н ы й и н т е р ф е й с

;|1 Для того чтобы выполнить вызов метода интерфейса через ссылку на созда-: ваемый объект, реализующий данный интерфейс, выполните следующие

действия:

1. В методе, в котором производится вызов метода интерфейса, объявите пе-ременную типа интерфейса. Например:

varMylnterface :IMyInterface ;

Page 362: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

362 Глава 9

2. Введите в тело метода код, выполняющий создание экземпляра классаи присвоение его как ссылки на интерфейс. Например:

MyInterface:=TMyClass.Create;

5. В завершение введите код, выполняющий вызов метода интерфейса черезссылку на интерфейс. Например:

ShowMessage(Mylnterfасе.GetUserName);

Р а з р у ш е н и е интерфейсовРазрушение интерфейсов происходит автоматически сразу, как только они вы-ходят за пределы области видимости. В рассматриваемом примере разрушениеинтерфейса выполняется при завершении метода обработчика события OnClick.Для того чтобы принудительно освободить интерфейс, ему следует присвоитьзначение nil. Такое назначение автоматически вызывает метод COM Release,который неявно вызывает деструктор для объекта типа TMyClass.

Реестр W i n d o w sДля того чтобы клиент мог найти компонент, запросить у него интерфейс и вы-звать метод этого интерфейса, и компонент и интерфейс должны быть зарегист-рированы в реестре Windows. В технологии СОМ клиентом называется прило-жение, использующее интерфейсы компонента.Ветвь HKEY_CLASSES_ROOT реестра (рис. 9.1.) содержит информацию обовсех зарегистрированных компонентах, интерфейсах и категориях. Эта инфор-мация включает в себя GUID, имя файла, содержащего компонент, и, возможно,дружественное имя компонента.

а'-' Редактор реестра -Реестр Драька В на Справка

F J^ Мой компьютеряетнкеу OASSES ROOTI

IE - ] HKEY_CURREHT_USERE-Q HK£Y_ LOCAL, MACHINEЙ'С! HKEY_USER£ШСЗ HKEY_CURRENT_CONFIGU-CD HKEY_DYN_DATA

Мой KOMnbioTep\HKEY_ClASSES_RQOT

ННЯННИВН Н Н _ 1 D I xl

Параметр i Значение

) [По имолчанию] (значение не присвоено]

< 1 1 Ил

Рис. 9.1. Редактор реестрп Windows

Дружественное имя компонента указывается в разделе ProgID и может быть ис-пользовано при создании компонента вместо GUID. В этом случае для получе-ния GUID используется функция Windows API CLSTDFromProglD.Для того чтобы просмотреть системный реестр, можно использовать утилитуRegedif, расположенную в корневом каталоге WINDOWS 9S/NТ/2000.

Page 363: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 363

Создание СОМ-компонентовПри использовании технологии СОМ единое монолитное приложение реализу-ется как. набор взаимосвязанных отдельных, компонентов. Клиент используеткомпонент через предоставляемые им интерфейсы.Компонент может быть реализован как DLL- или ЕХЕ-файл. В первом случаекомпонент называют сервером в процессе, во втором - сервером вне процесса.Клиентом называется приложение, запрашивающее интерфейсы.Компонент - это приложение, предоставляющее свои сервисы через интерфейсы.

Создание компонента как сервера в процессе

- Для того чтобы создать компонент- сервер в процессе, выполните следую-: шие действия:

1. Создайте новый проект, который будет содержать код компонента. Дляэтого выполните команду меню FHe|New|Qther и на вкладке ActiveX выбери-те пиктограмму ActiveX Library (рис. 9.2).

/ N e w Items

IntraWeb S WebServices } Business j WebSnap ) Web Documents | Corba

Hew ActiveX | Muliitier j Project! j Forms | Dialogs | Projects | Data Modules

Active Form Active Server ActiveXObject Control

V V

~_/*U

AutomationObject

COM Object COM+ Event СОИ+ Property Page Transactions!Object Subscript!... Object

Libary

Г Сср>. Г [nhsiit Г Use

Cancel Help

Рис. 9.2. Вкладка ActiveX диалога New hems

Будет создана библиотека, представляющая собой сервер СОМ.Модуль библиотеки начинается ключевым словом library:

library Projectl;

Page 364: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

364 Глава 9

Имя, с которым будет сохранен проект, станет также и именем создавае-мой DLL-библиотеки.В библиотеку автоматически добавляются четыре экспортируемые функ-ции, используемые для регистрации компонента в реестре Windows.Это следующие функции:exports

DllGetClassObject, //Для получения класса компонента

DllCanUnloadNow, // Для определения, можно ли выгрузить библиотеку

DllRegisterServer, //Для регистрации компонента

DHUnregisterServer; //Для отмены регистрации

2. Далее в созданную библиотеку следует добавить объекты СОМ. Для этоговыполните команду меню File |New|Other и на вкладке ActiveX выберите пик-тограмму COM Object.

3. Далее в диалоге COM Object Wizard введите в поле Class Name имясоздаваемого класса MyClassl.Поле Instancing предназначено для выбора способа создания объекта. Оп-ция Multiple Instance позволяет создавать для одного приложения несколь-ко копий объекта.Поле Threading Model определяет, будут ли создаваться потоки для запро-сов клиента к интерфейсу СОМ.

4. Если флажок Include Type Library включен, то для создаваемого класса бу-дет автоматически создан новый интерфейс, а информация об интерфейсеи обо всех его методах будет добавлена в библиотеку типа.Библиотека шипов позволяет задокументировать интерфейс. Она можетиспользоваться клиентом для получения информации об интерфейсахкомпонента.

На данном этапе автоматически создано определение класса и сформированпустой интерфейс. Автоматически открытый редактор библиотеки типов(рис. 9.3} позволяет добавлять новые интерфейсы, создавать методы и свойства,а также выполнять регистрацию библиотеки типов.В секцию initialization модуля библиотеки автоматически добавлен следующийметод:TTypedComObjectFactory.Create(CoraServer, TMyClassl, Class_MyClassl,

ciMultilnstance, traApartraent);

Этот метод используется для создания СОМ-комнонента.В поле GUID редактора библиотеки типов отображен уникальный идентифика-тор, автоматически сформированный для создаваемого компонента.Окно редактора библиотеки типов состоит из двух панелей: иа левой представ-лена структура всех входящих к библиотеку элементов, а на правой отобража-ются параметры текущего выделенного элемента.На этом этапе создан модуль, содержащий определение класса компонента. Да-лее в интерфейс можно добавлять объявление методов.

Page 365: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 365

!& Project i.tib

* Ф $ Д fr«d Ф £ i <>, #\ Proiectl

^ IMyClassI

Ф&ПЗШ!

Modified

•ЁНИЕ- " -IDl1

! Ш & \ 33 М

Attributes Implements] Flags ] COM* | Test j

Name1 JMiClassl

GUID: j{684BD98E-2EQ6-444A-BAC5-C451DFAC133B}

Veision: |l.O

, Help

Help Suing: jMjClassl

Help Context:

Help String Context: |

I.

2.

Рис. 9.3. Редактор библиотеки типов

Для того чтобы добавить метод в описание интерфейса, выполните сле-дующие действия:

Перейдите в окно редактора библиотеки типов или щелчком на окне ре-дактора, или выполнив команду меню View|Type Library.

Выделите на левой панели редактора библиотеки интерфейс IMyClassl,а затем щелкните на панели инструментов по кнопке New Hetod. По умол-чанию создается методе именем Metodl.Например, измените имя метода на МуМах.На этом шаге в код определения класса в модуле Unit l был автоматическидобавлен метод МуМах без параметров, имеющий тип HResultи модификатор вызова stdcall.

}. Выберите на правой панели вкладку Parameters, используемую для опре-деления параметров создаваемого метода.

4. Структура интерфейсов описывается на специальном языке ГОЬ. Delphiпозволяет создавать эту структуру как в терминах языка 1DL, так и на язы-ке Pascal.Для того чтобы использовать типы языка Object Pascal, выполните коман-ду меню Tools jEnvironment Options и на вкладке Type Library выберите опциюPascal.

Page 366: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

366 Глава 9

Теперь описание параметров создаваем о го метода будет выполняться наязыке Pascal.

5. Выберите из раскрывающегося списка Return Type тип возвращаемого зна-чения (например. Integer).По умолчанию устанавливается тип HResult. Это специальный тип дан-ных, используемый в СОМ для получения кодов ответа при выполнениифункции. HResult - это 16-битный тип данных, реализуемый в Delphi какLongint.

Тип HResult из Delphi соответствует типу HRESULT из Windows API.

Модель СОМ предоставляет несколько кодов ответа, используемых дляуказания успешного выполнения функции. Поэтому для того, чтобы опре-делить, не было ли ошибки при выполнении функции, а также при переда-че параметров или в результате каких-либо сбоев в сети при удаленномрасположении компонента, следует использовать специальный макросSUCCEEDED из Windows API. Макрос SUCCEEDED позволяет одной операциейопределить, возвращен ли код ответа, указывающий на успешное выпол-нение функции: все положительные коды ответа являются "успешными".

6. Щелкните в строке параметров в столбце Name и введите имя первого па-раметра (например, i).Столбец Modifier содержит список модификаторов параметров. Если пара-метр передается по значению, то модификатор можно не устанавливать.Для передачи параметра по ссылке следует выбрать модификатор out. Длятого чтобы параметр мог использоваться как переменная - и для передачизначения, и для получения возвращаемого значения, - следует установитьмодификатор var.

7. Далее щелкните на кнопке Add для добавления второго параметраи введите имя второго параметра (например,]).На этом этапе описание функции в редакторе библиотеки типов завершено.

8. Для того чтобы выполненные действия по вводу параметров были автома-тически занесены в код определения класса, щелкните на панели инстру-ментов редактора библиотеки типов на кнопке Jil Refresh Implementation.

Созданный модуль будет содержать описание интерфейсов. В имя модуля будетдобавлен префикс _TBL.В завершение следует в автоматически созданное пустое тело метода добавитькод, выполняемый методом.Например:

function TMyClassl.MyHaxli, j: Integer): Integer;beglr.

if i > j then MyMax := i else MyHax := j;end;

На этом шаге компонент COM полностью создан.

Page 367: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 367

Регистрация компонентаДля того чтобы клиенты СОМ могли находить компоненты, последние должныбыть зарегистрированы Е реестре Windows.

Зарегистрировать созданную DLL-библиотеку с СОМ-компонентом можнов редакторе библиотеки типов, щелкнув мышью на панели инструментов покнопке Register Type Library.

Класс TComObjectКласс TComObject используется для создания СОМ-компонентов. Основное от-личие класса TComObject от класса TInterfacedObject в том, что он поддержива-ет фабрики классов.

Используя этот класс, можно создавать DLL-библиотеку, содержащую компо-нент, и без применения библиотеки типов.

Если при создании СОМ-компонспта опция использования библиотеки типоввключена, то класс компонента будет наследовать классу TTypedComObject.

Если библиотеки типов не используется, то класс компонента будет наследоватьклассу TComObject. При этом добавление методов надо будет реализовыватьвручную.

Создание клиентаВ начале этой главы были рассмотрены различные способы вызова методов ин-терфейса. Применение библиотеки типов при создании клиента значительно уп-рощает реализацию вызова методов интерфейса. Это также дополнительно пре-доставляет посредством всплывающих подсказок окна редактора кода списоквсех доступных методов используемого интерфейса.

".;;! Для того чтобы использовать методы компонента в клиенте, необходимо

выполнить следующую последовательность действий:

1. Подключить модуль <имя npoei;Ta>_TLB с описанием предоставляемыхинтерфейсов. Этот модуль автоматически создается на основании инфор-мации, вводимой в окно редактора библиотеки.

2. Добавить в определение класса переменные типа интерфейса. Эти перемен-ные будут использоваться для вызова методов через ссылку на интерфейс.

?. Создать компонент и запросить его интерфейс через вызов методаQuerylnterface.

Далее можно вызывать методы запрошенного интерфейса.

Запрос интерфейсаПеред тем как выполнить запрос интерфейса, следует в секцию uses модуля до-бавить модуль библиотеки типа <имя СОМ-сервера>_ТХВ.

Page 368: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

368 Глава 9

В окне кода в секцию public описания класса TForml следует ввести объявле-ние переменных типа интерфейса, которые будут использоваться для вызова ме-тода, определенного в интерфейсе:II,MyClasslInterface : IMyClassl;

Далее следует создать компонент. Для этого в созданный обработчик события(например, procedure TForml.FormCreate(Sender: TObject);) можно ввестиследующий код:

II:=CoMyClassl.Create;

Метод CoMyClassl.Create присутствует в файле <имя COM-cepBepa>_TLB.pas,автоматически созданном из редактора библиотеки типов.Delphi автоматически создает так называемый CoClass для класса компонента.В нашем примере был создан CoClass CoMyClassl.CoChiss - это специальный тип объекта, используемый фабрикой класса длясоздания компонента.Любой СОМ-объект является экземпляром класса CoClass, который реализуетодин или несколько СОМ-интерфсйсов.Для запроса интерфейса можно ввести следующий код:II.Querylnterfасе(IMyClassl,MyClasslInterface };

При вводе в окне редактора кода переменном II, объявленной как интерфейс, длянее будет отображаться окно всплывающей подсказки со списком доступныхметодов (рис. 9.4).

В UMtcfant pai

т, _J [)з

l . ТocirCceflte (Render:

^Tt'^

Рис. 9.4. Окно редактора кода

Теперь переменная MyClass] Interface может использоваться для вызова методовинтерфейса IMyClass 1.Например:

Edit3.Text:=IntToStr(MyClasslInterface.MyMax(StrToInt(Editl.Text),StrToInt(Edit2.Text)J);

На этом этапе создание клиента завершается.

Page 369: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложении 369

ПРИМЕНЕНИЕ ТЕХНОЛОГИИ CORBAТехнология CORBA (Common Object Request Broker Architecture) позволяет раз-рабатывать распределенные приложения, которые могут выполняться не толькона разных компьютерах сети, но и использовать для выполнения различные плат-формы. Клиент вызывает методы интерфейсов серверных объектов CORBA черезброкер объектных запросов ORB (Object Request Broker)- Для того чтобы иметьвозможность использовать методы некоторого интерфейса, предварительно дол-жен быть запущен ORB. а затем объект должен зарегистрировать свои интерфейсы.ORB реализует объектную магистраль CORBA, позволяющую компонентам про-зрачно вызывать методы других объектов, расположенных в любом месте сети.Технология CORBA позволяет реализовывать как статический, так и дина-мический вызов методов CORBA-объектов. При статическом вызове метода наэтапе компиляции выполняется строгий контроль типов. При динамическом вы-зове метода, использующем механизм позднего связывания, поиск метода вы-полняется во время выполнения.Технология CORBA позволяет сохранять информацию обо всех CORBA-объектах в:

* хранилище Implementation Repository;

• хранилище Interface Repository-

Хранилище Implementation Repository используется службой CORBA OAD дляпоиска местоположения COftBA-объекта. К этой службе обращается ORB дляпоиска объекта. Если CORBA-объект запущен, то ORB позволит вызывать егометоды и без использования хранилищ.Для того чтобы создать распределенное приложение, использующее технологиюCORBA, следует:

1. Разработать серверный объект CORBA, предоставляющий свои интерфейсы.

2. Создать клиента CORBA, запрашивающего методы интерфейсов, предостав-ляемых серверным объектом CORBA.

Создание серверного объекта CORBAБудем называть серверный объект CORBA сервером CORBA.В настоящий момент Delphi поддерживает два пути создания сервера CORBA:

• использование IDL-файла для генерации шаблона серверного объектаCORBA;

* применение CORBA Object Wizard (в версию Delphi 7 эта возможность вклю-чена для обратной совместимости).

Page 370: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

370 Глава 9

Использование IDL-файла

J1-i( Для того чтобы создать сервер CORBA, выполните следующие действия:

I. Создайте lDL-файл с описанием интерфейса.Например:interface MyTestl I

any GetValueO;

2. Далее создайте приложение - сервер CORBA. Для этого выполните ко-манду меню File|New|Other и ни вкладке СогЬа выберите пиктограммуCORBA Server Application (рис. 9.5).

/'New Йе,

New j ActiveX j Multitier j Forms j Dialogs | Projects j

Dale Modules IntraWeb WebServices |

Business j WefaSnap j Web Documents Coiba

CORBA ClientApplication

CORBA ServerApplication

Cow f bi-i-w Г LL

OK Cancel Help

Рис, 9.5, Диалог New Hem - странииа Corba

J. Выполните генерацию PASCAL-файлов из данного IDL-файла. Для этогов диалоге IDL2Pas Create Server Dialog (рис. 9.6) добавьте имя IDL-файла,используемое для генерации PASCAL-фа и лов.

4. В результате будут созданы: основной файл проекта Project!, модуль Unitlи четыре файла со следующими окончаниями: _i, _c, _s, __impl.

Листинг файла Projectl :

program Projectl;usesForms,Unitl in 'Uni t l .pas ' {Forml},MyTestl__i in 'MyTestl_i.pas',

Page 371: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 371

MyTestl_c in 'MyTestl_c.pas',MyTestl_s in 'MyTest l_s .pas ' ,MyTestl_impl in 'MyTestl_irnpl.pas';

($R T . R E S }

beginApplication.Initialize;

Application.CreateForm(TForral, Forral);

Application.Run;

end.

IDLZPas Create Server Dialog

Application | Options}

- Application Type —

I Г Console Application

, £* Windows Application

•AddlDLFfes

G:SDelphi7_Piojects\P[_CORBA_IDL\MvTeEt1.idl Add

С е net ate Cancel

Рис. 9.6. Диалог lDL2Pas Create Server Dialog

Листинг файла MyTest1_impl:

unit MyTestl__impl;{This file was generated on 8 Jan 2003 22:37:03 GMT by version03.03.03.C1.A2 }{of the Inprise VisiBroker id!2pas COREA IDL compiler. }

interfaceusesSysUtils, CORBA, MyTestl_i, MyTestl_c;

typeTMyTestl = class;TMyTestl = class(TInterfacedObject, MyTestl_i.MyTestl)

protected

Page 372: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

372 Глава 9

I******************************!

{*** User variables go here ***}I ******************************** LI I

public

constructor Create;

function GetValue : Any;end;

implementation

constructor TMyTestl.Create/-begin

inherited;J *** J. * * *** **** ** S*** **** * *** 1

{ *** User code goes here *** ;I **************************** 1

end;function TMyTestl.GetValue : Any;begin

/ *************************** 1

( *** User code goes here *** }I I*******************ж ****** I

end,-initializationend.

Содержимое файлов, сгенерированных из IDL-файла, не следует редакти-ровать, за исключением специально указанных мест.

5. На этом этапе создан шаблон серрсра CORBA, реализующего один интер-фейс (в нашем примере - MyTestl). содержащий один метод {GetValue).Далее следует отредактировать модуль Unit 1 следующим образом(полужирным начертанием выделены сделанные изменения.):

unit Unitl;interface

usesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, Corba, MyTestl_i, MyTestl___c, MyTestl_s, MyTestl_impl,StdCtrls;

type

TForml = class(TForm)

Editl: TEdit;private -1 private declarations }

protected

{ protected declarations }

// Add Corba interface variables here like this

Page 373: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 373

// Acct : Account; // skeleton objectmyTest :MyTestl; {Имя интерфейса в IDL-файле]procedure InitCorba;

public{ public declarations }end;

varForml: TForml;

implementation($R * .DFH}procedure TForml.InitCotba;begin

Corbalnitialize;// Add CORBA server code here like this// Acct := TAccountSkeleton.CreateCName', TAccount.Create);// BOA,ObjIsReady(Acct as _0bject);myTest:= TMyTestlSkeleton,Create('Mu Server', THyTestl,Create);BOA.ObjIsReadyfmyTest as ^Object);

end;end.

6. Установите значение свойства Caption для формы равным Server CORBA ирасположите па форме компонент типа TEdit. Вводимые в это текстовоеполе данные будут передаваться в клиентское приложение CORBA.

7. Для того чтобы отредактировать код метода GelValue, следует открытьфайл реализации (файл с окончанием _impl).

8. Сначала следует сделать доступными объекты модуля Unitl. Дня этогов начало секции implementation следует ввести код:uses Unitl;

9. Далее введите в метод GetVulue (модуля MyTest l__impl) следующий код:Result:=StrToInt(Forml.Editl.Text);

10. В завершение следует откомпилировать проект. На этом этапе созданиесервера CORBA завершено.

Применение C O R B A Object Wizard

: Для того чтобы создать сервер CORBA, используя CORBA Object Wizard,выполните следующие действия:

I. СоадаГпс приложение - объект CORBA. Дтя этого выполните командуменю FHe|New|Other и на вкладке MultiHer выберите пиктограмму CORBAObject (рис. 9.7).

Page 374: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

374 Глава 9

К; Hew Items

Dala Modules Business

New J ActiveX Mullitier

CDRBA Data ИЙ-'Д'КН'.!Module

WebS nap WebServices Coiba

Project 1 ] Forms j Dialogs Projects

Йр 1 3Remote Dat-э Trensactional Data

Module Module

Г Т. Г Inherit Г Use•

OK Cancel Help

Рис. 9.7. Диалог New Items, используемый для создания объекта CORBA

2. В появц131ие.мся далее диалоге CORBA Object Wizard (рис. 9.S) следует опре-делить имя класса, введя его в поле Class Name. Поле Instancing позволяетуказать, как будет использоваться сервер CORBA: значение Instance-per-client указывает, что для каждого клиента будет создаваться новый объектCORBA; значение Shared instance определяет, что объект CORBA можетодновременно использоваться несколькими клиентами. В поле ThreadingModel выбирается однопоточпая или многопоточная модель для объектаCORBA.

Class Name:

instancing: Inslance-psr-dienl

f : Threading Model: [Single-thieaded-' '

ZJ

Cancel Help

Рис. 9.8. Диалог CORBA Object Wizard

В результате выполненных действий Delphi сформирует следующий код модуляUnit2:

unit Unit2;interfaceuses

Hir.dcws, Messages, SysUtils, Classes, Graphics, Controls, ContObj,StdVcl, CorbaObj, ProjectlJTLB;type

TMyCorbal = classfrcorbalmplementation, IMyCorbal)

Page 375: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 375

private[ Private declarations 1

public{ Public declarations ]

end;implementationuses Corblnit;initialization

TCorbaObjectFactory.Create('MyCorbalFactory', 'MyCorbal 1,1IDL:Projectl/MyCorbalFactory:1.0',IMyCorbal, TMyCorbal,iMultilnstance, tmSingleThread);

end.

Initialization-секция модуля содержит код. выполняемый для создания объектаCORRA.СозданныО класс TMyCorbal наследуется от класса TCorbalmplementation иреализует интерфейс IMyCorbal.Следующим шагом на пути создания сервера CORBA является объявлениеи реализация методов объявленного интерфейса.

fftf, .иг::! Для того чтооы создать новым метод интерфейса, выполните следующие

; действия:

1. Вызовите редактор библиотеки типа, выполнив команду меню View|TypeLibrary.

2. На правой панели библиотеки типа выделите секцию - интерфейсIMyCorbal и щелчком по кнопке New Metod панели инструментов окнаProjectl.tbl (рис. 9.9) создайте новый метод интерфейса IMyCorbal. Поумолчанию созданному методу будет назначено имя Metod 1.

J. Далее для созданного метода следует определить список параметров и ихтип. Для этого перейдите на вкладку Parameters окна библиотеки типа.

4. По умолчанию методы интерфейса описываются на языке IDL. Для тогочтобы для типов параметров использовать типы языка Object Pascal, вы-полните команду меню T o o l s | E n v i r o n m e n t Options и на вкладке Type Library(рис. 9.10) установите на панели Language язык Pascal.

Ч. Для процедуры тип возвращаемого значения устанавливать не надо (зна-чение None в поле Return Type). Для функции следует определить тип воз-вращаемого значения, выбрав его из списка значений поля Return Type. На-пример, выберите тип Integer.

6. Определите список параметров. Для добавления параметра щелкните мы-шью по кнопке Add панели Parameter s окна библиотеки типа. На рис. 9.11приведено окно библиотеки типа с созданным методом Metod 1, имеющимдва параметра типа Integer.

Page 376: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

376 Глава 9

Л Reject!

•тMj€orb.5l

Modified

Altiibules J Paiameters Flags ] Тек!

Name:

ID:

JMstnodl

"Help —

j HelpStrbj

. Help Context:

: HelpStiinj Context.

3

^Рис. 9.9. Окно библиотеки типа Projectl ,tbl

Envuorunem Opiiont

Designer | Db|ect Inspector | Palelte | Libiary J E*pl<vei

Тур* Library EnWorinienl Variable? J Delphi Direct ] Internet

SaleCall (unction mapping -

j f £11 viable interlace!

' (•" Only diral interfaces

<~ Do ncil map

г Language " •

Г IDL

Г kjnoie ;pecial CcClais Flags (4hen

I— .. j./. .-.j

Г

Г Hid

Г .-.'-'

Г~ Display updates before refreshing

Cancel Help

Рис. 9.10. Вкладка Type Library диалога Environment Options

Page 377: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 377

Projecll

IMjCorbal

т. Method!

MyCabsl

Attributes Parameters [ Flags

Return Type, jlritegei

Г Paiain=teiS-"

Sf'ie Ddaull Value

Parjrn!

Integer

Add Wove Up Move Dawn

'Modilied

Рис.9.11. Вкладка Parameters окна библиотеки типа

7. В завершение следует внести созданные изменения в проект (предваритель-но проект должен быть сохранен). Для этого щелкните мышью на кнопке

Ld Refresh Implementation панели инструментов окна библиотеки типа,

В результате выполнения этих действий в секцию type interface-секциимодуля будет добавлено следующее объявление созданного метода:

Protectedfunction Method!(Рагаш!, Param2: Integer): Integer; safecall;

В implementation-секцию модуля будет вставлена пустая реализация соз-данного метода:

function TMyCorbal.Methodl(Para.-nl, Param2: Integer): Integer;beginend;

8. Теперь можно определить код, выполняемый созданным методом. Напри-мер, введя втело созданной функции: Methodl:= Paraml* Param2;

9. С целью проверки правильности созданного кода можно выполнить ком-пиляцию проекта, пажа is CtrL+F9.

Page 378: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

378 Глава 9

Создание клиента C O R B AСоздавать клиента CORBA можно двумя способами:

* применяя ШЬ-файл, использованный для реализации сервера CORBA;

» применяя библиотеку типов и библиотеку CORBAObj (данный способ менеепредпочтителен).

Создание к л и е н т а C O R B A с и с п о л ь з о в а н и е м IDL-файлаPffffi

-|| Для того ч гобы создать клиента CORBA, выполните следующие действия:

1. Создайте приложение - сервер CORBA. Для этого выполните команду ме-ню File [New] Other и на вкладке СогЬа выберите пиктограмму CORBA ClientApplication.

2. В предлагаемом далее диалоге укажите имя используемого IDL-файла.

5. Расположите на форме элемент типа Label, который будет использоватьсядля отображения значения, получаемого от сервера щелчком мыши на ко-мандной кнопке.

4. Измените код модуля Unit2 следующим образом (полужирным начертани-ем выделены сделанные изменения):

unit Unit2;

interface

usesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, Corba, MyTestlJ, MyTestl_c, StdCtrls;

type

TForm2 = class(TForm|

Labell: TLabel;

Buttonl: TButton;

procedure ButtonlClick(Sender: TObject);private{ private declarations }

protected// declare your Corba interface variables like this

// Acct : Account;varl : MyTestl;

procedure InitCorba;f protected declarations }

public

{ public declarations }end ;

var

Form2: TForm2;

Page 379: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка распределенных приложений 379

implementation(SR * . D F M }procedure TForm2.InitCorba;

beginCorbalnitiaiize;•':' Bind ic the Corba server l ike this// Acct := TAccountHelper.bind;varl := TMyTestlHelper.bind; {Соединение с сервером}

enci;procedure T?orm2.EuttonlCiick(Sender: TObjeot);var myTestVar : Any;begin

myTestVar := varl.GetValue();Labell.Caption := Полученное значение = ' -I- IntToStr{myTestVar) ;

end;er.d.

5. В завершение клиентское приложение CORBA следует откомпилировать.

Создание клиента CORBA с использованием библиотеки типов

Для того чтобы создать клиента CORBA, выполните следующие действия:

1. Откройте менеджер проекта, выполнив команду меню View|ProjectManager, и добавьте новый проект щелчком мыши по кнопке New окнаProject Manage . На вкладке New отображаемого далее диалога выберитепиктограмму Application.

2. В текущую группу проектов добавился проект Project!.

5. Добавьте в начало implementation-секции модуля формы код подключениябиблиотеки типа и библиотеки CORBAObj. Для этого следует ввести:uses CORBAObj, ProjectlJTLB.

4. Для доступа к методам объекта TMyCorbal следует в секции var модуляобъявить переменную типа интерфейса. Например:MylCl: IMyCorbal;

5. Далее следует создать сервер CORBA. Это можно выполнить следующимкодом: MyICl:=TMyCorbalCorbaFactory. CreateInstance('');Фабрика класса TMyCorbalCorbaFaclory, используемая ORB для созданиякомпонента, объявляется в модуле библиотеки типа Projectl_TLB. Сам кодсоздания сервера CORBA должен быть выполнен до обращения к методаминтерфейса TMyCorbal.

6. После объявления объекта типа интерфейса и присвоения ему ссылки насервер, объект типа интерфейса можно использовать для вызова методов

Page 380: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

380 Глава 9

интерфейса. В процедуре, выполняющей вызов метода Metodi интерфейсаIMyCorbal, можно записать:var

MyVaiue: Integer;begin:= MylCl . Metodi(StrToInt(Editl.Text), StrToInt(Edi t2-Text]) ;Edit3.Text:=IntToStr(MyValue);end;

Запуск сервера CORBAСервер CORBA запускается брокером объектных запросов. Для того чтобы ис-пользовать ORB, его первоначально надо загрузить. Для этого достаточно вы-полнить команду меню Windows Пуск[Программы|У151ВгсЖег | Vis iBroker Smart Agent.После запуска ORB к нижнем правом углу рабочего стола будет отображена

пиктограмма LJ VisiBroker Smart Agent.

После этого можно запустить сервер CORBA (в нашем примере - приложениеProject!).

Далее любой запущенный клиент может получить доступ к выполняемому сер-веру CORBA через ORB.

На рис. 9.12 отображен результат взаимодействия сервера и клиента CORBA,созданных с использованием lDL-файла.

j

Рис. 9.1 2. Взаимодействие сервера и клиента CORBA

Page 381: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 1 О

РЕАЛИЗАМИЯ МЕХАНИЗМОВМЕЖСЕТЕВОГОВЗАИМОДЕЙСТВИЯ

В этой главе рассмотрены основы механизма межсетевого взаимодействия, ис-пользующего протокол TCP/IP.

ВЗАИМОДЕЙСТВИЕ по ПРОТОКОЛУ TCP/IPПротокол ТСРЛР (Transmission Control Protocol/Internet Protocol) предназначен дляустановления соединения между двумя компьютерами в сети, обычно называе-мыми клиентом и сервером. Протокол TCP/IP определяет IP-адрес и номер порта.IP-адрес задает имя компьютера в сети.

IP-адрес указывается или как числовой идентификатор компьютеру или при ис-пользовании сервера DNS как символьный псевдоним числового идентификатора.

Локальный компьютер всегда адресуется как 127.0.0.1 или localhost.При работе в Интернет все используемые IP-адреса уникальны. Поэтому для за-дания своему ПК некоторого IP-адреса следует получить его у провайдера.При работе без Интернет в локальной сети предприятия можно самостоятельноустановить р а з л и ч н ы е IP-адреса для каждого ПК. Например: 192.168.0.2;192.168.0.3; 192.168.0.4 нт. д.Номер порта - это значение, однозначно идентифицирующее некоторый логиче-ский порт приложения, через который можно получать и посылать данные.В Delphi соединение по протоколу TCP/IP может быть реализовано на базе тех-нологии сокетов. Соке т представляет собой окончание сетевого соединения(уровень приложения) со стороны сервера или со стороны клиента.Обычно при соединении приложение-сервер открывает порт с некоторым номе-ром п переходит в состояние ожидания. Приложение-клиент устанавливает со-единение с сервером. После этого сокеты можно использовать как канал для пе-редачи данных.

Создание сервераСначала следует создать приложение-сервер,rtff*

1 : Для того чтобы создать сервер, использующий сокет TCP/IP для реализациисетевого соединения, выполните следующие действия:

1 . Расположите па форме компонент TServerSocket со страницы Internet палит-ры компонентов (предварительно должен быть подключен соответствующий

Page 382: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

382 Глава 10

пакет). Этот компонент используется для реализации TCP/IP-соедмнения состороны сервера.

2. Создайте объекты, используемые для хранения передаваемых и прини-маемых значений.Например, расположите на форме два поля типа ТМето: первое - для вво-да передаваемых значений, второе - для отображения получаемых данныхили сообщений об ошибках.

5. Для того чтобы установить соединение, сервер первоначально должен на-ходиться в режиме прослушивания соединения.Например, расположите на форме командную кнопку типа TButton, вы-полняющую открытие соединения. В обработчик события OnCHck этойкомандной кнопки следует записать:ServerSocketl.Active := True;

4. Для отображения текущего состояния соединения со стороны сервераможно использовать строку состояния. Для этого расположите на формекомпонент типа TStatusBar со страницы Win32 палитры компонентов. Вы-полните на добавленном компоненте двойной щелчок мышью для вызоваредактора панелей строки состояния и щелчком на кнопке Add New до-бавьте новую панель. А затем в обработчик события OnClick созданнойкомандной кнопки введите следующий код:StatusBarl.Panels[0].Text := 'Прослушивание... ' ;

5. Выполните настройку ТСРМР-соединения со стороны сервера. Для этогоустановите в инспекторе объектов для компонента ServerSocketl значениесвойства Port равным любому значению, допустимому для номера портасервера (например, 1024).

6. Создайте для компонента ServerSocketl обработчик события OnClientConnect.Это событие будет инициализировано при подключении клиента.

7. Введите в созданный обработчик события код, информирующий об уста-новлении соединения.Например:Memo2.Lines.Add('ServerSocketlClientConnect');

8. Создайте для компонента ServerSocketl обработчик события OnAcceptи введите в него код, информирующий об установлении соединения с ло-кальным портом. Свойство LocalAddress определяет IP-адрес при уста-новке локального соединения. Для получения IP-адреса удаленного соеди-нения следует использовать свойство RemoteAddress.Например:Мегао2.Lines.Add('ServerSocketlAccept1);StatusBarl.Panels[0].Text := 'Соединено с: ' +

Socket.LocalAddress;

Page 383: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Реализация механизмов межсетевого взаимодействия 383

9. Создайте для компонента ServerSocket l обработчик событияOnClientDisconnect и введите в него код, информирующий о состоянии соеди-нения.Например: StatusBarl.Panels[0] -Text := 'Прослушивание соединения... ';

•; Для того чтобы реализовать прием и передачу данных по установленномуj ТСРМР-соединению, выполните следующие действия:

1. Используя объект типа TserverSocket, реализуйте передачу данных кли-енту. Для передачи строки по установленному ТСРМР-соединению ис-пользуется метод SendText объекта типа TCustomWinSocket.Например, создайте для поля Memol обработчик события OnKeyDown. Вве-дите в созданный обработчик события следующий код:if Key = VK_Return then

ServerSocketl.Socket.Connections[0].SendText(Memol.Lines[Memol.Lines.Count - 1])

2. После выполнения этих действий для приложения-клиента будет иниции-ровано событие OnRead.

J. Используя объект типа TserverSocket, реализуйте получение данных настороне сервера. Для этого создайте для компонента ServerSocketl обра-ботчик события OnClientRead. Это событие будет инициализировано припередаче по установленному соединению данных с клиента.

4. Введите и созданный обработчик события код, принимающий передавае-мые данные. Метод ReceiveText принимает данные, переданные объектуSocket.Например, следующий код отображает принимаемые данные в компонен-те типаТМето:HemoZ.Lines.Add('Получен текст:'+Socket.ReceiveText);

На этом этапе создание сокета со стороны сервера завершено.

В завершение для удобства можете установить значение свойства Caption длякомпонента Form! равным Sen'erSocket (рис. ЮЛ) и сохранить проект под име-нем SLTVCF.

Рис. 10.1. Приложение-сервер, используюшее сокет TCP/IP

Page 384: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

384 Глава 10

Создание клиента

Для того чтобы создать клиента, использующего сокет TCP/IP для реализа-ции сетевого соединения, выполните следующие действия:

1. Создайте повое приложение и расположите на форме компонентTClientSocket со страницы Internet палитры компонентов. Этот компо-нент используется для реализации TCP/IP-соединения со стороны клиента.

2. Создайте объекты, используемые для хранения передаваемых и прини-маемых значений.Например, расположите на форме два поля типа ТМето: первое -для вво-да передаваемых значений, второе - для отображения получаемых данныхили сообщений об ошибках.

J. Напишите код, выполняющий установление соединения с сервером. Сна-чала следует определить, открыто ли соединение, и если соединение от-крыто, то закрыть его.Если значение свойства Active сокета равно True, то соединение открыто.Открыть соединение можно, или установив это свойство равным True, иливызвав для объекта сокет метод Open.Закрыть соединение можно, или установив свойство Active равным False,или вызвав для объекта сокет метод Close.Например, расположите на форме командную кнопку типа TButton и в об-работчик события Onclick введите следующие строки:varServer: String;beginif ClientSocketl.Active then ClientSocketl.Active := False;end;

4. Далее следует установить IP-адрес подключаемого сервера.Например, введите для запроса IP-адреса следующий код:if InputQuery('Установить СЕЯЭЬ с ', Псевдоним IP-адреса:', Server)then

if Length(Server) > 0 then

5. Установите значения свойств компонента ClientSocketl. Свойство Hostдолжно содержать псевдоним для IP-адреса. Если значение этого свойстваустановлено, то оно преобладает над значением свойства Address, опреде-ляющего IP-адрес.Например:with ClientSocketl do

beginHost := Server;Active := True;

end;

Page 385: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Реализация механизмов межсетевого взаимодействия 385

6. Создайте код, выполняемый для закрытия соединения.Например, расположите на форме командную кнопку типа TButton и а об-работчик события OnClick введите код, закрывающий соединение:ClientSocketl , Active := False;

7. Для отображения текущего состояния соединения со стороны сервераможно использовать строку состояния. Для этого расположите на формекомпонент типа TStatusBar со страницы Win32 палитры компонентов. Вы-полните на добавленном компоненте двойной щелчок мышью для вызоваредактора панелей строки состояния и щелчком на кнопке Add New добавь-те новую панель.

8. Выполните настройку ТСРМР-соединения со стороны клиента. Для этогоустановите в инспекторе объектов для компонента ClientSocketl значениесвойства Port равным номеру порта, используемого сервером (в нашемпримере - 1024).

9. Создайте для компонента ClientSocketl обработчик события OnConnect.Это событие будет инициализировано при подключении клиента.Введите в созданный обработчик события код, информирующий об уста-новлении соединения. Свойство LocalHost содержит информацию о псев-дониме IP-адреса, с которым установлено соединение.Например;StatusBarl.Panels[0] .Text := 'Соединено с адресом: ' +

Socket. LocalHost;

10. Создайте для компонента ClientSocketl обработчик событияOnDisconnect. Введите в созданный обработчик события код, информи-рующий о состоянии соединения.Например: StatueBarl. Panels [0 ] .Text := 'Соединение Закрыто ' ;

11. Создайте для компонента ClientSocketl обработчик события OnError. Этособытие будет инициализировано при неудаче соединения с сервером.Введите в созданный обработчик события код, отображающий сообщениеоб ошибке соединения. Например:Memo2. Lines. Add (' Ошибка соединения с сервером : ' + Server);ErrorCode := 0;

Для того чтобы реализовать прием и передачу данных по установленному> ц ТСРМР-соед мнению со стороны клиента, выполните следующие действия:

v

1. Создайте код, выполняющий передачу данных серверу. Наряду с методомSendText объекта типа TCustomWinSocket для передачи данных по уста-новленному ТСРМР-соед и нению можно использовать метод SendBuf .Например, создайте для поля Memol обработчик события OnKeyDovm и вве-дите в него следующий код:if Key = VK_Return then

ClientSocketl. Socket. SendText (Hemol. Lines [Hemol. Lines. Count - 1]);

13 Зак. 1 1

Page 386: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

386 Глава 10

2. После выполнения этих действий для приложения сервера будет ини-циировано событие OnClientRead.

?. Создайте код, выполняющий получение данных на стороне клиента.Для этого создайте для компонента ClientSocketl обработчик событияOnRead, Метод ReceiveText принимает данные, переданные объекту Socket.Например, введите в созданный обработчик события код, принимающийпередаваемые данные и отображающий их в компоненте Меттю2:Memo2.Lines.Add('Получен текст: Ч Socket.ReceiveText);

На этом этапе создание сокета со стороны клиента завершено.В завершение для удобства можно установить значение свойства Caption длякомпонента Forml равным ClientSocket (рис. 10.2) и сохранить проект под име-нем Client.

ifCli ЕВ [Socket

Установить еоединек l

Отсоединиться

Рис. 10.2. Приложение-клиент, используюшее сокет TCP/IP

Для использования TCP/IP-соединения для передачи или приема данных сначаласледует запустить приложение-сервер и перевести его в режим ожидания соеди-нения с клиентом. Далее следует запустить приложение-клиент и указатьIP-адрес сервера. При выполнении сервера на локальном компьютере следуетвводить адрес 127.0.0.1.

ПРИЛОЖЕНИЯ, ВЫПОЛНЯЕМЫЕНА WEB-СЕРВЕРЕWEB-броузер, используя URL-адрес, запрашивает данные от WEB-сервера. Привыполнении запроса устанавливается ТСРЛР-соединение с сервером и данные пе-редаются в формате HTML. После завершения передачи данных ТСРЛР-соединениеразрывается.

При этом передаваемая HTML-страница может быть как HTML-файлом, таки результатом выполнения на WEB-сервере некоторого приложения.

Page 387: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Реализация механизмов межсетевого взаимодействия 387

Приложения, выполняемые на WEB-сервере, с целью формирования HTML-стра-ницы могут быть следующих типов:

* ISAPI/NSAPI;

« CGI;

• WIN-CGI.

CGI-приложенияЕсли WEB-броузер посылает в качестве запроса URL-адрес CGI-приложения, тоWeb-сервер запускает это приложение и передает ему параметры запроса черезстандартный ввод. Сформированная в результате выполнения CGI-приложенияHTML-страница возвращается WEB-серверу через стандартный вывод.

=| Для того чтобы создать CGI-приложение, запускаемое на сервере, выполни-те следующие действия:

1 . Создайте новый проект. Для этого выполните команду менюFile | New | Other и на вкладке New выберите пиктограмму Web ServerApplication.

2. В диалоге New Web Server Application (рис. 10.3) выберите опцию CGI Stand-alone executable.

New Web Server Application

i You may select from one of the following types of Worldi Wide Web server applications.

Г ISAPI/NSAPI Dynamic Link Library

<"* Apache 1.n Shared Module (DLL)

Г Apache 2.x Shared Module (DLL)

Г Web App Debugger executable

Class Name:" i

Г* Cross Platform

OK Cancel Help

Рис. 10.3. Диалог New Web Server Application

В результате будет создан проект, содержащий главный файл приложенияи модуль Unitl, код которых приведен в листинге 10.1.

Page 388: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

388 Глава 10

Листинг 10.1:

(Главный файл приложения]

program Projectl;

f$APPTYPE CONSOLE}

uses

WebBroker, CGIApp,

Unitl in 'Unitl.pas' (WebModulel: TWebModule};

|$R *.RES}

begin

Application.Initialize;Application.CreateFormtTWebModulel, WebModulell;Application.Run;

end.(Модуль Unitl.pas}unit Unitl;interfaceusesSysUtils, Classes, HTTPApp;

typeTWebModulel = class(TWebModule)private { Private declarations }public { Public declarations }end;

varWebModulel: WebModulel;

implementation($R *.DFM(end.

Для того чтобы создать код, формирующий HTML-страницу, выполните\\ следующие действия:

1. Для объекта TWebModulel выполните двойной щелчок мышью на свойст-ве Act ion.

2. В диалоге Editing WebModulel.Actions (рис. 10.4} создайте новый элемент.Для этого щелкните мышью на кнопке Add New.

3. Создайте для объекта WebAciionltemI обработчик события OnAction. Приэтом автоматически будет сформирован следующий код:

procedure TWebModulel.WebModulelWebActionltemlAction(Sender: TObject;Request: TWebRequest; Response: TWebResponse;var Handled: Boolean);

beginend;

Page 389: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Реализация механизмов межсетевого взаимодействия 389

7' Editing WebModulel. Actions

Name _ | PathlnfgJ. EnabjedJ _Ре|аиЦГ

WetActrarJteml

<J ±!Рис. 10.4. Диалог Editing WebModulel .Actions

4. Сформируйте в созданном обработчике события код, создающий текстHTML-страницы. Этот текст должен быть записан в свойство Contentобъекта Response.Например;

Response,Соп1еп1:='<1>результат выполнения </!> '+

<Р> <В> CGI-приложения </В></Р>;

Если требуется сформировать HTML-страницу большого размера, то можноввести следующий код:

V3T

аРаде : TStringList;i: ir.teger;

beginaPage:= TStringList.Create;

aPage.Addl'Method = ' +Request.Method 4- '<BR>');aPage.Add('URL = ' 4- Request.URU '<BRV)

;

aPage.Add('User Agent = ' + Request.UserAgentt '<BR>');aPage.Add{'Remote Address = ' + Request.RemoteAddr+ '<BR>'};aPage.AddCRemote Host = ' + request.RemoteHost-t- '<3R>');

Response.Content := aPage.Text;

aPage.Free;

После размещения созданного CGI-приложения в каталог WEB-сервера, предна-значенный для исполняемых файлов, WEB-броузер может формировать запрос,указывая URL-адрес данного CGI-приложения.Например: http://localhost/webpub/Projectl.exe.

Публикация данных в InternetСерверные приложения можно использовать для публикации информации изтаблиц баз данных.Для публикации данных из базы данных на HTML-страницы применяются сле-дующие классы:

Page 390: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

390 Глава 10

• TQueryTableProducer - для создания HTML-страницы, содержащей таблицус данными, являющимися результатом выполнения SQL-запроса. Параметрывыполняемого SQL-запроса передаются в HTTP-запросе.

• TDataSetTableProducer - для создания HTML-страницы, содержащей таблицус данными из сформированного набора данных. Набор данных может бытьсоздан любым компонентом, реализующим функциональность наборов дан-ных (например, компонентом Table).

Компонент типа TDataSetTableProducer при формировании HTML-страницы,как правило, обрабатывает следующие события:

• OnCreateContent - при создании содержимого HTML-страницы;

• OnFormatCell - при формировании содержимого отдельной ячейки таблицы:

• OnGetTableCaption - при получении заголовка создаваемой таблицы.

Для того чтобы создать серверное приложение, отображающее наj HTML-странице поля таблицы базы данных, выполните следующие действия:

1. Создайте новое приложение, запускаемое на WEB-сервере. Для этого вы-полните команду меню File|New[Other и на вкладке выберите пиктограммуWeb Server Application.

2. Диалог New Web Server Application отображает различные виды приложе-ний, выполняемых на сервере. Для создания CGI-приложения выберитеопцию CGI Stand-alone executable и завершите диалог.

J. Для реализации доступа к источнику данных расположите в Web-модулекомпонент Table со страницы ВОЕ палитры компонентов. Установите зна-чение свойства DatabaseName компонента Tablel равным DBDEMOS (им-псевдонимя источника данных), выбрав значение из предлагаемого спи-ска. Установите значение свойства TableName компонента Tablel равнымanimals.dbf(i\MZ таблицы базы данных).

4. Двойным щелчком мыши в Web-модуле на компоненте Tablel вызовитередактор полей.

5. Выполните команду контекстного меню AddFields и добавьте следующие по-ля: NAME, SIZE, WEIGHT, AREA. Завершите диалог WebModulel.Tablel.

6. Разместите в Web-модуле компонент DataSetTableProducer со страницыInternet палитры компонентов.

7. Для определения связи с источником данных установите значение свойст-ва DataSet компонента DataSetTableProdticerl равным Tablel, выбравзначение из предлагаемого списка.

Page 391: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Реализация механизмов межсетевого взаимодействия 391

8. Для указания заголовка, отображаемого на HTML-странице, перед ото-бражаемой таблицей установите значение свойства Caption компонентаDataSetTableProducerl равным Таблица базы данных.

9. Для формирования начальных и завершающих тегов HTML-страницы ис-пользуются значения свойств Header и Footer. Содержание самой таблицыопределяется свойством Columns.

Ю.Определите начальные теги формируемой HTML-страницы. Для этогов инспекторе объектов выполните двойной щелчок мышью на значениисвойства Header и в диалоге String List Editor введите следующие строки:<HTML><HEAD><T1TLE> Запрос данных из таблицы </ТГП_Е></HEAD><BODY>Текст, указываемый между тегами TITLE, будет отображен в заголовкеокна Web-броузера.Тег BODY открывает область, в которой размещается отображаемое со-держимое HTML-страницы.

11 .Определите завершающие теги формируемой HTML-страницы.

12.Для этого в инспекторе объектов выполните двойной щелчок мышью назначении свойства Footer и в диалоге String List Editor введите следующиестроки:</BODY></HTML>

1 J.Вызовите редактор свойства Column. Для этого или в инспекторе объек-тов выполните двойной щелчок мышью на значении свойство Columnкомпонента DataSetTableProducerl, или в Web-модуле выполните двойнойщелчок мышью на компоненте DataSetTableProducerl. В диалогеEditing.DataSetTableProducerl.Columns выполните команду контекстного менюAdd All Fields. На расположенной справа панели отобразились названия до-бавленных столбцов таблицы. Выделите на правой панели диалогаEdiring.DataSetTableProducerl.Columns первый столбец (в нашем примере этостолбец с именем NAME). Это объект DataSetTableProducerl. Columns [0].

Н.Определите заголовок, который будет отображаться на HTML-страницедля первого поля. Для этого в инспекторе объектов откройте вложенныесвойства для свойства Title и установите значение свойства Caption объ-екта DataSetTableProducerl.Columns[0] равным Название ноля !.

15.Последовательно определите заголовки для всех других используемых по-лей таблицы.

16.Для определения цвета фона отображаемой таблицы на левой панели диа-лога Editing.DataSetTableProducerl.Columns установите значение свойства

Page 392: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

392 Глава 10

BgColor (например, равным Lirne) и закройте диалогEditing.DataSetTableProducerl.Columns.

17.0прелелите элементы действия для Web-модуля. Для этого выполнитедвойной щелчок мышью на компоненте WebModulel в окне дерева.

18.В диалоге Editing WebModulel .Act ions добавьте новый элемент действия.Для этого щелкните мышью на кнопке Add New.

19. Определите для созданного объекта действия WebActionlteml обработ-чик события OnAction. и в созданный обработчик события введите сле-дующий код:Response.Content:= DataSetTableProducerl.Content;

20. Свойство Content объекта DataSetTableProducerl содержит текст сформиро-ванной таблицы с соответствующими HTML-тегами.

21. Далее следует сохранить и откомпилировать созданный проект.

На рис. 10.5 представлена HTML-страница, сформированная в результате вы-полнения серверного приложения.

'J Запрос данным из таблицы - Microsoft Internet Exploier

I Файл Правка Вии Переход Избранное £гравка

НазадШ)

"'.,-. " Останов^/ть Обноеить Домой Поиск Избранное X?

Адрес №] hltpV/localhcsl/™bpub/PrajecG exe ~r\ .! j ССЫЛКИ

Название

Angel Fish

Boa

Critters

House Cat

Ocebt

Parrot

Tetras

2

10

30

10

40

5

2

Таблица базы данных

Размер Вес Местность

Computer Aquariums

South America

Screen Savers

ITew Orleans

Africa and Asia

South America

Fish Bowls

20

5

35

5

Рис. 10.5. Результат публикации полей таблицы базы данных

Сформированная HTML-страница содержит таблицу, отображающую наборданных, указываемый в Web-модуле.

Page 393: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 1 1

ИСПОЛЬЗОВАНИЕ СЕРВЕРОВАВТОМАТИЗАШИ

В этой главе рассматриваются основы создания приложений, испольчующихсерверы автоматизации Microsoft Word и Microsoft Excel.

СЕРВЕР АВТОМАТИЗАЦИИ MICROSOFT WORDРеализация доступа к объектам автоматизации Word

Из приложения Delphi можно управлять практически всеми функциями Wordпосредством механизма OLE-автоматизации.Доступ к объектам автоматизации можно осуществлять различными способами:

• доступ через переменные типа Variant и интерфейс IDispatch - самый про-стой, но и самый медленный;

• доступ через СОМ-интерфейсы - намного более производительный, нои значительно сложнее в реализации;

• доступ через компоненты TWordApplication и TWordDocment страницыServers палитры инструментов - простой способ доступа при помощи объек-тов, производных от класса TOleServer.

Запуск сервера Word через СОМ-интерфейсыИнтерфейсы СОМ для OLE-сервера Word в зависимости от версии сервера со-держатся в файле wt»rd97.pas или \vord2000.pas из каталога Delphi7\Ocx\Servers.Этот файл фактически является импортом библиотеки типов сервера Word.Для создания экземпляра Word СОМ-сервер предоставляет CoClassCoWordApplication.Для управления приложением СОМ-сервер предоставляет интерфейс_Application.

| Для того чтобы выполнить запуск сервера Word через СОМ-интерфейсы,выполните следующие действия:

1. Создайте новый проект,

2. Для получения доступа к СОМ-серверу Word через СОМ-интерфейсы пе-рейдите в окно кода и добавьте в конец списка uses следующие модули:ActiveX, word97 (или word2000).

Page 394: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

394 Глава 11

5. Создайте новый класс TWordObject, используемый для управления объек-том Word. Для этого введите после определения класса TForml следую-щий код:

.tyneTWordObjecfc=class

private

FWordApp:_Application;procedure SetVisible(Value: Boolean);

publicconstructor Create;

destructor Destroy;override;published

property Application: _Application read FWordApp;end;

4. Объявите переменную типа TwordObject. Для этого введите в разделе varследующий код:

WordObject:TWordObject;

5. Добавьте в implementation-секцию следующий код:

uses ComObj;

6. Все методы, объявленные в объекте TwordObject, должны быть реализо-ваны. Для этого вставьте в impiementation-секцию код, выполняющий реа-лизацию конструктора:

constructor TWordObject.Create;

FHordApp:=CoWordApplication.Create; {Создание объекта-сервера автоматизации},

end;

7. Далее вставьте в implementation-секцию код, выполняющий реализациюдеструктора:

destructor TWordObject.Destroy;var

S, 0, R : OleVariant;begirt

S := WdDoWotSaveChanges ;0 := UriAssigned;R := UnAssigned;cry FffordApp.Quit(S, 0, R ) ; exceptend;

end;

8. Для того чтобы сделать сервер автоматизации видимым, добавьте код,реализующий метод SetVisible:

Page 395: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Использование серверов автоматизации 395

procedure TWordObject.SetVisible(Value: Boolean);begin

FWordApp.Visible:=Value;end;

На этом этапе реализация класса TWordObject завершена.Теперь для того чтобы запустить сервер автоматизации Microsoft Word, следуетзаписать:

WordObject:= TWordObject.Create;

WordObject.SetVisible(True);Для того чтобы завершить выполнение сервера автоматизации, можно записать:

WordObject.Free;

WordObject:=nil;

Этот код будет выполнять закрытие сервера автоматизации, однако созданноеприложение не отслеживает ситуации самостоятельного закрытия СОМ-сервера.

Запуск OLE-сервера Word через интерфейс IDispathКлиент СОМ, взаимодействующий с сервером через интерфейс IDispatch, назы-вается контроллером автоматизации.

Компонент СОМ, который реализует интерфейс IDispatch, называется серверомавтоматизации.

" ! Для того чтобы выполнить запуск сервера Word через интерфейс Idispath,выполните следующие действия:

1. Создайте новый проект и добавьте в модуль Unitl переменную типаVariant.Для этого в секции public описания класса TForml введите:

V: Variant;

В переменной типа Variant могут храниться данные различных типов.Если методы внешнего объекта вызываются через переменную типаVariant, то при компиляции кода Delphi не может проверить наличие вы-зываемых функций и правильность типов передаваемых и получаемыхданных.

2. Вставьте в 1тр1етеш.а1юп-секцию следующий код:

uses ComObj;

Модуль ComObj всегда должен быть включен в приложение, являющеесяконтроллером автоматизации. В этом модуле содержится все необходимоедля доступа к объектам сервера автоматизации и диспетчеризации вызо-вов их методов.При работе через интерфейс IDispatch для создания объекта используется

Page 396: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

396 Глава П

функция CreateOleObject, которая вызывает из ComObj следующие функ-ции: VarDispInvoke, Dispatchlnvoke и GatlDsOfNames.

J. Создайте сервер автоматизации Word. Для этого введите (например, в об-работчик события OnClick) следующий код:

V:*Create01eObject{ 'Word. Application' ) ;

Этот код запустит сервер Word, но он будет работать в фоновом режиме.

Метод CreateOleObject возвращает ссылку на интерфейс IDispatch для создан-ного объекта.Переменная V может использоваться для доступа к любым методам объектаApplication.При обращении к свойству объекта Application через переменную типа Variantвыполняется последовательность вызовов внутренних функций механизма ав-томатизации: сначала вызывается метод GetlDsOfHames интерфейса IDispatchдля получения идентификатора функции, а затем по этому идентификатору ме-тод Invoke интерфейса IDispatch выполняет вызов функции.

1. Установите новый заголовок для окна Word. Это выполняется следующимкодом:

V.Caption:='MyWord' ;

При использовании переменной типа Variant лля доступа к методами свойствам объект Delphi не отображает всплывающей подсказки со спи-ском доступных свойств и методов, так как эта информация недоступна.Если разработчик сделает ошибку, то ее нельзя будет определить и вовремя компиляции приложения. Неправильное задание свойства или не-верный вызов метода будут обнаружены только во время выполнения.

2. Для отображения окна сервера автоматизации Word следует записать:

V.Visible:=True;

}. Перейдите на форму, выберите в инспекторе объектов страницу Eventsи создайте обработчик события OnOestroy.Введите в созданный обработчик события код, закрывающий сервер Word:

if not VarlsEmpty(V) thenV.Quit;

Запуск сервера Word с использованиемкомпонента TWordApplication

-у-!1 Для того чтобы использовать сервер Word, выполните следующие действия:

1. Расположите на форме компонент TWordApplication. со страницы Serversпалитры компонентов.

Page 397: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Использование серверов автоматизаиии 397

При этом в секцию uses модуля Unitl автоматически добавились модулиWord2000 и OleServer.

2. Класс TWordApplication является производным от класса TOleServer.Установите значение свойства AutoConnect объекта Word Application! рав-ным True.

5. Установите значение свойства AutoQuit объекта WordApplication 1 равнымTrue.

4. Установите значение свойства ConnectKind объекта WordApplicationl рав-ным ckRunningOrNew. Это значение будет гарантировать, что в этом слу-чае если есть уже запущенный СОМ-сервер, то он и будет использован.

5. Расположите на форме компонент TWordDocment.

6. Установите значение свойства ConnectKind объекта WordDocumentl рав-ным ckAttachTolnterface.В этом случае будет выполняться подключение к существующему интер-фейсу.

7. Расположите на форме командную кнопку типа TEutton и создайте для нееобработчик события OnClick. Создайте в обработчике события перемен-ную типа OleVariant.Например:

var n:01eVariant;

Тип OleVariant используется для создания параметра любого типа.Если параметр не используется, то вместо него можно указывать значениеEmptyParam.Тип OleVariant в отличие от типа Variant содержит толькоСОМ-совместимые типы.

8. Далее введите в тело обработчика события код, выполняющий созданиенового документа:

WordApplicationl.Documents.Add(EmptyParam,EmptyParam);

Для работы с документами предназначен объект Documents. Он доступенчерез объект типа TWordApplication.

9. Для того чтобы связать объект WordDocumentl с существующим интер-фейсом текущего активного документа, введите далее:

WordDocumentl.ConnectTo(WordApplicationl.ActiveDocumsnt);

10. Для ввода текста в документ можно использовать метод TypeText объектаSelection.Например:

WordApplicationl.Selection.TypeText('Документ, созданный в W o r d 1 ) ;

11.Укажите в переменной типа OleVariant имя файла, в который будет запи-сан документ.

Page 398: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

398 Глава 11

Varn:= 'newl.doc1 ;

12.Дпд сохранения текущего документа следует выполнить код:

WordDocumentl.SaveAs(n);

Для работы с активным документом можно использовать методы объектаTWordDocument, включая следующие:

• Save - для сохранения документа;

е SaveAs - для сохранения документа под другим именем;

• Printout - для выдачи документа на принтер;

• Close -для закрытия документа;

• SendMail - для отправки документа по почте (получательзапрашивается установленной на ПК почтовой службой);

• PrintPreviw - для предварительного просмотра документа;

• Undo - для отмены сделанных изменений;

• Redo ~- для повтора сделанных изменений;

» CheckSpelling - для запуска проверки правописания в документе.

1J. Для того чтобы закрыть текущий документ, следует записать:

WordDocuraentl.Close;

14. Введите код, выполняющий отображение окна сервера Word:

WordApplicationl.Visible:=True;

Для того чтобы выполнить предварительный просмотр документа, можно ис-пользовать следующий код:

WordDocumentl.PrintPreview();

СЕРВЕР АВТомАТизлиии MICROSOFT EXCELЗапуск сервера Exce l

Класс TExcelApplication реализует объект приложение - Application.Сервер Excel предоставляет для управления объектом Application большой на-бор свойств и методов.Для объекта Application можно применять следующие свойства:

* CalculateBeforeSave - выполнять вычисление формул перед сохранением доку-мента;

* Caption — заголовок окна приложения;

* Cells - определение диапазона ячеек;

Page 399: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Использование серверов автоматизации 399

• Charts - доступ к листам-диаграммам;

о Columns - определение диапазона столбцов;

• Rows - определение диапазона строк;

• DisplayFormulaBar - переключение режима отображения строки формул,Строка формул в Excel используется для быстрого перехода на именованныйдиапазон ячеек, для ввода и редактирования значений и формул, а также дляотображения значения текущей ячейки;

• DisplayFullScreen - распахивание окна приложения на весь экран;

в DisplayCommentlndicator - отображение индикатора, указывающего, чтоячейка имеет текст примечания;

• Visible - отображение окна приложения {переключение между фоновым ивидимым режимами);

о Workbooks - доступ к книгам Excel. Книга Excel может содержать листы раз-личных типов, включая листы-таблицы и листы-диаграммы;

• Worksheets - доступ к листам-таблицам книги Excel;

• Windows - доступ к окнам, в которых отображаются книги Excel;

• Selection - доступ к выделенному диапазону ячеек;

• Sheets - доступ ко всем листам книги;

. Range - доступ к диапазону ячеек.

j j Для того чтобы использовать сервер автоматизации Microsoft Excel, выпол-|| ните следующие действия:

1. Расположите на форме компонент TExcelftpplication со страницы Serversпалитры компонентов.В список модулей, указываемых ключевым словом uses, автоматическидобавились модули ЕхсеШОО и OleServer.

2. Для запуска и отображения окна сервера Excel введите следующий код:

ExcelApplicationl.Visible[0];=True;

5. Для закрытия приложения введите:

ExcelApplicationl.Quit;

Объект WorkbooksОбъект Workbooks извлекается из объекта Application и представляет собой ра-бочую книгу Excel.Из объекта Workbooks можно извлечь объекты Sheets, Worksheets и Charts, рас-положенные ниже в иерархии объектов Excel.

Page 400: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

400 Глава 11

Объект Workbooks - это объект контейнер, содержащий объекты Workbook.Для того чтобы получить доступ к какому-либо объекту Workbook контейнераWorkbooks, можно использовать следующий синтаксис:

Workbooks[индекс_книги]Workbooks["имя_файла_ХЬЗ"]-При доступе через интерфейс IDispath и при доступе с использованием компо-нентов со страницы Servers палитры компонентов синтаксис вызова некоторыхсвойств и методов несколько различается.

Для того чтобы иметь возможность использовать книгу Excel, выполнитеследующие действия:

1. Расположите на форме объект типа TExcelWorkbook со страницы Serversпалитры компонентов.

2. Для создания новой книги используйте следующий код:

ExcelApplicationl.Workbooks.Add(EmptyParam,0);

На этом этапе в приложении Excel будет открыта новая рабочая книга.

5. Дня того чтобы открыть книгу из файла в методе Add, первым параметромдолжен быть параметр типа OleVariant, содержащий имя открываемойкниги. Например:

var n: OleVariant;begin

n : = ' c : \ m y b o o k . x l s ' ;ExcelApplicationl.Workbooks.Add(n,0);

end;

4. Для того чтобы управлять объектом рабочая книга с помощью компонентаTexcelWorkbook, его следует соединить с созданной рабочей книгой.Для этого можно записать:

ExcelWorkbookl.ConnectTo(ExcelApplicationl.ActiveHorkbook);

5. Для закрытия текущей рабочей книги можно ввести следующий код:

ExcelWorkbookl.Close;

flfiM| Для того чтобы произвести ввод значений в лист Excel, выполните следую-

щие действия:

1. Введите значение в ячейку, указав ее адрес свойством Item. Например, дляячеек А1 и В1:

ExcelApplicationl.Cells.Uem[l,l].Value:='10';ExcelApplicat ionl .Cel ls .I temfl,2] .Value:='20 ' ;

Page 401: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Использование серверов автоматизации 401

Объект Cells используется для доступа к ячейкам листа рабочей книгиExcel.Свойство Item определяет номер ячейки: |номер_строки, номер_столбца1.Свойство Value используется для доступа к значению ячейки.

2. Для того чтобы ввести формулу в ячейку текущего листа рабочей книги,можно описан, следующий код;

ExcelApplicationl.Cells.Iteml3,l].Formula:='=А1+А2' ; (Вводзначения вячейку A3)

Свойство Formula используется для ввода в ячейку формулы Excel.

Создание диаграмм

Для того чтобы программно создавать диаграммы, используя сервер авто-матизации Excel, выполните следующие действия:

1. Создайте новый проект, а затем перейдите в окно кода и введите в секциюuses имена подключаемых пакетов Ехсе12000, OleServer и ComObj.

2. Объявите переменную, которая будет использоваться для полученияссылки на объект приложение Excel. Для этого введите в секцию var гло-бальных переменных модуля следующий код:

V:Variant;

J. Перейдите на форму и расположите на ней две кнопки: одну для созданияобъекта приложение Excel, а вторую для построения диаграммы.

4. Введите в обработчик события кнопки Button! код, выполняющий созда-ние объекта и его отображение:

V:=Create01eObject('Excel.Application'};

V.Visible:=True;

5. Введите в обработчик события кнопки Button2 код, используемый для по-строения диаграммы. Сначала объявите в секции var четыре локальныхпеременных:

Sheet: Variant;Sheets: Variant;ARange: Variant;Charts: Variant;

6. Добавьте новую книгу Excel. Для этого введите далее:

V. Workbooks. Md;

7. Добавьте лист в эту рабочую книгу:

V.Workbooks[1].Sheets,Add(,,1,xlWorkSheet);

Page 402: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

402 Глава 11

8. Определите имя добавленного листа:

V.Workbooks[I].Worksheets[1].Маше:*'Мой лист 1';

9. Создайте объект Sheet, используемый как ссылка на конкретный лист кни-ги Excel:

Sheet:= V.Workbooks[1].WorkSheets['Мой лист 1'];

10. Добавьте в книгу новую диаграмму:

V.Workbooks[l].Sheets.Md(,,l,xlChart),•

11.Определите имя добавленного листа диаграммы:

V.Workbooks[l].Charts[l],Нате:='Д1',•

12. Создайте объект Charts, используемый как ссылка на конкретную диа-грамму:

Charts:=V.Workbooks[l].Charts[^l'];

15. Введите значения в ячейки созданного листа:

Sheet.Cells[l,l]:=10;

Sheet.Cells[l,2I:=30;

14.Создайте объект Sheeis, используемый как ссылка на все листы книгиExcel:

Sheets:=V. Sheets;

1 .Создайте диапазон ячеек, используемый для построения ряда данных диа-граммы:

ARange:=Sheets.Itern['Мой лист 1'].Range['А1:ВГ];

16.Добавьте созданный диапазон к объекту SeriesCollection, описывающе-му все ряды диаграммы:

Sheets.Item!'ДГ]-SeriesCollection.Add(ARange);

В результате выполнения этих действий на листе Д1 текущей рабочей книги бу-дет создана диаграмма.

Page 403: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ГЛАВА 12

РАЗРАБОТКА ИНТЕРФЕЙСА

Эта глава содержит ряд типичных примеров, которые можно использовать дляразработки интерфейса пользователя. Приводимый код иллюстрирует, как за-программировать обработчик события или некоторую операцию (изменение па-раметров шрифта, управление всплывающим окном подсказки и т. п.). Рассмат-ривается последовательность действий программиста при создании готового при-ложения, содержащего систему меню для управления графическим объектом.

РЕАЛИЗАУИЯ ДИАЛОГОВ и СООБЩЕНИЙ

Создание диалога для ввода значения

Стандартные функции Object Pascal реализуют различные виды диалогов, вклю-чая диалоги, позволяющие получать вводимое пользователем значение. Для по-лучения вводимого значения можно использовать две функции: InputBoxи InpuiQuery.На рис. 12.1 показан диалог Input, отображаемый при вызове функции InputBox.

I* Feiml

Вызов

Диалог Input

Вызов InputQuerji

Новая строка: 'Detaull String'

Гх!

OK Cancel

Рис. 1 2,1. Вызов диалога для ввода сообщения

Пример:

;Форма, приведенная на рис. 12.1, содержит две кнопки - Buttonl (вызовфункции InputBox} и Button2 (вызов функции InputQuery) - и компонент типаTLabel для отображения введенного пользователем значения в поле вводаотображаемого диалога (только для Button2).}суре {Объявление формы }

Page 404: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

404 Delphi 7. Самоучитель программиста

TForml = class(TForra)

Buttonl: TButton;Eattcn2: TBUttcn;

Labell: TLabel;procedure ButtonlClick(Sender: TObject);procedure Button2Click(Sender: TObject);

privatepublicend;

uar Forral: TForml; {Создание объекта форма J{implementation-секиия(

procedure TForml.ButtonlClick(Sender: TObject);varInputString: string;

beginInputString:= InputBox('Диалог Input

1, 'Сообщение',

'Введите строку1);

end;

procedure TForml.Button2CHck(Sender: TObject);varHewString: string;ClickedOK: Boolean;

beginHewString := 'Default String';label!.C3ption := NewStri

nc; (.Новое значение поля Евол

ClickedOK := InputQuery('Диалог Input', 'Сообщение:',

HewString);if ClickedOK then iNewString содержит новое значение}Labell.Caption := 'Новая строка: '" + NewString +• '"'

end;

Отображение окна сообщенийДля отображения диалогов сообщений, содержащих текст самого сообщения,кнопки и стандартные уведомляющие изображения, можно использовать функ-цию MessageDlg. На рис. 12.2 приведены два окна сообщений, отображаемыепри вызове этой функции.

Confirm ЕЗ

(~ф~\ Диалог MessageDlg. Завершить?

! Yes ]| No |

Blnformjtion ЕЭ

/'• \ Завершение приложения.

XT

г "ж "i|

Рис. 1 2.2. Окна сообщений, содержащие кнопки и изображения

Page 405: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 405

Эти окна сообщений реализуются следующим кодом:

{При щелчке на кнопке Button3 вызывается обработчик события, отображающийдва окна сообщений (рис. 1 2 . 2 ) )procedure TForml.ButtonSCUck (Sender: TObject);begin

(В левом окне сообщений будут отображены две кнопки[mbYes, mbtJo] и изображение mtConfirmation}

if MesaageDlg['Диалог MessageDlg. Завершить? 1,mtConfimation, [mbYes, mbNo], 0) = mrYes then

begin (Пользователь нажал на кнопку Yes)MessageDlg('Завершение приложения. ' , mtlnformation,

[mbOk], 0 ) ;Close;

end;end;

Отметим, что аналогичные окна сообщений, но с цветными изображениямипредупредительных знаков можно получить, вызвав функцию MessageBox дляобъекта Application.Например;

if Applicat ion.MessageBox( 'Текст сообщения','Заголовок окна сообщений',

MBJMONCEL + MB_ICOHEXCLAMATION) о IDOK

then . . .

Создание самого простого диалога сообщенийДля показа окна сообщений с одной кнопкой ОК (рис. 12.3) можно выполнитьвызов функции ShowMessage ( 'Текст сообщения');.

PipiecLl

Т екст сообщения

ОК

Рис. 1 2.3. Простой диалог сообшений

Отображение диалогов выбора каталогаНа рис. 12.4 приведен диалог, отображаемый при вызове функции SelectDirectoryи используемый для выбора каталога. Для этого необходимо только указать пер-воначальный каталог, показываемый в поле Directory Name диалога SelectDirectory.

Page 406: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

406 Delphi 7, Самоучитель программиста

Этот диалог реализуется следующим кодом:

uses FileCtrl; {Следует добавить в оператор uses ]const SELDIRHELP = 1000;procedure TForml.ButtonSClickfSender: TObject);var Dir: string;

beginDir := ' C : \ D e l p h i 1 ; (Первоначальный каталог)if SelectDirectory(Dir,

[sdAllcwCreate, sdPerformCreate, sdPrompt],SELDIRHELP) then

Labell.Caption := Dir; (Имя выбранного каталога}end;

Select Difectoiy

Directory fJame:

JCADelphi"

Clireclories:

Detoh'Bool-; еяеFioiecll .dotProject!. dpfFrojecll.iesUratl.dcuUnitl.dfmUriin.oas

Drives:

с: [system]

Cancel Help

Рис. 1 2.4. Диалог Select Directory

Другим вариантом диалога для выбора каталога, также отображаемого при вызовефункции SelectDirectory, является диалог Обзор папок (рис. 12.5), который по сво-ему поведению идентичен левой части окна Проводник в Windows.Этот диалог реализуется следующим кодом:

procedure TForml.Button5Click(Sender: TObject] ;var

Dirl, Dir2: string;beginDirl := 'C:\Delphi';

SelectDirectory('Просмотр каталога' , Dirl, Dir2);{Dirl - начало отображаемого дерева каталогов ,Dir2 - выбранный каталог}

end;

Page 407: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 407

Обзор палок.

Просмотр tiara лог а

E - j Рабочий столЕа

! Я-& Дни. 3,5 (А']Е-е» SysleralClВ Lingua [GO

Н- Сетевое окружение; --Q LesjonDelphi

Рис. 1 2.5. Диалог Обзор папок

Создание всплывающих подсказокТекст всплывающей подсказки для любого компонента, расположенного в фор-ме, содержится в свойстве Hint. Свойство ShowHint определяет, следует ли по-казывать для данного компонента всплывающее окно подсказки.Свойство Hint может содержать разделенные символом | две строки текста под-сказки. В этом случае первая по умолчанию отображается во всплывающем окнеподсказки, а вторая — в строке состояния.

z Дня того чтобы отобразить для компонента всплывающую подсказку, следует:

1 . В инспекторе объектов или программно определить значение свойстваHint компонента (например: Editl.Hint= 1 Введите значение';).

2. Установить:

- или значение свойства ShowHint компонента равным True (например:Editl.ShowHint=True;};

или значение свойства ParentShowHint компонента равным Trueи значение свойства ShowHint формы равным True.

J. Установить значение свойства ShowHint объекта Application равным True(по умолчанию установлено).

; Для того чтобы отобразить для компонента подсказку в строке состояния,,следует:

1. В инспекторе объектов или программно определить значение свойстваHint компонента, указав его после символа | (например: Editl.Hint-' ]Вводзначения';).

Page 408: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

408 Delphi 7. Самоучитель программиста

2. Определить действие для обработчика события OnHint объектаApplication. Для этого достаточно назначить этому обработчику событияимя процедуры, устанавливающей значение свойства SimpleText для ком-понента типа TStatusBar (например:Application.OnHint := DisplayHintlnStatus;). Этот код можно вставитьв обработчик события OnCreate для формы.

J. Ввести объявление процедуры, устанавливающей значение свойстваSimpleText для компонента типа TStatusBar, в секцию public объявлениякласса, а определение процедуры - в implementation-секцию модуля.

4, В блок begin., end данной процедуры вставить код определения значениясвойства SimpleText {например: StatusBarl. SimpleText : =A p p l i c a t i o n . H i n t ; ) .

Следующий пример иллюстрирует отображение всплывающей подсказки и под-сказки в строке состояния для компонента типа TEdit:

unit Unitl;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs,

ComCtrls, StdCtrls;typeTForml = class(TForm)Editl: TEdit; {Компонент типа TEdit:

его свойство Hint равно'введите значение в диапазоне от 1 до 100|Ввод значения')

StatusBarl; TStatusBar; (Строка состояния}procedure FormCreate(Sender: TObject); {Обработчик события

OnCreate для формы]publicprocedure DispHint (Sender: TObject);{Отображение подсказки

в строке состояния}end,-

implementation-procedure TForml.FormCreate(Sender: TObject);beginApplication.OnHint := DispHint; (Назначение процедуры}end;procedure TForml.DispHint(Sender: TObject);beginStatusBarl.SimpleText := Application.Hint;

end;end.

Page 409: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 409

Результат выполнения данного примера приведен на рис. 12.6.

ГПп|х|*f Foiral

ШЭЯШШШ

значение е диапазсие от 1 до 1Ш

i Ввод значения ^

Рис. 12.6. Отображение подсказок для компонента

Пример:

{Создание списка из пяти элементов и определение всплывающей подсказки)with ListBoxl dobegin

for I := 1 to 10 do (Цикл добавления элементов списка}Iterns.Add('Элемент ' + IntToStr(I)I;

Hint := 'Выберите любой элемент';

ShowHint := True;end;

Application.ShowHint := True;

ПРОГРАММИРОВАНИЕ МЕНЮМеню для работы с графическими объектами

Рассмотрим приложение 1, состоящее из одной формы, содержащей меню, и не-скольких компонентов, которые позволяют отображать различные геометриче-ские фигуры и изменять как цвет фона, так и цвет линии.Создадим новое приложение. Добавим в него компонент TMainMenu. Выполнимна нем двойной щелчок мышью и в открывшемся окне (рис. 12.7) определимзаголовки всех пунктов меню.Для того чтобы отобразить пользователю, какая буква является акселератором,перед ней следует вводить символ &. Визуально это будет отображено подчер-киванием. Ввод заголовка можно выполнять как непосредственно в окне опре-деления заголовков, так и в инспекторе объектов. Переход от одного пункта ме-ню к другому или создание нового пункта меню автоматически изменяет теку-щий отображаемый компонент инспектора объектов.

Пример аналогичного приложении можно посмотреть в пакете Delphi 7 в каталогеDelphi 7\Help\Examples\Menu.

Page 410: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

410 Delphi 7. Самоучитель программиста

f MenuFoim MainMenu

Приложение Цвет 5игуpa Добавления £правка

Злил с

Прямоугольник

Квадрат

Рис. 1 2.7. Окно определения заголовков пунктов меню

Создадим следующие пункты меню:

Приложение

Выход

Цвет

Линии

Произвольный

Выбор

Внутри

Произвольный

Выбор

Фигура

КругЭллипсПрямоугольник

Квадрат

Добавления

Для линии

Для углов

Справка

0

Пункты меню Произвольный и Выбор создаются как подменю. Для этого следуетв окне определения заголовков выделить пункт Линии, щелчком правой кнопкимыши вызвать контекстное меню и выбрать в нем пункт Create Submenu. Визу-ально пункты меню, открывающие подменю, отображаются с символом >в крайнем левом углу.Пункты меню Фигура являются группой переключателей радиокнопок. Поэтомудля каждого пункта этого меню следует установить в инспекторе объектов зна-чения свойств Checked и Radioltem равными True.Далее изменим в инспекторе объектов имена вновь созданных компонентов типаTMenuItem так, чтобы они отражали название соответствующего пункта меню.Для этого следует ввести новые значения в поле Name каждого компонента.

Например: заменим N1 на Application!, N2- на Exit l , N3 - на Color 1 и т. д.Далее добавим в окно формы компонент TPanel и установим его размер с помо-щью мыши таким образом, чтобы панель покрывала всю форму, за исключениемстроки меню.После этого добавим со страницы Additional компонент TShape, а со страницыDialogs - два компонента TColorDiaiog для определения цвета линии и цветафона геометрической фигуры.В результате проектируемая форма будет выглядеть как показано на рис. 12.8.

Page 411: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 411

"£" MenuForm

Приложение Цвет Фигура Добавления Справка

Рис. 12.8. Проектируемая форма

Для завершения разработки меню следует определить обработчики для каждогопункта меню. Рассмотрим некоторые из них.Для команды меню Приложение|Выход в код обработчика события надо вста-вить вызов метода Close, завершающего выполнение приложения.

procedure TMenuForm.ExitlClick(Sender: TObject);begin

Close;end;

Код обработчиков событий для пунктов Фигура|Круг и Фигура|Эллипс долженсодержать следующие строки:

procedure TMenuForm.CirclelClickfSender: TObject);begin

SetCheck(Sender];AlterShapelstCircle, False);

end;procedure IMenuForm.EllipselClick(Sender: TObject);begin

SetCheck(Sender);AiterShapefstEllipse, False);

end;В код обработчика события для выбора цвета линии следует ввести:procedure TMenuForm.SelectlClick(Sender: TObject);begin

trySolidColorDialog.Color := DemoShape.Pen.Color;if SolidColorDialog.Execute then {Запуск диалога}DemoShape.Pen.Color := SolidColorDialog.Color;

exceptShowMessage('Ошибка загрузки диалога

1);

end;end;

Page 412: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

412 Delphi 7. Самоучитель программиста

Подробное описание всех обработчиков событий приведено ниже в листингефайла MyMenuGraphic.

Листинг файла MyMenuGraphic для формы MenuForm:

unit MyMenuGraphic;

interface

uses (Список используемых модулей}Windows, Messages, SysUtils, Classes, Graphics, Controls,

Forms, Dialogs, Menus, ExtCtrls, ComCtrls;

type

TMenuForra = class(TForm) (Класс формы}форму:}{Компоненты, добавленные Е

DisplayPanel: TPanel;

DerccShape: TShape;

MainMenu: TMainMenu;Application!: TMenuItem;

Exitl: TMenuItem;

Color!: TMenuItem;

Outline!: TMenuItem;Randomize!: TMenuItem;

Selectl: TMenuItem;

Insidel: TMenuItem;Randcmize2: TMenuItem;

Select2: TMenuItem;Shape!: TMenuItem;

Circlel: TMenuItem;

Ellipse!: TMenuItem;Rectangle!: TMenuItem;

Square!: TMenuItem;Miscl: TMenuItem;ThickOutlinel: TMenuItem;

RoundedShapel: TMenuItem;

TMenuItem;

(панель)

(фигура}

(главное меню}(пункт меню Приложение}

(пункт; меню Выход}

(пункт меню Цвет}

(пункт меню Линия}

{пункт меню Произвольный)

(пункт меню Выбор}

(пункт меню Внутри)

(пункт меню Произвольный}(пункт меню Выбор)

(пункт меню Фигура}

About!: TMenuItem;SolidColorDialog: IColorDialog

AnyColorDialog: TColorDialog;

PopupMenu: TPopupMenu;

Randoml: TMenuItem;RandomizeColorsl: TMenuItem;InvertColorsl: TMenuItem;

procedure DisplayPanelResize(Sender: TObject);

procedure ExitIClick(Sender: TObjecti;

procedure RandomizelClick(Sender: TObject);procedure SelectlClickfSender: TObject);

(пункт меню Дополнения]

(пункт меню Для линии)

(пункт меню Для углов}'пункт меню Справка)

(пункт меню 0}

(диалог Выбор цвета}

(диалог Выбор цвета)

(контекстное меню}(пункт контекстного меню]

(пункт контекстного меню)

(пункт контекстного меню)

Page 413: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 41 3

procedure Randomize2Click(Sender: TObject);procedure Select2Click(Sender: TObject);procedure CirclelClick(Sender: TObject);procedure EllipselClick(Sender: TObject);procedure RectanglelClick(Sender: TObject);procedure SquarelClick(Sender: TObject);procedure ThickOutlinelClick(Sender: TObject);procedure RoundedShapelClickfSender: TObject);procedure AboutlClick(Sender: TObject);procedure RandomlClick(£ender: TObject);procedure RandomizeColorslClick{Sender: TObject);procedure InvertColorslClick(Sender: TObject);

privateRoundable: Boolean;function RandoraColor: TColor;procedure AlterShapefshape: TShapeType; roundable: Boolean);

publicend;const SHAPEoff = 4;var MenuForm: TMenuForm;implementationuses about; (модуль для диалога «О приложении»)(SR *.DFM)procedure TMenuForm.DisplayPanelResize(Sender: TObject);begin

DemoShape.Top := SHAPEOFF; (Определение координат фигуры]DemoShape.Left := DemoShape.Top;DemoShape.Height := DisplayPanel.Height - 2 * SHAPEOFF;DemoShape.Width := DisplayPanel.Width - 2 * SHAPEOFF;

end;procedure TMenuForm.ExitlClick(Sender: TObject);begin Close; end;function TMenuForm.RandomColor; (Выбор произвольного цвета)var red, green, blue: Byte;beginred := Random(255); green := Random(255);blue := Random(255);Result := red or (green shl 8) or (blue shl 16);

end;procedure TMenuForm.RandomizelClicHSender: TObject);begin {для команды меню Цвет!Линия|Произвольный)

DemoShape.Pen.Color := RandomColor;end;procedure TMenuForm.SelectlClick(Sender: TObject);

Page 414: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

414 Delphi 7. Самоучитель программиста

begin |для команды меню Цвет|Линия|Выбор}try(первоначальный цвет:}SolidColorDialog.Color ;= DemoShape.Pen.Color;if SolidColorDialog.Execute then{выбранный в диалоге цвет;}

DemoShape.Pen.Color := SolidColorDialog.Color;exceptShowMessage('Сбой при загрузке диалога Выбор цвета');

end;епа;procedure TMenuForm.Randomize2Click(Sender: TObject);begin DeraoShape.Brush.Color := RandoraColor;end;procedure TMenuForm.Select2Click(Sender; TObject);

begin {для команды меню Цвет|Внутри|Выбор|AnyColorDialog.Color := DemoShape.Brush.Color;tryif AnyColorDialog.Execute thenDemoShape.Brush.Color := AnyColorDialog.Color;

except

ShowMessage {'Сбой г.ри загрузке диалога Выбор цвета'};end;

end;procedure ToggleCheck(Sender: TObject);var {для пункта меню переключателя;

Item: TMenuItera;begin

Item := Sender as TMenuItem;Item.Checked := not Item.Checked;

end;procedure SetCheckfSender: TObject);

var Item: TMenuItera;begin

Item := Sender as TMenuItem;Item.Checked := True;

end;procedure TMenuForm.AlterShape(shape: TShapeType; roundable: Boolean);beair.

Self.Roundable := roundable; DeraoShape.Shape ;= shape;end;

procedure TMenuForm.CirclelClickfSender: TObject);

begin {для команды меню Фигура(Круг)SetCheck(Sender);AlterShape(stCircle, False);

Page 415: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 415

end;procedure TMenuForm.EllipselClick(Sender: TObject);

beginSetCheck(Sender); AlterShape(stEllipse, False);

enc;procedure TMemiForm.RectanglelClick(Sender: TObject);begin

SetCheck (Sender);if RoundedShapel.Checked then [проверка режима Дополнения}AlterShape(stRoundRect, True) {скругленные углы)

else

AlterShape(stRectangle, True); {прямые углы}

end;procedure TMenuForm.SquarelClick(Sender: TObject);begin (для команды меню Фигура|Квадрат}

SetCheck(Sender);if RoundedShapel.Checked thenAlterShape(stRoundSquare, True)

else

AlterShape (stSquare, True);

end;procedure TMenuForm.ThickOutlinelClick(Sender: TObject);

begin {пункт меню переключатель!

ToggleCheck(Sender);DemoShape.Pen.Width := 12 - DemoShape.Pen.Width;

end;procedure TKenuForm.RoundedShapelClickfSender: TObject);begin {пункт меню переключатель}

ToggleCheck(Sender);case DemoShape.Shape of {установка скругленных углов)

stRectangle: DeraoShape.Shape := stRoundRect;

stRoundRect: DemoShape.Shape := stRectangle;stSquare: DemoShape.Shape := stRoundSquace;

stRoundSquare: DemoShape.Shape := stSquare;

end;end;procedure TMenuForm.AboutlClick(Sender: TObject);

var AboutBox: TAboutBox;

beginAboutBox := TAboutBox.Create(Self); {Создание формы)

tryAboutBox.ShowKodal; (Показ модального диалога}

finallyAboutSox.Free; (Освобождение памяти}

Page 416: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

416 Delphi 7. Самоучитель программиста

end;end;procedure TMenuForm.RandomlClick(Sender: TObject);

var (для контекстного меню}

newshape: TShapeType;

begin

// Изменение фигуры

repeat newshape := TShapeType(Random(6)) untilnewshape <> DemoShape.Shape;

// Изменение в пунктах меню Фигура и Для углов

case newshape of

stEllipse: EIlipsalClick(£llipsel);stCircle: CirclelClick(Circlel);stRectar.gle, stRoundRect:beginRoundedShapel.Checked := newshape = stRoundRect;RectanglelClick(Rectanglel);

end;stSquare, stRoundSquare:beginRoundedShapel.Checked := newshape = stRoundSquare;SquarelClick(Squarel);

end;end;

end;procedure TKenurorm.RandcimizeColorslClick(Sender: TObject);begin {для контекстного меню)

DemoShape.Brush.Color := RandoraCoior;

DeraoShape.Per..Color := RandomColor;

end;procedure TMenuForm.InvertColorslClick(Sender: TObject);var (для контекстного меню)

i : Integer;begin {инвертирование цвета}

i := IntegerfDemoShape.Brush.Color] xor SFFFFFF;DeraoShspe.Sr'jsh.Color := T C o l o r f i ) ;

end;end.

Листинг главного файла приложения:

program menu; {Этот файл будет создан автоматически}uses Forms,

raenudemo in ' MyMenuGraphic.pas1 {MenuForm},about in 'about.pas' {AboutEox};

Page 417: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 417

iSR * . R E S tbegin

Application.Initialize;Application.CreateFormlTMenuForm, MenuForm);Application.Run;

end.

В результате выполнения этого приложения будет показана следующая форма(рис. 12.9).

J* MenuFoim

Приложение Цвет ; фигура Добавления Справка

• Круг

Прямоугольник

Квапрзг

Рис, 12.9. Результат выполнения разработанной формы

Программирование главного меню формы

Для того чтобы программно создать главное меню, выполним следующиеl действия:

1 . Создадим форму.

2. Определим необходимые переменные:

varMyMainMemi: TMainMenu;MySubIteml,MySubItem2 : TMenuItem;MySubltems: array[0..4] of TMenuItem;

5. Определим код обработчика события, по которому будет создано главноеменю:

MyMainMenu:= TMainMenu. Create (Self ) ;

4. Добавим пункты главного меню:

varMyltem: array[0. .2] of TMenuItem;i: Integer;

143ак.

Page 418: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

418 Delphi 7. Самоучитель программиста

beginfor i := 0 to 2 do begin

Myltemfi] := TMenuItem.Create(Self);Myltemfi] .Caption := 'Новый пункт ' + IntToStrli);MyMainMenu.Items.Add(MyItem[i]);

end;

5, Добавим вертикальную и горизонтальную разделительные линии:

MySubItems[3].Break := mbBarBreak;MySubItems[2j-Caption :='-';

Программирование контекстного менюb: n'-<• Для того чтобы программно создать контекстное меню, выполним следую-

! щие действия:

1. Определим необходимые переменные:

varMyPopUpMenu: TPopUpMenu;MySubIteml,MySubItem2 : TMemiltem;MySublteras: array[0..4] of TMenuItem;MyPopUpItems: a r r a y [ 0 . . 4 ] of TMenuItem;

2. Создадим контекстное меню:MyPopUpMenu ;= TPopUpMenu.Create(self);

J. Добавим пункты контекстного меню:

vari : Integer;

beginfor i := 0 to 3 do begin

MyPopUpItems [ i j := TMenuItem.Create(Self);MyPop'JpItems[i] .Caption := 'Новый пункт ' + IntToStr (i) ;MyPopUpMenu.Items.Add(MyPopUpItems[ij];

end;end;

4. Добавим в обработчик события щелчком правой кнопки мыши код вызоваконтекстного меню:

MyPopUpMenu.Popup(Forml.Left + 60, Forml.Top + 140};

5. Назначим действия для каждого пункта контекстного меню:

vari: Integer;

begin

Page 419: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 419

for i := 0 to 3 do begin

MyPopUpItems[i] .OnClick := ShowMessage (Caption) ;

snd;end;

Назначение действия для пункта контекстного меню

1. Объявим следующие переменные (если они не были созданы в режимепроектирования);

MyPopUpMenu : TPopUpMenu;MySubIteml,MySubItem2 : TMemiltem;MySubltems: array [0.. 4] of TMenuItem;My Popup I terns : ar r .ay[0 . .4] of TMenuItem;

2. Определим процедуру, которая должна будет выполняться при выборекоманды контекстного меню:

procedure TForml.MyPopupHandler (Sender: TObject);begin

with Sender as TMenuItem do beginShowMessage (Caption) ;

end;end;

5. Определим имя вызываемой процедуры для обработчика события OnClick:

MyPopUpItems[i] .OnClick := KtyPopupHandler;

Добавление в сушествуюшее меню списка всех форм:

- ; ; Для того чтобы добавить в существующее меню имена всех форм приложе-ния, следует;

1 . Создать переменную типа TMenuItem.

2. Реализовать цикл по всем формам приложения. Список всех форм содер-жится в переменной Screen: Screen. Forms [I] -Name- имя формы.

J. Создать для каждой формы отдельный пункт меню:Newltem t= TMenuItem. Create (Self );.

4. Установить для вновь созданного пункта свойство Caption.

5. Добавить созданный пункт к конкретному меню; Windows. Add (Hewltem) ;.

Следующий пример иллюстрирует добавление названий всех форм приложенияк меню Windows:

Page 420: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

420 Delphi 7. Самоучитель программиста

varNewltem: TMenuItem;I : integer;

begin

(Создание пункта меню Разделительная линия )Newltem := TMenuItem.Create(Self);Hewltem.Caption := '-';

{Добавление в меню Windows разделительной линии}Windows.Add(Newltem);

{Добавляем пункт меню для каждой формы }

for I := 0 to Screen.FormCount-1 do

beginNewltem ;= TMenuItem.Create(Self);

Newltem.Caption := Screen.Formsfl].Name;

Windows.Add{Newltem);

end;end;

РАБОТА с мышьюУправление видом курсора мыши

По умолчанию вид курсора мыши изменяется в зависимости от того, над какимэлементом он позиционирован, а также от выполняемой операции. Используе-мые для этого предопределенные курсоры содержатся в свойстве Cursors гло-бальной переменной Screen. Пользователь имеет возможность добавлять в при-ложение свои курсоры.

га•~у-': Для того чтобы применять в приложении курсор пользователя, следует:X

1. Вызвать редактор изображений, выполнив команду Tools | Image Editor.

2. Открыть файл ресурсов проекта и добавить в него новый курсор.

J. Нарисовать растровое представление курсора и сохранить файл ресурсов.

4. Определить константу-номер нового курсора: const crMyCursor= 5;.

Ч, Создать обработчик события OnCreate для формы и ввести в него сле-дующий код:

( NewCursor - имя нового курсора в файле ресурсов}Screen.Cursors[crMyCursor] ;= LoadCursor(HInstance, 'NewCursor');

6. Установить новый вид курсора: Cursor := crMyCursor;.

Page 421: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 421

ПРОГРАММНОЕ ИЗМЕНЕНИЕ свойствКОМПОНЕНТОВ

Изменение шрифта для компонента типа TRichEditРазместите в форме компонент типа TComboBox для выбора экранного шрифтаи компонент типа TRichEdit.<ГГГ??..

:|! Для того чтобы изменять шрифт текущего выделенного фрагмента текста. в компоненте типа TRichEdit, можно выполнить следующие действия:

I . Создать обработчик события OnCreate для формы.

2. Заполнить в созданном обработчике событий TForml.FormCreate списокComboBoxl с названиями экранных шрифтов:

ComboBoxl. Items ;= Screen. Fonts;

J . Установить первоначальное значение поля ввода в комбинированном списке:

ComboBoxl. Text := Screen. Fonts[0] ;

4. Создать обработчик события OnClick для компонента ComboBoxl.

5. Ввести в созданном обработчике событий TForml.ComboBoxlClick код,определяющий новый шрифт для выделенного фрагмента текста:

RichEditl.SelAttributes.Hame :=ComboBoxl . Items [ComboBoxl . Itemlndex] ;

На рис. 12.10 приведен пример созданной формы с компонентом типа TRichEdit,использующим различные шрифты для отображения текста.

-Г Изменение шрифта для компоненте TRichEdil

Список ШРИФТОВ

Times New RomanTimes New Rornah CyrTimes NR

iTimesET

Те ист компонента |TRichEditSTRING 1STRING 2STR.IUG3STRING4

Рис. 1 2.10. Форма с компонентом типа TRichEdit, использующим различныешрифты

Page 422: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

422 Delphi 7. Самоучитель программиста

Работа с датой

Для того чтобы отобразить дату в указанном формате, можно:

1. Создать обработчик события, который будет вызываться для измененияпараметров отображаемой даты (например, Button I Click).

2. Установить значения глобальных переменных, отвечающих за формат да-ты. Например:

DateSeparator := '-';DateFullYear := True;DateLeadZero := True;

J. Запросить текущую дату, вызвав функцию Data, преобразовать ее в строкуи присвоить свойству Text или Caption компонента. Например:

Labell.Caption := DateToStr(Date);

|; Для определения текущего времени для соответствующего сообщенияр пользователю можно:

1. Создать обработчик события, который будет вызываться для отображениясообщения (например, ButtonlClick).

2. Объявить в нем переменную типа даты/времени: var ATime: TDateTime;.

5. Запросить текущую дату: ATime := DateToStr(Date);.

4. Определить время и отобразить сообщение:

if ATime < 0.50 thenShowMessage ['Доброе утро')

elseShowMessagef'Добрый день'];

Запуск таймера

- . Для отображения в поле редактирования нового времени каждую секундуможно:

1. Расположить в форме компонент типа TTimer со страницы System палит-ры компонентов.

2. Установить свойства Interval Property компонента Ttimer (по умолчаниюоно равно: 1000 = 1 секунда). Событие OnTimer для компонента будетинициироваться автоматически каждый раз через указанный интервал времени.

J. Расположить в форме компонент, в котором будет отображаться значениетекущего времени, Наиболее удобно использовать для этого компоненты

Page 423: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 423

типа TLabel или TEdit. Если используется компонент типа TEdit, то уста-новить значение его свойства Enabel равным False.

4. Создать обработчик события для компонента TTimer, выполнив на немдвойной щелчок мышью.

5. Ввести в созданный обработчик события TFormLTimerlTimer код для оп-ределения текущего времени. Например:Editl.Text:= TiraeToStr(Time];

На рис. 12.11 приведен пример формы с таймером и компонентом типа TEdit дляотображения текущего времени.

Таймер

t Компоненттипа TTimer

Рис. 12.11. Форма для запуска таймера

Работа со строкамиЯзык Object Pascal имеет большое разнообразие функций для работы со строка-ми. Рассмотрим примеры использования некоторых из этих функций,

Разбор полного пути для имени файла:

var FileNamel, HaraePatt: PChar; P: PChar;

beginOpenDialogl.Execute;

FileNamel:=OpenDialogl.FileName;{Определение части строки от последнего символа-разделителя (в нашем

примере '\') ДО конца строки (функция StrRScan в этом примере аналогична

функции ExtractFileHame])Р := StrRScan[FileNamel, '\'}; (Имя файла}

if ? = nil thenbeginP := StrRScan(FileNamel, ':');

if P = nil then P := FileNamel;end;NamePart := P;

end;

Выделение пути из полного имени файла:

S : string;

3 := s t r ing(NamePart( 'C:\MyTestFi le . tx t ' ) ) ;

Page 424: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

424 Delphi 7. Самоучитель программиста

Сравнение строк:const SI: PChar = 'Enterl23' S2: PChar = 'Enter1

var ComStr: string;{Сравнение без учета регистра)

if StrLComp(Sl, S2, 5) = 0 thenComStr := 'равны'

elseCoraStr := 'различны

1;

Canvas.TextOutflO, 10, 'Первые 5 символов ' + ComStr);

{Сравнение с учетом регистра

if StrLICompfSl, 32, 5) = 0 then }ComStr := 'равны'

elseComStr := 'различны';

Canvas.TextOut(10, 10, 'Первые 5 символов ' + ComStr);

Сравнение строкСоздадим форму, содержащую два компонента типа TEdit и кнопку типаTButton, при щелчке мышью на которой будет выполняться сравнение строк.Результат будет отображаться в окне сообщений.Введем следующий код для обработчика события OnCIick компонента Buttonl;

procedure TForml.ButtonlClicMSender: TObject);var Msg; string; CompResult: Integer;begin

Msg := Editl.Text;CompResult := StrComp(PChar(Editl.Text),

PChar(Edit2.Text));if CompResult < 0 then

Msg := Msg + ' меньше, чем 'else if CompResult > 0 then

Msg := Msg т ' больше, чем 'else

Msg := Msg + ' равно 'Msg := Msg + Edit2.Text;ShowMessage(Msg);

e.id;

Используя вместо StrComp другие функции сравнения строк, легко протестиро-вать результаты их работы.На рис. 12.12 приведен пример формы для сравнения строк.

.

Page 425: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 425

*f Сравнение строк

EDIT1

|Е*2Сравнить строки

Project!

EDIT1 меньше чем Edil2

Рис. 12.12. Форма для тестирования функций сравнения строк

Разработка интерфейса для компонента типаTRichEdit

Компонент типа TRichEdit является многострочным полем редактирования, кото-рое наряду с текстом может отображать и его форматирование. Пользовательдолжен иметь возможность форматировать выделенный фрагмент текста. Дляпредоставления этой возможности следует в форму, содержащую компонент типаTRichEdit, добавить компоненты, реализующие интерфейс работы с форматируе-мым полем редактирования. Это могут быть кнопки или списки, результатом вы-полнения которых будет установка новых атрибутов параграфа или шрифта.Приведем пример реализации обработчиков событий для загрузки текста, егоформатирования и печати.

procedure TForml.FormCreate(Sender: TObject);const {Чтение RTF-файла}

// Путь размещения загружаемого файла of filesPath = '..\DEMOS\RICHEDIT\OVERVIEW.RTF1;

beginRichEditl,Lines.LoadFromFile(Path);

end;procedure TForml.ButtonAddStrClick(Sender: TQbject);begin with RichEditl.SelAttributes do

begin {Добавление строки}Color := clYellow;Height := Height + 2;

end;RichEditl.Lines.Add('Добавляется строка желтого цвета 1);

end;procedure TFoml.ButtohDefAtrClick(Sender: TObject);begin {Изменение атрибутов по умолчанию}

RichEditl.DefAttributes.Color := clBlue;RichEditl.DefAttributes.Style := [fsBold, fsltalic];

Page 426: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

426 Delphi 7. Самоучитель программиста

end;procedure TForml.ButtonlClick(Sender: TObject);

begin{Печать содержимого поля типа TRichEdit}

RichEditl.Printl'My Document Наше1);

end;

ПРОГРАММИРОВАНИЕ ИНТЕРФЕЙСОВЛАЯ ФОРМ БАЗ ДАННЫХ

Копирование в ы д е л е н н ы х строк таблицыОкно таблицы реализовано компонентом типа TDBGrid. Для того чтобы скопи-ровать выделенные строки таблицы DBGridl в список Listboxl при щелчке мы-шью на командной кнопке Button!, можно записать следующий код в обработ-чик события OnClick для кнопки:

procedure TForral.ButtonlClick(Sender: TObject);var i, j: Integer; s: string;begin

if DBGridl.SelectedRows.Count>0 then{Есть выделенные строки}

with DBGridl.DataSource.DataSet do{Действия над набором данных)

for i :=0 to DBGridl.SelectedRows.Count-1 dobegin

GotoBookmark (pointer(DBGridl.SelectedRows.Items[i]));for j := 0 to FieldCount-1 do

begin {Формирование элемента списка)if (j>0) then s:=si', ' ;s:=s+Fields[j].AsString;

end;Listboxl .I tems.Add(s); {Добавление элемента в список}

end;end;

Контроль за правильностью вводимых данныхПеред записью данных в базу данных вызывается обработчик событияBeforelnsert, в который можно ввести код проверки достоверности записывае-мых данных.Создадим форму, записывающую значения полей таблицы базы данных из ком-понентов типа TEdit. В этом случае надо контролировать совпадение типа полятаблицы с типом введенного значения.

Page 427: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 427

_ Для того чтобы внести в базу данных достоверные значения попей из ком-

/понента типа TEdit, следует;

1. Добавить в набор данных, новую запись: Tablel. Insert;.

2. Присвоить полям этой записи значения из компонентов типа TEdit. Напри-мер: Tablel.FieldByNameCintFieldl1) .Aslnteger : =StrToInt(Edit!.Text);

J. Записать изменения в базу данных: Tablel.Post;

4. Создать обработчик события Beforelnsert, контролирующий правильностьзаписываемых данных. Например, для контроля за тем, чтобы вводимоезначение могло быть преобразовано в тип Integer, можно внести код:

procedure TForml.TablelBeforelnsertfDataSet: TDataSet);begin

try(Инициация исключения при ошибке преобразования}

StrToInt(Editl.Text);except

Editl.Text := ' О ' ;end;

end;

Последовательный просмотр записей таблицы:" Для того чтобы реализовать цикл по всем записям набора данных, можно

/выполнить следующий код:

var i: Integer;begin

with ProgressBarl do [Отображение завершенности просмотра}begin

Tablel.First;for i := 0 to Tablel.RecordCount do (Цикл по набору записей}begin

Position := i; Tablel.Next;end;

end;end;

ПРОСМОТР ГРАФИЧЕСКИХ ФАЙЛОВСоздадим форму, позволяющую просматривать графические файлы различныхформатов.

Page 428: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

428 Delphi 7, Самоучитель программиста

Для этого выполним следующие действия:

1. Расположим в форме компоненты (рис. 12.13):

WFwml f-тптаFile

| SE1 с: [system) "31 3• Help

Examples

jpegdemo.dcujpegdemo.dlmipegdemo.pasjpegproi.dpripegproj.exejpegprojjesleslimg jpg

--- J

Рис. 1 2.1 3. Форма для просмотра графических файлов

PanelI: TPanel;DirectoryListBoxl: TDirectoryListBox; [Для выбора каталога

из списка}FileListBoxl: TFileListBox; {Для отображения

списка графических файлов!Panel3: TPanel;DriveCornboBoxl: TDriveComboBox; (Для выбора диска}

{Для определения масштаба просмотра/(Для 24- или 8-битового цвета}

(Для RGB- или Gray-модели}(Линейка главного меню}(Элемент меню)

Scale: TCoraboBox;PixelFormat: TComboBox;ColorSpace: TComboBox;MainMenul: TMalnMenu;Filel: TMenuItem;Openl: TMenuItem;N1: TMenuItem;Printl: TMenuItem;PrinterSetupl: TMenuItera;N2: TMenuItem;Exitl: TMenuItera;

2. Определим следующие значения свойств для компонентов формы:

object Forml: TFormlOnCreate = FormCreateobject Panel!: TPanel

object DirectoryListBoxl: TDirectoryListBoxFileList = FileListBoxl

end

Page 429: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 429

object FileListBoxl: TFileListBoxOnClick = FileListBoxlDblClick

endendobject Panel3: TPanelobject DriveComboBoxl: TDriveComboBoxDirList = DirectoryListBoxl

endobject Scale: TComboBoxStyle = csDropDownListEnabled = FalseOnClick = SetJPEGOptionsItems.Strings = ( Ч:Г '1:2' '1:4' '1:8')

endobject PixelFormat: TComboBoxOnClick = SetJPEGOptionsItems.Strings - ('24 bit' '8 bit')

endobject ColorSpace: TComboBoxOnClick = SetJPEGOptionsItems.Strings = ('RGB

1 'Grayscale')

endendobject ScrollBoxl: TScrollBox (Область для просмотраobject laagel: TImage изображения)AutoSize = True

endend

object OpenDialogl: TOpenDialogOptions = [ofPathMustExist, ofFileMustExist]

endobject PrinterSetupDialogl: TPrinterSetupDialogendobject PrintDialogl: TPrintDialog

endend

5. В операторе uses укажем следующие пакеты:

usesqWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, jpeg, ExtCtrls, FileCtrl, ComCtrls, Menus,printers;

4. Определим обработчики событий:

procedure FileListBoxlDblClick{Sender: TObject);procedure SetJPEGOptions(Sender: TObject);

Page 430: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

430 Delphi 7. Самоучитель программиста

procedure ForraCreate(Sender: TObject);procedure OpenlClick(Sender: TObject); (Меню открыть]procedure PrintlClick(5ender: TObject) ; (Меню Печать!procedure PrinterSetuplClick(Sender: TObject];procedure ExitlClicMSender: TObject);

5. Введем код для загрузки выбранного графического файла:procedure TForrol.OpenFilelconst Filename: string);begin

:ry 'Загрузка файла Fi lenameImagel.Picture.LoadFromFile(Filename);

excepton ElnvalidGrapliic do

Imagel.Picture.Graphic := nil;end;SetJPEGOptions ( s e l f ) ; {Установка параметров}

end;

6. Введем код для открытия графического файла:procedure TForml.FileListBoxlDblCHckfSender: TObject);begin

OpenFile(FileListboxl,Filename);end;

7. Установим первоначальные параметры для отображения файла. Если типграфического файла отличен от JPEG, то его можно загрузить, но компонен-ты типа TcomboBox для определения параметров будут недоступны,procedure TForml.SetJPEGOptions (Sender: TObject);var Temp: Boolean;begin

Temp := Imagel.Picture.Graphic is TJPEGImage;if Temp then

with TJPEGImage(Imagel.Picture.Graphic) dobegin

PixelFormat :=TJPEGPixelForraatfSelf.PixelFormat.Iteralndex);

Scale := TJPEGScalefSelf.Scale.Iteralndex);Grayscale := Boolean(Colorspace.Itemlndex);

end;Scale.Enabled := Temp;PixelFormat.Enabled := Temp;Colorspace.Enabled := Temp;

end;

8. Определим код обработчика события OnCreate для формы:procedure TForml.FormCreate(Sender: TObject);beginq

Page 431: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 431

Scale.Itemlndex := 0;PixelFormat.Itemlndex := 0;Colorspace.Itemlndex := 0;OpenDialogl.Filter := GraphicFilter(TGraphic); (Фильтр

и маска для поиска файлов)FileListboxl.Mask := GraphicFileMask(TGraphic);

end;

9. Определим кол обработчика события OnCHck для элемента меню Open:procedure TForml.OpenlClick(Sender: TObject);begin

if OpenDialogl.Execute thenOpenFile(OpenDialogl.FileName) ;

end;

Ю.Определим код обработчика события OnCHck для элемента меню Print:procedure TForml.PrintlClick(Sender: TObject);var AspectRatio: Single;

OutputWidth, OutputHeight: Single;,begin

if not PrintDialogl.Execute then Exit;Printer.BeginDoc;tryOutputWidth := Imagel,Picture.Width; (Ширина)OutputHeight := Imagel.Picture.Height; (Высота)AspectRatio := OutputWidth / OutputHeight;if (OutputWidth < Printer.PageWidth) and

(OutputHeight < Printer.PageHeight) then

beginif OutputWidth < OutputHeight thenbeginOutputHeight := Printer.PageHeight,-OutputWidth := OutputHeight * AspectRatio;

endelsebeginOutputWidth := Printer.PageWidth;OutputHeight :* OutputWidth / AspectRatio;

endend;if OutputWidth > Printer.PageWidth thenbegin

OutputWidth := Printer.PageWidth;OutputHeight := OutputWidth / AspectRatio;

end;if OutputHeight > Printer,PageHeight then

Page 432: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

432 Delphi 7. Самоучитель программиста

beginOutputHeight := Printer.PageHeiglit;OutputWidth := OutputHeight * AspectRatio;

end;Printer.Canvas.StretchDrawfRect(0,0,

Trunc(OutputWidth), Trunc(OutputHeight)Imagel.Picture.Graphic);

finallyPrinter.EndDoc;

end;end;

11. Определим код обработчика события OnClick для элементаPrinterSetup:procedure TForml.PrinterSetuplClick(Sender: TObject);begin

PrinterSetupDialogl.Execute;end;

12.Определим код обработчика события OnClick для элемента меню Exit:procedure TForml.ExitlClickfSender: TObject);begin Close; end;

На рис. 12.14 приведен пример выполнения созданного приложения.

меню

827001.JPG827004.BMPB27D04.JPG8270D5.6MPB27005.JPG827006. BMP

627007 BMP827007.JPG827008. BMPS27008.JPG327009. BMP

.'-

Рис. 12.14. Форма для загрузки и отображения графических файлов

Page 433: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 433

РАБОТА с ФОРМАМИ и ДИАЛОГАМИПереход ллежлу формами п р и л о ж е н и я

По умолчанию при добавлении в проект новой формы для нее в главном файлеприложения автоматически формируется строка кода для создания формы. На-пример: Application.CreateFora(TForml, Forml);.Для добавления в проект новой формы достаточно выполнить команду менюFile| New Form.Если приложение включает много форм и нет необходимости их сразу созда-вать, тогда эти формы следует исключить из списка автоматически создаваемыхформ, выполнив команду меню Project OptionsjForms. Исключение формы изсписка автоматически создаваемых форм вызовет удаление из главного файлаприложения строки Application.CreateForro для исключенной формы.

Для того чтобы динамически создать форму во время выполнения, следует:

1. Добавить модуль определения динамически создаваемой формы в модульформы, из которого новая форма будет создаваться. Для этого выполнитькоманду меню File | Use Unit и выбрать добавляемую форму.

2, Вызвать для создания формы метод Create. Например:

Form2:=TForm2.Create(se l f ) ;

5. Отобразить форму, используя метод Show для немодальных форм или ме-тод ShowModal для модальных форм. Например: Form2.ShowModal;.

После выполнения в форме требуемых действий следует закрыть форму,вызвав метод Close.

4. Освободить меню из-под закрытой формы вызовом метода Free. Напри-мер: Form2.Free;

Приведем пример приложения из двух форм - Forml и Form2, в котором втораяформа создается как модальная при щелчке мышью на кнопке Button!.

unit Unitl; {Модуль Unit l)interfaceuses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs,StdCtrls, CoraCtrls, ExtCttls;type

TForml = class(TForm)Buttonl: TButton,-procedure ButtonlClick(Sender: TObject);

end;var Forml: TForml;

Page 434: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

434 Delphi 7. Самоучитель программиста

implements tic;-.uses Unit2;{SR *.DFM}procedure TForial.ButtonlClick( Sender: TObject);beginForra2:=TForm2.Create(self) ;Form2.ShowModal;?orm2.Free;er.d;end.unit Unit2; {Модуль Unit2}interfaceuses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;type

TForm2 = clsss(TFonn)Buttonl: TButtonClose;procedure ButtonCloseClickfSe^der: TObject];

end;var Form2: ?Forra2;implementation•'$3 *.DFM)

procedure rForrr.2.ButtonCloseClick{Sender: TObject);begin Close; end;end.

На рис. 12.15 приведем пример выполнения созданного приложения.

межяч Фо

Шкрыгь форму Рол

B^kM'f ._ ftлГ Form2

Рис. 12.15. Динамически созданная из Form'l модальная форма Form2

Page 435: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Разработка интерфейса 435

Запрос полного имени файла из стандартногодиалога Open

**щ:'\ Для того чтобы определить полное имя файла, следует:

1. Расположить в форме невизуальный компонент типа TOpenDialog со стра-ницы Dialogs палитры компонентов.

2. Запустить стандартный диалог, а котором пользователь должен будет вы-брать имя файла: QperiDialogi.Execute;.

}. Присвоить значение свойства FileName свойству Text или Caption компонен-та, отображающего полный путь для выбранного имени файла. Например:

Edit2.Text:=QpenDialogl.FileName;

Page 436: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ

Abs 69

AnslCompareStr 84

AnsiLowerCase 85

AmiStr Cornp 81

Application.CreateForm 433

Application. Hint , 408

Arrangelcons 159

array 42

AsBoolean 258

AsDate 258AsFloat 258

AssignFile 92

AssignPrn 97

AsString 258

В

Beep 98

BeglnAutoDrag 140

BeginDrag 141

biHelp 154

biMaximize 154

biMinimize 154

biSystemMenu 154

Bof 257

Boolean 38

Break 98

BringToFront 141

Broadcast 145

bsDialog 155

bsNone 155

bsSingle 155

bsSizeable 155

bsSizeToolWin 155

bsToolWindow 155

Byte 37

Char 38

ChDir 93

Chr 88

Clear 186

ClearSeiection 186

Click 141

ClientToScreen 141

Close 287CloseDatasets 285

CloseFile 93Commit 285

CompareSfr 85

CompToCurrency 79

ConnectionString 288

Continue 98

ControlAfPos 145

Copy 86

CopyToClipboard 186Create 142

CreateDir 93

CreateForm 148Currency 38

CurrToSf r 80

CutToCI[pboard 187

D

Date 75

DateTimeToStr 75

DateToStr 75

DayOfWeek 75

DblClick 142

Delete ...86

DELETE (SQL-оператор) 275

DeleteFile 93

Directory 405

DirectoryExists 93

CanAutoSize 141

CanFocus 146

CanResize 141

Cascade 159

Changed 141

EAbort 66

EDatabaseError 68

EDivByZero 67

EMathError 67

Eof.. ..257

Page 437: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Предметный указатель 437

Eoln 97

EPrinter 69

Erase 97

Exception 68

Execute 286

Exit 98

F

FieldByName 427

FtndText 194

FloatToDecimal 71

FloalToStr 72

FloatToText 72

fsMDIChild 155

fsMDIForm 155

fsNormal 155

fsStayOnTop 156

function 56

G

GetControlsAlignm&nt 142

GelDeviceContext 146

GetOle2AcceleratorTable 161

GetSelTextBjf 194

GetTextLen 142

Grouplndex 16S

H

Hide..

Hint ..

.142

.407

1

Initalize 148

InputBox 89, 403

InputQuery 89, 403

Insert 86

INSERT (SQL-оператор) 274

Int 70

Integer 37

Invalidate 142, 198

ItemAlPos 198

IternRect 198

L

Length 86

LoadCursor 1 52

LoadFromFile 430

LoginDialog 89

MManualDock 142

ManualFloat 142

Max 70MaxIntValue 70Merge 161

MessageBox 149MessageDIg 89, 149, 404

MessageDlgPos 90MessageDlgPosHelp 90

Minimize 150

mr Abort 173

mrAII 173mrCancel 172

mrlgnore 173

mrNo 173

mrNone 172

mrOk 172mrRetry 173

mrYes 173

MSecsPerDay 74

N

Next 159

NormalizeAIITopMosts 150NormalizeTopMosts 150

NotifyControls 145

Now .. ..77

OnActivate 225

OnChange 225

OnClick 223

OnClose 226

OnCreate 225

OnDblClick 223

OnDeactivate 225

OriDragDrop 223

OnDragOver 223

OnEndDrag 223OnEnter 225

OnException 225

OnExit 225

OnHelp 225

OnHint 225

OnKeyDown 222

OnKeyPress 222

Page 438: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

438 Delphi 7. Самоучитель программиста

OnKeyUp 222

OnMouseDown 222

OnMouseMove 222

OnMouseUp 222

OnPopup 170

OnStarfDrag 223OnTimer 226

Open 287

P

PaintTo 146

PasteFromClipboard 187

PChar 423

PopulateOle2Menu 161

Previous 159

Print 194

procedure 55

R

Readln 98

Refresh 142

R epaint \A 2

Restore 150

Rollback 287

Round 70

S

Screen.Cursors 420

ScreenToClient 141

SecsPerDay 74

SELECT (SQL-оператор) 273SdectAll 187

SelecfDireclory 91

SelLength 187

SelSlart 187

SendToBack 143

SelFocus 146

SetOle2MenuHandle 162SetTextBuf 98

Show 143

ShowException 150

ShowMessage 92, 405

Sqrt 70

St arilransaction 287

stdcall 57

Sir 87

SlrCat 82

StrComp 42d

SfrCopy 82

string 38

StrLen 83StrRScan 423

StrToCurr 73SfrToOale 78

StrToDaf eTime 78

SfrToFloat 74

StrToInf 79StrTolnt64 79

SlrToTime 78

SfrUpper 84

Sum 71

Т

TActionLst 162

TADOConnection 288

TADODalaSef 255TApplicatlon 147

HelpFile 147Hint 147

HintColor 147

Icon 147MainForrn 147ShowHInt 148

ShowMairiForm 148Title 148

TApplicat.onEvents 147TAreaSeries 341

TBarSeries 341

TBasicAct.on 162

TBDEDalaSet 255TBitBnt 171

TBiiBtn 174

Glyph 174Kind 175Layout 176

Margin 176NurnGlyphs 176

TButtonStyle 176TBgfton 171

Cancel 172

Default 172

ModalResult 172TButfonSet 298

TCheckBox 171, 178

AllowGrayed 178

Checked 179

State 179

TCheckListBox.. ..200

Page 439: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Предметный указатель 439

TCIass 129TCIientDataSet 255

TColor 134

TCornboBox 198TComponent 130

ComponentCount 1 30

Componentlndex 131

Components 131

Name 131Owner 131

TControl 131

Action 132

AutoSize 132

BoundsRect 132

ClientHeight 132

ClientOrigin 133ClientRect 133

ClientWidth 132

Color 134

ControlStyle 133Cursor 135

DesktopFont 137

DragCursor 137DragKind 138

DragMode 138

Enabled 137

Floating 137Height 137

HelpConlext 138HelpKeyword 138

HelpType 138

Hint 138

Left 138

Parent 139

ParentColor 139

ParentFont 140ParentShowHint 140PopupMenu 140

ShowHinl 140

Text 140

TFont 137

Top 138

Visible 140

Width 137

TControlBar 213Т ControlStyle 133

TCoolBar 21!

TCursor 135

TCustomControl 1Л6

TDatabase 279AliasName 280

Connected 280DatabaseName 281

Exclusive 281KeepConnection 282

Session 282SessionAlias 282

SessionNarne 282

Translsolafion 283

TDataSet 255, 256

Active 256ActiveRecord 257

Current Record 257

DataSource 257

TDataSource 262TDataSource DataSet 262

TDateTime 74, 422

TDBCheckBox 171

TDBComboBox 302

TDBCtrlGrid 30d

TDBDataSet 255

TDBEdit 299TDBGrid 290, 426

Columns 292DataSource 294

Selectedlndex 294

TDBGridOption 294

TDBlmage 300TDBListBox 302

TDBLookupListBox 303

TDBMerno 300

TDBNavigator 296

TDBRadioGroup 171, 300

Items 301

Values 301

TDBText 299

TDirectoryListBox 428

TDriveComboBox 428

TEdlt 184

AutoSelect 185

AutoSi^e 185BorderStyle 185

CanUndo 185CharCase 185

HideSelection 185

MaxLength 185Modified 185

PasswordChar 186

Readonly 186SelLength 186

SelStart 186

SelText 186

TabOrder... 186

Page 440: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

440 Delphi 7. Самоучитель программиста

TabStop 186Texl 186

TextToFloat 74TFields 258TFileListBox 429

TFIoatFormat 71TFIoatRec 71TForm 153

Active 154

ActiveControl 154

ActiveMDIChild 154Border Icons 154

BorderStyle 15-1

FormState 155

FormStyle 155HelpFile 156

Icon 156

KeyPreview 156MDIChildCount 156MDIChildren 156

Menu 156ObjectMenultern 157

Parenl 157Position 157PrintScale 158Scaled 158

Visible 158

WindowMeiui 158

WindowState 158

TGroupBox 171, 182Tile 159Tlmage 430

TlmageLisI 208Time 78

TimeToStr 78

TJPEGImage 430

TLabel 183

Alignment 183

AutoSize 183

BorderStyle 184

FocusContro! 183

Layout 183

ShowAccelChar 184

Transparent 184

Wordwrap 184

TLrneSeries 341

TListBox 195

Columns 195It emlndex 196Items 196MultiSelect 196

SelCount... ..196

Selected 197

Style 197

Toplndex 197

TLislBoxStyle 197

TMainMenu 160, 417

AutoMerge 161

Handle 161

TMaskEdit 187

TMemo 190TMenu 159

Images 160

Items 160

OwnerDraw 160

TMenultern 162, 410Action 162

Add 167AutoHotkeys 163

Bitmap 163

Break 163Caption 164Checked 164

Clear 168

Default 164Enabled 164Grouplndex 165

HelpContext 166

Hint 166

Imagelndex 166Items 166

Menu Index 166

Parent 166

Radioltem 166

Shortcut 167

SubMenulmages 167

Visible 167

TObject 129

TOpenDialog 220, 435

TPoint 79

TPopupMenu 169

Alignment 169AutoPopup 169HelpContext 170MenuAnimalion 170

PopupComponent 170

TrackButton 170TPopUpMenu 418TPrintDialog 429TPrinterSetupDialog 429

TQuery 255, 273

ExecSQL 278

Prepare 278

TRadioButton .. 171, 180

Page 441: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Предметный указатель 441

Alignment 181

Checked 131

TRadioGroup 171, 182Columns 182Itemlndex 182Items 182

TRect 78

TRichEdit 192, 425DefAtlributes 193

HideSelection 193

Lines 193

SelAttributes 193SelLength 194

SelStart 194

SelText 19d

Trim 87

TrimLeft 87

TrimRight 87

Trunc 70

TRvProject 314

Active 315

Engine 315

Execute 316

Open 315

SelectReport 315

TScreen 151

AcliveContro! 151

ActiveCustomForm 1 51

AcliveForm , 151

Cursor 152

Cursors 152

CijstomForrnCoijnt 153FormCoLint 153Forms 153Height 153HintFont 153MenuFont 153Width 153

TSpeedButton 171, 176

Glyph 178

Grouplndex 177

TSQLDataSet 255

TSQLQuery 255

TSQLTable 255

TStaticText 183

TStatusBar 219Panels 220

SimpiePanel 220SimpleText 220

TSlatusPanel 219

TStoredProc 255

TStringGrid 213Cells 214

ТТаЫе 2S5, 263

DatabaseNarne 264

Exclusive '265Filter 269Filtered 269IndexName 266Locate 272MasterFields 268Post 272Readonly 269

RecNo 270SessionName 269SelRange 271

TableName 269'TDataSource 269

TTextAttributes 193

TTimer 422

TToolBar 208

TToolButton 171, 210

TTreeView 201

TWinControl 143

Brush 143ClientOrigirt 14J

ClientRecl 144ControlCount 144

Controls 144HelpContext 144

TabOrder 145TabStop 145

UUndo 187

Unmerge 162

Update 143

UPDATE (SQL-оператор) 274

V

Val 88

ValueListEditor 204

WWriteln 98

wsMaximiied 158

wsMinimized 158

wsNorrnal 158

Page 442: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

ОГЛАВЛЕНИЕ

ГЛАВА 1. ИНТЕГРИРОВАННАЯ СРЕДА РАЗРАБОТКИ IDE 3

Первый вход в Delphi 3

Окно редактора кода 4

Окно проводника кода , 9

Инспектор обьектов 10

Проекты 11Группы проектов '3

Менеджер проекта 13

Шаблоны приложений IS

Редактор меню 1>

Редактор изображений 30

Встроенный отладчик 21

ГЛАВА 2. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ 25

Основные понятия 25

Создание нового класса 24Объявление типа 26Объявление переменных и методов класса 26

Работа с классами 27

Свойства, методы и обработчики событий 30

ГЛАВА 3. OBJECT PASCAL 31

Структура программы 31

Основы синтаксиса 32Типы данных 36Базовые типы данных 37Производные типы данных 39

Указатели 48

Структурированный тип 49

Определение типа и объявление переменных 50

Константы 51Приведение типов 54

Процедуры и функции 5SОпределение процедур ч функций 55

Перегрузка процедур и функций 57

Операторы 57Оператор присваивания 57

Вызовы процедур и функций 58

Структурированные операторы 58

Составной оператор begin...end 58

Оператор if...(hen 58

Оператор case...end 59

Операторы цикла 60

Page 443: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Предметный указатель 443

Оператор with 62Операторы goto и label 63

Операторы исключений 63

Стандартные процедуры и функции 69

Математические процедуры и функции 69

Процедуры и функции над действительными числами 71

Процедуры и функции даты/времени 74

Процедуры и функции преобразования типов 78Процедуры и функции для работы со строками и символами 80

Функции для работы с указателями и адресами 88

Процедуры и функции диалогов и сообщений 89Процедуры и функции для работы с файлами и каталогами 92

Процедуры и функции для работы с текстовыми файлами через файловую

переменную 97

Процедуры и функции общего назначения 98

ГЛАВА 4. ОБЪЕКТЫ И КОМПОНЕНТЫ 99

Основные понятия 99

Объекты 99

Компоненты 99Элементы управления 99

Работа с объектами и компонентами 100

Палитра компонентов 101

Страница Standard 102

Страница Additional 103

Страница Win32 106

Страница System 108

Страница DataAccess 109

Страница DataControl 1 iO

Страница dbExpress 111

Страница BDE 112

Страница ADO 43

Страница InterBase 114

Страница DataSnap "6

Страница Internet 116

Страница Internet Express 118

Страница WebServices 118

Страница WebSnap 49

Страница COM4- 121

Страница Rave 121

Страница Dialogs 122

Страница ActiveX 123

Страница QReport 124

Страница Servers '26

ГЛАВА 5. БИБЛИОТЕКА ОМПОНЕНТОВ DELPHI - VCL 128

Иерархия классов VCL-библиотеки 128

Классы, инкапсулирующие общее поведение компонентов 119

Класс TObject 129

Класс TCIass 129

Класс TComponent 130

Класс TControl.. 131

Page 444: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

444 Delphi 7. Самоучитель программиста

Класс TWinConlro! 143Класс TCustomControl 146Класс TApplication 147

Класс TScreen 151

Базовый класс окна формы 153Класс TFortn 153

Классы для системы меню 1S9Класс TMenu 159

Класс TMainMenu 160Класс TMenuIfem 162

Класс TPopupMenu 169

Классы командных кнопок, флажков и радиокнопок 171Класс TBuiton 172Класс TBUBfn 174Класс TSpeedBullon 176Класс TCheckBox 178Класс TRadioButton 180Класс TRadloGroup 182Класс TGroupBox 182

Классы для работы с текстом 182Классы TLabel и TStalicText 183Класс TEdlt 184Класс TMaskEdit 187Класс ТМето 190Класс TRichEdil 192

Классы списков 195Класс TListBox 195Класс ТСотЬоВох 198

Класс TCheckLlslBox 200Класс TTreeView 201Класс ТСотЬоВохЕх 202Класс TValueListEdilor 204

Классы панелей инструментов ..208Класс TToolBar 208Класс TToolButlon 210

Класс TCoolBar 211Класс TConlrolBar 213

Классы для табличного отображения данных 213Класс TSIringGrid 213

Класс строки состояния 21?Класс TStalusBar 219

Классы стандартных диалогов 220

Обработка событий 221События от клавиатуры 222События от мыши 222

События перемещения и сброса объектов 223

События, инициируемые для компонентов 224

События, обрабатываемые приложением 226

Page 445: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Предметный указатель 445

ГЛАВА 6. СОЗДАНИЕ ПРИЛОЖЕНИЙ В СРЕДЕ DELPHI 227

Первые шаги 217

Управление свойствами визуальных компонентов 227

Проектирование SDI- и MDI-приложений 230

Проектирование меню окна формы 235Создание главного меню 235

Создание и использование DLL-библиотек 236Создание DLL-библиотеки 236

Статическое подключение DLL-библиотеки 239

Динамическое подключение DLL-библиотеки 240

Использование DLL-библиотеки для вызова общих модальных диалогов 242

ГЛАВА 7. РАБОТА С БАЗАМИ ДАННЫХ 24S

Реляционные базы данных 245Основные понятия 245

Таблицы 246Индексы и ключи 246

Сеансы данных 246Транзакции 247

Базы данных в Delphi , 247Источники данных 248Машина баз данных BDE 249

Псевдонимы 249

Защита доступа к БД 250SQL Explorer 252

Компоненты для доступа к источникам данных 253Наборы данных , 25SКласс TDataSef 256Класс TDataSource 262

Класс ТТаЫе 263Класс TQuery 273Класс TSQLTable 278

Классы, реализующие соединение с базой данных 279Класс TDalabase 279Класс TADOConneclion 288

Компоненты управления данными , 290Класс TDBGrid 290Класс TDBNavigalor 296Класс TDBTexl 299Класс TDBEdit 299Класс TDBMemo 300Класс TDBImage 300Класс TDBRadioGroup 300Класс TDBCheckBox 301Классы TDBLisiBox и TDBComboBox 302Класс TDBLookupListBox 303Класс TOBCIrlGrid 304

Дополнительные классы, предназначенные для работы с данными 305Класс TSession 305Класс TBatchMove 306Класс TUpdaleSQL 307

Page 446: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

446 Delphi 7. Самоучитель программиста

Классы, предназначаемые для создания отчетов 307Класс TQRSubDetail 308Класс TQRSlringsBand 309

Класс TQRSand 309Класс TQRChiidBabd 310Класс TQRGroup 310

Класс TQRLabel 310

Класс TQRDBTexf 310

Класс TQRExpr 311

Класс TQRSysData 311Класс TQRMemo 312

Класс TQRExprMemo 312Класс TQRRichText З Т 2

Класс TQRDBRichText 312Класс TQRShape ' 312Класс TQRImage 313

Класс TQRDBImage 313Классы TQRTextFIHer, TQRCSVFilter и TQRHTMLFiller 313

Класс TQRChart 31J

Класс TRvProject 314

События, инициируемые при работе с базами данных 316

ГЛАВА 8. РАЗРАБОТКА ПРИЛОЖЕНИЙ БАЗ ДАННЫХ 320

Создание формы для работы с базой данных через BDE 320Форма для одной таблицы, использующая компонент типа ТТаЫе 324

Форма для двух таблиц, использующая компонент тила TQuery 328

Использование страницы Diagram для работы с базами данных 333

Основные шаги при создании приложений, работающих с таблицами 335

Настройка столбцов таблицы типа TDBGrid 338

Форма с диаграммой для набора данных 340

Выполнение SQL-операторов и хранимых процедур 343Создание генераторов значений для БД InterBase 343

Создание триггеров 344

Создание и выполнение хранимых процедур , 345

Обработка данных для многозвенной архитектуры 349Применение многозвенных архитектур 349

Создание сервера и клиента для доступа к данным 349

Создание отчетов в Rave Reports 352

ГЛАВА 9. РАЗРАБОТКА РАСПРЕДЕЛЕННЫХ ПРИЛОЖЕНИЙ 358

Модель компонентных объектов СОМ 358Интерфейсы 358

Создание СОМ-компонентов 363

Класс TComObject 367

Создание клиента 367

Применение технологии CORBA 369Создание серверного объекта CORBA 369Создание клиента CORBA 378

Запуск сервера CORBA 380

Page 447: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

Предметный указатель 447

ГЛАВА 10. РЕАЛИЗАЦИЯ МЕХАНИЗМОВ МЕЖСЕТЕВОГО ВЗАИМОДЕЙСТВИЯ ...381

Взаимодействие по протоколу TCP/IP 381Создание сервера 381

Создание клиента 384

Приложения, выполняемые на WEB-cepaepe 386

CGI-приложения 387Публикация данных в Internet 389

ГЛАВА 11. ИСПОЛЬЗОВАНИЕ СЕРВЕРОВ АВТОМАТИЗАЦИИ 393

Сервер автоматизации Microsoft Word 393Реализация доступа к объектам автоматизации Word 393Запуск сервера Word через СОМ-интерфейсы 393

Запуск OLE-сервера Word через интерфейс IDispath 395

Запуск сервера Word с использованием компонента TWordApplication 396

Сервер автоматизации Microsoft Excel 398Запуск сервера Excel 398Создание диаграмм 401

ГЛАВА 12. РАЗРАБОТКА ИНТЕРФЕЙСА 403

Реализация диалогов и сообщений 403Создание диалога для ввода значения 403Отображение окна сообщений 404

Создание самого простого диалога сообщений 405

Отображение диалогов выбора каталога 405

Создание всплывающих подсказок 407

Программирование меню 409Меню для работы с графическими объектами 409

Программирование главного меню формы 417

Программирование контекстного меню 4Н

Назначение действия для пункта контекстного меню 419

Добавление в существующее меню списка всех форм 419

Работа с мышью 420Управление видом курсора мыши 420

Программное изменение свойств компонентов 421Изменение шрифта для компонента типа TRichEdil 421Работа с датой 422Запуск таймера 422

Работа со строками 423Сравнение строк 424

Разработка интерфейса для компонента типа TRichEdil 425

Программирование интерфейсов для форм баз данных 426Копирование выделенных строк таблицы 426

Контроль за правильностью вводимых данных 426

Последовательный просмотр записей таблицы 427

Просмотр графических файлов 427

Работа с формами и диалогами 433Переход между формами приложения 433

Запрос полного имени файла из стандартного диалога Open 435

ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ 436

Page 448: Delphi 7 САМОУЧИТЕЛЬ ПРОГРАММИСТА

И З Д А Т Е Л Ь С Т В О

«OU КУАИЦ-ОБРАЗ»

Тел.: (095) 333-82-11; okljjikudits.ru, hup:/fwww.kudits.ru/pub!ish

ПРИОБРЕТАЙТЕ КНИГИ У НАШИХ ПАРТНЕРОВ

Барнаул

Социалистический пр-т, 117а,(3852) 38-18-72

Великий Новгородул. Б. Санет-Петербургская, 44тел. (81622) 73-188 доб. 34

Екатеринбург

"Книжный мир",ул. 8Марта. 8г, (3432) 71-18-87

Краснодар

"Мир книги",ул. Буденного, 147

Москва"ОПТИМА+"

Розничная торговля

м. Тульская, Варшавское ш,9,книжная ярмарка "Центральная",зеленая линия, павильон 412-57

Оптовая торговля

(095) 333-65-57

Нижний Новгород

"Нижегородский Дом книги",ул. Советская, 14,тел. (8312) 44-22-73

Новосибирск

"Книжный пассаж".ул.Ленина, 10а, (3832) 29-50-30

"Сибирский Дом Книги",Красный пр-т, 153, (3832) 26-62-39

"Книжный мир". Пр-т К.Маркса, 51

Омск

"Книжный Мир",ул. Ленина, 17/19, (3812) 24-32-54

Ростов-на-До ну"Мир книги'.Ворошиловский пр-т, 33,(8632) 62-54-61

Санкт-Петербург"Санкт-Петербургский Дом книги"Невский проспект, 28,тел. (812) 312-01-84

издательство "Наука и Техника"пр. Обуховской Обороны, 107,тал. (812) 567-70-25,567-70-26

Саратов"Книжный Мир",пр-т Кирова, 32, (8452) 32-98-14

Ставрополь

"Книжный Мир",ул. Мира,337, (8652) 35-47-90

Томск

"Книжный Мир",ул. Ленина, 141, (3822) 51-07-16

Уфа

000 ПКП "Азия", тел./факс: (3472) 50-39-00

Оптовая торговля

Ул. Зенцова, 70Розничная торговля

Магазин "Оазис",ул. Чернышевского,88Магазин "Книжник", пр. Октября, 106

Ханты-МансийскМагазин "Книги", ул. Ленина, 39

Челябинск

"Книжный Мир",ул. Кирова,90, (3512) 33-19-58

ЯрославльМагазин "Наука",ул. Володарского, 63, (0852) 25-95-04

РОЗНИЧНАЯ ТОРГОВЛЯ ПО ИЗДАТЕЛЬСКИМ ЦЕНАМ В МОСКВЕВаршавское ш., 9, м. Тульская, трамвай 3, 35, 47 до ост. "Стройдвор"

книжная ярмарка "Центральная", зеленая линия, павильон 412-57