Ошибка: Failed to parse the Currency Converter XML document.
$2 275.12


Ошибка: Failed to parse the Currency Converter XML document.
$18 827.61


Ошибка: Failed to parse the Currency Converter XML document.
$18 906.63


Невизуальные классы в Delphi

В этом обзоре мне хотелось бы рассказать про несколько классов Delphi, которым обычно в книгах и других обучающих материалах уделяется (если уделяется) весьма скромное внимание. Это так называемые невизуальные классы, не порожденные непосредственно от TComponent и не имеющие владельца. Следовательно, начинающий разработчик в палитре компонентов их не видит, в книжках о них не пишут, а help’ы ему читать неохота или он просто не знает английского… Так уж получается что RAD не способствуют обучению работы с невизуальными классами, что плохо отражается как на квалификации такого it-специалиста, так и на предлагаемых им программных решениях. Отсюда и множество вопросов из разряда FAQ задаваемых по этой теме в конференциях.


Итак, подробнее я хочу остановиться на трех классах инкапсулирующих список (TList), поток данных (TStream) и поток приложения (TThread).

Класс TList. Это удачное решение программистов Borland, которое реализует большинство возможностей для работы со связными списками нетипизированных указателей. Список – это наиболее гибкая структура данных, позволяющая хранить в индексированном виде объекты разных типов. Массив нетипизированных указателей размещается в куче.


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

TList имеет всего четыре свойства, из которых полезными для нас являются два:

· property Count: Integer; — определяет количество элементов списка

· property Items[Index: Integer]: Pointer; — индексированный массив указателей на объекты.

Эти два свойства служат для доступа к объектам списка. Обратите внимание, что многие из объектов, построенных с использованием списков, для доступа к своим элементам используют аналогичные свойства (TStrings, TStringGrid, TListView и другие).

Стоит также отметить свойство Capacity. Если вы заранее знаете количество элементов в списке, то стоит присвоить это значение свойству Capacity.

Методов у класса TList заметно больше чем свойств. Рассмотрим наиболее важные из них:

· function Add(Item: Pointer): Integer; — добавляет объект в список. Указатель на объект указывается как параметр функции. Стоит отметить, что большинство объектов в Delphi уже являются указателями. Так, переменная Form1: TForm, является указателем на объект Form. В отличие от Borland Pascal for DOS, в Delphi в этом случае не применяется запись ^TForm.

· procedure Clear; dynamic; — как следует из названия, очищает список, при этом удаляются все ссылки на объекты и занимаемая ими память. Счетчик Count устанавливается в нуль. Сами объекты должен удалить программист используя, например, метод Dispose.

· procedure Delete(Index: Integer); — удаляет заданный индексом элемент из списка. Элементы нумеруются начиная с 0! Следующие за удаленной записью элементы, смещаются на один «вверх».

· procedure Exchange(Index1, Index2: Integer); — вспомогательная функция, используется для обмена местами двух элементов списка.

· function IndexOf(Item: Pointer): Integer; — определяет, является ли конкретный указанный объект элементом списка, и если это так, возвращает его индекс.

· procedure Insert(Index: Integer; Item: Pointer); — вставляет объект на место в списке, указанное параметром Index.

· procedure Sort(Compare: TListSortCompare);

type TListSortCompare = function (Item1, Item2: Pointer): Integer;
Данная процедура весьма удобное средство для сортировки списка.

Для сравнения двух элементов списка используется пользовательская функция, которая возвращает результат сравнения на основе тех или иных свойств. В процедуре сортировки используется метод QuickSort, который дает достаточно приемлимый результат (по скорости) на реальных данных. Хотя при «неблагоприятных» данных он проигрывает методу пирамидальной сортировки. В случае такого рода данных процедуру сортировки можно написать самому используя метод Exchange.

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

для сравнения текста:

CompareStr – для регистрозависимого текста

CompareText — для регистронезависимого текста

для сравнения дат

CompareFileTime — даты в системном формате

для сравнения регионов

EqualRgn

другие

EqualRect,

EqualSid,

IShellFolder::CompareID.

Следующая остановка – потоки данных. В Delphi есть несколько видов потоков – файловый поток, поток в памяти, поток связанный с handle объекта, строковый поток и т.д. Все они унаследованы от своего абстрактного предка TStream. Разобравшись с ним вы сможете единообразно работать с любыми другими потоками.

Поток — это некоторая обобщенная модель двоичных данных

У базового класса есть два свойства, унаследованные всеми потомками: Position и Size, которые определяют позицию в потоке и его размер, соответственно.

Рассмотрим основные функции класса. Если вы уже работали с файлами, то обращение к этим методам весьма схоже:

function Read(var Buffer; Count: Longint): Longint; virtual; abstract; — читает данные из потока в буфер;

function Write(const Buffer; Count: Longint): Longint; virtual; abstract; — пишет данные в поток;

function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract; — устанавливает позицию в потоке.

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

Есть и пара просто полезных функций

function CopyFrom(Source: TStream; Count: Longint): Longint; — эта функция копирует часть или весь поток из другого потока. Этим методом, например, очень удобно копировать файлы. Есть мнение, что работа с потоками, быстрее работы с файлами. К сожалению у меня не было возможности проверить это утверждение…

procedure SaveToFile(const FileName: string); — позволяет сохранить участок памяти в дисковый файл.

Вот мы и подошли к одному из самых мощных, полезных и удобных решений – инкапсуляции потоков в Delphi. Понятие потока представлено программистами Borland в виде абстрактного класса TThread Каждый разработчик может унаследовать от него свой поток, наделив его нужной функциональностью. Все проблемы по управлению потоками, их синхронизации и т.д. остаются на долю VCL. В рамках данной статьи я не берусь подробно описать и объяснить все механизмы и тонкости задействованные при работе с потоками и все же отошлю вас к литературе данной в конце статьи, а сам же дам лишь обзор потоков.

Итак, когда и зачем используются потоки? Что это такое? Потоки – это объекты, которым процессор выделяет время. Обратите внимание, не процессам или программам, а порожденным им потокам. Так что любая программа содержит в себе хотя бы один поток. Он называется главным. Когда появляються потоки, появилась возможность отдавать для решения каждой задачи ровно столько ресурсов, сколько ей нужно. Для этого используется понятие приоритета потока. Каждый процесс имеет свой приоритет (от фонового до реального времени). В рамках процесса существуют потоки, приоритетом которых (потоков) может управлять процесс. Таким образом приоритет может иметь значение от 0 до 31. Следует заметить, что программы написанные в Delphi по умолчанию порождают процесс с нормальным приоритетом (он может быть переднего или заднего плана, в зависимости от активности задачи и меняться от 9 до 7). Процессы реального времени используются очень редко.

Чтобы сделать свой поток, вам нужно унаследовать свой класс от объекта TThread. Это можно сделать из меню File -> New… Будет создан модуль с заготовкой для класса. Все что вам нужно сделать – перекрыть метод Execute. Для этого его нужно объявить как override и наделить нужной функциональностью.

При написании метода Execute нужно учесть следующее: поток работает параллельно с основным потоком программы и может обращаться к каким-то элементам или компонентам также параллельно с основным потоком. Чтобы избежать этого, нужно использовать метод Synchronize. В его параметре следует указать действия, производимые с «общими» объектами. Например

Synchronize(MainForm.Label1.Caption:=’Hello!’);

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

Процесс может находиться в двух состояниях – выполняться или быть приостановленным. За это отвечают методы

procedure Suspend;

procedure Resume;

Также процесс может самоуничтожаться по завершении — свойство FreeOnTerminate.

Метод

function WaitFor: LongWord; ожидает завершения потока.

Вот в принципе и все, что я хотел рассказать. Этот обзор не является полным. Он призван подтолкнуть начинающих изучать Delphi к более глубокому проникновению в возможности этой среды программирования. Почти половина информации из этой статьи взята мной из help-файла, поставлявшегося с Delphi. Чаще в него заглядывайте! Читайте книги. Знакомьтесь с эхоконференциями. Смотрите исходники программ. И все у вас получится!

 

Интересное

Типизированные файлы
Типизированный файл — это файл в котором записанны идентичные структуры. Например любой файл можно считать файлом байтов — т.е. можно его читать байт за байтом, можно перейти сразу к любому...
Подробнее...
Сделать первый небольшой...
С чего начать?Я думаю, сейчас самое время перейти от слов к делу — сделать первый небольшой скрипт.Возьмем для примера следующую задачу. Нужно сделать базу с книгами, которые появились или скоро...
Подробнее...
SSI - что, когда, как?
Основным, простейшим, но в то же время чрезвычайно мощным инструментом поддержки больших наборов документов является SSI (Server-Side Includes — включения на стороне сервера). Если кто-то из...
Подробнее...
Firefox: Настройка RSS
Много слышал об RSS и даже несколько раз пытался пользоваться специальными программами для чтения. Но устанавливать дополнительное ПО не хочется, тем более что в Firefox есть встроенный клиент...
Подробнее...
Протоколы интернет
Прародителем сети интернет была сеть ARPANET. Первоначально её разработка финансировалась Управлением перспективного планирования (Advanced Research Projects Agency, или ARPA). Проект стартовал...
Подробнее...
Linux Format
Linux Format Номер 1 Январь 2007 Автор: Linux Format Формат: PDF
Подробнее...
Выпадающие меню с помощью CSS
Каждый, кому хоть раз приходилось создавать выпадающие меню, знаком с тем, какое количество скриптов требуется для этого. Между тем, используя грамотно структурированный HTML-код и несложные...
Подробнее...
База данных методами...
В статье рассматривается работа с бинарными файлами из Delphi, а так же использование Object Pascal для управления записью, чтением и изменением собственных типов файлов.Постановка задачи:...
Подробнее...
Средства восстановления...
Чтобы ни говорили про повышенную надежность Windows 2000/ХР, иногда она все же подводит. Правда, по сравнению со своими предшественницами Windows 9x/Me это случается гораздо реже. А поскольку...
Подробнее...
CSS дизайн: с учетом контекста
Веб-стандарты обещают нам улучшенную поддержку мультимедиа: возможность оптимизировать контент под возможности компьютерных экранов, портативных устройств, принтеров, проекторов, и подобных...
Подробнее...