Четверг, 14 Ноя 2024, 06:19
Uchi.ucoz.ru
Меню сайта
Форма входа

Категории раздела
Высшая математика [11]
Экономическая социология [95]
Основы Менеджмента [64]
Бухгалтерский учёт [157]
Философия [163]
Мировая Экономика [603]
Бизнес планирование [29]
Финансирование и кредитование инвест [105]
Ценообразование [46]
Гражданское право [196]
Права Человека [173]
Основы Маркетинга [207]
Основы энергосбережения [55]
Информатика [0]
Экология и устойчивое развитие [0]
Физика для студентов [0]
Основы права [0]
Политология [0]
Не стандартные примеры на Delphi [169]
Примеры на Delphi7 [108]
Алгоритмы [94]
API [110]
Pascal [152]
Базы Данных [6]
Новости
Чего не хватает сайту?
500
Статистика
Зарегистрировано на сайте:
Всего: 51642


Онлайн всего: 55
Гостей: 55
Пользователей: 0
Яндекс.Метрика
Рейтинг@Mail.ru

Каталог статей


Главная » Статьи » Студентам » Pascal

Реализация собственного потока
Я хотел бы создать конструктор Load, загружающий список из
потока...
Новые потоки в Delphi более разносторонние, чем в BP7. Поскольку вы знаете
как пользоваться потоками в BP7, а размер статьи ограничен, то я думаю, что для
начала вам необходимо попробовать в действии описанный ниже модуль,
инкапсулирующий класс для работы с потоками в стиле BP7. Класс является
наследником TComponent, но в нашем случае не было бы никакой разницы, если бы он
был наследником TObject. К примеру, вы могли бы адаптировать данный код к своему
наследнику TList.

Более важен тот факт, что вы можете использовать поток так, как вам это
необходимо, исходя из вашей задачи и специфики. Я сделал работу потока похожую
по стилю на BP7, где вначале идет ID класса. В каком-нибудь месте вам необходимо
вызвать RegisterType( TYourClass, UniqueIDLikeBP7 ), после чего TYourClass готов
к работе с потоками.

Вы наверняка обратили внимание, что я реализовал список зарегистрированных
классов (регистратор), где с помощью ID легко можно найти классы, читающие и
пишущие в поток в момент вызова конструктора Load соответствующего класса. Код
простой и не требующий пояснений. Имейте в виду, что данный код можно
использовать для организации передачи данных между существующим файловым потоком
BP7 в объекты Delphi - я создал это для осуществления миграции с текущего
приложения BP7 в Delphi и осуществления совместимости.

Если вам необходима более подробная информацио о работе потоков в Delphi,
обратитесь к соответствующему разделу электронной справки Delphi.

Успехов.

Mike Scott.

unit CompStrm;

interface

uses Classes ;

type
TCompatibleStream = class ;

{ TStreamObject }

TStreamObject = class( TComponent )
constructor Load( S : TCompatibleStream ) ; virtual
; abstract ;
procedure Store( S : TCompatibleStream ) ; virtual ;
abstract ;
function GetObjectType : word ; virtual ;
abstract ;
end ;

TStreamObjectClass = class of TStreamObject ;

{ TCompatibleStream }

TCompatibleStream = class( TFileStream )
function ReadString : string ;
procedure WriteString( var S : string )
;
function StrRead : PChar ;
procedure StrWrite( P : PChar ) ;
function Get : TStreamObject ; virtual ;
procedure Put( AnObject : TStreamObject ) ; virtual
;
end ;

{ Register Type : используйте это для
регистрации ваших объектов для
работы с потоками с тем же ID, который они имели в OWL
}

procedure RegisterType( AClass : TStreamObjectClass ;
AnID : word ) ;

implementation

uses SysUtils, Controls ;

var Registry : TList ; { хранение ID
объекта и информации о классе }

{ TClassInfo }

type
TClassInfo = class( TObject )
ClassType : TStreamObjectClass ;
ClassID : word ;
constructor Create( AClassType : TStreamObjectClass ;
AClassID : word ) ; virtual ;
end ;

constructor TClassInfo.Create( AClassType :
TStreamObjectClass ;
AClassID : word ) ;

var AnObject : TStreamObject ;

begin
if not Assigned( AClassType ) then
Raise EInvalidOperation.Create( 'Класс не
инициализирован') ;

if not AClassType.InheritsFrom( TStreamObject )
then
Raise EInvalidOperation.Create( 'Класс
' + AClassType.ClassName +
' не является потомком
TStreamObject') ;

ClassType := AClassType ;
ClassID := AClassID ;
end ;

{ функции поиска информации о классе
}

function FindClassInfo( AClass : TClass ) : TClassInfo
;

var i : integer ;

begin
for i := Registry.Count - 1
downto 0 do begin
Result := TClassInfo( Registry.Items[ i ] ) ;
if Result.ClassType = AClass then exit ;
end ;
Raise EInvalidOperation.Create( 'Класс
' + AClass.ClassName +
' не зарегистрирован для работы с
потоком' ) ;
end ;

function FindClassInfoByID( AClassID : word ) : TClassInfo
;

var i : integer ;
AName : string[ 31 ] ;

begin
for i := Registry.Count - 1
downto 0 do begin
Result := TClassInfo( Registry.Items[ i ] ) ;
AName := TClassInfo( Registry.Items[ i ] ).ClassType.ClassName
;
if Result.ClassID = AClassID then exit ;
end ;
Raise EInvalidOperation.Create( 'ID
класса ' + IntToStr( AClassID ) +
' отсутствует в
регистратореклассов' ) ;

end ;

procedure RegisterType( AClass : TStreamObjectClass ;
AnID : word ) ;

var i : integer ;

begin
{ смотрим, был ли класс уже зарегистрирован
}
for i := Registry.Count - 1
downto 0 do
with TClassInfo( Registry[ i ] ) do if ClassType =
AClass then
begin
if ClassID <> AnID then
Raise EInvalidOperation.Create( 'Класс
' + AClass.ClassName +
' уже зарегистрирован с ID ' +
IntToStr( ClassID ) ) ;
exit ;
end ;
Registry.Add( TClassInfo.Create( AClass, AnID ) ) ;
end ;

{ TCompatibleStream }

function TCompatibleStream.ReadString : string
;

begin
ReadBuffer( Result[ 0 ], 1 ) ;
if byte( Result[ 0 ] ) > 0 then ReadBuffer( Result[ 1 ],
byte( Result[ 0] ) ) ;

end ;

procedure TCompatibleStream.WriteString( var S :
string ) ;

begin
WriteBuffer( S[ 0 ], 1 ) ;
if Length( S ) > 0 then
WriteBuffer( S[ 1 ], Length( S ) ) ;
end ;

function TCompatibleStream.StrRead : PChar ;

var L : Word ;
P : PChar ;

begin
ReadBuffer( L, SizeOf( Word ) ) ;
if L = 0 then StrRead :=
nil else
begin
P := StrAlloc( L + 1 ) ;
ReadBuffer( P[ 0 ], L ) ;
P[ L ] := #0 ;
StrRead := P ;
end ;
end ;

procedure TCompatibleStream.StrWrite( P : PChar )
;

var L : Word ;

begin
if P = nil then L := 0
else L := StrLen( P ) ;
WriteBuffer( L, SizeOf( Word ) ) ;
if L > 0 then
WriteBuffer( P[ 0 ], L ) ;
end;

function TCompatibleStream.Get : TStreamObject ;

var AClassID : word ;

begin
{ читаем ID объекта, находим это в
регистраторе и загружаем объект }
ReadBuffer( AClassID, sizeof( AClassID ) ) ;
Result := FindClassInfoByID( AClassID ).ClassType.Load( Self )
;
end ;

procedure TCompatibleStream.Put( AnObject : TStreamObject )
;

var AClassInfo : TClassInfo ;
ANotedPosition : longint ;
DoTruncate : boolean ;

begin
{ получает объект из регистратора
}
AClassInfo := FindClassInfo( AnObject.ClassType ) ;

{ запоминаем позицию в случае проблемы
}
ANotedPosition := Position ;
try
{ пишем id класса и вызываем метод store
}
WriteBuffer( AClassInfo.ClassID, sizeof( AClassInfo.ClassID ) )
;
AnObject.Store( Self ) ;
except
{ откатываемся в предыдущую позицию и, если
EOF, тогда truncate }
DoTruncate := Position = Size ;
Position := ANotedPosition ;
if DoTruncate then Write( ANotedPosition, 0 ) ;
Raise ;
end ;
end ;

{ выход из обработки, очистка регистратора
}

procedure DoneCompStrm ; far ;

var i : integer ;

begin
{ освобождаем регистратор }
for i := Registry.Count - 1
downto 0 do TObject( Registry.Items[ i
]).Free ;

Registry.Free ;
end ;

begin
Registry := TList.Create ;
AddExitProc( DoneCompStrm ) ;
end.
Категория: Pascal | Добавил: Lerka (22 Ноя 2012)
Просмотров: 474 | Рейтинг: 1.0/ 3 Оштрафовать | Жаловаться на материал
Похожие материалы
Всего комментариев: 0

Для блога (HTML)


Для форума (BB-Code)


Прямая ссылка

Профиль
Четверг
14 Ноя 2024
06:19


Вы из группы: Гости
Вы уже дней на сайте
У вас: непрочитанных сообщений
Добавить статью
Прочитать сообщения
Регистрация
Вход
Улучшенный поиск
Поиск по сайту Поиск по всему интернету
Наши партнеры
Интересное
Популярное статьи
Портфолио ученика начальной школы
УХОД ЗА ВОЛОСАМИ ОЧЕНЬ ПРОСТ — ХОЧУ Я ЭТИМ ПОДЕЛИТ...
Диктанты 2 класс
Детство Л.Н. Толстого
Библиографический обзор литературы о музыке
Авторская программа элективного курса "Практи...
Контрольная работа по теме «Углеводороды»
Поиск
Главная страница
Используются технологии uCoz