.
Tuesday 22nd of May 2012    

Информация

Счетчики

Голосование

Лучшая марка телефона
 

Реклама

фильмы онлайн

фильмы онлайн


Место класса THandleStream
загрузка...

К сожалению, в огромном списке компонентов VCL Delphi не нашлось места для специализированных классов, инкапсулирующих методы для работы с почтовыми слотами или именованными каналами. Однако в Delphi реализован потенциальный прототип для создания объектов, работающих в рамках изучаемых в этой главе технологий, - класс THandleStream.

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

Заслуга класса THandleStream состоит в том, что он инкапсулирует то общее, что имеется в механизмах почтовых слотов и именованных каналов. Под «общим» следует понимать набор свойств и методов, обеспечивающих операции ввода/вывода в разделяемый коммуникационный ресурс. Снабдив класс всем необходимым для работы, например с mailslot, можно получить великолепный экземпляр компонента VCL. Этим мы займемся позже, а пока немного теории. У класса THandleStream всего три свойства. В первую очередь это дескриптор коммуникационного ресурса:

property Handle: Integer; //только для чтeния

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

property Size: Int64; //paзмep

property Position: Int64; //позиция

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

constructor Create(AHandle: Integer);

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

function Read(var Buffer; Count: Longint): Longint; override; function Write(const Buffer; Count: Longint): Longint; override;

Здесь Buffer - буфер для чтения (записи) и Count - количество прочитанных (записанных) байт. Еще два метода обеспечивают позиционирование и определение размеров ресурса:

function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; procedure SetSize(const NewSize: Int64); override;

А теперь рассмотрим листинг, объединяющий в себе преимущества VCL и гибкость методов Win32 API. В примере создается класс TMailSlot, обладающий всеми функциональными возможностями почтового ящика. Вначале рассмотрим заголовок модуля, в котором объявляются наши намерения:

unit vcl_mailslot;

interface

uses Windows, Classes, SysUtils; type TMailSlot=class(THandleStream)

public

constructor Create(const SlotAddress : string); destructor Destroy;

function ReadMail(MailText : TStrings): boolean; procedure WriteMail(const MailAddress, MailText : string); end;

В интерфейсной части модуля объявлен класс TMailSlot - прямой наследник только что изученного класса THandleStream. С его помощью мы планируем решать следующие задачи:

1. Создание почтового слота. С этой целью объявлен конструктор Create().

2. Освобождение ресурса почтового слота, например при завершении работы программы. С этой целью реализован деструктор Destroy().

3. Просмотр поступившей почты - метод ReadMail().

4. Отправка почты заданному адресату - метод WriteMail(). Исходя из этого раздел реализации будет выглядеть примерно так:

implementation

{ TMailSlot }

constructor TMailSlot.Create(const SlotAddress: string); begin

fHandle:=CreateMailSlot(pAnsiChar(SlotAddress), 0, MAILSLOT_WAIT_FOREVER, nil); if fHandle=INVALID_HANDLE_VALUE then

raise EOSError.CreateFmt('Ошибкa почтового cлoтa %d',[GetLastError]);

end;

В конструктор передается всего один параметр - строка с названием почтового слота на серверной стороне. Дескриптор почтового ящика, созданного методом Win32 API CreateMailSlot(), передается в поле fHandle и позже используется при чтении полученной корреспонденции. В случае возникновения ошибки при создании слота инициируем ошибку. Сейчас, чтобы не отвлекаться на возможные варианты ее обработки, просто создадим экземпляр класса EOSError.

Определение деструктора элементарно: метод CloseHandle() освобождает ресурс почтового слота:

destructor TMailSlot.Destroy; begin

CloseHandle(Handle); end;

Следующий метод предназначен для чтения полученных сообщений:

function TMailSlot.ReadMail(MailText : TStrings) : boolean; var NextSize, MessageCount : Cardinal;

Buf: PChar;

begin

{пepвoнaчaльнo получим дaнныe о почтовом ^0Te} GetMailSlotInfo(Handle, nil, NextSize, @MessageCount, nil);

Предлагаемая функция ReadMail() в качестве параметра получает ссылку на набор строк MailText:TStrings. Благодаря этому метод может применяться совместно с компонентом класса TMemo. Например, следующая строка кода:

MailSlot.ReadMail(Memo1.Lines);

получит все почтовые отправления из объекта MailSlot : TMailSlot и загрузит их в строки memo-поля Memol. Сам код функции получения корреспонденции не будет для нас откровением. Метод Win32 API GetMailslotInfo() информирует о наличии сообщений в почтовом ящике с дескриптором Handle. Если сообщения есть (MessageCount>0), они перебираются в цикле и считываются методом Read(), унаследованным от класса THandleStream.


загрузка...
 

Самое популярное:

bottom

карта сайта