Upload
-
View
5.110
Download
46
Embed Size (px)
Citation preview
И. Ю. БАЖЕНОВА
Delphi 7САМОУЧИТЕЛЬ ПРОГРАММИСТА
Object Pascal
Доступ к реляционным базам данныхКлассы палитры компонентов Delphi
BDE и InterBaseODBC и OLE DB
Работа с базами данныхСоздание отчетов в Rave Reports
Разработка SDI и MDI приложенийСОМ и CORBA
Серверы и контейнеры автоматизацииПубликация данных в Internet
КУДИ1_1-ОБРАЗМосква • 2003
ГЛАВА 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.
Глава 1
Рис. 1.1. Интегрированная среда разработки - IDE
ОКНО РЕДАКТОРА КОДАОкно редактора кода первоначально открывается состоящим из двух частей: ок-на проводника кода Code Explorer и самого окна редактора кода, содержащего двестраницы Code и Diagram. Сам редактор кода расположен па странице Code. Стра-ница Diagram окна редактора кода предоставляет визуальный инструментарийдля определения логических взаимоотношений между визуальными и невизу-альными компонентами, отображаемыми в окне Object TreeView. СтраницаDiagram может быть использована как инструментарий для документированияпроекта, так как позволяет выводить на печать схематически представленныевзаимоотношения между компонентами.
Окно кода представляет собой мощный редактор для создания и редактированиякода модулей программы. Он поддерживает такие возможности, как:
и цветовое и позиционное отображение кода модуля;
« контекстно предлагаемый набор шаблонов операторов языка программиро-вания, которые можно добавлять в код модуля;
• редактирование и добавление шаблонов предлагаемого набора операторов;
* отображение классов, функций, методов;
Интегрированная среда разработки 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.
Глава 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
Интегрированная среда разработки 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. Отображение списка имен
Глава 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-секции) и двух необязательных секций — инициализации и завершения.
Интегрированная среда разработки 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.
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 содержит в левой части список всех доступных во время про-ектирования свойств для текущего объекта, а в правой части — их значения.Символ + перед именем свойства указывает, что это свойство является состав-ным и содержит другие вложенные свойства. Для распахивания или сворачива-ния составного свойства следует щелкнуть мышью на расположенном слева отнего символе + или - соответственно.Для изменения значения свойства необходимо ввести это значение или выбратьего из предлагаемого списка.
Интегрированная среда разработки 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,
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 и указать имя файла.
Интегрированная среда разработки 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
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 можно опреде-лить каталоги для различных файлов проекта.
Интегрированная среда разработки 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, то после запросаимени создаваемого приложения и каталога для его размещения сразу будетсоздан проект, содержащий шаблон готового приложения, обладающего свойст-
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.Приведем с некоторыми пояснениями листинги трех автоматически созданныхфайлов шаблона приложения.
Интегрированная среда разработки 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;(Обработка команд меню}
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];
Интегрированная среда разработки 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, определяемые в редакторе меню.
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} . При создании приложения автоматически создается и одноименный
По умолчанию при создании нового приложения гакая директива уже присутствует
в файле проекта.
Интегрированная среда разработки IDE Л
файл ресурсов. Файл ресурсов отображается деревом, содержащим имена всехсозданных ресурсов. Эти имена можно использовать п коде приложения для бы-строй загрузки ресурсов. Загрузка изображения непосредственно из BMP-файлавыполняется значительно медленнее, чем из файла ресурсов, и дополнительнотребует доступа к этому ВМР-фай.чу.
Mintage Editor
Fi!a flesouiee V^indow Kelp
Рис. 1.1 8. Редактор изображений
ВСТРОЕННЫЙ ОТЛАДЧИКВстроенный отладчик позволяет выполнять пошаговую отладку приложений.Точки, в которых производится остановка выполнения приложения, называютсяконтрольными точками (breakpoint).
Вставить контрольную точку очень просто: достаточно щелкнуть в редакторе кодана серой полосе слева от кода строки. Контрольная точка отмечается красным бул-летом. Строка с контрольной точкой также выделяется красным фоном.
Дополнит&тьно, используя команду меню Run|Add Breakpoint, можно устанаапиватьконтрольные точки на конкретный адрес или на загрузку определенного модуля.
Если в приложении установлены контрольные точки, то при запуске приложе-ния, например нажатием клавиши F9. автоматически будет запущен встроенныйотладчик. Выполнение приложения прервется на первой контрольной точке. Та-кая точка будет в окне кода отмечена зеленой стрелкой (рис. 1.19).
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 - переход к следующей строке кода и останов, исключая переходывнутрь процедур;
Интегрированная среда разработки 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). Такой диалог можно создавать для каждого отслеживаемого выражения.
Щелчком мыши по кнопке с тремя точками справа от поля значения можно вы-звать диалог для изменения текущего значения отслеживаемого свойства илипеременной.
Глава 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
Это окно является самым удобным средством для одновременного отслежива-ния текущих значений выражений, изменяемых в процессе отладки.
Г Л А В А 2
ОБЪЕКТНО-ОРИЕНТИРОВАННОЕПРОГРАММИРОВАНИЕ
Delphi является объектно-ориентированной средой программирования. В каче-стве языка программирования используется язык Object Pascal. Эта глава позна-комит вас с основными понятиями объектно-ориентированного программирова-ния и с терминологией, используемой для среды программирования Delphi.
ОСНОВНЫЕ понятияОбъектно-ориентированное программирование позволяет программироватьв терминах классов:
* определять классы;
с конструировать новые и производные (дочерние) классы на основе сущест-вующих классов;
* создавать объекты, принадлежащие классу (экземпляры класса).
Класс описывает свойства (атрибуты) объекта и его методы (включая обработ-чики событий).При создании объекта он наследует структуру (переменные) и поведение (мето-ды) своего класса.
В свою очередь, класс, называемый потомком, производным или дочерним клас-сом (подклассом), также может быть создан на основе другого родительскогокласса (предка) и при этом наследует его структуру и поведение.
Любой компонент (элемент управления) или объект в Delphi всегда являетсяэкземпляром класса.Программно объект представляет собой переменную объектного типа.
Для каждого компонента Delphi существует свой класс, наследуемый отTComponent.
Предком всех объектов, включая компоненты, является класс TObject.
Наследование позволяет определять новые классы в терминах существующихклассов.Инкапсуляция - это создание защищенных объектов, доступ к свойствам и мето-дам которых разрешен только через определенные разработчиком «точки вхо-да». Иначе говоря, инкапсуляция - это предоставление разработчику конкретно-го набора свойств и методов для управления поведением и свойствами объекта,определяемыми внутри класса.
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".
Объектно-ориентированное программирование 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 содержит поддеревоиерархии классов, начиная с класса-предка для выделенного на левой панеликласса.
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
Объектно-ориентированное программирование 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, обеспечивающие контроль доступа к свойствам объекта.
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 и выполнить двойной щелчок мышью в поле,расположенном справа от имени события. Это поле представляет собой комби-нированное окно списка - в него можно вводить новое значение имени обработ-чика события двойным щелчком м ы ш и или выбирать имя уже существующейпроцедуры. Это позволяет при необходимости определять одну процедуру обра-ботки событий одновременно для нескольких событий.
Г Л А В А 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;
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.
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
34 Глава 3
КомментарииКомпилятор игнорирует любой комментарии.
Комментарий может быть указан:
* между парными фигурными скобками { ];
* между символами {* и *);
* после символов // и до конца строки.
Директивы компилятораЕсли после символа { или символов * следует знак $, то это называется дирек-тивой компилятора.В следующей таблице приведено описание наиболее часто используемых дирек-тив компилятора.
Директива
$0
$Н
SHINTS
$1
SJ
$L
$М
$М
$0
$fl
SR
SRUNONLY
SWARNINGS
[№}...{SEND1F} ...
Описание
Директива-переключатель, инициирующая генерацию информации дляотладчика
Директива-переключатель, позволяющая использовать в приложении длин-ные строки
Директива-переключатель,
Директива-переключатель
Директива-переключательзначений типизированных
Директива с параметрами
Директива-переключательвремени выполнения
Директива с параметрамивыделяется под стен
Директива-переключательпрограммного кода
инициирующая генерацию подсказок компилятора
инициирующая проверну ошибок ввода/вывода
позволяющая выполнять модификациюконстант
указывающими линкуемые объектные файлы
инициирующая генерации) информации о типе
, указывающими размер памяти, которая
указывающая на необходимость оптимизации
Дирентивз-переключатель, инициирующая проверку принадлежностизначения заданному диапазону
Директива с параметрамив выполняемый ЕХЕ-файл
Директива-переключательпакета выполнения
Директива-переключателькомпилятора
, указывающими, какие ресурсы будут включены
указывающая, что производится генерация
инициирующая генерацию предупреждений
Директивы условной компиляции, определяющие компиляцию толькоодной ветви кода
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(сдвиг значения вправо);
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 можно разбить на следующие группы:
базовые типы данных:
* целочисленный тип;
* действительный тип;
* логический тип;
* символьный тип;
» строковый тип;
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
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
Для строковых переменных выполняются следующие правила:
» строки могут быть постоянной или переменной длины: при объявлении стро-ки можно указать только идентификатор или идентификатор и в квадратныхскобках длину строки. Далее при любом присваивании значение будет усе-каться до указанной длины строки;
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 для объявления переменных.
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).
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.
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 Гип;
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;);
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;
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;
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, указав его тип.
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-секции модуля.
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 байтам.
Основными операциями, выполнимыми над указателями, являются:
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, то данные будут храниться в сжатом состоянии.
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 : Тип;
При описании функции объявляются тип возвращаемого значения и типы фор-мальных параметров,. передаваемых в функцию.
Object Pascal 51
Объявление функцийОбъявление функции описывается следующим синтаксисом:
function Функция(Список_парам1: Тип1; Список___парам2: Т и п 2 ) : ТипЗ;I Список_парам содержит имя переменной или список переменных одного типа }
Объявление функции (или процедуры) должно удовлетворять следующим пра-вилам:
* формальные параметры указываются в круглых скобках;
* список переменных одного типа указывается через запятую;
• тип формального параметра (или списка параметров) указывается после сим-вола двоеточия;
« сами формальные параметры отделяются друг от друга точкой с запятой;
• порядок перечисления параметров при вызове функции должен соответство-вать порядку формальных параметров при объявлении функции.
КонстантыКонстанты бывают двух видов:
• простые константы:
s которые не могут содержать значения типа массива, записи указателя илизначения процедурного типа;
• могут использоваться в выражениях;
* типизированные константы:
• которые не могут использоваться в выражениях;
« могут содержать значения типа массива, записи, указателя, или значенияпроцедурного типа;
• при определении которых указывается не только значение, но и его тип.
Если указана директива компилятора {$J+|, то значение типизированной кон-станты можно изменять во время выполнения (по умолчанию). Такая константаведет себя как проинициализированная переменная. Если указана директивакомпилятора (SJ—}, то значение типизированной константы нельзя изменять вовремя выполнения. Ее поведение аналогично переменной только для чтения.
Определение констант описывается следующим синтаксисом:
const Идентификатор: Тип = Значение; (типизированная константа!const Идентификатор = Константное_выражение; (простая константа)
Примеры:
const Max: Integer = 100;
const Min = 1;
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;
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 Глобальная переменная является частью сегмента кода: поэтому компилятор можетопределить ее адрес.
Строка символов размещается а памяти кап глобальная константа.
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
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;
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 Иногда формальные параметры называют просто параметрами процедуры или функции.
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 ) ;
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.
Этот оператор описывается следующим синтаксисом:
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 может быть представлен одним значениемили набором значений, перечисленных через запятую. Каждое значение из спи-ска значений может быть числом, объявленной константой или другим выраже-нием, чей тип совместим с типом условного выражения. Дополнительно требу-ется, чтобы компилятор мог определить указываемое выражение без выполне-ния программы.
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, могут соответственно присутствовать в списке значений.
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;
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;
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размещаются блоки обработки ошибок.
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 является необязательным и позволяет определить оператор,который будет выполняться в том случае, если для возникшего исключения не
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
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. Это следующиеклассы:ЕАЬогс - исключение, при котором не отображается сообщение об ошибке;
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-автоматизацию;
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) - исключение происходит при неудачной попыткеприложения открыть файл;
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;Округляет значение параметра до первого наименьшего целого.
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.
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, в значение в десятичном представлении.
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 может содержать следующие символы:
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.
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-огрэннченной строкой.
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.
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);
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. Значение даты при этом не изменяется.
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;
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.
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;
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.
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, функция
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.
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 без учета регистра.
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-кодов.Например, 'АВ» будет меньше, чем 'аа'.
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);Устанавливает длину строки.
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 с удаленными завершающими пробеламии управляющими символами.
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;Возвращает адрес указанного объекта. Вызов этой функции эквивалентенприменению оператора @.
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 может определять различные типы диалогов, содержащиеследующие изображения:
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;Отображение диалога в указанной позиции экрана и с используемым файломсправки, отличным от заданного по умолчанию.
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:';
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); {Читаем из файла первую строку}
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 — диск А;
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 - режим использования открытого файла.
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.
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.
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
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 и пере-ходит на начало следующей итерации.
ГЛАВА 4
ОБЪЕКТЫ И КОМПОНЕНТЫ
В этой главе дается краткий обзор компонентов, входящих в VCL-библ истеку.
ОСНОВНЫЕ понятияОбъекты
Объект Delphi представляет собой набор свойств и методов, включающих такжеобработчики событий. Свойства, называемые иногда атрибутами, являются дан-ными, содержащимися в объекте. Методы описывают действия, реализованныедля данного объекта.
Вес объекты имеют общего предка - класс TObject.Объект — это экземпляр класса. Например, форма реализуется классом TForm.При создании формы:
1. Создается класс TForm 1, производимый отТгогт.
2. Объявляется переменная объектною типа (объект) Forml. При объявлениипеременной происходит создание объекта (выделение памяти).Все компоненты, как визуальные, так и невизуальные, добавляемые в формуво время проектировании, становятся дочерними для формы. Для них автома-тически объявляются переменные соответствующего объектного типа.
КомпонентыКомпонент Delphi - это особый вид объектов - визуальный объект (визуальныйдля проектирования, а не для отображения пользователю). Создавать и редактиро-вать такой объект можно как программным путем, так и на этапе проектирования.Компоненты при выполнении программы могут быть визуальными или невизу-альными. Последние не могут быть непосредственно отображены во время вы-полнения программы (например, компонент TDalabase).Все компоненты имеют общего предка - класс TCoinponent.Delphi предоставляет широкий набор компонентов, называемый иногдаVCL-библиотекой. Все компоненты Delphi могут быть доступны через палитрукомпонентов.
Элементы управленияЧасть компонентов является элементами управления. В основном это элементыуправления Windows. Доступ к элементам управления возможен не только наэтапе проектирования, но и во время выполнения приложения.
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.
Объекты и компоненты 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 по умолчанию сразу отображаются в палитрекомпонентов. При необходимости палитру компонентов можно расширить.
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
Обьекты и компоненты 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.
Пиктограмма
2В
BitBtn
Класс
TBitBtnОписание действия
Создает кнопку, на которой можно отобра-жать растровые изображения
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(линия разбиения) между двумя рядом рас-положенными и выравненными элементамиуправления. Это позволяет пользователямизменять во время выполнения размеры зтихэлементов управления с помощью переме-щения мышью линии разбиения
Объекты и компоненты 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
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, выполнив на встав-ленном компоненте двойной щелчок мышью
Объекты и компоненты 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-клипа, представляющего собой последо-вательность изображений [без звука)
Отображает окно списка, позволяющеевыбрать дату или время
Отображает помесячный календарь
Создает обьект, позволяющий отображать мно-жество объектов на основе их иерархии как не-которое свертываемое и развертываемое дерево
Предоставляет возможность отображать спи-сок данных в различных видах и по столбцам
Создает обьект, который отображает один илинесколько заголовков столбцов. Текст заголов-ков может быть выравнен влево, вправо или поцентру. Каждый заголовок может быть опреде-лен как некоторая командная кнопнз, при щелч-ке на которой выполняется указанная функция
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-обмене
Обьекты и компоненты 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-документ
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в текущей записи
Создает обьент группа радиокнопок для ото-бражения или установки значений столбца
Объекты и компоненты 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
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 данные,получаемые от компонента, в базу данных
Объекты и компоненты 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-базе данных без возвращения резуль-тирующего набора
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к удаленной
Позволяет выполнить хранимую процедурубез возврата результирующего набора
Объекты и компоненты 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 без использо-вания внешнего провайдера и клиентскогорезультирующего набора
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
Объекты и компоненты 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
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-анализатору
Объекты и компоненты 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-приложения
120 Глава 4
Пиктограмма
» - *<я»>
iвейяВкГЯ'т
1у
i&
Класс
TApplicationAdapter
TEndUserAdapter
TEndUserSessionAdapter
TPageDispatcher
TAdapterDispstcher
TLocateFileService
TSessionsService
TWebUserList
TXSLPageProducer
Описание действия
Содержит компоненты поля и компонентыдействия, которые могут быть доступнычерез переменные серверного скрипта.По умолчанию первоначально объектTAppticationAdapter содержит единственноеполе Title. Для отображения значения этогополя можно использовать следующий син-таксис:<%= App!ication.Title%>
Предоставляет информацию о пользовате-ле: имя пользователя, права доступаи подключен ли данный пользователь
Предоставляет информацию о пользовате-ле: имя пользователя, права доступа и ста-тус подключения
Разбирает HTTP-запрос и передает егоWEB-шдулю в соответствии с указаннымURL
Компонент, автоматически добавляемый поумолчанию для всех WehSnap-приложений
Позволяет в режиме выполнения контроли-ровать нахождение файлов шаблонови include-файлое
Позволяет в течение необходимого периодавремени сохранять в памяти информациюо пользователях
Содержит список имен пользователей,паролей и прав доступа
Формирует содержание WEB-страницы, вы-полняя преобразования ХМЬданных на ос-нове XSL-шаблона
Объекты и компоненты 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 палитры компонентов.
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
Обьекты и компоненты 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, и поддерживает еефункционирование. Этот компонент позво-ляет выполнять ввод данных в ячейки, вводи вычисление формул, перемещение и ко-пирование данных с помощью мыши
Создает трехмерную диаграмму
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. Текстможет располагаться как на несколькихстроках, так и на нескольких страницах
Обьекты и компоненты 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)данных
Позволяет объединять вместе несколькоотчетов
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-библиотеки.
Библиотека компонентов 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
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;Указывает количество компонентов, принадлежащих данному компоненту.Используется для последовательного доступа ко всем компонентам (напри-мер, формы).
В книге приведено описание только наиболее значимых свойств и методов рассматри-ваемы* компонентов. Если класс, в котором объявляются свойство или метод, нерассматривается, то эти свойство и метод могут быть описаны при рассмотрениипроизводного класса.
Библиотека компонентов 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 - это базовый класс всех визуальных компонентов - элементов управ-ления (включая и окно формы). Эти компоненты могут быть видимы во времявыполнения. Для них определены такие свойства, как позиция, курсор, всплы-вающая подсказка; методы для рисования йили перемещения элемента управле-ния, события для манипуляций с помощью мыши.
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 минус высота строки заголовка и линейкипрокрутки.
Библиотека компонентов 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 не было установлено непосредственно
Полностью заполняет свою клиентскую область
Может получать и реагировать на двойные щелчки мышью. Если этотфлажок не установлен, то двойной щелчок воспринимается как обыч-ный щелчок мышью
Ширина не может быть изменена
Высота не может быть изменена
Является невидимым во время проектирования
Не реагирует на стандартные сообщения от мыши, от клавиш и от щелч-ков. Это значительно увеличивает скорость выполнения приложения
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
Текущий цвет строки заголовка
Текущий цвет строки заголовка
активного окна
неактивного окна
Текущий фоновый цвет меню
Библиотека компонентов 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];.
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)
Библиотека компонентов 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;Определяет вид указателя мыши при перемещении мышью элемента управления.
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-координату верхнего левого угла элемента управления относи-тельно его родительского элемента.
Библиотека компонентов 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.
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. Для указания собственныхдействий в производном классе следует переопределить этот метод.
Библиотека компонентов 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;Преобразовывает экранные координаты точки в координаты, указываемыеотносительно клиентской области.
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 для одно-временной перерисовки и нижерасположенных элементов управления.
Библиотека компонентов 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.
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;
Библиотека компонентов 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.
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. Перерисовка оконныхэлементов управления выполняется значительно медленнее, чем для графиче-ских элементов управления.
Библиотека компонентов 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.Автоматически при создании приложения главной формой устанавливаетсяпервая созданная на этапе проектирования форма.
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-секции всех пере-численных в проекте модулей.
Библиотека компонентов 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
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.
Библиотека компонентов 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 для формы,на которую устанавливается фокус. Также изменить активную форму можно,
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}
Библиотека компонентов 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-окиа.
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;
Библиотека компонентов 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-окном;
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, добавленным в форму.
Библиотека компонентов 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 - форма появляется в той позиции и такого размера, как это былоопределено в режиме проектирования;
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);
Библиотека компонентов 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 кон-текста справки для любого пункта меню.
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;
• выполнения на нем двойного щелчка мышью и ввода в открытое далее окнозаголовков всех пунктов линейки меню и пунктов ниспадающих меню;
• определения кода обработчиков событий для каждого пункта меню.
Библиотека компонентов 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
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. Вызвать редактор объекта действие, выполнив на нем двойной щелчокмышью.
Библиотека компонентов 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 - происходит разрыв меню, данный пункт меню отображается в но-вом столбце, столбцы отделены друг от друга только визуально и без разгра-ничительной линии.
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.
Библиотека компонентов 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.
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, устанавливается поведение как группы
Библиотека компонентов 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 }
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;Позволяет выбрать заголовкам подменю клавиши-акселераторы таким обра-зом, чтобы они не дублировали друг друга.
Библиотека компонентов 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;
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.
Библиотека компонентов 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 командные кнопки и радиокнопки иногда называются просто
кнопками.
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
Библиотека компонентов 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 Свойства или методы, описываемые в разделах наследуемых свойств или методови ранее рассмотренные в своем классе, приводятся кратно и только для напоминания.Все соответствующие ссылки можно найти ло предметному указателю.
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-файла), отображаемое на кнопке.В одном файле может содержаться или одно изображение, или четыре после-довательно расположенных по горизонтали изображения одинакового разме-ра. В последнем случае на кнопке в зависимости от ее состояния будет ото-бражаться одно из четырех отображений. Состояния кнопки приведеныв следующей таблице.
Библиотека компонентов 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).
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 могут быть объединены в группы.
Библиотека компонентов 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не устанавливается.
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;Определяет, может ли флажок отображать состояние «частичное включение»,которое отображается галочкой на сером фоне.
Библиотека компонентов 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;Заголовок флажка.
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.Обычно радиокнопки объединяют в группы. Радиокнопки — это взаимоисклю-чающие опции: в каждой группе одновременно может быть выделена толькоодна радиокнопка.
Библиотека компонентов 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.
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 - однострочное поле редактирования;
Библиотека компонентов 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.
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.
Библиотека компонентов 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.
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.
Библиотека компонентов 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 как лидирующие пробелы, а иначе - как завершающие пробелы
Все символы, следующиеются в прописные буквы
за символом > и до символа < , преобразовыаа-
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 сов-падают.
Библиотека компонентов 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
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.
Библиотека компонентов 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 }
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.
Библиотека компонентов 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
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.
Библиотека компонентов 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, вы-делять щелчком мыши последовательный диапазон элементов списка. А так-
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.
Библиотека компонентов 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
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);и может принимать следующие значения:
Библиотека компонентов 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;Определяет, будут ли элементы списка отсортированы в алфавитном порядке.Если список сортируемый, то добавляемые элементы будут также вставлять-ся соответственно отсортированному порядку.
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;Определяет состояние каждого флажка списка.
Библиотека компонентов 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.
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. Добавленный элемент сразу отображается в окне де-рева объектов.
Библиотека компонентов 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;Содержит выделенный фрагмент текста в поле редактирования ниспадающе-го списка.
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).
Библиотека компонентов 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 соответственно.
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.
Библиотека компонентов 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
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
Библиотека компонентов 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;Определяет размер отступа для расположения первой кнопки панели инст-рументов.
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;
Библиотека компонентов 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.
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 содержит список всех дочерних панелей компонента ТСооШаг.
Библиотека компонентов 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.
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;
Библиотека компонентов 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.
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.
Библиотека компонентов 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;
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
Библиотека компонентов 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;
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);
Библиотека компонентов 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
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;
Библиотека компонентов 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;.
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-библиотека содержит ряд предопределенных обработчиков событий, кото-рые должны вызываться при перемещении фокуса ввода, редактировании значе-ния объекта, создании или активизации объекта, изменении его размеров.
Библиотека компонентов 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 !
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;
В этом случае при возникновении такого события для приложения будет вызва-на созданная процедура.
"
'
ГЛАВА 6
СОЗДАНИЕ ПРИЛОЖЕНИЙВ СРЕДЕ DELPHI
В этой главе подробно рассмотрен порядок действий разработчика для созданияконкретных приложений и для реализации наиболее общих элементов интер-фейса пользователя.
ПЕРВЫЕ ШАГИ
Управление свойствами визуальныхкомпонентов
Начинать разработку нового приложения всегда следует с создания нового проек-та. Затем в него можно добавлять уже готовые модули или создавать новые.
;i| Первыми шагами при разработке любого нового приложения на базе окна' >' формы должны быть:
1. Создание нового проекта. Для этого можно выполнить команду менюFile |New[ Application.
2. Сохранение проекта в отдельном каталоге. При этом сохраняется как файлпроекта и файл модуля (Unii l) , так и для вспомогательных файлов.
Первоначально создаваемый проект состоит из одной формы. На эту формуможно помещать различные компоненты из палитры компонентов.Настраивать свойства компонентов можно как в инспекторе объектов, таки программным способом.Рассмотрим пример простого приложения, состоящего из одной формы Forml.Расположим на форме несколько компонентов, определив их свойства, как опи-сано в следующей таблице.
Типкомпонента
TLabel
TListBox
ЗначениесвойстваName
Label!
ListBoxl
Свойства,устанавливаемыев инспекторе объектов
Caption(изменение цвета формы)
items [красный, желтый;синий, белый). Hint,ShowHint
Свойство,устанавливаемоепрограммно
Программируемыйобработчиксобытий
ListBoxl Click
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;
Создание приложений в среде 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;
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;
Создание приложений в среде 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;
{Панель инструментов}{Кнопки панели инструментов)
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;
Создание приложений в среде 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 (Именованное действие,
которое будет выполнено при щелчке на кнопке)
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)
Создание приложений в среде 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 и т. д.).
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).
Создание приложений в среде 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-библиотеке и ее объявление в приложениидолжны использовать одинаковый механизм передачи параметров.
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 для любых создаваемых компонентов.
Создание приложений в среде 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
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).
Создание приложений в среде 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 }
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,
Создание приложений в среде 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
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.
ГЛАВА 7
РАБОТА С БАЗАМИ ДАННЫХ
В этой главе рассматриваются компоненты VCL-библистеки, обеспечивающиедоступ к различным источникам данных, и элементы управления, позволяющиеотображать и редактировать информацию из таблиц баз данных.
РЕЛЯиИОННЫЕ БАЗЫ ДАННЫХ
Основные понятияСуществуют различные модели баз данных. Наибольшее распространение полу-чила реляционная модель '. Она лежит в основе таких БД (СУБД), как Paradox,FoxPro, Access. InterBase. Oracle, и многих других.Реляционная база данных представляет собой совокупность таблиц (отношений),содержащих данные.Основными преимуществами реляционных баз данных являются:
• ссылочная целостность - контроль за изменением, удалением или вводомзависимых данных;
• различные типы индексов - для обеспечения более быстрого доступа и кон-троля вводимых данных;
• первичный и вторичный ключи - для реализации отношений между таблицами;
• связь таблиц один-к-одному - одна запись одной таблицы, называемой роди-тельской или основной, связывается с одной записью другой таблицы, назы-ваемой дочерней;
• связь таблиц одип-ко-многим - одна запись родительской таблицы связыва-ется с несколькими записями дочерней таблицы;
• объединение таблиц - работа с несколькими таблицами как с одной объеди-ненной таблицей;
• отсутствие избыточное/ни данных - использование нормализованногопредставления данных гарантирует, что таблица не будет содержать повто-ряющиеся записи или повторяющиеся части записи.
Отметим, что реляционная СУБД только предоставляет разработчику наборсредств для построения реляционной модели. Проектирование конкретной мо-дели данных, обладающей ссылочной целостностью и отсутствием избыточно-сти, полностью лежит на разработчике.
1 В последнее время быстро развивается объектно-ориентированная модель баз данных,
также поддерживаемая компонентами Delphi.
246 Глава 7
ТаблицыТаблица представляет собой двумерный набор строк, называемых также запися-ми, и столбцов, называемых полями или атрибутами.Поле содержит информацию об одной категории данных и имеет тип и имя.
Индексы и ключиИндексы используются для ускорения доступа к данным, усиления ограничений,а также для упорядочения записей.В различных СУБД могут применяться разные виды индексов.Однако, как бы эти индексы ни назывались, любая реляционная СУБД поддер-живает следующие типы индексов:
• первичный индекс - таблица может иметь только один первичный индекс,значения первичного индекса должны быть уникальны;
• вторичный уникальный индекс - таблица может иметь несколько таких ин-дексов, значения индекса должны быть уникальны. Как правило, вторичныйуникальный индекс используется для упорядочения записей;
• простой вторичный индекс - таблица может иметь несколько таких индек-сов, значения индекса не должны быть уникальны.
Любой индекс может быть как простым, так и составным. Простой индексстроится на основе одного поля, а составной - на основе нескольких полей.Физически любой индекс представляет записи в упорядоченном виде и реализу-ется как таблица ссылок на реальное местоположение записей.Ключи используются для связывания данных. Существуют первичный и вто-ричный (внешний) ключи: первичный ключ родительской таблицы связываетсясо вторичным ключом дочерней таблицы.Отметим, что для большинства СУБД ключ может быть установлен только наиндексированное поле. Поэтому понятия индекса и ключа очень часто путают.Следует помнить, что, говоря о связи таблиц, мы всегда имеем в виду ключ,а говоря об упорядочении записей или их уникальности, - индекс.
Сеансы д а н н ы хДля любого приложения баз данных автоматически создается сеанс данных поумолчанию, именуемый Sessions. Сеанс позволяет управлять соединениямис базой данных. Сеанс BDE управляет соединениями с БД, курсорами, запроса-ми и т, п. Компоненты TSession и TSessionList используются для управления се-ансами BDE.Для каждого сеанса данных создается свой объект типа TSession.Использование в приложении нескольких сеансов необходимо в том случае, если:
• требуется для каждой формы иметь свой сеанс данных;
• к одной базе данных а многопотоковом приложении выполняются парал-лельные запросы.
Работа с базами данных 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-серверами.
При этом для удаленных БД может быть реализована:
* архитектура клиент/сервер - двухзвенная архитектура;
* архитектура клиент/сервер приложений/сервер БД - трехзвенная архитектура;
* многозвенная архитектура.
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.
Работа с базами данных 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,
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. Диалог определения драйвера для доступа к базе данных
Зашита доступа к БЛДоступ к информации, хранимой в базах данных, часто требуется ограничиватьили санкционировать. Для этих целей используются пароли и права доступа.Права доступа могут устанавливаться для действий над таблицами и полями или
Работа с базами данных 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
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;
Работа с базами данных 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 позволяет реализовывать различные механизмы манипулирования дан-ными. Самый простой механизм управления данными может быть реализован последующей схеме.
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 и др.
Работа с базами данных 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;).
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;
Работа с базами данных 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
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;
Работа с базами данных 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 - набор данных находится в процессе открытия.
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;Вставляет в набор данных новую пустую запись и делает ее активной.
Работа с базами данных 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' ; .
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;Определяет ассоциируемый набор данных.
Работа с базами данных 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-опера-тор, выполняемый для создания таблицы, индексов, первичного и вторичногоключей, триггеров, в зависимости от выбранного на левой панели элемента сло-варя данных.
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 и имеющиеся привиле-гии доступа.
Работа с базами данных 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)
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, а затем открыть набор данных, то он будетотсортирован по выбранному индексу.
Работа с базами данных 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
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
Работа с базами данных 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;
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 для синхронизи-руемых наборов данных должны совпадать.
Работа с базами данных 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;
• отменяются ранее установленные границы ранга записей;
• устанавливаются новые начальное и конечное значения для ранга;
• выполняется назначение ранга набору данных.
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;Записывает измененную запись в базу данных.
Работа с базами данных
Для класса ТТаЫе предусмотрены следующие обработчики событий:
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 имя синонима!]
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
Работа с базами данных 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,
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).
Работа с базами данных 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;
Имя подключаемой базы данных.
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.
Работа с базами данных 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,
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;Определяет, является ли созданное соединение с базой данных активным.Если соединение не является активным, то перед использованием базы дан-ных набор данных должен быть открыт.
Работа с базами данных 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-драйверами сторонних производителей).
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;Определяет, установлен ли для соединения базы данных доступ только начтение.
Это свойство должно быть задано до открытия базы данных.
Работа с базами данных 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
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. Для компонента база данных начинается транзакция.
Работа с базами данных 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
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]
Работа с базами данных 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.
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.
Работа с базами данных 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
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.
Работа с базами данных 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 можно с помощью верти-кальной линейки прокрутки. Но для того чтобы иметь возможность добавлятьновые записи, вносить сделанные в таблице изменения в базу данных или уда-
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- выравнивание;
Работа с базами данных 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— массив элементов, отображаемый как комбинированный список приредактировании ячейки столбца;РорирМепи - контекстное меню;
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.
Работа с базами данных 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. Для дан-нога объекта можно устанавливать следующиесвойства:
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.
Работа с базами данных 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 обработчик события
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 ' ;
Работа с базами данных 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.
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.
Работа с базами данных 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';
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 текушейзаписи. При переходе к следующей записи изменения вносятся в базу данных.
Работа с базами данных 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.
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, связанный с тем же источником данных.
Работа с базами данных 305
iFTo.ml
Рис. 7.1 8. Форма с компонентом типа TDBCtrlGrid
ДОПОЛНИТЕЛЬНЫЕ КЛАССЫ,ПРЕДНАЗНАЧЕННЫЕ ЛЛЯ РАБОТЫС ДАННЫМИ
Класс TSessionОбъект типа TSession автоматически создается для каждого Delphi-приложенияработы с базой данных. Этот компонент используется только для многопоточ-ных приложений баз данных: для каждого потока баз данных своя собственнаясессия.
Свойства:
property Active: Boolean;Определяет, открыт ли сеанс данных.
property SessionName: String;Определяет имя сеанса данных, используемое для связи с ним.
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.
Работа с базами данных 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 и подключить соответствующий пакет.
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.
Работа с базами данных 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.
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.
Работа с базами данных 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.
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 позволяет отображать в отчете простые фигуры, такие, какпрямоугольник, линия или круг.
Работа с базами данных 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 позволяет экспортировать содержание отчетав текстовый формат;
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
Работа с базами данных 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 список всех отчетов из открытого проекта от-четов.
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Происходит после того, как приложение вставит новую запись.
Работа с базами данных 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Происходит перед тем, как приложение вставит новую запись.
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Инициируется, если при попытке удаления строки произошла ошибка — былоброшено исключение.
Работа с базами данных 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Инициируется, если при попытке передать изменение или вставку новой записипроисходит ошибка - бросается исключение.
ГЛАВА 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)каталог расположения базы данных и таблицу (в случае для двух таблиц -родительскую таблицу).
Работа с базами данных 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
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). Они могут бытьрасположены на форме или в отдельном модуле данных. Во втором случаеэтот модуль данных может быть использован для нескольких форм.
Работа с базами данных 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-и шаг
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. В этом файлеописаны все объекты и все их свойства. Рассмотрим наиболее важные свойстваи отметим жирным шрифтом и курсивом те из них, которые всегда необходимоустанавливать.
Работа с базами данных 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
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}
Работа с базами данных 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. Выполняемая форма
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.
В данном примере нами на последнем шаге была выбрана опция, определяющаясоздание отдельно модуля формы и модуля данных.
В этом случае в модуль данных будут помещены четыре невизуальных компо-нента: два источника данных и два набора данных.
Работа с базами данных 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;
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
Работа с базами данных 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;
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
Работа с базами данных 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).
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.
Работа с базами данных 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 компонента типа ТТаЫе. Отметим,что если во время проектирования для таблицы установлено свойство
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
Работа с базами данных 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.
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. Выбрать в нем имя поля и перейти в инспектор объекгов для изменениязначения свойств данного столбца.
Работа с базами данных 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 редактируется как комбинированный список
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
Работа с базами данных 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,
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 приведена полученная в результате этих действий форма,
Работа с базами данных 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, выбрав это значение из списка.
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
Работа с базами данных 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:ш_персмсиная тнп_персм(;нной;
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.
Работа с базами данных 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
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.
Работа с блзами данных 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 (предварительно та-кой псевдоним должен быть создан), и таблицы.
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. выбран его из предложенного списка. (В
Работа с базами данных 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. На этом шаге построение доступа к базе данных с использованием трех-звенноП .архитектуры завершено. Остается только добавить в форму эле-менты управления, используемые для отображения значений столбцовтаблицы.
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-файл проекта отчетов. Этотфайл может содержать несколько шаблонов отчетов.
Работа с базами данных 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.
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.
Работа с базами данных 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).Далее созданный проект отчетов можно использовать в приложениях.
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;
Работа с базами данных 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.
ГЛАВА 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.Интерфейс не реализуется самостоятельно, а создается как часть класса.
Разработка распределенных приложении 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.
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;
Разработка распределенных приложений 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 ;
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.
Разработка распределенных приложений 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;
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 редактора библиотеки типов отображен уникальный идентифика-тор, автоматически сформированный для создаваемого компонента.Окно редактора библиотеки типов состоит из двух панелей: иа левой представ-лена структура всех входящих к библиотеку элементов, а на правой отобража-ются параметры текущего выделенного элемента.На этом этапе создан модуль, содержащий определение класса компонента. Да-лее в интерфейс можно добавлять объявление методов.
Разработка распределенных приложений 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.
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 полностью создан.
Разработка распределенных приложений 367
Регистрация компонентаДля того чтобы клиенты СОМ могли находить компоненты, последние должныбыть зарегистрированы Е реестре Windows.
Зарегистрировать созданную DLL-библиотеку с СОМ-компонентом можнов редакторе библиотеки типов, щелкнув мышью на панели инструментов покнопке Register Type Library.
Класс TComObjectКласс TComObject используется для создания СОМ-компонентов. Основное от-личие класса TComObject от класса TInterfacedObject в том, что он поддержива-ет фабрики классов.
Используя этот класс, можно создавать DLL-библиотеку, содержащую компо-нент, и без применения библиотеки типов.
Если при создании СОМ-компонспта опция использования библиотеки типоввключена, то класс компонента будет наследовать классу TTypedComObject.
Если библиотеки типов не используется, то класс компонента будет наследоватьклассу TComObject. При этом добавление методов надо будет реализовыватьвручную.
Создание клиентаВ начале этой главы были рассмотрены различные способы вызова методов ин-терфейса. Применение библиотеки типов при создании клиента значительно уп-рощает реализацию вызова методов интерфейса. Это также дополнительно пре-доставляет посредством всплывающих подсказок окна редактора кода списоквсех доступных методов используемого интерфейса.
".;;! Для того чтобы использовать методы компонента в клиенте, необходимо
выполнить следующую последовательность действий:
1. Подключить модуль <имя npoei;Ta>_TLB с описанием предоставляемыхинтерфейсов. Этот модуль автоматически создается на основании инфор-мации, вводимой в окно редактора библиотеки.
2. Добавить в определение класса переменные типа интерфейса. Эти перемен-ные будут использоваться для вызова методов через ссылку на интерфейс.
?. Создать компонент и запросить его интерфейс через вызов методаQuerylnterface.
Далее можно вызывать методы запрошенного интерфейса.
Запрос интерфейсаПеред тем как выполнить запрос интерфейса, следует в секцию uses модуля до-бавить модуль библиотеки типа <имя СОМ-сервера>_ТХВ.
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);
На этом этапе создание клиента завершается.
Разработка распределенных приложении 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 эта возможность вклю-чена для обратной совместимости).
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',
Разработка распределенных приложений 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
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
Разработка распределенных приложений 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).
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)
Разработка распределенных приложений 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.
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
Разработка распределенных приложений 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.
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;
Разработка распределенных приложений 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. После объявления объекта типа интерфейса и присвоения ему ссылки насервер, объект типа интерфейса можно использовать для вызова методов
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
ГЛАВА 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 палит-ры компонентов (предварительно должен быть подключен соответствующий
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;
Реализация механизмов межсетевого взаимодействия 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
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;
Реализация механизмов межсетевого взаимодействия 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
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-сервере некоторого приложения.
Реализация механизмов межсетевого взаимодействия 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.
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;
Реализация механизмов межсетевого взаимодействия 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-страницы применяются сле-дующие классы:
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, выбравзначение из предлагаемого списка.
Реализация механизмов межсетевого взаимодействия 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 установите значение свойства
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-модуле.
ГЛАВА 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).
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:
Использование серверов автоматизации 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 для создания объекта используется
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палитры компонентов.
Использование серверов автоматизаиии 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 имя файла, в который будет запи-сан документ.
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 - определение диапазона ячеек;
Использование серверов автоматизации 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.
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 ' ;
Использование серверов автоматизации 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);
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 текущей рабочей книги бу-дет создана диаграмма.
ГЛАВА 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).}суре {Объявление формы }
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. Окна сообщений, содержащие кнопки и изображения
Разработка интерфейса 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.
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;
Разработка интерфейса 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-' ]Вводзначения';).
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.
Разработка интерфейса 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.
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.
Разработка интерфейса 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;
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}
(диалог Выбор цвета}
(диалог Выбор цвета)
(контекстное меню}(пункт контекстного меню]
(пункт контекстного меню)
(пункт контекстного меню)
Разработка интерфейса 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);
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);
Разработка интерфейса 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; (Освобождение памяти}
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};
Разработка интерфейса 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ак.
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
Разработка интерфейса 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:
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;.
Разработка интерфейса 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, использующим различныешрифты
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. Расположить в форме компонент, в котором будет отображаться значениетекущего времени, Наиболее удобно использовать для этого компоненты
Разработка интерфейса 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 ' ) ) ;
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 приведен пример формы для сравнения строк.
.
Разработка интерфейса 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];
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. В этом случае надо контролировать совпадение типа полятаблицы с типом введенного значения.
Разработка интерфейса 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;
ПРОСМОТР ГРАФИЧЕСКИХ ФАЙЛОВСоздадим форму, позволяющую просматривать графические файлы различныхформатов.
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
Разработка интерфейса 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);
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
Разработка интерфейса 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
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. Форма для загрузки и отображения графических файлов
Разработка интерфейса 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;
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
Разработка интерфейса 435
Запрос полного имени файла из стандартногодиалога Open
**щ:'\ Для того чтобы определить полное имя файла, следует:
1. Расположить в форме невизуальный компонент типа TOpenDialog со стра-ницы Dialogs палитры компонентов.
2. Запустить стандартный диалог, а котором пользователь должен будет вы-брать имя файла: QperiDialogi.Execute;.
}. Присвоить значение свойства FileName свойству Text или Caption компонен-та, отображающего полный путь для выбранного имени файла. Например:
Edit2.Text:=QpenDialogl.FileName;
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ
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
Предметный указатель 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
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
Предметный указатель 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
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
Предметный указатель 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
ОГЛАВЛЕНИЕ
ГЛАВА 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
Предметный указатель 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
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
Предметный указатель 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
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
Предметный указатель 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
И З Д А Т Е Л Ь С Т В О
«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