Термінова допомога студентам
Дипломи, курсові, реферати, контрольні...

Програмування на Delphi

РефератДопомога в написанніДізнатися вартістьмоєї роботи

Сторінки подій (Events) Селектор компонентів є выпадающий комбінований список і призначений для вибору компонент для перегляду і редагування. Зазвичай, в використанні селектора не потрібно, оскільки виділений компонент з’являється у інспектора об'єктів автоматично. Селектор компонентів відображає ім'я компонента і клас, від якої даний компонент відбувається. Наприклад, кнопка безпосередньо з… Читати ще >

Програмування на Delphi (реферат, курсова, диплом, контрольна)

Цей курс присвячений середовищі розробки Delphi фірми Borland (відому як Inprise), що протягом багато років успішно витримує (і виграє!) жорстку конкуренцію коїться з іншими середовищами програмування. Концепція Delphi1 реалізували наприкінці 1994 року, коли перша версія середовища розробки. У основу цього програмного продукту лягли концепції объектно-ориентированного програмування (ОВП) з урахуванням мови Object Pascal і візуального підходу до побудови додатків. Після виходу Delphi 1 все комп’ютерні видання писали про цю середовищі, як про «вбивці Visual Basic». Поява Delphi 2 (32-разрядной) ознаменувало нову епоху, — з’явився доступом до можливостям програмних інтерфейсів Windows NT і Windows 95, протоколів OLE. Delphi 2 стала засобом розробки повноцінних додатків клиент/сервер. Невдовзі Delphi 3 надала розробникам кошти створення розподілених багаторівневих додатків і повноцінний інструментарій проектування додатків для Internet і intranet. З’явилася повноцінна підтримка COM — моделі об'єктів, що стала наріжним каменем сучасного програмування. Четверта версія Delphi дозволяє цілком інтегрувати ваші розробки з об'єктами COM. Підтримка архітектури CORBA (Common Object Request Broker Architecture) відкриває перед додатками, створеними в Delphi для платформи Wintel (Windows + Intel), світ інших операційними системами (UNIX, OS/2, WMS). Спілкуватися з великими корпоративними СУБД стала просто, як і з старим добрим Paradox. Можете використовувати у своїй роботі будь-які рівні межзадачного взаємодії: від найпростішого лише на рівні сокетов, до зв’язки й з такими перспективними інструментами, як Microsoft Transaction Server. Delphi представляє такі нових властивостей і усовершенствования:

. Нові розширення мови. У Delphi у мову Object Pascal включені динамічні масиви, методи обробки переповнення, установка значення параметрів за умовчанням, і що другое.

. Менеджер Проекту Новий менеджер проекту дозволяє Вам об'єднувати проекти які працюють разом у одину проектну групу. Це дозволяє Вам організувати як роботу взаємозалежних проектів, як-от однозадачные і многозадачные докладання чи DLL, і спільну роботу виконуваних программ.

. Новий провідник Новий провідник містить що їх класи, навігацію по модулями, і браузер коду. Провідник коду робить створення класів простіше, автоматизирую частина з кроків. Запровадьте прототип методу розділ інтерфейсу і вміння виконуваного класу згенерує скелетний код розділ реалізації. Також провідник дозволяє швидко переміщатися через файли модуля, а як і між інтерфейсом і реалізацією. Використання символу Tooltip, дозволяє переглядати інформацію про оголошення будь-якого ідентифікатора, потім використовуючи борузер код, можна можливість перейти до його объявлению.

. Що Закріплюються вікна інструментів. IDE (Інтегрована Середовище азработки) містить понад перенастраеваемую конфігурацію вікон інструментів, які можна закріплювати з редактором коду. Просто перетягнете і відпустіть вікно інструмента до місця, якого хочете. Провідник коду і менеджер проекту можна як закріплювати, і незакреплять.

. Поліпшена налагодження. Інтегрований отладчик має багато нових властивостей, включаючи найвіддаленіші і многопроцессорную налагодження, перегляд коду центрального процесора, інспекторів, удосконалені точки переривання, отладчик специфічних підміню і закріплених окон.

. Підтримка MTS. Явна підтримка від використання MTS інтегрована на підтримку багаторівневих баз даних. З іншого боку, новий майстер облегчит.

Вам створення об'єктів серверу MTS.

. Удосконалення ActiveX.

. Delphi забезпечує розширену підтримку ActiveX.

. Удосконалення VCL. Ієрархія об'єктів Delphi быда розширено, аби включити новий компонент для NT Service додатків. З іншого боку, новий компонент виконуваного списку (на Стандартної сторінці палітри), дозволяє Вам централізувати управління меню і команд від кнопок.

Управління VCL розширене, щоб поддерживають drag-and-drop перетягування, забезпечувати додатковий контроль над розміщенням вікна, і що другое.

. Підтримка RTL для 2000;го года.

. Глобальна змінна TwoDigitYearCenturWwindow використовується функциями.

StrtToDate і StrToTateTime, щоб керувати інтерпретацією років із двома цифрами при перетворення дат.

. Підтримка CORBA. Версії Клинт/Сервер і підприємство включають підтримку для CORBA клієнт і сервер додатків. Майстра допоможуть Вам легко створити сервер CORBA і Динамічний Інтерфейс Виклику (DII), позволяя.

Вам записувати клієнтів для існуючих серверів CORBA. CORBA має можливість підтримки у много-уровневых баз даних. Можете навіть створити сервер, який обробляє COM клієнтів — і CORBA клієнтів одночасно. Delphi — це комбінація кількох найважливіших технологий:

. Високопродуктивну компілятор в машинний код.

. Объектно-ориентированная модель компонент.

. Візуальне (отже, і швидкісний) побудова додатків з програмних прототипов.

. Масштабируемые кошти на побудови баз даних Компілятор, вмонтований в Delphi, забезпечує високу продуктивність, необхідну побудови додатків у архітектурі «клієнт-сервер». Він пропонує легкість розробки та швидке час перевірки готового програмного блоку, властивого мов четвертого покоління (4GL) й у той час забезпечує якість коду, властивого компілятора 3GL. З іншого боку, Delphi забезпечує швидку розробку без необхідності писати вставки на Сі чи ручного написання коду (це можливо). У процесі побудови докладання розробник вибирає з палітри компонент готові компоненти митець, робить великі мазки пензлем. Ще компіляції він бачить результати своєї роботи — після підключення до джерела даних їх можна побачити відображеними на формі, можна переміщатися по даним, представляти в тому чи іншому вигляді. У цьому сенсі проектування в Delphi мало чому відрізняється від проектування в интерпретирующей середовищі, однак після виконання компіляції ми маємо код, який виконується 10−20 раз швидше, ніж таке саме, зроблене з допомогою інтерпретатора. З іншого боку, компілятор компілятору ворожнеча, в Delphi компіляція виробляється у рідний машинний код, тоді як існують компілятори, здатні перетворювати програму так званий p-код, і потім інтерпретується віртуальної p-машиной. Не може зашкодити фактичному быстродействии готового докладання. Объектно-ориентированная модель програмних компонент. Основний упор цієї моделі у Delphi робиться на максимальному реиспользовании коду. Це дозволяє розробникам будувати докладання дуже швидко з заздалегідь підготовлених об'єктів, і навіть дає можливість створювати свої власні об'єкти для середовища Delphi. Ніяких обмежень за типам об'єктів, які можуть опинитися створювати розробники, немає. Справді, всі у Delphi написано нею ж, тому розробники мають доступом до тим самим об'єктах та інструментах, що були для створення середовища розробки. Через війну немає різниці між об'єктами, що поставляються Borland чи третіми фірмами, і об'єктами, які ви можете створити. У стандартну поставку Delphi входять основні об'єкти, що утворюють вдало підібрану ієрархію базових класів. Але якщо виникне потреба у рішенні якийсь специфічної проблеми на Delphi, радимо, як спробувати починати вирішувати проблему «від початку», переглянути список розповсюдження чи комерційних компонент, розроблених третіми фірмами, розмір цих компонент нині становить кілька тисяч. Подієва модель в Windows завжди була складна розуміння і налагодження. Але саме розробка інтерфейсу в Delphi є найпростішої завданням для програміста. Об'єкти БД в Delphi засновані на SQL і містять у собі повну потужність Borland Database Engine. До складу Delphi також включений Borland SQL Link, тому доступом до СУБД Oracle, Sybase, Informix і InterBase приміром із високої ефективністю. З іншого боку, Delphi включає у собі локальний сервер Interbase у тому, щоб було розробити расширяемые на будь-які зовнішні SQL-сервера докладання в офлайновом режимі. азработчик серед Delphi, проектирующий інформаційну систему для локальної машини (до прикладу, невелику систему обліку медичних карток на одне комп’ютера), може використовуватиме зберігання інформації файли формату .dbf (як і dBase чи Clipper) чи .db (Paradox). Якщо ж вона використовуватиме локальний InterBase for Windows (це локальний SQL-сервер, входить у поставку), його додаток без жодних змін працюватиме й у складі великої системи з архітектурою клієнт-сервер. Ось воно — масштабованість практично — один і той ж додаток можна використовувати як локального, так серйознішого клиент-серверного вариантов.

1. Основи объектно-ориентированного програмування Поняття класу. Класом в Delphi називається особливий тип, що мати у собі поля, методи лікування й властивості. Такий тип також називають об'єктним типом.

type.

tMyClass=class (tObject).

fMyFiled: integer;

function MyMethod: integer;

end; Поля класу аналогічні полях записи. Це — дані, унікальні у програмі кожному за створеного програмі примірника класу. Описаний вище клас tMyClass має одне полі - fMyFiled. На відміну від полів, методи двох примірників одного класу загальні. Методи — це процедури і функції, описані всередині класу, і призначені для операцій її полями. У склад класу входить покажчик на спеціальну таблицю — таблицю віртуальних методів (VMT), у якій міститься всю інформацію, необхідна для виклику методів. Від звичайних процедур та зняття функцій методи вирізняються тим, що з виклик у яких передається покажчик на примірник класу, що їх викликав. Тому оброблятися будуть поля саме тієї об'єкта, що викликало метод. Усередині методів покажчик на що викликав їх об'єкт доступний через зарезервоване слово Self. Властивістю класу називається сукупність поля і методів чтения/записи, які забезпечують доступом до цьому полю. У цьому саме полі декларується як private (доступні лише всередині даного класу), і доступу до нього можлива лише у вигляді відповідних методів. Докладніше властивості обговорюватимуться нижче. Поняття об'єкта Щоб використовувати новим типом у програмі, потрібно, принаймні, визначити зміну цього. Змінна об'єктного типу називається примірником типу чи объектом:

var aMyObject: tMyClass; До запровадження поняття «клас» у мові Pascal існувала двозначність визначення «об'єкт», яку міг означати і тип, і зміну цього типу. Тепер існує чітка кордон: клас — це опис, об'єкт — то, створене відповідно до цим описом. Створення і знищення об'єктів На відміну від З++ і Turbo Pascal в Delphi об'єкти може лише динамічними… Це означає, що у наведеному вище прикладі змінна aMyObject насправді є покажчиком, що містить адресу об'єкта. Об'єкт створюється конструктором і знищується деструктором.

aMyObject := tMyClass. Create;

// дії створеному объектом.

aMyObject.Destroy; Слід звернути увагу, що створення об'єкта aMyObject викликається метод класу tMyClass.Create. Конструктор класу (й інших методів) успішно працює до створення об'єкта. Проте оскільки більшість звичайних методів (зокрема все віртуальні і динамічні методи). Викликати до ініціалізації об'єкта годі було. У Delphi конструкторів у класу може бути кілька. Загальноприйнято називати конструктор Create, на відміну Turbo Pascal, де конструктори називалися Init, і З++, у якому ім'я конструктора збігаються з ім'ям класу. Типове назва деструктора — Destroy.

type.

tMyClass=class (tObject).

fMyFiled: integer;

Constructor Create;

Destructor Destroy;

function MyMethod: integer;

end; Для знищення об'єкта в Delphi рекомендується використовувати не деструктор, а метод Free, котрий спочатку перевіряє покажчик, і лише для того викликає деструктор Destroy:

procedure tObject. Free; Передадуть управління тілу конструктора відбувається власне створення об'єкта: під нього відводиться пам’ять, значення всіх полів обнуляются. Далі виконується код конструктора, написаний програмістом для ініціалізації об'єктів даного класу. Отже, як і раніше, що синтаксис конструктора схожий із викликом процедури (відсутня яке значення), насправді конструктор — це функція, повертає створений і проинициализированный об'єкт. Примітка. Конструктор створює новий об'єкт в тому разі, якщо перед іменем Тараса Шевченка зазначено ім'я класу. Якщо вказати ім'я вже не існуючого об'єкта, він поведеться інакше: не створить новий об'єкт, лише виконає код, який міститься у тілі конструктора. Щоб правильно проинициализировать у створюваному об'єкті поля, що стосуються до класу — предку, треба навіть за вході у конструктор викликати конструктор предка з допомогою зарезервованого слова inherited:

constructor tMyClass. Create;

Begin.

inherited Create;

// Код ініціалізації tMyClass.

End; Зазвичай, в коді програм, написаних на Delphi, практично зв зустрічається викликів конструкторів і деструкторів. Річ у тім, що кожен компонент, потрапив при візуальному проектуванні в додаток з палітри компонентів, входить у певну ієрархію. Ця ієрархія замикається на формі (клас tForm): всім її складових частин конструктори і деструкторы викликаються автоматично, незримо для програміста. Хто створює і знищує форми? Це додаток (об'єкт безпосередньо з ім'ям Application). У файлі проекту (з розширенням DPR) ви можете побачити виклики методу Application. CreateForm, покликаного забезпечити цього. Що ж до об'єктів, створюваних динамічно (під час виконання програми), то тут потрібен явний виклик конструктори і методу Free. Властивості Як відомо, існує три основних принципу, складових суть объектноорієнтованого програмування: інкапсуляція, запозичення ро-сійських та поліморфізм. Класичне правило объектно-ориентированного програмування стверджує, що з забезпечення надійності небажаний прямий доступом до полях об'єкта: читання і журналістам зміну їх вмісту має здійснюватися у вигляді виклику відповідних методів. Це називається инкапсуляцией (приховування даних). У старих реалізаціях ОВП (наприклад, у Turbo Pascal) ця думка впроваджувалася лише за допомогою закликів прикладів в документації; в Delphi є відповідна конструкція. Користувач об'єкта в Delphi можна повністю відгороджений від полів об'єкта з допомогою властивостей. Зазвичай властивість визначається трьома елементами: полем і двома методами здійснюють його чтение/запись:

type.

tMyClass=class (tObject).

function GetaProperty: tSomeType;

procedure SetaProperty (Value: tSomeType);

property aProperty: tSomeType read GetaProperty.

write SetaProperty;

end; У цьому прикладі доступом до значенням властивості aProperty здійснюється через виклики методів GetaProperty і SetaProperty, однак у зверненні до цих методам вочевидь не потрібно: досить написать.

aMyObject.aProperty:=aValue;

aVarable:= aMyObject. aProperty; і Delphi откомпилирует ці оператори в виклики відповідних методів. Те є зовні властивість виглядає у точності як звичайне полі, але за всяким зверненням щодо нього можуть стояти виклики необхідних програмісту методів. Наприклад, є об'єкт, являє собою квадрат на екрані, та її властивості «колір» присвоюється значення «білий», відбудеться негайна промальовування, яка веде реальний колір на екрані у відповідність значенням властивості. У методах, які визначають значення властивості, може здійснюватися перевірка значення потрапити у заданий діапазон значень і виклик інших процедур залежать від внесених змін. Якщо ж потреби у спеціальних процедурах чтения/записи немає, можна замість імен методів застосовувати імена полей.

tPropClass=class.

fValue: tSomeType;

procedure SetValue (aValue: tSomeType);

property Value: tSomeType read fValue write SetValue;

End; У цьому вся прикладі полі fValue модифікується з допомогою методу SetValue, а читається безпосередньо. Якщо властивість має лише читатися або тільки записуватися, у його описі можуть бути лише відповідний метод:

tReadOnlyClass=class.

property NotChanged: tSomeType read GetNotChanged;

End; У цьому вся прикладі властивість доступні лише для читання. Спроба привласнити значення властивості NotChanged викликає помилку компіляції. Властивостями можна присвоювати значення за умовчанням. І тому служить ключовим словом default:

Property Visible: boolean read fVisible write SetVisible default TRUE; Це означає, що з запуску програми властивість буде встановлено компілятором в TRUE. Властивість може бути векторным. І тут виглядає як массив:

Property Points[index:integer]: tPoint read GetPoint write SetPoint; Для векторного властивості необхідно описати як тип елементів масиву, але й тип індексу. Після ключових слів read і write повинні імена відповідних методів. Використання тут полів масивів неприпустимо. Метод, читає значення векторного властивості, може бути описаний як функція, повертає значення тієї самої типу, як і елементи властивості, і має єдиний параметр тієї самої типу, і з тим самим ім'ям, як і індекс свойства:

function GetPoint (index:integer):tPoint; Аналогічно, метод, що друкує значення таке властивість, повинен першим параметром мати індекс, а другим — зміну потрібного типа.

procedure SetPoint (index:integer; Value: tPoint); У векторних властивостей є ще одне важливе особливість: деякі класи в Delphi (списки tList, набори рядків tStrings тощо.) «побудовано» навколо одного основного векторного властивості. Основний метод такого класу дає доступом до елементам деякого масиву, проте основні методи є як б допоміжними. Для спрощення роботи з об'єктами такого класу можна описати подібне властивість з ключовим словом default:

type tMyList=class.

property list[Index:integer]: string read Getlist write Setlist; default;

end; Якщо в об'єкта є таке властивість, може бути говорити, а ставити індекс в квадратних дужках відразу після імені объекта:

var MyList: tMyList.

Begin.

MyList.list[1]: ='First'; {Перший способ}.

MyList. 2]: ='Second'; {Перший способ}.

End; Застосовуючи ключовим словом default необхідно дотримуватися обережності, т.к. для звичних і векторних властивостей воно вживається у різних значеннях. Про роль властивостей в Delphi промовисто свідчить те що, в усіх наявних у розпорядженні програміста стандартних класів 100% полів недоступні і замінені які базуються ними властивостями. Такого ж правила слід дотримуватися і розробки власних класів. Успадкування Другим «стовпом» ОВП є успадкування. Цей простий принцип означає, що й необхідно створити новий колектив, лише трохи відрізняється від вже наявного, не потрібно в переписуванні наново вже не існуючого коду. Ви повідомляєте, новий класс.

tNewClass=class (tOldClass); нащадок чи дочірнім класом класу tOldClass, званого предком чи батьківським класом, і додаєте щодо нього нові поля методи лікування й властивості. У Delphi все класи є класу tObject. Тому, коли ви будуєте дочірній клас прямо від tObject, то визначенні може бути не згадувати. Наступні два описи однаково верны:

tMyClass=class (tObject);

tMyClass=class; Докладніше клас tObject розглядатимуть нижче. Успадковані від класса-предка поля та фізичні методи доступні в дочірньому класі; коли має місце збіг імен методів, кажуть, що вони перекриваються. Розглянемо поведінка методів при успадкування. З того, що насамперед відбуваються при виклик, методи діляться втричі групи. До першої віднесемо статичні методи, на другу — віртуальні (virtual) і динамічні (dynamic) і, нарешті, по-третє - що з’явилися лише у Delphi 4 перегружаемые (overload) методи. Статичні методи, і навіть будь-які поля була в классах-потомках поводяться однаково: можна без обмежень перекривати старі імена і навіть змінювати тип методів. Код нового статичного методу повністю перекриває (заміняє собою) код старого метода:

type.

tFirstClass=class.

fData:Extended;

procedure SetData (aValue:Extended);

end;

tSecondClass=class (tFirstClass).

fData:Integer;

procedure SetData (aValue:Integer);

end;

procedure tFirstClass. SetData (aValue:Extended);

Begin.

fData:=1.0;

End;

procedure tFirstClass. SetData (aValue:Extended);

Begin.

fData:=1;

inherited SetData (0.99);

End; У цьому вся прикладі різні методи безпосередньо з ім'ям SetData привласнюють значення різним полях безпосередньо з ім'ям fData. Перекрите (однойменне) полі предка недоступно в нащадку. Тому два однойменних половіючі жита із ім'ям fData наведено лише прикладу. На відміну від поля, другими методів перекритий метод доступний при вказуванні ключового слова inherited. За умовчанням методи об'єктів класів статичні - їх адресу визначається на етапі компіляції проекту, тому вони викликаються найшвидше. Принципово від статичних віртуальні і динамічні методи. Вони повинні бути оголошено шляхом додавання відповідної директиви dynamic чи virtual. З погляду наслідування методи цих двох категорій однакові: є підстави перекриті в дочірньому класі лише однойменними методоми, мають хоча б тип. Поліморфізм. Віртуальні і динамічні методи Розглянемо наступний приклад. Нехай є якесь узагальнену полі для зберігання даних — клас tFiled і його нащадка — для зберігання рядків, цілих і речовинних чисел:

type.

tFiled = class.

function GetData: string; virtual; abctract;

end;

tStringFiled = class (tFiled).

fData:string;

function GetData: string; override;

end;

tIntegerFiled = class (tFiled).

fData:Integer;

function GetData: string; override;

end;

tExtendedFiled = class (tFiled).

fData:Extended;

function GetData: string; override;

end;

function tStringFiled. GetData: string;

Begin.

Result:=fData;

End;

function tIntegerFiled. GetData: string;

Begin.

Result:=IntToStr (fData);

End;

function tExtendedFiled. GetData: string;

Begin.

Result:=FloatToStr (fData, ffFixed, 7, 2);

End;

function ShowData (aFiled:tFiled): string;

Begin.

Form1.Label1.Caption:=aFiled.GetData;

End; У цьому вся прикладі класи містять різнотипні поля даних fData, і навіть мають успадкований від tFiled віртуальний метод GetData, возвращающий дані в вигляді рядки. Зовнішня стосовно ним процедура ShowData отримує об'єкт як параметра і цю рядок. Відповідно до правил контролю відповідності типів (typecasting) ObjectPascal, об'єкту, як покажчику на примірник класу, то, можливо присвоєно адресу примірника кожного з дочірніх типів. Це означає, що у попередньому прикладі в процедуру ShowData можна передавати об'єкти класів tStringFiled, tIntegerFiled, tExtendedFiled й іншого нащадка tFiled. Але якою (точніше, чий) метод GetData буде цьому викликаний? Той, який відповідає класу фактично переданого об'єкта. Цей принцип називається полиморфизмом. Повертаючись до розглянутому вище прикладу, відзначимо, що з компілятора немає можливості визначити клас об'єкта, фактично переданого в процедуру ShowData на етапі компіляції. Механізм, дозволяє визначити цей клас просто під час виконання називається пізнім зв’язуванням. Природно, що механізм може бути пов’язані з переданих об'єктом. І тому служить таблиця віртуальних методів (Virtual Method Table, VMT) і таблиця динамічних методів (Dynamic Method Table, DMT). Різниця між віртуальними і динамічними методами залежить від особливості пошуку адреси. Коли компілятор зустрічає звернення до віртуальному методу, він підставляє замість прямого виклику у конкретній адресою код, який звертається до VMT і дістає звідти потрібний адресу. Така таблиця є кожному за класу. У ньому зберігаються адреси всіх віртуальних методів класу, незалежно від цього, успадковані вони від предка чи перекриті у цьому класі. Звідси й чесноти та вади віртуальних методів: вони викликаються порівняно швидко, проте до зберігання покажчиків ними в таблиці VMT потрібно дуже багато пам’яті. Динамічні методи викликаються повільніше, але дозволяють ощадливіше витрачати пам’ять. Кожному динамічному методу системою присвоюється унікальний індекс. У таблиці динамічних методів класу зберігаються індекси лише з тих методів лише про тих динамічних методів, описаних в даному класі. При виклик динамічного методу відбувається пошук у цій таблиці. Що стосується невдачі проглядаються DMT всіх классов-предков в порядку їх ієрархії, і, нарешті, tObject, де є стандартний оброблювач виклику динамічних методів. Економія пам’яті очевидна. Для перекриття і заснування віртуальних і динамічних методів служить директива override, з допомогою якої (і тільки з ній!) можна перевизначати обидва цих типу методов.

type.

tParentClass=class.

fFirstFiled:Integer;

fSecondFiled:longInt;

procedure StaticMethod;

procedure VirtualMethod1; virtual;

procedure VirtualMethod2; virtual;

procedure DynamicMethod1; dynamic;

procedure DynamicMethod2; dynamic;

end;

tChildClass=class (tParentClass).

procedure StaticMethod;

procedure VirtualMethod1; override;

procedure DynamicMethod1; override;

end; Перший метод класу tChildClass створюється наново, два інших перекриваються. Створимо об'єкти цих классов:

var Obj1: tParentClass;

Obj2: tChildClass; Внутрішня структура цих об'єктів показано нижче. [pic] Перше полі кожного примірника кожного об'єкта містить покажчик з його клас. Клас, як структура і двох частин. Починаючи з адреси, на який посилається покажчик класом, розташовується таблиця віртуальних методів. Вона має адреси всіх віртуальних методів класу, зокрема й успадковані від предків. Перед таблицею віртуальних методів розташована спеціальна структура, що містить додаткову інформацію. У ньому містяться дані, повністю що характеризують клас: ім'я, розмір примірників, покажчики на класс-предок тощо. Один із полів структури містить адресу таблиці динамічних методів класу (DMT). Таблиця має наступний формат: на початку — слово, що містить кількість елементів таблиці. Потім — слова, відповідні індексам методів. Нумерація індексів починається з -1 і відбувається у напрямку убування. Після індексів йдуть власне адреси динамічних методів. Слід звернути увагу, що DMT об'єкта Obj1 і двох елементів, Obj2 — вже з, відповідного перекрытому методу DynamicMethod1. Що стосується виклику Obj2. DynamicMethod2 індекс нічого очікувати знайдений за DMT Obj2, і буде звернення до DMT Obj1. Саме такими економиться пам’ять під час використання динамічних методів. Як зазначалося вище, покажчик класом свідчить про перший віртуальний метод. Службові дані розміщуються перед таблицею віртуальних методів, то є з негативним зміщенням. Ці усунення описані у модулі SYSTEM. PAS:

vmtSelfPtr = -76.

vmtIntfTable = -72.

vmtAutoTable = -68.

vmtInitTable = -64.

vmtTypeInfo = -60.

vmtFiledTable = -56.

vmtMethodTable = -52.

vmtDynamicTable = -48.

vmtClassName = -44.

vmtInstanceSize = -40.

vmtParent = -36.

vmtSafeCallException = -32.

vmtAfterConstruction = -28.

vmtBeforeDestruction = -24.

vmtDispatch = -20.

vmtDefaultHandler = -16.

vmtNewInstance = -12.

vmtFreeInstance = -8.

vmtDestroy = -4 Поля vmtDynamicTable, vmtDispatch і vmtDefaultHandler визначають виклик динамічних методів. Поля vmtNewInstance, vmtFreeInstance і vmtDestroy містять адреси методів створення і знищення примірників класу. Поля vmtIntfTable, vmtAutoTable, vmtSafeCallException запроваджені задля забезпечення сумісності з моделлю об'єкта COM. Інші поля доступні через методи об'єкта tObject. У Object Pascal цю інформацію відіграє і може використовуватися програмістом неявно. У мові визначено два оператора — is і as, неявно які звертаються до неї. Оператор is призначений для перевірки сумісності з привласнення примірника об'єкта з заданим класом. Вислів вида:

AnObject is tObjectType Приймає значення True лише коли об'єкт AnObject сумісний з привласнення з класом tObjectType, тобто є цього або його нащадком. Оператор as введений у правове мову спеціально доведення об'єктних типів. З його допомогою так можна трактувати примірник об'єкта як що належить до іншому совместимому типу:

with AObjectOfSomeType as tAnotherType do. .. Від стандартного способу приведення типів використання оператора as відрізняється наявністю перевірки на сумісність типів під час виконання: спроба приведення до несовместимому типу призводить до виникнення виняткової ситуації eInvalidCast. По виконанні оператора as сам об'єкт залишається незмінною, але виконуються його методи, які відповідають присваиваемому класу. Уся інформація, яка описувала клас, створюється й міститься у пам’яті на етапі компіляції. Доступ до інформації поза методів цього можна отримати, описавши відповідний покажчик, який називається покажчиком на клас, або покажчиком на об'єктний тип (class reference). Він описується при допомоги зарезервованих слів class of. Наприклад, покажчик класом tObject описаний в модулі SYSTEM. PAS і називається tClass. Аналогічні покажчики визначено й й інших найважливіших класів: tComponentClass, tControlClass тощо. З покажчиком класом тісно пов’язані поняття методів класу. Такі методи можна викликати й без створення примірника об'єкта — із зазначенням імені класу де вони описані. Перед описом методу класу потрібно поставити ключовим словом class. Зрозуміло, методи класу що неспроможні використовувати значення, які у полях класу: адже примірника класу немає!!! Методи класу служать для вилучення внутрішньої інформації класу. Нижче перераховані методи класу tObject: Метод і Описание.

сlass function ClassName: ShortString.

Возвращает ім'я класса.

сlass function ClassNameIs (const Name: ShortString):Boolean.

Принимает значення True, якщо ім'я класу одно заданному.

сlass function ClassParent: tClass.

Возвращает покажчик на батьківський класс.

сlass function ClassInfo: pointer.

Возвращает покажчик на структуру з додатковими даними про опублікованих методах і свойствах.

сlass function InstanceSize: Longint.

Возвращает розмір примірника класса.

сlass function InheritsFrom (aClass: tClass):Boolean.

Возвращает True, якщо це клас успадковує від заданного.

сlass function MethodAddress (const Name: ShortString):Pointer.

Возвращает адресу методу з його імені (лише опублікованих методов).

сlass function MethodName (Addres: pointer):ShortString.

Возвращает ім'я методу з його адресою (лише опублікованих методів) У Delphi 4 до класу tObject додано решта 2 віртуальних методу — AfterConstruction і BeforeDestruction. Відповідно до назви, вони викликаються відразу після створення примірника об'єкту і безпосередньо перед знищенням. Перевантаження методів У Delphi 4 з’явилася нова різновид методів — перегружаемые. Перевантаження потрібна у тому, щоб зробити однакові чи схожі дії над різнотипними даними. Перегружаемые методи описуються з ключовим словом overload.

Type.

tFirstClass=class.

E:extended;

procedure SetData (aValue: Extended); overload;

end;

tSecondClass=class (tFirstClass).

I:integer;

procedure SetData (aValue: Integer); overload;

end; Оголосивши метод SetData перегружаемым, у програмі можна використовувати обидві його реалізації одночасно. Це можна оскільки компілятор визначає тип переданого параметра (цілий чи речовинний) і залежно від рівня цього підставить виклик відповідного методу. Для перевантаження віртуального методу використовується зарезервоване слово reintroduce:

procedure SetData (aValue:string); reintrouce;overload; На перевантаження методів накладається обмеження: не можна перевантажувати методи, перебувають у області видимості published. Абстрактні методи Абстрактними називаються методи, визначених у п’ятому класі, але з містять ніяких дій, будь-коли викликаються і запитають обов’язково би мало бути перевизначені в классах-потомках. Абстрактними може лише віртуальні і динамічні методи. Для описи абстрактного методу використовується директива abstract:

Procedure NeverCallMe; virtual; abstract; Ніякого коду абстрактний метод зовсім позбавлений. Його виклик призведе до створення виняткової ситуації eAbstractError. Події Операційна система Windows® полягає в повідомленнях. Повідомлення ці творяться у результаті дій користувача, апаратури комп’ютера чи інших програм. Таких повідомлень в Windows сотні, і з великим рахунком, написати програму для Windows — отже визначити реакцію певні з них. Працювати з такою кількістю повідомлень, навіть маючи б під руками довідник, нелегко. Тож з головних переваг Delphi і те, що програміст повністю позбавлений необхідності працювати з повідомленнями Windows (хоча таку можливість в нього є). Типових подій у Delphi — трохи більше двох десятків, й вони мають просту інтерпретацію, яка потребує глибоких знань середовища. З погляду мови, подія — це полі процедурного типу, призначене до створення користувальницької реакцію ті чи інші вхідні воздействия:

Property OnMyEvent: tMyEvent read FMyEvent write FMyEvent; Тут OnMyEvent — полі об'єкта, що містить адресу деякого методу. Присвоїти такому властивості значення — отже вказати програмі адресу методу, який викликати у початок події. Такі методи називаються обработчиками подій. Усередині бібліотеки часу виконання Delphi виклики оброблювачів подій перебувають всередині методів, обробних повідомлення Windows. Виконавши необхідне, його перевіряє, відомий чи адресу оброблювача, і, якщо це, викликає його. Події мають різну кількість і тип параметрів, залежно від походження та призначення. Спільним всім події є параметр Sender — вказує на об'єкт, що викликав подія. Найпростіше подія — tNotifyEvent — немає інших параметров.

tNotifyEvent = procedure (Sender:tObject) of object; Тип методу, готовий до повідомлення про натисканні клавіші, передбачає передачу в процедуру коду цієї клавіші, про пересуванні миші - її поточних координат тощо. Ім'я події у Delphi починається з префікса On: OnClick, OnCreate, OnMouseDown тощо. Імена методів — оброблювачів подій складаються з імені об'єкта, генеруючого подія, і кореня імені події: OkButtonClick. Двічі клацнувши мишею в інспектора об'єктів сторінка Events на полі навпаки будь-якого події, ви отримаєте скелетний код (заготівлю) цього події. Оскільки події - це властивості об'єкта, їх значення можна змінювати у будь-якій момент під час виконання програми. Ця можливість називається делегуванням. Можна будь-якої миті взяти способи реакцію події у одного об'єкту і привласнити (делегувати) їх іншому. Принцип делегування дозволяє уникнути трудомісткого процесу породження нових класів кожному за специфічного випадку, замінюючи ндо простий підстановкою процедур. Один і хоча б оброблювач може обробляти події від різних об'єктів. Типовий приклад — у сприйнятті сучасних програмах один і той ж дію можна викликати кількома способами — через головне меню, контекстне меню тощо. буд. Цього легко домогтися, призначивши і той ж оброблювач всім необхідними об'єктах в інспектора об'єктів. азумеется, події мали бути зацікавленими один і тієї самої типу. Складніший випадок — коли всередині оброблювача необхідно визначити, що саме об'єкт викликав подія. Якщо об'єкти, котрі потенційно можуть це, мають різний тип, те ж саме їх тип можна застосувати в ролі критерия:

If Sender is tMenuItem then … Якщо усе об'єкти, те що розмежовує між собою один оброблювач події, ставляться одного класу, можна використовувати властивість tObject.Tag. Нижче наведені назви деяких, найбільш уживаних подій Delphi:

Событие — Тип оброблювача — Коли стається OnClick — TNotifyEvent — При натисканні лівої клавіші миші OnActivate — TnotifyEvent — Після передачі об'єкту фокусу OnCreate — TnotifyEvent — Після створення об'єкта OnDestroy — TnotifyEvent — Перед знищенням об'єкта OnDeactivate — TnotifyEvent — Перед відходом фокусу з об'єкта OnKeyPress — TkeyPressEvent — При натисканні клавіші OnMouseDown — TmouseEvent — При натисканні клавіші миші OnMouseMove — TmouseMoveEvent — При русі миші над об'єктом OnMouseUp — TmouseEvent — При відпусканні клавіші миші і навіть їх типы:

Тип Описание.

TnotifyEvent.

type TnotifyEvent = procedure (Sender: TObject) of object;

TkeyPressEvent.

type TkeyPressEvent = procedure (Sender: TObject; var Key: Char) of object;

TmouseEvent.

TmouseEvent = procedure (Sender: TObject; Button: TmouseButton; Shift: TShiftState; X, Y: Integer) of object;

TmouseMoveEvent.

TmouseMoveEvent = procedure (Sender: TObject; Shift: TShiftState; X, Y: Integer) of object; Стандартні події описані у модулі Classes. Динамічні масиви У Delphi існують динамічні масиви, тобто масиви, довжину яких можна змінювати під час виконання програми. аньше проблема динамічних масивів стояла досить гостро. Стандартних коштів на роботи із нею не було, і програмістам доводилося вручну створювати подібні структури (як правило, з урахуванням динамічних змінних). Тепер компілятор Delphi сам виконує всю «брудну» роботу. Паралельно зі динамічними, в Delphi збереглися та звичайні, статичні масиви. Довжина динамічних масивів визначається вже під час виконання програми. Описав зміну как.

var A1: array of real, ми не матимемо покажчик, відповідний масиву речовинних чисел. Пам’ять під нього виділяється процедурою SetLength:

procedure SetLength (var A; NewLength: Integer); Тут A — покажчик на динамічний масив, NewLength — довжина масиву. У динамічних масивах нумерація індексів починається тільки з нуля. Те, що динамічні масиви фактично є покажчиками, призводить до певних нюансам у використанні. Перший із них стосується присвоєння масивів. Запись.

Var A1, A2:array[0.4] of real;

A1:=A2; Що стосується зі статичними масивами, означає, що всім елементам масиву A1 присвоюються значення відповідних елементів масиву A2, та заодно, перемінні A1и A2 — різні перемінні, які у різних галузях памяти.

В випадку з динамічними масивами присвоєння їх одне одному — лише присвоєння покажчиків. ассмотрим пример:

Var A1, A2:array of real;

.. .

SetLength (A1,5);

A1[0]: =0.0;

A2:=A1;

A2[0]:=2.0; Значення A2[0] також зміниться і став одно 2. Це тому, що після присвоєння покажчики посилаються однією і хоча б адресу у пам’яті і зміни у одному масиві приведуть до синхронним змін у іншому. А, аби вона дійсно скопіювати елементи в A2, необхідно використовувати функцію Copy:

function Copy (A; Index, Count: Integer): string; Тут, А — покажчик на копируемый масив, Index — індекс першого копируемого елемента, Count — число копируемых елементів. A2:=Copy (A1,0,Length (A1)); Звільнити виділену під масив пам’ять можна з допомогою процедури finalize: procedure Finalize (var A [; Count: Integer]); тут V — покажчик на динамічний масив, Count — кількість масивів (в разі, коли кілька людей динамічно створюваних структур розміщуються поспіль щодо одного безупинному блоці пам’яті, їх можна звільнити одним викликом Finalize); чи навіть присвоївши покажчику на масив значення nil. У цьому вся разі пам’ять нічого очікувати втрачені (як могла б здавалося б), а буде викликана відповідна процедура, коректно вона звільняла пам’ять. Причому, пам’ять звільнитися тільки тоді ми, коли її у не не посилається жодна динамічно створена структура. Значення граничних індексів (як статичних і динамічних) можна отримати з допомогою функцій Low (A) — нижній граничний індекс і Hight (A) — верхній граничний індекс. Кількість елементів масиву — функцією Length: function Length (A): Integer; Подальшим розвитком ідеї динамічних масивів є багатовимірні динамічні массивы.

Var AA: array of arrray of real;

SetLength (AA, 10,5);

AA[9,4]: =1;

AA[9][4]:=1; Можна піти ще, і створити динамічні масиви з перемінної довжиною з різних індексам. До сформування такого масиву спочатку потрібно поставити його розмірність за першим индексу:

SetLength (AA, 10); Це означає, що масив складатиметься з десяти рядків. Тепер довжина кожного рядка задається отдельно:

SetLength (AA[0], 5);

SetLength (AA[1], 6);

SetLength (AA[2], 3);

SetLength (AA[3], 8);

... У використанні багатомірних динамічних масивів є одне обмеження: передавати в процедури як параметри не можна. Перегружаемые функції Перевантаження функцій нічим не відрізняється від перевантаження методів. Основна ідея перевантаження функцій і методів у тому, що у програми мати два чи болеефункции з іменами та різними наборами параметрів. Перегружаемые функції, як і методи описуються з ключовим словом overload. Например:

function OverloadDemo (val: Byte): string; overload;

function OverloadDemo (val: Char): string; overload; Такий їхній підхід робить ваш код простішим, його легше супроводжувати і розширювати. Перевантаження потрібна у тому, щоб зробити однакові чи схожі дії над різнотипними даними. При виклик перевантаженої функції компілятор визначає тип фактично переданого параметра (у наведеному вище прикладі - Byte чи Char) й у залежність від цього підставить виклик відповідного варіанта функції. Параметри функцій за умовчанням Параметри функцій за умовчанням прийшли о Delphi з З++. Часто при виклик процедур і державних функцій них треба передати параметри, зазвичай мають один і той ж значення. Це має місце у частковості у наукових розрахунках. Нині ця проблема спрощується шляхом введення параметрів за умовчанням. Це означає, аж в оголошенні функції можна вказати, що ті чи інші параметри враховували певні значення, якщо де вони задано явно. Нарпример, можна описати функцию.

function Test (x:extended; Rz: extended = 6371):extended; За її виклик другий параметр можна вказати явно:

Test (100,6372); А можна й не указывать:

Test (100); У першому випадку параметр Rz матиме значення 6372, тоді як у другому — по вмовчанням — 6371. Параметри за умовчанням мають бути наприкінці списку параметрів. Допускається помовчати останній, останній і передостанній, тощо. параметри У цьому полягає на відміну від З++ - там можна опускати будь-які з параметрів за умовчанням. При застосуванні параметрів за умовчанням слід дотримуватись обережність. ассмотрим наступний пример:

Procedure Confused (I:integer); overload;

Procedure Confused (I:integer; J: integer = 0); overload;

.. .

Confused (x); Компілятор зможе визначити, яку саме реалізацію Confused слід викликати, і видасть повідомлення про помилку. 2. Прийоми роботи у середовищі розробки Репозиторий Репозиторий (Repository) є сховище різнорідних об'єктів, об'єднаних спільною призначенням. Основна Мети створення репозитория — надання розробникові можливості використання вже готових і отлаженных частин програми. Тут можна знайти готове стандартне додаток, динамічну бібліотеку, форму, модуль, майстра діалогів і додатків, і навіть різні допоміжні програми. Репозиторий в Delphi є текстовий файл, у якому данны про всіх об'єктах храняться у спеціальній форматі. Відкрити репозиторий можна з допомогою команди New меню File головного вікна Delphi. Розглянемо деякі об'єкти, що входять до репозиторий. Основу будь-який розробки в Delphi становить проект, який би найрізноманітніші структурні елементи у єдиний додаток. До нього найчастіше входять модулі і форми різних видів. Типи додатків представлені виконуваними програмами, динамічними бібліотеками і додатками для запуску служб. Особливе останнє місце посідають докладання до роботи з базами даних (БД), тому значної частини об'єктів репозитория варта конструювання таких програм. Задля більшої віддаленого доступу до даних призначені стандартні заготівлі для додатків, використовують використовувала різні механізми взаємодії, зокрема технології CORBA і Microsoft Transaction Server (MTS). Склад об'єктів репозитория можна оновлювати, теж можна створювати, перейменовувати сторінки змінювати склад об'єктів їм. едактирование репозитория ввозяться діалоговому вікні Object Repository яке з’являється під час виборів команди Repository меню Tools головного вікна Delphi, або за виборі команди Properties спливаючого меню репозитория. Додати нової форми в репозиторий можна командою Add to repository спливаючого меню форми, чи перетягуванням форми в панель репозитория. Проект і велика група проектів Будь-яка робота у Delphi починається зі створення нового проекту. Зазвичай, з одного проекту виходить одне додаток. Отже, проект є фундамент чи каркас, який «кріпляться» все потрібні деталі. Найменший проект є лише одне файл з розширенням DPR, вона називається головним файлом проекту. Серйозний великий проект містить десятки різноманітний форм, файлів і модулів. У головному файлі міститься опис всіх модулів і форм, які входять у проект. З іншого боку, в секції begin … end може розташовуватися будь-який код, який повинен виконуватися до початку роботи докладання чи процесі її закриття. Модулем називається текстовий файл з розширенням PAS, де міститься певний вихідний код мовою Object Pascal. З модулем вочевидь пов’язана форма, що є окреме вікно програми з розташованими у ньому интерфейсными елементами. Службовий інформацію про формах зберігається в файлах з розширенням DFM. У випадку, у складі проекту можуть входити модулі, які мають що з ними форм. У репозитории міститься кілька заготовок для форм (сторінка Forms), а також існують деякі стандартні діалоги, що з погляду користувальницького інтерфейсу є модальними формами (сторінка Dialogs). У проекті Delphi крім модулів і форм можуть бути присутні різні службові файли. У тому числі важливе останнє місце посідають ресурси (розширення RES), які зберігають значки, курсоры, рядки повідомлень інформацію версію програми розвитку й т.д. Репозиторий пропонує вплинув на вибір кілька типів проектів: наприклад проекти з многодокументным (MDI) і однодокументным (SDI) інтерфейсом. При необхідність створення динамічної бібліотеки теж можна скористатися відповідної заготівлею з репозитория. Крім проекту на Delphi пристствует й важливіша структурна одиниця — група проектів, яка, з назви, об'єднує для спільної розробки кілька проектів. Файл групи проектів имет розширення BPG і є текстовий файл з системної інформацією і описом проектів, які входять у групу. Фундаментальна обізнаність із групою проектів практично нічим не відрізняється від співпраці з окремим проектом, необхідно тільки стежити за приналежністю окремих форм і модулів і овремя переключатися на потрібний проект в Диспетчері проектів. При компіляції групи також потрібен вибрати потрібний проект з списку на панелі інструментів Delphi чи Диспетчери проектів. Диспетчер проекту призначений керувати складовими частинами проекту чи групи проектів. Серед опитаної можна додати чи видалити окремий проект, у проекті - додати чи видалити окремий модуль. Управління проектом здійснюється кнопками на панелі інструментів диспетчера проекту або команди спливаючого меню. Викликається диспетчер командою Project Manager меню View головного вікна Delphi. Створення нової групи проектів здійснюється також за допомоги диспетчера проекту. Можливість об'єднання груп чи включення груп у інші групи відсутня. У цілому нині, параметри проекту доступні в діалоговому вікні, що відкривається під час виборів команди Project Options меню Project головного вікна Delphi. Палітра компонентів Основна палітра компонентів Delphi має дванадцять сторінок. Standard. Більшість компонентів в цій сторінці є аналогами екранних елементів самої Windows. Меню, кнопки, смуги прокручування — тут є всі. Але компоненти Delphi мають також деякими зручними додатковими умонтованими можливостям. Additional. Ця сторінка містить понад розвинені компоненти. Наприклад, компонент Outline зручний відображення інформації з ієрархічної структуройДанная сторінка також має компоненти, головне призначення яких — відображення графічної інформації. Компонент Image завантажує і відображає растрові зображення, а компонент Shape дозволяє малювати графічні примітиви — окружності, квадрати, і т.д. System. Сторінка System містить неотображаемые системні компоненти: Timer, MediaPlayer, компоненти, реалізують механізм DDE. Сторінка System також має компоненти, обробні обмін високого рівня між програмами у вигляді OLE (Object Linking and Embedding). Win32. Ця сторінка містить компоненти, дозволяють створеним з допомогою Delphi програмам вживати такі нововведення в користувальному інтерфейсі 32-разрядной Windows, як перегляд деревоподібних структур, перегляд списків, панель стану, розширений текстовий редактор та інших. Dialogs. Windows 3.1 запровадила у її слововжиток стандартні діалогові вікна для операцій над файлами, вибору шрифтів, кольорів та т.д. Проте задля використання у звичайній програмі Windows може знадобитися написати чимало допоміжного коду. Сторінка Dialogs надає програмам Delphi простий доступом до цим стандартним діалоговим вікнам. Data Access і Data Controls. Delphi використовує механізм баз даних компанії Borland (Borland Database Engine, BDE) в організацію доступу до файлам баз даних різних форматів. Компоненти цих двох сторінок полегшують програмам Delphi використання сервісу баз даних, наданого BDE, наприклад многопользовательского зчитування, записи, індексації й видачі запитів для таблиць dBASE і Paradox. З використанням цих компонентів створення програми перегляду і редагування бази даних майже вимагає програмування. Win 3.1. І на цій сторінці перебувають компоненти Delphi 1.0, можливості яких перекриваються аналогічними компонентами Windows 95. Internet. Ця сторінка надає компоненти і розробити додатків, дозволяють створювати HTML-файлы безпосередньо з файлів баз даних, і інших типів, котрі взаємодіють із іншими додатками для Internet. Delphi 4 дає можливість створювати докладання для Web-сервера як DLLфайлів: (Dynamic Link Library — Динамічно компонуемая бібліотека), здатних утримувати невізуальні компоненти. З допомогою компонентів сторінки Internet досить просто створювати оброблювачі подій для звернення до певному URL (Uniform Resource Locator — Уніфікований локатор ресурсу), уявленню документів мають у HTML-формате і пересилки їх клієнтпрограмі. Samples. Ця сторінка містить компоненти, які вмонтовані в Delphi, але демонструють міць системи компонентів. Для цих компонентів немає вбудованої інтерактивною довідки. І все-таки де вони менше корисні, ніж компоненти з інших сторінок. ActiveX. Ця сторінка містить компоненти ActiveX, розроблені незалежними виробниками програмного забезпечення: сітка, діаграма, засіб перевірки правопису. QReport. Ця сторінка надає компоненти баз даних. Тут містяться особливі версії написів, полів, приміток та інших елементів управління. Midas і Decision Cube. Тут зібрані компоненти для доступу до віддаленим серверам і здійснення SQL — запитів. Розміщення компонентів Розміщувати компоненти на формі досить легко. Потрібно лише клацнути на потрібної вкладке палітри компонентів, потім на кнопці з піктограмою відповідного компонента і після цього клацнути з вікна форми. Якщо клацнути на компоненті, та був намалювати прямокутник з допомогою миші на формі — компонент з’явиться всередині цього прямокутника. Якщо розміри компонента піддаються зміни, у разі на формі він заповнить собою прямокутник. Якщо ви хоч забули, який сторінці розташований конкретний компонент, виберіть пункт Component List з меню View, й з’явиться список компонентів в алфавітному порядку. Якщо клацнути на компоненті в палітрі компонентів, його кнопка виявиться натиснутій. Якщо клацнути іншою компоненті, перша кнопка повернеться вихідне стан: лише одне компонент то, можливо обраний у кожний час. Щоб все кнопки опинилися у вихідному стані, і це відновлено нормальне використання миші, слід клацнути на кнопці зі стрілкою вибору, з’являється з лівого боку кожної сторінки палітри. Для розміщення кількох копій компонента під час виборів компонента необхідно натиснути й утримувати клавішу Shift. Якщо двічі клацнути на піктограмі компонента, то компонент автоматично з’явиться у центрі активної форми проекту. При переміщенні і зміну величини компоненти вирівнюються по точкам координатної сітки форми. Зазвичай, це добре — таку можливість допомагає підтримувати лад у формах. Для скасування такої можливості чи зміни щільності точок координатної сітки необхідно выберать пункт Options меню Tools. Перша сторінка параметрів варта настройки користувачем параметрів середовища. І на цій сторінці є група Form designer, прапорці опцій Display grid і Snap to grid якої визначають, видно чи координатна мережа і активна вона. Можна ще змінити значення параметрів Grid Size X (Крок по осі X) і Grid Size Y (Крок по осі Y), що призведе зміну кроку координатної сітки за горизонталлю і вертикалі, відповідно. Мало який компонент видно на формі під час запуску програми. Наприклад, розміщення на формі компонента MainMenu призводить до появи в разрабатываемом додатку меню, але відповідна піктограма під час запуску програми не відображається. Компоненти, які мають діалогові вікна загального призначення, загалом ніяк не визуализируются під час роботи програми. азмеры невидимого компонента у процесі розробки не змінюються: вона завжди відображається як піктограми. Інспектор об'єктів Інспектор об'єктів призначений для установки доступних на етапі проектування властивостей компонентів (тобто властивостей, оголошених як published). Вікно інспектора складається з з трьох основних частей:

. Селектора компонентов.

. Сторінки властивостей (Properties).

. Сторінки подій (Events) Селектор компонентів є выпадающий комбінований список і призначений для вибору компонент для перегляду і редагування. Зазвичай, в використанні селектора не потрібно, оскільки виділений компонент з’являється у інспектора об'єктів автоматично. Селектор компонентів відображає ім'я компонента і клас, від якої даний компонент відбувається. Наприклад, кнопка безпосередньо з ім'ям OkButton звучатимуть як «OkButton: TButton». Сторінка Properties інспектора об'єктів відображає все властивості обраного компонента, доступні стадії проектування. Сторінка розділена на два шпальти. Стовпець Property зліва показує ім'я властивості, стовпець Value справа — значення цієї властивості. Якщо властивість має тип класу, записи, чи безлічі, то зліва його від імені відображається знак +. Двічі клацнувши на імені такого властивості, можна було одержати доступом до окремим його полях. Такого ж ефекту можна досягнути, обравши пункт Expand в контекстном меню інспектора об'єктів. Для закриття розгорнутої списку полів необхідно повторно двічі клацнути на імені властивості, або скористатися пункт Collapse в контекстном меню інспектора об'єктів. В багатьох випадках редактор відображає список можливих значень властивості. Для властивостей, що становлять об'єкти (екземпляри класів VCL) є дві змогу редагування. По-перше, можна, клацнувши на кнопці із кількома крапками (…) в стовпці Value властивості викликати редактор відповідного властивості; або, клацнувши двічі на імені властивості, можна розгорнути список його полів, як описано вище. Коли формі виділено кілька компонентів, інспектор об'єктів покаже їх як загальні властивості. Це дозволяє змінювати властивості кількох компонентів одночасно. Сторінка Events редактора об'єктів містить список подій, що може обробляти даний компонент. До сформування оброблювача події необхідно двічі клацнути на стовпці Value поруч із ім'ям цієї події. У цьому Delphi створить метод, з усіма параметрами, необхідні обробки події. Активізується вікно редактора коду з курсором, розташованим всередині оброблювача події. Ось тільки запровадити код оброблювача! Зазвичай ім'я оброблювача події генерується автоматично, проте, можна вручну поставити необхідну ім'я в стовпці Value навпаки імені події. Після натискання клавіші Enter станеться генерація кістякового коду оброблювача події з заданим ім'ям. Можна сплести подія з роботи вже які є оброблювачем. Для цього використовують выпадающий список, з’являється при натисканні відповідної кнопки в стовпці Value навпаки імені події. До списку включаються лише оброблювачі подій, збіжні на кшталт з цим подією. Редактор коду Основні кошти спрощення процесу створення вихідного коду приложений зібрані в едакторе коду (Code Editor), що з вікна для отображения і редагування коду модулів докладання перетворився на зручне середовищство з численними довідковими і допоміжними можливостями. Шаблони компонентів Шаблони компонентів надають зручний спосіб використання наибільш часто застосовуваних груп компонентів (наприклад, часто потрібно об'єднати пояснювальну напис, полі редагування і кнопку). У цьому зроблені під час створення шаблону настройки властивостей складових його компонентів зберігаються переносяться нові форму разом із цими компонентами. Створення шаблону входять такі кроки: 1. На формі необхідно розмістити необхідні компоненти, вирівняти їх і налаштувати потрібні властивості. 2. Виділити на формі компоненти, що передбачається включити в шаблон, у групу. 3. Вибрати в меню Components Головного вікна середовища розробки команду Create Component Template. 4. У який з’явився діалозі потрібно поставити ім'я нового шаблону і зазначити сторінку Палітри компонентів, де шаблон буде приступний. Натиснути кнопку ОК. Тепер шаблон можна використовувати звичайним способом: після вибору його за сторінці Палітри компонентів й переносу, на формі з’являється поставлене набір компонентів з деякими раніше властивостями. Шаблони коду Шаблони коду призначені для швидкої вставки в вихідні код моду-. лей проекту стандартних (чи часто використовуваних) комбінацій операторів мови Object Pascal. Для виклику шаблону коду використовується комбінація клавіш иш +, після натискання якої з’являється список доступних нині шаблонів. Вибір найменування шаблону з раскрывшегося списку призводить до появлению на зазначеному мишею місці набору операторів, визначених шаблоном. Стандартна постачання Delphi включає кілька типових шаблонів з найбільш поширеними наборами операторів. Опція завершення коду Опція завершення коду застосовується за необхідності залучити до вихідному коді проекту властивості та фізичні методи стандартних компонентів Delphi. Включення механізму завершення коду відбувається після введення символу точки за назвою класу, або об'єкта. едактор коду автоматично розгортає список всіх властивостей і методів компонента. Після вибору потрібного елемента списку та натискання клавіші властивість чи метод дописується в імені класу, або об'єкта. Оскільки багато класи мають. уселительным списком властивостей, доступних програмісту, то, при виборі потрібного елемента із списку можна скористатися наращиваемым пошуком — при введення після точки перших літер властивості чи методу здійснюється автоматичне позиціонування списку перший схожий елемент. Опція включається сторінка Code Insight в діалоговому вікні команди Environment Options меню Tools Головного меню середовища розробки з допомогою прапорця Сні Completion (рис. 2.1). Опція параметрів Опція параметрів здійснює висновок довідкової інформації про кількість і типах параметрів, входять до складу будь-який процедури чи функції, назва якого є в вихідному коді проекту на вікні едактора коду. Довідкові дані з’являються при позиціонуванні курсору на назві процедури чи функції. Опція включається сторінка Code Insight в діалоговому вікні команди Environment Options меню Tools Головного меню середовища розробки з допомогою прапорця Соді Parameters (рис. 2.1). Опція заповнення класу Ця функція автоматично генерує вихідний код для будь-яких складових частин нового класу (властивостей і методів), у яких були оголошені у секції interface, і навіть створює оголошення тим елементів, у яких описані у секції implementation. Щоб створити опис оголошених властивостей і методів, необхідно встановити курсор у будь-яку довільну місце оголошення класу в секції interface й тицьнути на комбінацію клавіш ++. Після цього Delphi, по-перше, створить для оголошених властивостей класу необходимые властивості і силові методи для читання і запис в секції private. Удругих, в секції implementation буде сгенерировано опис необхідних методів. Наприклад, є найпростіший класс:

type.

TSimpleObject = class (TObject).

property Empty: Integer;

function ClearEmpty: Boolean;

end; Тоді, після натискання комбінації клавіш ++, вихідний код в секції interface буде приведено ось до чого виду:

type.

TSimpleObject = class (TObject).

property Empty: Integer read FEmpty write SetEmpty;

function ClearEmpty: Boolean;

private.

FEmpty: Integer;

procedure SetEmpty (const Value: Integer);

end; На секції implementation з’являться такі строки:

function TSimpleObject. ClearEmpty: Boolean;

begin.

end;

procedure TSimpleObject. SetEmpty (const Value: Integer);

begin.

FEmpty := Value;

end; 3. Межпрограммное взаємодія Часто виникла потреба організувати взаємодія програм, написаних різними особами чи навіть різними фірмами. Завдання вирішується в рамках ідеології «клієнт-сервер», коли одна додаток має реагувати на запити інших додатків. Нарешті, з недостатнім розвитком мереж цілком звичайній постало завдання взаємодії докладання різними машинах. Для організації взаємодії між завданнями існує багато інструментів. Деякі їх дозволяють працювати у рамках лише однієї машини, деякі - у межах локальної чи глобальної мережі. Зв’язок між двома програмами можна встановити в такий спосіб, що у одному додатку позначатимуться у другому. Наприклад, коли міняєте число в електронної таблиці, то у другому додатку дані обновляться автоматично і отобразят зміни. З іншого боку, можна зі свого докладання управляти іншими додатками такі як Word for Windows, Excel та інших. Dynamic Data Exchange (DDE) DDE дає можливість перейти через рамки докладання і взаємодіяти з іншими додатками і системами Windows. Dynamic Data Exchange одержало своє ім'я оскільки дозволяє двом додатків обмінюватися даними (текстовими, через глобальну пам’ять) динамічно під час виконання. DDE — давній і який прижився протокол обміну даними, що з’явився на зорі ери Windows. Ніша, зайнята DDE — це оперативна передача і синхронізація даних в додатках. Додатка, використовують DDE, поділяються на дві категорії: клієнти і сервери. Обидва учасника процесу роблять контакти (conversations) по певним тем (topics), причому у рамках теми виробляється обмін елементами даних (items). Встановлює контакт DDE-клиент, який посилає запит, у якому імена контакту і теми. Після встановлення контакту всяке зміна елемента даних на DDE-сервере передається елементу даних клієнта. Одне і то-жі додаток може одночасно бути і сервером, і клієнтом (наприклад, MicroSoft Word). DDE-серверы Для побудови DDE-сервера в Delphi є об'єкта, розташовані на сторінці System Палітри Компонент — TDdeServerConv і TDdeServerItem. Зазвичай у проекті використовується об'єкта TDdeServerConv і тільки чи більше TDdeServerItem. Для отримання доступу до сервісу DDE-сервера, клієнту знадобиться знати кілька параметрів: ім'я сервісу (Service Name) — це ім'я докладання (зазвичай — ім'я виконуваного файла без розширення EXE, можливе з повним шляхом); Topic Name — до назви теми; Item Name — назва елемента даних. Призначення об'єкта TDdeServerConv — загальне управління DDE та обробка запитів від клієнтів виконання макросу. Останнє виконується в обработчике події OnExecuteMacro, наприклад, як це робиться ниже:

procedure TDdeSrvrForm. DoMacro (Sender: TObject;Msg: TStrings);

var.

Text: string;

Begin.

Text := «» ;

if Msg. Count > 0 then Text := Msg. Strings[0];

MessageDlg («Executing Macro — «+ Text, mtInformation, [mbOK], 0);

End; Найважливішим властивістю компонента TDdeServerConv є назва теми, що міститься в властивості Name. Клієнт повинен знати це під час встановлення контакту, крім випадку, що він підключається до даних контакту, скопійованим в буфер обміну. У моменти відкриття і закриття контакту виникають события:

Property OnOpen: tNotifyEvent;

Property OnClose: tNotifyEvent; Об'єкт TDdeServerItem пов’язують із TDdeServerConv у вигляді свойства.

Property ServerConv: tDDEServerConv, яких і визначає, що, власне, буде пересилатися по DDE. У принципі так, потокол DDE передбачає обмін будь-якими даними, формат яких зареєстровано системі передачі через буфер обміну. Проте задля аналізованих компонентів ці можливості так обмежуються лише текстовими даними. І тому у компонента TDdeServerItem є властивості Text і Lines (Text має саме значення, як і Lines[0]).

Property Text: string;

Property Lines: tStrings; При зміні значення цих властивостей автоматично відбувається пересилання оновлених даних в усі приложения-клиенты, котрі встановили зв’язку з сервером. Цей компонент дозволяє також здійснюватиме встановлення зв’язку через буфер обміну (Clipboard). І тому служить метод CopyToClipboard. Необхідна інформації міститься у через буфер обміну і то, можливо викликана з приложения-клиента під час встановлення зв’язку. Зазвичай, в DDE-серверах для цього є спеціальний пункт меню Paste Special чи Paste Link. DDE-клиенты Для побудови DDE-клиента в Delphi використовуються два компонента TDDEClientConv і TDDEClientItem. Аналогічно серверу, у програмі зазвичай використовується об'єкта TDDEClientConv і тільки і більше пов’язаних із нею TDDEClientItem. TDDEClientConv служить задля встановлення зв’язки й з сервером й загальним управлінням DDE-связью. Встановити зв’язку з DDE-сервером можна як під час розробки, і під час виконання програми, причому двома шляхами. Перший спосіб — заповнити вручну необхідні властивості компонента. Це DdeService, DdeTopic і ServiceApplication. Якщо під час розробки двічі клацнути на одному із перших двох властивостей в Інспектора Об'єктів — з’явиться діалог для визначення DDE-связи. Для встановлення через Clipboard у діалозі є спеціальна кнопка Past Link. Їй можна скористатися, коли запустили DDE-сервер, зберегли якимось чином інформацію зв’язок і ввійшли у цей діалог. Наприклад, якщо DDE-сервером є DataBase Desktop, то потрібно завантажити до нього якусь таблицю Paradox, вибрати будь-яке полі, і вибрати пункт меню Edit|Copy. Властивість ServiceApplication заповнюється у цьому разі, тоді як полі DDEService міститься ім'я, не на імені програми, або Якщо ця програма не в поточної директорії. У цьому вся полі вказується повний шлях збереження та ім'я програми без розширення (.EXE). Ця інформація потрібна для автоматичного запуску серверу під час встановлення зв’язку по DDE, що той ще було запущено. Імена серверу DDE і теми зберігають у свойствах:

Property DDEService: string;

Property DDETopic: string; Спосіб входження до контакт визначається свойством.

Property ConnectMode: tDataMode;

Type tDataMode = (DDEAutomatic, DDEManual); Метод.

Function SetLinc (const Service: string; const Topic: string):Boolean;

Присваивает властивостями DDEService і DDETopic відповідні значення, а разі, якщо заданий режим DDEAutomatic, й встановлює контакт. У режимі DDEManual задля встановлення контакту необхідно додатково викликати метод.

Function OpenLink: Boolean;

Этот метод спочатку закриває попередній контакт, потім намагається зв’язатися з сервером DDEService на задану тему DDETopic. Якщо не вдається відразу, робиться спроба завантажити додаток безпосередньо з ім'ям, певним в свойстве:

Property ServiceApplication: string;

Можно зв’язатися з сервером, поместившим дані в буфер обміну з допомогою метода.

Function PasteLink: boolean; Нижче наведено приклад процедури, здійснює зв’язку з сервером.

procedure TMainForm. doNewLink (Sender: TObject);

begin.

DdeClient.SetLink (AppName.Text, TopicNameEdit. Text);

DdeClientItem.DdeConv := DdeClient;

DdeClientItem.DdeItem := ItemName. Text;

end;

procedure TMainForm. doPasteLink (Sender: TObject);

var.

Service, Topic, Item: String;

begin.

if GetPasteLinkInfo (Service, Topic, Item) then begin.

AppName.Text := Service;

TopicName.Text := Topic;

ItemName.Text := Item;

DdeClient.SetLink (Service, Topic);

DdeClientItem.DdeConv := DdeClient;

DdeClientItem.DdeItem := ItemName. Text;

end;

end; Потому, як встановлено зв’язок, слід подбати про вступників по DDE даних, робиться у обработчике події OnChange об'єкта TDdeClietItem:

procedure TFormD. DdeClientItemChange (Sender: TObject);

begin.

DdeDat.Lines := DdeClientItem. Lines;

end; Це був єдиний завдання об'єкта TDdeClientItem. Властивість Property DDEConv: TddeClientConv Цього компонента призначено для зв’язки Польщі з відповідним об'єктом DdeClientConv. А властивість Property DDEItem: string; Повинно утримувати ім'я елемента даних. Свойства.

Property Text: string;

Property Lines: tStrings; Аналогічні відповідним властивостями tDDEServerItem мають дані. На об'єкт TDdeClientConv покладаються ще завдання: пересилання даних на сервер і виконання макросів. І тому цього об'єкта є відповідні методы.

Function ExecuteMacroLines (Cmd:tStrings, WaitFlg: Boolean):Boolean;

Function PokeDataLines (const Item: string, Data: tStrings):Boolean; Обмін повідомленнями Як згадувалося раніше, операційна система Windows® полягає в повідомленнях, що виникають унаслідок дій користувача, апаратури комп’ютера чи інших програм. Поведінка кожного вікна повністю залежить від того, які він приймає повідомлення й як його обробляє. У вона найчастіше, обробка повідомлень в Delphi виконується через події. Проте, бувають ситуації, коли може знадобитися послати і/або обробити повідомлення самостійно. Існують два типу повідомлень, які можуть зажадати обробки обхід звичайній системи повідомлень Delphi:

Повідомлення Windows®, не оброблювані VCL.

Сообщения, зумовлені користувачем У принципі так, повідомлення діляться на дві категории:

Командні сообщения Уведомляющие повідомлення Командні повідомлення використовують як програмістами, протікав і Windows®. Вони управляють елементам операційної системи й прикладним програмам. Уведомляющие повідомлення містять інформацію про зміну стану вікон Windows®, їх окремих елементів і пристроїв системи. Вони посилаються лише самої середовищем вікон Windows®. Кожне повідомлення має дві параметра: WPARAM і LPARAM. У 32-х бітної середовищі обидві ці параметра мають розмір 32 біта (longword). У 16-битной Windows WPARAM — це 16 бітне число (word), а LPARAM — 32-битное (longint). Для відправки повідомлень АПІ Windows® містить дві функции:

function PostMessage (HWND hWnd, // handle of destination window.

UINT Msg, // message to post.

WPARAM wParam, // first message parameter.

LPARAM lParam // second message parameter.

):BOOLEAN;

function SendMessage (HWND hWnd, // handle of destination window.

UINT Msg, // message to send.

WPARAM wParam, // first message parameter.

LPARAM lParam // second message parameter.

): LRESULT; Перша їх відправляє повідомлення чергу повідомлень Windows® і негайно повертає управління. PostMessage повертає TRUE, якщо виклик функції пройшов успішно, й FALSE інакше. Функція SendMessage відрізняється від PostMessage тим, що, відправивши повідомлення, вона поверне управління до того часу, поки повідомлення нічого очікувати доведено до одержувача. Обидві функції мають однакові параметри: HWND — дескриптор вікна, якому призначається повідомлення, UINT — повідомлення, що має бути послано, WPARAM і LPARAM — параметри повідомлення. Наступного прикладі головною формі проекту посилається повідомлення про закриття приложения:

PostMessage (Handle, WM_QUIT, 0,0); На додачу функцій АПІ Windows® VCL містить метод Perform, який можна використовуватиме посилки повідомлень кожному вікна VCL.

function Perform (Msg: Cardinal; WParam, LParam: Longint): Longint; Perform обходить систему передачі повідомлень Windows® і направляє повідомлення безпосередньо механізму обробки даного вікна. З використанням попередній приклад виглядатиме наступним образом:

Perform (WM_QUIT, 0,0); VCL має події приблизно тільки до 20% найчастіше використовуваних повідомлень Windows®. У програміста може виникнути необхідність обробити повідомлення, котрим в VCL події не передбачені. Для обробки повідомлень ОС, які мають відповідних подій у Delphi є ключовим словом message. З його за допомогою конкретний метод в коді програми може бути зв’язаний із кожним повідомленням Windows®. Коли вікно докладання отримує це повідомлення викликається відповідний метод. Задля реалізації обробки повідомлення в таких межах необхідно: 1. Включити оголошення методу в обробці сполучення оголошення класу, вказавши ключовим словом message і назву повідомлення, в обробці якого даний метод редназначен. 2. Включити визначення методу в розділ implementation. Наведемо приклад визначення методу, обробного повідомлення WM_ERASEBKGND:

Procedure WmEraseBkgnd (var Msg: tWMEraseBkgnd); message WM_ERASEBKGND; Ключове слово message зазначає, що це метод використовується для обробки повідомлення ОС, ім'я якого зазначено після цього ключового слова: WM_ERASEBKGND. Слід зазначити, що параметр методу є записом типу tWMEraseBkgnd.

type TWMEraseBkgnd=record.

Msg:Cardinal;

DC:HDC;

Unused:Longint;

Result:Longint;

end; У VCL є записи більшість повідомлень Windows® (їх визначено в модулі Messages. pas). Ім'ям записи є ім'я повідомлення з префіксом t і без підкреслення. Сам метод можна назвати скільки завгодно, але наведена вище форма усталена. У цьому вся методі може виникнути необхідність викликати оброблювач повідомлення, встановлений за умовчанням. І тому необхідно викликати віртуальний метод класу tObject DefaultHandler:

procedure tObject. DefaultHandler (var Message); virtual; Крім нормальних повідомлень Windows®, можна створити свій власний повідомлення. еализация і перехоплення що визначається користувачем повідомлення ідентичні обробці повідомлень Windows®. Єдина відмінність у тому, що це повідомлення потрібно спочатку определить:

Const My_Message = WM_USER + 1; Ця рядок оголошує користувальницьке повідомлення безпосередньо з ім'ям My_Message. Для обробки повідомлень, певних користувачем як типу параметра оброблювача повідомлення варто використовувати запис загального виду tMessage:

type tMessage = record.

Msg:Cardinal;

WParam:Longint;

LParam:Longint;

Result:Longint;

end; Тут, як і всіх інших визначених у VCL для повідомлень записах, полі Msg визначає передане повідомлення, полі Result — результат дії оброблювача. Унікальні для даного запису поля WParam і LParam містять відповідні параметри повідомлення. Для посилки визначених користувачем повідомлень можна використовувати функції SendMessage, PostMessage, проте, краще у разі використовувати Perform. Сокеты Найбільш сучасним і навіть «модним «є спілкування процесів лише на рівні сокетов. Популярність їх обумовлена вибуховим зростанням інтересу як користувачів, і фахівців до Internet і цілому, що пов’язані з цієї мережею. Узвичаєна і стандартизованной міжнародною рівні є семиуровневая модель структури протоколів зв’язку під назвою інтерфейс відкритих систем (Open Systems Interface, OSI). На кожному з рівнів — від першого, фізичного, до вищих рівнів уявлення та додатків — вирішується свій обсяг завдань і використовується свій інструментарій. Сокеты перебувають саме на проміжному, так званому транспортному рівні семиуровневой структури. «Під ним », на мережному рівні, перебуває протокол IP (основа TCP/IP — Transmission Control Protocol/Internet Protocol). Над ним перебувають протоколи сеансового рівня (сервіси), зорієнтовані конкретні завдання — наприклад, FTP (передачі файлів), SMTP (поштовий), усім відомий гіпертекстову протокол HTTP та інші. Використання сокетов, з одного боку, дозволяє абстрагуватися від подробиць роботи з нижніх рівнях, з іншого — вирішувати широке коло завдань, недоступний спеціалізованим протоколів. З погляду своїй суті сокет — це модель одного кінця мережного сполуки, відносини із своїми властивостями і можливість читати і записувати дані. З погляду змісту — це прикладної програмний інтерфейс, вхідний у складі різних операційними системами, зокрема Windows — починаючи з версії 3.11. Остання його реалізація називається WinSock 2.0. Прототипи функцій зберігають у файлі WINSOCK. PAS, який поставляє з Delphi. АПІ сокетов вперше виник середовищі Unix і став популярний разом із (і завдяки) протоколом TCP/IP. Саме є будівельний матеріал, з яких побудована мережу Internet. Але сокеты необов’язково базуються на TCP/IP, можуть базуватися на IPX/SPX та інших протоколах. Механізм сполуки з допомогою сокетов такий. На одному боці створюється клієнтський сокет. Для ініціалізації зв’язку він повинен поставити шлях до серверному сокету, з які мають встановити з'єднання. Шлях у мережі задається двома параметрами: адресою чи рівноцінним йому ім'ям хоста, чи навіть хостом і номером порту. Хост — це система, у якій запущено додаток, що містить сокет. Неправильно прирівнювати поняття «хост «чи «адресу «до поняття «комп'ютер «— у комп’ютера може бути кілька мережевих пристроїв і кілька адрес. Адреса у мережах TCP/IP задається четвіркою чисел буде в діапазоні 0.255, наприклад, так: 192.168.99.1. Природно, кожен адресу навіть у межах Internet унікальний — для цього стежить спеціальна організація. Ім'я хоста, зазвичай, — символьна рядок, поставлена відповідність адресою й записана за правилами UNC, наприклад internet Взаємна відповідність між іменами та адресами може здійснюватися по-різному, залежно від масштабу сіті й застосовуваної ОС. У Internet існує система імен доменів (DNS) — спеціальні сервери, бережуть і підтримують таблиці відповідності між символьним ім'ям і адресою. Але за будь-якого разі з'єднання за адресою швидше, бо взагалі треба поводитися за додаткової інформацією. Що стосується, якщо ваші клиент/серверные докладання отлаживаются в одній і тією ж машині, можна зв’язати сокеты чотирма способами:

. Вказівкою мережного імені вашого комп’ютера (ознайомитися можна через апплет «Мережа «Панелі управления).

. Вказівкою IP — адреси вашого комп’ютера (ознайомитися за властивості протоколу ТСР/IP: машиною має бути цей протокол і матись постійний IP-адрес).

. Вказівкою імені localhost, яке зазначає, що сервер перебуває в тому самому компьютере.

. Вказівкою IP-адреси 127.0.0.1, яке зазначає на те ж саме Номер порту — просте засіб підтримки одночасно кількох перетинів поміж двома хостами. Ця кількість, зазвичай зарезервоване для протоколів вищого рівня. Так, для протоколу FTP виділено порт 21, SMTP — 25, популярна гра Quake II використовує порт 27 910 тощо. п. Програміст повинен ознайомитися з списком вже закріплених портів, колись ніж встановить і який використовує своє значення. В одній із двох йдуть на зв’язок сторін запускається серверний сокет. Спочатку він перебуває у стані просушування (listening), тобто очікування зв’язку. Після набуття запиту одної боку — клієнта — встановлюється зв’язок. Але водночас створюється новий сокет для продовження прослуховування. Природно, у складі Delphi є повноцінна підтримка сокетов. Ще версії 2 з’явився заголовний файл WINSOCK.PAS. Є і зараз — для бажаючих використовувати АПІ WinSock безпосередньо. Ми ж розглянемо тут компоненти TServerSocket і TClientSocket, що у Delphi 4 сторінка Internet Палітри компонентів. Дуже важливим моментом використання сокетов є завдання їх типу — блокуючого (синхронного) і неблокирующего (асинхронного). Фактично, роботу з сокетами — нічим іншим, як операції ввода/вывода, які, як ми знаємо, також може бути синхронними і асинхронними (відкладеними). У першому разі за виклик функції ввода/вывода додаток блокується до його закінчення. У другому — ініціюється ввод/вывод і виконання докладання відразу ж потрапляє триває; закінчення ввода/вывода буде «ознаменоване «в системі виникненням деякого події. У бібліотеці WinSock 2.0 підтримуються обидва типу операцій із сокетами; відповідно, в компонентах Delphi теж можна встановити потрібний тип. Відповідають для неї властивості serverType і clientType, про які розказано нижче. Специфіка компонентів TServerSocket і TClientSocket у цьому. що є «двоповерховими «надбудовами над АПІ сокетов. І в цього й в іншого є свойство:

property Socket: TClientWinSocket; у компонента TClientSocket и.

property Socket: TServerWinSocket; у компонента TServerSocket Це властивість є об'єкт — власне оболонку сокета, зі усіма функціями підтримки встановлення сполуки, читання і запис. азделение праці з-поміж них такое—на рівні TServerSocket (TClientSocket) зосереджені основні опубліковані властивості і, обробку яких можна запрограмувати; лише на рівні TServerWinSocket (TClientWinSocket) слід шукати функції, зокрема читання і запис в сокет. Об'єкт TServerWinSocket На рівні цього об'єкта ведеться список сполук з клієнтськими сокетами, що міститься у свойстве:

property Connections [Index: Integer]: TCustomWinSocket; Загальна кількість сполук (і кількість елементів в властивості connections) одно значенням свойства:

property ActiveConnections: Integer; Цим списком і лічильником зручно користуватися для розсилки всім клієнтам який-небудь широкомовної інформації, например:

for i:=0 to ServerSocket.Socket.ActiveConnections-1 do.

ServerSocket.Socket.Connections[i]. SendText («Hi! »); Тип серверу (блокирующий/неблокирующий) задається свойством.

type TServerType = (stNonBiocking, stThreadBiocking);

property ServerType: TServerType; Оскільки сервер, який блокується кожним чтением/записью, уявити важко, розробники фірми Inprise пішли у такий спосіб. Блокуючий режим замінений режимом stThreadBlocking. І тут під час встановлення кожної нової сполуки запускається окремий програмний поток3 (об'єкт класу TServerclientThread). Він відпо-відає зв’язку з окремим клієнтом, і його блокування впливає працювати інших сполук. Якщо ви хоч не хочете породжувати TServerclientThread, а хочете описати свій клас потоку і використати його до роботи з сокетом, ви повинні створити оброблювач события:

property OnGetThread: TGetThreadEvent;

type TGetThreadEvent = procedure (Sender: TObject;

ClientSocket: TServerClientWinSocket; var SocketThread: TServerCiientThread) of object; На відміну від stThreadBlocking, тип stNonBlocking своєю амбіційною поведінкою нічим не відрізняється від описаного вище — операції відбуваються асинхронно, і програміст має лише описати реакцію на події, що у момент їх закінчення. Як відомо, створення умов та знищення нового програмного потоку тягне за собою певні системні накладні витрати. Щоб уникнути цього, в аналізованому об'єкті ведеться кеш потоків. Після закінчення сполуки потоки не знищуються, а перетворюються на стан очікування нового сполуки. Властивість: property ThreadCacheSize: Integer; задає кількість вільних потоків, які можуть перебувати з готовністю задля встановлення з'єднання з клієнтом. Це кількість має розраховуватися залежно від інтенсивності і тривалості контакту з клієнтами. Зайві потоки поглинають системні ресурси, насамперед пам’ять і процессорное час. Щоб оптимізувати використання кешу вільних потоків, корисно поцікавитися значенням двох свойств:

property ActiveThreads: Integer;

property IdieThreads: Integer; що б число активних (зайнятих обслуговуванням клієнтів) і простоюючих (очікують) потоків відповідно. Старт також завершення потоку, котрий з сокетом, обрамлені событиями:

property OnThreadStart: TThreadNotifyEvent;

property OnThreadEnd: TThreadNotifyEvent;

type TTnreadNotifyEvent=procedure (Sender: TObject;

Thread: TServerClientThread) of object; Щоб уникнути ситуацій глухих кутів чи гонок під час роботи з сокетами, є два метода:

procedure Lock;

procedure Unlock; Якщо вами передбачено код, котрі можуть викликати проблеми, у многозадачной середовищі, укладіть його між викликами методів Lock і unlock — цей час інші потоки, хто з сокетами, будуть блоковані. Методи читання і запис для блокуючого і неблокирующего режиму істотно відрізняються. ассмотрим спочатку ті, що призначені для неблокирующего (асинхронного) режиму. Кошти в організацію читання представлені групою із трьох методов:

function ReceiveLength: Integer; повертає число байт, які можна ухвалюватимуть у у відповідь оповіщення клієнта про передаче.

function ReceiveText: string; повертає прочитану з сокета текстову строку.

function ReceiveBuf (var Buf; Count: Integer): Integer; повертає дані, прочитані з сокета в буфер Buf, у кількості count байт Аналогічно, методи: function SendBuf (var Buf; Count: Integer): Integer; procedure SendText (const P. S: string); function SendStream (AStream: TStream): Boolean; посилають клієнту буфер, текстову рядок і потік даних. На додачу до цьому метод: function SendStrearoThenDrop (AStream: TStream): Boolean; посилає клієнту потік даних, і завершує з'єднання. Рухаючись як параметра двох функцій потік даних AStream переходить «під нагляд «об'єкта TServerWinsocket і видаляється ним мері пересилки. Програміст ні робити спроб видалити AStream після виклику методів SendSrteam чи SendSrteamThenDrop. З допомогою методу: function GetClientThread (ClientSocket: TServerClientWinSocket): TServerClientThread; можна було одержати покажчик на потік, займається обслуговуванням конкретного сокета. События:

property OnClientConnect;

property OnClientDisconnect;

property OnClientRead;

property OnClientWrite; мають однакову тип:

TSocketNotifyEvent=procedure (Sender: TObject;

Socket: TCustomWinSocket) of object; Вони відбуваються при соединении/отключении від клієнта, і навіть під час читання і записи. Якщо відбулася помилка, виникає событие:

property OnClientError; TSocketErrorEvent;

type.

TErrorEvent = (eeGeneral, eeSend, eeReceive, eeConnect, eeDisconnect, eeAccept);

TSocketErrorEvent = procedure (Sender: TObject;

Socket: TCustomWinSocket;

ErrorEvent: TErrorEvent;

var ErrorCode: Integer) of object; Параметри його мають таке призначення. ErrorEvent свідчить про тип операції, під час яких стався помилка. У цьому ErrorCode містить код помилки Windows. Якщо ви і самі обробили помилку і наявність не хочете подальших дій зі її обробці із боку системи, встановити параметр ErrorCode в 0. Компонент TServerSocket Найголовніше властивість цього компонента — вже згадувана посилання объект:

property Socket: TServerWinSocket; Саме нього доступні все функціональні можливості сокета. Компонент ж створено лише тим, щоб опублікувати необхідні властивості і події. У ньому є свої події OnclientConnect, OnClientDisconnect, OnClientRead, OnClientWrite, OnClientError, але вони самостійні, а лише відсилають до відповідним подій об'єкта TServerWinSocket. Також само і зі властивостями serverType і ThreadCacheSize. Додатково в компоненті передбачені события:

property OnListen: TSocketNotifyEvent; відбувається по тому, як задано адреса київська і порт сокета і для тим, як і входить у режим прослуховування (готовності до соединению).

property OnAccept: TSocketNotifyEvent; відбувається одразу після установки сполуки Властивість property Active: Boolean;

отвечает за стан сокета. Для клієнтського сокета зміна значення відповідає подключению/отключению від серверу. Для серверного — умикання/вимикання стану прослуховування. Використання цього властивості рівносильне застосуванню наступних методов:

procedure Open;

procedure Close; Властивість property Service: string;

служит для ідентифікації призначення сокета. Тут має зберігатися символьне ім'я сервісу, котрій використовується сокет (ftp, http, telnet та інших.) Об'єкт TClientWinSocket Чимало з подібних подій і методів цього об'єкта вже описані вище (див. об'єкт TServerwinSocket), оскільки вони теж мають загального предка. Але є договір відмінності, потребують коментарю. Як вона та серверний, клієнтський сокет то, можливо двох типов:

type TCiientType = (ctNonBlocking, ctBlocking);

property ClientType: TCiientType; На відміну від серверу, в блокування клієнта великого лиха немає. Якщо встановлено режим ctBlocking, клієнтське додаток блокується до завершення операції. У режимі ctNonBiocking операції виконуються асинхронно. Компонент TClientSocket Чільну увагу під час розгляду цього компонента звернімо на логіку подій, що відбуваються при підключенні клієнтського сокета до сервера. Вона така: 1. Викликається метод open (чи властивість Active встановлюється в True). 2. Перед початком ініціалізації відбувається событие.

property onLookup: TSocketNotifyEvent;. Саме тоді ще можна змінити властивості об'єкта TClieniwinSocket: адресу, номер порту тощо. п. 3. Сокет повністю инициализируется й починає пошук. Коли серверний сокет виявлено, відбувається событие.

property onConneciing: TSocketNotifyEvent;. 4. Коли клієнтський запит задоволений сервером і встановлено з'єднання, відбувається событие.

property OnConnect: TSocketNotifyEvent; Проілюструємо сказане з прикладу пересилки інформації дату і часу. Процес підключення до сервера виглядає таким образом:

procedure TClientForm. FileConnectltemClick (Sender: TObject);

Begin.

if ClientSocket. Active then ClientSocket. Active := False;

if InputQuery («Сервер », «Адреса (ім'я) », Server) then.

if Length (Server)>0 then.

with ClientSocket do begin.

Host := Server;

Active := True;

end;

End; Після встановлення сполуки клієнт реагує на подія onClientRead:

procedure TCiientFom. ClientSocketRead (Sender: TObject; Socket: TCustomWinSocket);

var p. s: string;

Begin.

s:= Socket. ReceiveText;

if ((s[l]= «T ») and (TimeSpeedButton.Down)) then.

TimeSpeedButton.Caption:=Copy (s, 2, Length (s)).

else if ((s[l]= «M ») and (MemSpeedButton. Down)) then.

KemSpeedButton.Caption:=Copy (s, 2, Length (s));

End; У серверном додатку сокет встановлюється в активний стан (прослуховування) під час запуску програми. Усі котрі підключаться клієнти автоматично заносяться елемент списку (властивість connections). Саму інформацію дату і часу сервер розсилає по таймеру як отформатированных текстових строк:

procedure TServerForm. TimerITimerlSender: TObject);

var і: Integer;

s: string;

ms: TMemoryStatus;

Begin.

with ServerSocket. Socket do.

for i:=0 to ActiveCcnnections-I do.

Connections[i]. SendText («T «+TimeToStr (Now));

GlobaiMemoryStatus (ms);

s:=Format («%1OdK » ,[(ms.dwAvaiiPageFile + ms. dwAvaiiPhys) divx 1024]); with ServerSocket. Socket do.

for i:=0 to ActiveConnections-I do.

Connections [ і ]. SendText («M «+p.s) ;

End; Сервер може відреагувати на повідомлення від клієнта. Відповідь слід відправляти через параметр socket що сталося події onClientRead:

procedure TServerForm. ServerSocketClientRead (Sender: TObject;

Socket: TCustomWinSocket);

Begin.

Memo1.Lines.Add (Socket. ReceiveText);

Socket.SendText («I am understand »);

End; До сокетам цікавляться багато розробники, що можна пояснити їх універсальністю і значним поширенням. Якщо ви хоч не знайшли чогось для вас необхідного в компонентах TClientSocket і TServerSocket, навпаки — вважали їх заважкими при застосуванні, ви можете використовувати компонент TPowersock, розроблений компанією NetMasters. Він лежить на сторінці Internet Панелі інструментів. Спільне використання спільної па-м'яті Традиційним є метод межзадачного взаємодії з допомогою спільно використовуваної пам’яті. У DOS і 16-разрядной Windows він був простий і які вимагають пояснень — в усіх завдань, зокрема у операційній системи, був суцільний адресне простір. Але саме від цього проистекали всі біди і проблеми даних ОС. У 32x розрядних версіях Windows в кожного докладання своє адресне простір, недоступне іншим додатків. Тим щонайменше, спосіб обміну даними через пам’ять існує. Поділ даних здійснюється з допомогою відображення деякого обсягу спільно використовуваної пам’яті в адресне простір кожного докладання, що у обміні. Пам’ять то, можливо поділюваної вона фактично розташовується поза адресного простору докладання. Взагалі кажучи, в 32-разрядной Windows під «пам'яттю «мається на увазі як оперативна пам’ять (ОЗУ), але й пам’ять, резервируемая операційній системою на жорсткому диску. Цей вид пам’яті називається віртуальної пам’яттю. Код і такі відбиваються на жорсткий диск у вигляді страничной системи (paging system) підкачування. Страничная система використовує для відображення посторінковий файл (win386.swp в Windows 95 і pagefile. sys в Windows NT). Необхідний фрагмент віртуальної пам’яті переноситься з сторінкового файла в ОЗУ отже, стає доступним. Для виділення фрагмента спільно використовуваної пам’яті має бути створений спеціальний системний об'єкт Win 32, званий відтворюваним файлом. Цей об'єкт «знає «, як співвіднести файл, які перебувають на жорсткому диску, з пам’яттю, адресуемой процесами. У нашому випадку файл, який ми у вигляді об'єкта файлового відображення хочемо зробити доступним нашому додатку — це файл з розширенням ТХТ, DLL. чи ЕХЕ. Це посторінковий файл підкачування, використовуваний системою. Відбивши фрагмент сторінкового файла на згадку про, адресуемую нашим додатком, ми, щодо справи, отримали фрагмент пам’яті, який має у подальшому будемо посилатися, як у дані об'єкта файлового відображення. Примітка. Об'єкти файлового відображення можна використовувати для відображення на згадку про будь-якого файла, Не тільки сторінкового файла ОС. Одне чи більше додатків можуть відчинити відображуваний файл й одержати тим самим доступом до даним цього об'єкта. Отже, дані, вміщені у посторінковий файл додатком, використовує відображуваний файл, будуть доступні іншим додатків, якщо вони відкрили й використовують той самий відображуваний файл. Поділ даних між додатками здійснюється з допомогою використання функцій АПІ, наданих Win 32 до створення і використання об'єктів файлового відображення. Ось найважливіші з цих функций:

CreateFileMapping.

MapViewOfFile.

UnMapViewOfFiie Створення об'єкта файлового відображення Відображуваний файл створюється операційній системою при виклик функції CreateFileMapping. Цей об'єкт підтримує відповідність між вмістом файла і адресним простором процесу, котрий використовує цей файл. У нашому разі метою буде спільного використання даних. Посторінковий файл ОС використовують як розширення пам’яті. Отже, створивши відображуваний файл, пов’язаний із страничным файлом операційній системи, маємо як результату виділення глобально доступною пам’яті. Оскільки ця пам’ять є загальнодоступною, то інший примірник об'єкта файлового відображення, відкритий програмою, запущеній як іншого процесу, може мати до неї доступ. Функція CreateFileMapping має шість параметров:

function CreateFileMapping (hFile: THandle;

ipFileMappingAttributes: PSecurityAttributes;

flProtect,.

dwMaximumSizeHign,.

dwMaximurnSizeLow: DWORD;

lpName: PChar): THandle; stdcall; Перший параметр має тип THandle. Для нашої мети значення цієї параметра завжди має бути $FFFFFFFF (значок «$ «зазначає, що значення шестнадцатеричное). У принципі так цьому місці має бути дескриптор вже відкритого з допомогою функції CreateFile файла; але, оскільки ми маємо справу із незвичним файлом, вказівку значення $FFFFFFFF призводить до зв’язування об'єкта файлового відображення саме з страничным файлом операційній системи. Другий параметр — покажчик на запис типу TSecurityAttributes. У нашому разі значення цієї параметра завжди одно nil. Третій параметр має тип dword. Він визначає атрибут захисту. Щоб з допомогою відображуваного файла організувати спільного використання даних, третьому параметру слід привласнити значення PAGE_READWRITE. Четвертий і п’ятий параметри також мають тип dword. У 32-разрядной операційній системі значення dword має дайну 32 біта. Коли виконується функція CreateFileMapping, значення типу dword четвертого параметра зсувається вліво чотирма байта і далі об'єднується багатозначно п’ятого параметра у вигляді операції and. Інакше кажучи, значення об'єднують у одне 64-разрядное число, однакову обсягу пам’яті, виділеної об'єкту файлового відображення з сторінкового файла ОС. Оскільки ви навряд чи спробуєте здійснити виділення більш як чотирьох гігабайтів даних, ті значення четвертого параметра завжди має бути одно нулю. Використовуваний потім п’ятий параметр повинен показувати, скільки пам’яті в байтах необхідно зарезервувати як спільної. Шостий параметр має тип pСhar. Це значення є ім'я об'єкта файлового відображення, що має бути унікальним. Функція СreateFileMapping повертає значення типу THandle. Що стосується завершення яке функцією значення є дескриптор створеного об'єкта файлового відображення. У разі будь-якої помилки яке значення дорівнюватиме 0. Наступний фрагмент коду демонструє використання функції СreateFileMapping:

var.

hMappedFiie: THandie;

Begin.

hMappedFile:=CreateFileMapping ($FFFFFFFF, nil, PAGE_READWRITE, 0,.

25, «SharedBiock »);

if (hMappedFiie = 0) then ShowMessage («Mapping error ! »);

End; У цьому вся прикладі функція виділяє 25 байт. езультирующий відображуваний файл називається SharedBlock. Що стосується успіху функція поверне описувач поточного об'єкта файлового відображення в зміну hFileMapObj. Змінна hFileMapObj має тип THandie. Якщо змінна hFileMapObj дорівнює нулю, то це що означає, що функція завершилася з помилкою, про що буде виведено відповідне повідомлення. Підключення об'єкта файлового відображення до адресне простору З допомогою функції CreateFileMapping ми лише створили об'єкт типу «відображуваний файл »; наступна завдання — спроектувати дані файла в адресне простір нашого процесу. Цією мети служить функція MapViewOfFile. Функція MapViewOfFile має п’ять параметров:

function MapViewOfFile (hFileMappingObject: THandie;

dwDesiredAccess: DWORD;

dwFileOffsetHigh,.

dwFiieOffsetLow,.

dwIMumberOfBytesToMap: DWORD): Pointer; stdcall; Перший параметр має тип THandle. Його значенням може бути дескриптор створеного об'єкта файлового відображення — той, який повертає функція CreateFileMapping. Другий параметр має тип dword. Значення одеського форуму має бути встановлено в FILE_MAP_WRITE (чи. що таке саме, в FILE_MAP_ALL_ACCESS); це, що ці об'єкта файлового відображення будуть доступні як у зчитуванню, і за попереднім записом. Третій і четвертий параметри також мають тип dword. Це — усунення відображуваного ділянки щодо початку файла в байтах. У нашому випадку ці параметрів має бути в нуль, оскільки значення, яке ми даємо п’ятому (останньому) параметру функції MapViewOfFile, також одно нулю. П’ятий і другий параметр функції MapViewOfFile, як і попередні параметри, має тип dword. Він використовується визначення (в байтах) кількості даних об'єкта файлового відображення, що треба відобразити в процес (зробити доступними вам). Досягнення нашої мети це значення має бути встановлено в нуль, що означає автоматичне відображення у процес всіх даних, виділених які були функцією CreateFileMapping. Значення, яке функцією MapViewOfFile, має тип «покажчик ». Якщо функція відпрацювала успішно, вона поверне початковий адресу даних об'єкта файлового відображення. Наступний фрагмент коду демонструє виклик функції MapViewOfFile:

var.

hMappedFile: THandie;

pSharedBuf: PChar;

Begin.

hMappedFile:=CreateFileMapping ($FFFFFFFF, nil, PAGE_READWRITE, 0,.

25, «SharedBlock »);

if (hMappedFile = 0) then ShowMessage («Mapping error ! ») else begin.

pSharedBuf:=MapViewOfFile (hMappedFile, FILE_MAP_ALL_ACCESS, 0,0,0);

if (pSharedBuf = nil) then ShowMessage («MapView error »);

end;

End; У цьому вся прикладі виділяється 25 байт поділюваної пам’яті з допомогою функції CreateFileMapping. Ім'я результуючого об'єкта файлового відображення буде SharedBlock. Якщо функція завершиться успішно, то посилання новий відображуваний файл її повернуть в зміну hMappedFile. Змінна hMappedFile має тип Thandle, якщо значення перемінної hMappedFile одно нулю, це означатиме, що функція відпрацювала з помилкою, буде про що виведено відповідне повідомлення. Якщо значення не нульовий, він викликана функція MapViewOfFile. Дескриптор hMappedFile є першою параметром цієї функції пов’язує створений відображуваний файл з поточним процесом. Якщо функція завершиться успішно, то зміну pSharedBuf буде поміщений початковий адресу пам’яті, яким розташовуються дані об'єкта файлового відображення безпосередньо з ім'ям SharedBlock. Якщо функція відпрацює з помилкою, ті значення, яке функцією MapViewOfFile дорівнюватиме nil, у разі буде показано повідомлення, яке констатує цього факту. Спільне використання відображуваних даних Щоб розділити між процесами пам’ять, виділену з сторінкового файла ОС, кожен процес, що у поділі, повинен відобразити і той ж фрагмент однієї й тієї ж файла. Такий результат може бути досягнуто передачею переважають у всіх зазначених процесах однакових параметрів для функцій CreateFileMapping і MapViewOfFile. Покажчик, возвращаемый останньої функцією, ви можете згодом зчитувати чи записувати відповідно до своїх потребам. Якщо є, пов’язані з цим покажчиком, доступні одного з процесів, всі вони також доступні та інших процесам. Займемося черговим «клонуванням «нашого приклади з передачею даних про часу й вільної пам’яті. Спільним клієнтові і серверу нині є описане вище код з відкриття і відображенню файла. Він описаний як на подія форми onCreate. Коли запускається програму і створюється форма, відповідно створюється і підключається відображуваний файл. Код виглядає так:

procedure TSrvForm. FormCreate (Sender: TObjecr);

begin.

hFileMapObj:=CreateFiieMapping (MAXDWORD, nil, PAGE_READWRITE, 0, 25,.

" SharedMem ");

if (hFiieMapObj:=0) then ShowMessage («Error: cannot map this file »).

else begin.

pSharedBuf:=MapViewOfFile (hFiieMapObj, FILE_MAP_WRITE, 0,0,0);

if (pSharedBuf = nil) then.

ShowMessage («Error: pSharedBuf is nil »);

end;

end; Наведений вище код працює точно оскільки описано вище розділ «Підключення об'єкта файлового відображення до адресне простору ». Єдиною відмінністю є лише те, що змінних hFileMapObj і pSharedBuf перенесені в розділ var секції interface оскільки показано ниже:

interface.

var Form1: TForm1;

hFileMapObj: THandle;

pSharedBuf; Pointer;

implementation Компоненти типу TTimer є й в імені клієнта й у серверу. При кожному наступному подію що від цього компонента сервер поміщає потрібні дані в спільно що використовується область памяти:

type.

pDataRecord = ^TDataRecord;

TDataRecord = record.

DateTime: TDateTime;

Mem: Cardinal ;

end;

procedure TServerForm. Timer1Timer (Sender: TObject);

var ms: TMemoryStatus;

begin.

GlobalMemoryStatus (ms);

pDataRecord (pSharedBuf)^.DateTime:= Now;

pDataRecord (pSharedBuf)^.Mem := ms. dwAvailPageFile + ms. dwAvaiiPhys;

end; а клієнт — читає ці дані, якщо натиснута відповідна кнопка:

procedure TClientForm. TimerITimerfSender: TObject);

begin.

if MemSpeedButton. Down then MemSpeedButton. Caption:=.

Format («%8dK » ,[pDataRecord (pSharedBuf)^.Mem divx 1024]);

if TimeSpeedButton. Down then TimeSpeedButton. Caption:=.

TimeToStr (pDataRecord (pSharedBuf)^.DateTime);

end; Останнім штрихом стане відновлення написи на кнопці по тому, як вона знову натиснута пользователем:

procedure TClientForm. TimeSpeedButtonClick (Sender: TObject);

begin.

if not TimeSpeedButton. Down then TimeSpeedButton. Caption:= «Time » ;

end;

procedure TClientForm.Mem.SpeedButtonClick (Sender: TObject);

begin.

if not MemSpeedButton. Down then MemSpeedButton. Caption:= «Memory » ;

end; У програмі кілька операторів, необхідні припинення відображення даних, і звільнення об'єкта файлового відображення. Ці оператори обговорюються наступного розділі. Припинення відображення даних, і закриття об'єкта файлового відображення Останні два функції, які стосуються об'єкту файлового відображення, називаються UnMapViewOfFile І CloseHandle. ФУНКЦІЯ UnMapViewOfFile робить те, що передбачає її повна назва. Вона припиняє відображення в адресне простір процесу того файла, який які були було відображено при допомоги функції MapViewOfFile. Функція CloseHandle також робить те, що передбачає що дослівно; вона закриває дескриптор, у разі це дескриптор об'єкта файлового відображення, возвращаемый функцією CreateFileMapping. Функція UnMapViewOfFile повинна викликатися перед функцією CloseHandle Функції UnMapViewOfFile передається єдиний параметр типу указатель:

procedure TCIientForm. FormDestroy (Sender: TObject);

begin.

UnMapViewOfFiie (pSharedBuf) ;

CloseHandle (hFileMapObj);

end; Крім можливості спільного доступу що відобразяться файли помітно прискорити доступом до файлам, особливо великого розміру, будучи дуже сильним інструментом доступу до даних. Канали Протокол DDE пережив смугу свого найбільшого розквіту, і було згодом з’явилася його мережна версія (Network DDE, чи NDDE), стандартом де-факто вона стала. Однією з кандидатів зміну DDE став механізм каналів (pipes). Про його ролі свідчить хоча б її, що це з основних протоколів роботи цього продукту, як Microsoft SQL Server. Відразу зазначимо, що канали бувають два види — іменовані (named pipes) і безіменні (anonymous pipes). Другі не призначені для зв’язок між самостійними додатками і є, як кажуть, рудимент Win32 АПІ. У цій книзі розглядаються лише іменовані канали. І ще одне дуже важлива обмовка. Канали розглядалися Microsoft як протокол в організацію клиент-серверных додатків. Тому і серверна частина реалізована лише серед Windows NT і підтримується в Windows 95/98; клієнти можна створити в усіх цих ОС. Канал можна уявити як середовище, якою можуть обмінюватися даними два докладання. Обмін даними може бути як одностороннім, і двостороннім. Проте, одна з додатків ж виконує функцію серверу (воно створює канал), інше (й інші) лише підключається щодо нього. Суперечності з вищезгаданої фразою про поїздку двох додатках але немає: на сервері канал видно як ресурс з унікальним ім'ям. Коли до сервера підключається черговий клієнт, йому створюється унікальний примірник каналу відносини із своїми дескриптором, буфером тощо, п. Але ім'я каналу всім клієнтів однаково. Ім'я каналу записується відповідно до так званим угодою UNC (Universal Naming Convention). Виглядати він повинен так: servernamepipepipename де servernanie — мережне ім'я комп’ютера — серверу, ipename — ім'я каналу. Що стосується, якщо клієнту потрібно підключитися до сервера тому ж комп’ютері, його мережне ім'я замінюється точкою: .pipepipename Максимальна довжина імені каналу обмежена 256 символами; рядкові і великі літери немає. Для програміста алгоритми створення серверного і клієнтського «кінців «каналу відрізняються. До сформування серверу застосовуються спеціальні функції Win 32 АПІ; клієнтський ж кінець відкривається як звичайний файл і з нею також нагадує роботи з файлом. Не дивно, що у ми «позаховуємо «цих функцій до класу Delphi — нащадок HandleStream, найближчого родича файлового потоку TFileStream. Поки ж розглянемо шукані функції АПІ. Головна їх нам следующая:

function CreateNainedPipe (lpName: PChar;

dwOperiMode,.

dwPipeMode,.

nMaxInstances,.

nOutBufferSize,.

nInBufferSize,.

nDefauitTimeOut: DWORD;

lpSecurityAttributes:PSecurityAttributes):THandle; Вона створює серверний кінець каналу безпосередньо з ім'ям lpName. Інші параметри перераховані в табл. 8.1. Параметри функції createNamedPipe Параметр Призначення dwOpenMode.

Режим відкриття. Флаги:

PIPE_ACCESS_DUPLEX — двунаправленный обмін данными.

PIPE_ACCESS_INBOUND — тільки від клієнта до серверу.

PIPE_ACCESS_OUTBOUND — тільки від серверу до клиенту.

FILE_FLAG_WRITE_THROUGH — запис даних, минаючи кэш.

FILE_FLAG_OVERLAPPED — режим відкладеної операції введення/ виведення dwPipeMode.

Режим роботи каналу. Флаги:

PIPE_TYPE_BYTE — запис як потоку байт.

PIPE TYPE_MESSAGE — запис як потоку сообщений.

PIPE_READMODE_BYTE — читання як потоку байт.

PIPE_READMODE_MESSAGE — читання як потоку сообщений.

PIPE_WAIT — функції ввода/вывода ні повертати управління до завершення операции.

PIPE_NOWAIT — функції ввода/вывода повертають управління негайно nMaxinstances Максимальне кількість відкритих примірників каналу, від 1 до PIPE_UNLIMITED_INSTANCES.

nOutBufferSize.

Размер буфера для записи.

nInBufferSize.

Размер буфера для чтения.

nDefauitTimeOut.

Задает час очікування кінця операції ввода/вывода в каналі (в мс).

IpSecurityAttributes.

Указатель на структуру Windows NT, що містить інформацію про права доступу до каналу Pежимы потоку байт і потоку повідомлень дуже відрізняються одна від друга — у разі система змішує дані від різних операцій чтения/записи у єдиний потік, у другому — поділяє їх у окремі порції. Канал як PIPE_TYPE_BYTE може працювати для читання лише у режимі читання PIPE_READMODE_BYTE, канал як PIPE_TYPE_MESSAGE — в обох режимах читання. Функция.

function ConnectNainedPipe (hNamedPipe: THandle;

lpOverlapped: POverlapped): BOOL; дозволяє підключитися до створеному каналу hNamedPipe, а функция.

function DisconnectNaitledPipe (hNamedPipe: THandie): BOOL; дозволяє відключити клієнта — вона розриває зв’язок клієнтського і серверного кінців каналу hNamedPipe. Щоб зібрати інформацію про стан каналу hNamedPipe, потрібно викликати функцию.

function GetNamedPipeln. fo (hMamedPipe: THandle;

var ipFlags: DWORD;

lpOutBufferSize,.

lpInBufferSize,.

lpMaxInstances: Pointer): BOOL; Покажчики lpOutBufferSize, lpInBufferSize, ipMaxInstances повинні вказувати на перемінні, куди будуть записані розміри буферів і кількість відкритих примірників каналу. Параметр lpFlags свідчить про зміну, у якому будуть записані прапори стану каналу. У тому числі вже знайомий прапор PIPE_TYPE_MESSAGE, і навіть прапор PIPE_SERVER_END. Він установлений, якщо hNamedPipe — серверний кінець канала.

function PeekNamedPipe (hNamedPipe: THandle;

lpBuffer: Pointer;

nBufferSize: DWORD;

lpBytesRead,.

lpTotalBytesAvail,.

lpBytesLeftThisMessage: Pointer): BOOL; Ця функція дозволяє прочитати дані з буфера каналу, залишивши їх там (доступними на подальше читання). З іншого боку, вона повертає додаткову корисну інформацію про стан каналу, зокрема у адресою, зазначеному в параметрі lpTotalBytesAvail, прописано число ще не прочитаних байт в каналі. Функция.

Function WaitNamedPipe (lpNamedPipeName: PChar; nTimeOut: DWORD): BOOL; дозволяє організувати очікування закінчення операції в каналі. Параметр nTimeOut задає час очікування в миллисекундах; можливі решта 2 особливих значення — NMPWAIT_USE_DEFAULT_WAIT (очікувати протягом часу, указаного під час створення каналу) і NMPWAIT_WAIT_FOREVER (чекати нескінченно). Залишилося додати, що читання і запис в канал здійснюється як і, як і у звичайний файл — функціями ReadFile і WriteFile. Канали добре пристосовані обмінюватись даними у мережі. І все-таки їх застосування стримується наявністю необхідних протоколів і UNC. Тож у глобальних мережах застосовується інший варіант механізму межзадачного взаємодії — сокеты. 4. Многопоточные докладання Потоки — це об'єкти, отримують час процесора. Потоки дозволяє однієї програми вирішувати кілька завдань одночасно. Операційна система надає додатку певний інтервал часу центрального процесора (званий квантом) й у момент, коли додаток переходить до очікуванню повідомлень чи звільняє процесор, ОС передає управління інший завданню. Плануючи час центрального процесора, Windows розподіляє його між потоками, а чи не між додатками. Час процесора виділяється квантами (близько 19 мс). Щоб використати всі можливості операційній системи, програміст повинен знати, створювати потоки. Існує дві типу потоків: асиметричні і симетричні. Асиметричні потоки (asymmetric threads) вирішують різні завдання, як і правило, не поділяють спільні ресурси. Симетричні потоки (symmetric threads) виконують те роботу, поділяє одні й самі ресурси, і виконують один код. Приклад докладання з симетричними потоками — електронні дошки оголошень (Bulletin Board Systems, BBS). Для обслуговування кожного дозвонившегося туди користувача BBS запускає новий потік. Програма в термінах ОС є процес. Процес — це сукупність віртуальної пам’яті, виконуваного коду, потоків і даних. Процес мусить мати по крайнього заходу один потік. Якщо завдання докладання можна органічно розділити різні підмножини: обробка подій, вхід-видобуток, зв’язок тощо., то потоки може бути органічно вмонтовані в програмне рішення. Зробивши додаток многопоточным, програміст отримує додаткових можливостей управління ним. Наприклад, через управління пріоритетами потоків. Інший важливий перевагу використання потоків — за умов зростання «навантаження «на додаток можна збільшити їх кількість і можна збільшити їх кількість, і тим самим, зняти проблему. Дві типові проблеми, із якими може зіштовхнутися програміст під час роботи з потоками — це ситуації глухих кутів і гонок. Гонки Ситуація гонок виникає, коли чи більш потоків намагаються отримати доступом до загальному ресурсу змінити яке стан. ассмотрим наступний приклад. Нехай потік 1 отримав доступом до ресурсу змінив у своїх інтересах; потім активізувався потік 2 і модифікував той самий ресурс до завершення потоку 1. Потік 1 вважає, що ресурс залишився у тому самому стані, коли він був до перемикання (слід сказати, потоку 1 взагалі нічого невідомо про переключенні). Залежно від цього, коли було змінено ресурс, результати будуть варіюватися — іноді код буде виконуватися правильно, іноді - немає. Програміст ні будувати ніяких ілюзій щодо виконання потоків, т.к. планувальник ОС може запускати їх і зупиняти у час. Глухі Куточки Глухі Куточки мають місце, коли потік очікує ресурс, які цей момент належить іншому потоку. ассмотрим приклад: потік 1 захоплює об'єкт, А і, щоб продовжувати роботу, чекає можливості захопити об'єкт Б. У той самий час, потік 2 захоплює об'єкт Б і чекає можливості захопити об'єкт А. Через війну обидва потоку виявляються заблокованими — жодного з них виконуватиметься. Щоб не допустити ситуацій глухих кутів і гонок потоки слід синхронізувати. Пріоритети потоків Операційна система планує час у відповідність до пріоритетами потоків. Коли натовп створюється, йому призначається пріоритет, відповідний пріоритету який породив його процесу. Процеси, своєю чергою, мають такі класи пріоритетів: 1. Pеального часу (Real Time). Цей класу виявляє пріоритет навіть більший, ніж в багатьох процесів ОС. Такий процес необхідний процесів, обробних високошвидкісні потоки даних. 2. Високий (High). Цей класу виявляє пріоритет вище нормального. Він використовується процесами, які мають завершитися швидко. 3. Нормальний (Normal). Більшість процесів запускається у межах цього класу. 4. Фоновий (Idle). Процеси з такою пріоритетом запускаються лише у разі, тоді як черги диспетчера завдань немає інших процесів. Програмісти може використати цей клас пріоритетів в організацію фонових процедур й реорганізації даних. Прикладом може бути перевірка орфографії і збереження файла в MS Word. Пріоритети мають значення від 0 до 31. Пріоритет потоку може відрізнятиметься від пріоритету який породив його процесу на плюс-мінус дві одиниці. Відповідні величини показані ниже.

Низший Пониженный Нормальный Повышенный Высший Фоновый.

6 Нормальний заднього плана.

9 Нормальний переднього плана.

11 Высокий.

15 Реального времени.

26 Клас tThread Потрібно віддавати усвідомлювали, що з погляду ОС, потік — це стосується її об'єкт. Під час створення то здобуває дескриптор і відстежується ОС. Об'єкт класу tThread — це конструкція Delphi, відповідна потоку ОС. До сформування потоку служить конструктор

Constructor Create (CreateSuspended:Boolean); Якщо параметр CreateSuspended дорівнює TRUE, знову створений потік не починає виконуватися до того часу, поки що не викликаний метод Resume. У протилежному разі одразу після створення потік починає виконання. Метод Procedure Resume; класу tThread викликається, коли потік відновлюється після зупинки, чи коли він створили конструктором з параметром CreateSuspended, рівним TRUE.

Вызов методу Procedure Suspend; Призупиняє потік із можливістю повторного запуску згодом. Виконання магістралі триває з точки зупинки. Властивість Property Suspended: boolean; Дозволяє програмісту визначити, не призупинений чи потік. З допомогою цього властивості можна також ознайомитися запускати і зупиняти потік. Для остаточного завершення потоку (без наступного запуску) існує метод procedure Terminate; він зупиняє потік і повертає управління який викликав його процесу тільки тоді, як. Властивість property Terminated: boolean; дозволяє дізнатися, викликали вже метод Terminate. Метод Function WaitFor: integer; Призначений для синхронізації і дозволяє одному потоку дочекатися моменту, коли завершиться інший. Якщо всередині потоку FirstThread написати код: Code:=SecondThread.WaitFor; це означатиме, що потік FirstThread зупиняється до завершення потоку SecondThread. Метод WaitFor повертає значення властивості ReturnValue. Властивість Property Priority: tThreadPriority; Визначає пріоритет потоку. Припустимими значеннями пріоритету є: tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritrcal. Метод Procedure Synchronyze (Method: tTHreadMethod); призначений для безпечного виклику методів VCL всередині потоків. Цей метод гарантує, що кожному об'єкту VCL одночасно має доступ лише один потік, що дозволяє запобігти ситуації гонок. Аргумент, рухаючись в метод Synchronyze — це методу, що проводить звернення до VCL. Виклик Synchronyze з такою аргументом, це саме саме, як і виклик самого методу. Synchronyze перебуває у області видимості protected, і, отже, доступний лише у методах нащадків класу tThread. Головним методом класу tThread є абстрактний метод Procedure Execute; virtual; abstract; Цей метод може бути перевизначений в классе-потомке tThread. У його тілі має бути код, що й є власне потік. Якщо потік створили з аргументом CreateSuspended, рівним FALSE, то метод Execute викликається відразу після створення потоку; інакше — після виклику методу Resume. Якщо потік вміщує однократне виконання жодних дій, то ніякого спеціального коду завершення йому писати непотрібно. Після виконання методу Execute спричинить деструктор, який завжди робить усе необхідне. Якщо ж у потоці виконуватиметься нескінченний цикл, і потік повинен завершитися разом із додатком, то умови закінчення циклу мали бути зацікавленими приблизно такими:

rocedure tMyThread. Execute;

Begin.

Repeat.

// Код потока.

Until CancelCondition or Terminated;

End; Тут CancelCondition — ваша особиста умова завершення потоку, а властивість Terminated говорить про завершенні потоку ззовні (швидше за все, завершився що породив його процес). Із завершенням потоку треба дуже уважним: коли він зациклився, зависне все додаток. Властивість Property ReturnValue: Integer; Дозволяє дізнатися код завершення потоку. Ця величина повністю визначається користувачем. До сформування свого потоку треба знайти в репозитории значок Thread Object (він перебуває в сторінці New). Подвійний щиголь у цьому значку викликає діалогове вікно New Thread Object, у якому слід також запровадити ім'я майбутнього класса-потомка tThread. Натискання кнопки ОК викликає генерацію шаблону нового потока:

unit ThreadUnit;

interface.

uses Classes;

type.

tMyThread = class (TThread).

private.

{ Private declarations }.

protected.

procedure Execute; override;

end;

implementation.

{ Important: Methods and properties of objects in VCL can only be used in a method called using Synchronize, for example,.

Synchronize (UpdateCaption);

and UpdateCaption could look like,.

procedure tMyThread. UpdateCaption;

begin.

Form1.Caption := «Updated in a thread » ;

end; }.

{ tMyThread }.

procedure tMyThread. Execute;

begin.

{ Place thread code here }.

end;

end. Кошти синхронізації потоків Головні поняття механізму синхронізації - функції очікування й об'єкти очікування. У АПІ передбачено ряд функцій, дозволяють призупинити виконання що викликав цю функцію потоку до моменту, як буде змінено стан якогось об'єкта, званого об'єктом очікування. (Під цим терміном розуміється не об'єкт Delphi, а об'єкт операційній системи.) До можливих варіантів ставляться чотири об'єкта, розроблених спеціально для синхронізації: 1. Подія (event); 2. Взаємна виняток (mutex); 3. Семафор (semaphore); 4. Таймер (timer). Крім лідерів, чекати можна й інших об'єктів, дескриптор якої використовуються в основному задля іншого, а може застосовуватися й у очікування. До них ставляться: процес, потік, оповіщення про зміну в файлової системі (change notification) і консольний введення. Відповідні класи перебувають у модулі SYNCOBJS.PAS. Подія (клас tEvent) має дві методу: SetEvent і ResetEvent, що переводять об'єкт в активне і пасивне стан відповідно. Конструктор класу має вид: Constructor Create (EventAttributes: pSecurityAttributes; ManualReset, InitialState: Boolean; const Name: string); Тут параметр EventAttributes визначає права доступу до події й у вона найчастіше має дорівнювати nil. Параметр InitialState визначає початкова стан події. Параметр ManualReset — спосіб його скидання. Якщо цей параметр дорівнює TRUE, то подія має бути скинуто вручну. У іншому разі подія скидається автоматично по тому, як стартує хоча б тільки дожидавшийся його потік. Метод.

type tWaitResult = (wrSignaled, wrTimeOut, wrAbandoned, wrError);

Function WaitFor (TimeOut:DWORD): tWaitResult; Дає можливості очікувати активізації події у протягом TimeOut мілісекунд. Метод повертає wrSignaled у разі, якщо відбулася активізація події та wrTimeOut, якщо на час тайм-ауту сталося. Якщо потрібне чекати як довго, слід встановити параметр TimeOut в значення INFINITE. Для синхронізації потоків слід вставити виклик WaitFor у необхідному місці коду потоку (методу Execute), і тоді виконання потоку буде призупинено досі активізації події (тобто будь-якої інший потік викликає його метод SetEvent) чи закінчення тайм-ауту. Взаємні винятку Об'єкт типу взаємне виняток (клас tMutex, файл IPCTHRD. PAS) дозволяє лише потоку в момент мати його. Його можна порівняти з естафетної паличкою. Спочатку, даний об'єкт не належить нікому. Метод.

function Get (TimeOut:Integer):Boolean; Виробляє спробу протягом TimeOut мілісекунд заволодіти об'єктом (у тому разі метод повертає TRUE). Якщо об'єкт большє нє потрібен, слід викликати метод.

function Release: boolean; Критична секція Критичні секції (клас tCriticalSection) подібні взаємним винятків по суті, але з-поміж них існують два головних відмінності: 1. Взаємні винятку може бути спільно використані потоками в різних процесах. 2. Якщо критична секція належить іншому потоку, котрий очікує потік блокується до звільнення критичної секції. На відміну від послуг цього, взаємне виняток дозволяє продовження після закінчення тайм-ауту. Критичні секції ефективніше взаємних винятків, оскільки вони використовують менше системних ресурсів. Фундаментальна обізнаність із критичними секціями справляє враження роботи з взаємними винятками. У многопотоковом додатку створюється і инициализируется загальна всім потоків критична секція. Коли одна з потоків сягає критично важливого ділянки коду, він намагається захопити секцію викликом методу Enter.

.. .

CriticalSection.Enter;

try.

// критичний ділянку кода.

finally.

CriticalSection.Leave;

end;

... Коли інші потоки сягають оператора захоплення секції і виявляють, що вже захоплена, вони припиняються до звільнення секції першим потоком шляхом виклику методу Leave. Критичні секції є системними об'єктами і підлягають обов’язковому визволенню (втім, як і й інші аналізовані тут об'єкти). Процес. Породження дочірнього процесу Об'єкт типу процес можна використовувати у тому, щоб призупинити виконання потоку у разі, для свого продовження він вимагає завершення процесу. З практичного погляду що ситуація виникає, як у рамках вашого докладання виникла потреба виконати інше додаток. Замість застарілою, і підтримуваної лише сумісності функції WinExec, більш правильний користуватися потужнішою функцией:

function CreateProcess (lpApplicationName: pChar; lpCommandLine: pChar; lpProcessAttributes, lpThreadAttributes: pSecurityAttribytes;

bInheritHandles:BOOL;

dwCreationFlags: DWORD;

lpEnviroment: Pointer;

lpCurrentDirectory:pChar;

const lpStartupInfo: tStartupInfo;

var lpProcessInformation: tProcessInformation):BOOL; Перші дві параметра — це запускаемого докладання і передані то командної рядку параметри. Параметри dwCreationFlags містить прапори, що визначають засіб створення нового процесу його пріоритет. Структура lpStartupInfo містить інформацію про розмірі, кольорі, становищі вікна створюваного докладання. На виході функції заповнюється структура lpProcessInformation. У ньому програмісту повертаються дескриптори і ідентифікатори створеного процесу його первинного потоку. Локальні дані потоку Цікава проблема виникає, тоді як додатку буде кілька однакових потоків. Як уникнути спільного використання одним і тієї ж змінних різними потоками? Передусім варто використовувати поля об'єкта — нащадка tThread. Кожен потік відповідає окремому примірнику об'єкта, та його дані перетинатися ні. Проте, може виникнути потреба у використанні функцій АПІ, які знати не знають про об'єкти Delphi та його полях і властивості. Для підтримки поділу даних на нижньому рівні у Object Pascal введена спеціальна директива — threadvar, що відрізняється від звичної var тим, що вживається лише до локальних даним потоку. Наступне описание:

var data1: integer;

threadvar data2: integer; Означає, що змінна data1 використовуватиметься усіма потоками даного докладання, а змінна data2 буде в кожного потоку своя.

Єрмаков P.В. |Основні разделы.

Железо:

> розділ hardware.

Обзоры программ:

> розділ software.

Программирование:

> розділ programming.

Операционные системы:

> розділ ОС Графика і дизайн:

> розділ graphics.

Сетевые технологии:

> розділ network.

| |.

Показати весь текст
Заповнити форму поточною роботою