2 {*******************************************************}
4 { Borland Delphi Visual Component Library }
6 { Copyright (c) 1995,99 Inprise Corporation }
8 {*******************************************************}
14 { ACTIVEX.HPP is not required by CLASSES.HPP }
15 (*$NOINCLUDE ActiveX*)
20 uses kol
, SysUtils
, Windows
, ActiveX
;
24 { Maximum TList size }
26 MaxListSize
= Maxint
div 16;
28 { TStream seek origins }
34 { TFileStream create mode }
38 { TParser special tokens }
47 {!! Moved here from menus.pas !!}
48 { TShortCut special values }
57 { Text alignment types }
59 TAlignment
= (taLeftJustify
, taRightJustify
, taCenter
);
60 TLeftRight
= taLeftJustify
..taRightJustify
;
61 TBiDiMode
= (bdLeftToRight
, bdRightToLeft
, bdRightToLeftNoAlign
,
62 bdRightToLeftReadingOnly
);
64 { Types used by standard events }
66 TShiftState
= set of (ssShift
, ssAlt
, ssCtrl
,
67 ssLeft
, ssRight
, ssMiddle
, ssDouble
);
69 THelpContext
= -MaxLongint
..MaxLongint
;
71 {!! Moved here from menus.pas !!}
72 TShortCut
= Low(Word)..High(Word);
76 TNotifyEvent
= procedure(Sender
: TObject
) of object;
77 THelpEvent
= function (Command
: Word; Data
: Longint;
78 var CallHelp
: Boolean): Boolean of object;
79 TGetStrProc
= procedure(const S
: string) of object;
83 EStreamError
= class(Exception
);
84 EFCreateError
= class(EStreamError
);
85 EFOpenError
= class(EStreamError
);
86 EFilerError
= class(EStreamError
);
87 EReadError
= class(EFilerError
);
88 EWriteError
= class(EFilerError
);
89 EClassNotFound
= class(EFilerError
);
90 EMethodNotFound
= class(EFilerError
);
91 EInvalidImage
= class(EFilerError
);
92 EResNotFound
= class(Exception
);
93 EListError
= class(Exception
);
94 EBitsError
= class(Exception
);
95 EStringListError
= class(Exception
);
96 EComponentError
= class(Exception
);
97 EParserError
= class(Exception
);
98 EOutOfResources
= class(EOutOfMemory
);
99 EInvalidOperation
= class(Exception
);
101 { Duplicate management }
103 TDuplicates
= (dupIgnore
, dupAccept
, dupError
);
105 { Forward class declarations }
115 PPointerList
= ^TPointerList
;
116 TPointerList
= array[0..MaxListSize
- 1] of Pointer;
117 TListSortCompare
= function (Item1
, Item2
: Pointer): Integer;
118 TListNotification
= (lnAdded
, lnExtracted
, lnDeleted
);
120 TList
= class(TObject
)
126 function Get(Index
: Integer): Pointer;
127 procedure Grow
; virtual;
128 procedure Put(Index
: Integer; Item
: Pointer);
129 procedure Notify(Ptr
: Pointer; Action
: TListNotification
); virtual;
130 procedure SetCapacity(NewCapacity
: Integer);
131 procedure SetCount(NewCount
: Integer);
133 destructor Destroy
; override;
134 function Add(Item
: Pointer): Integer;
135 procedure Clear
; virtual;
136 procedure Delete(Index
: Integer);
137 class procedure Error(const Msg
: string; Data
: Integer); overload
; virtual;
138 class procedure Error(Msg
: PResStringRec
; Data
: Integer); overload
;
139 procedure Exchange(Index1
, Index2
: Integer);
140 function Expand
: TList
;
141 function Extract(Item
: Pointer): Pointer;
142 function First
: Pointer;
143 function IndexOf(Item
: Pointer): Integer;
144 procedure Insert(Index
: Integer; Item
: Pointer);
145 function Last
: Pointer;
146 procedure Move(CurIndex
, NewIndex
: Integer);
147 function Remove(Item
: Pointer): Integer;
149 procedure Sort(Compare
: TListSortCompare
);
150 property Capacity
: Integer read FCapacity write SetCapacity
;
151 property Count
: Integer read FCount write SetCount
;
152 property Items
[Index
: Integer]: Pointer read Get write Put
; default
;
153 property List
: PPointerList read FList
;
156 { TThreadList class }
161 FLock
: TRTLCriticalSection
;
162 FDuplicates
: TDuplicates
;
165 destructor Destroy
; override;
166 procedure Add(Item
: Pointer);
168 function LockList
: TList
;
169 procedure Remove(Item
: Pointer);
170 procedure UnlockList
;
171 property Duplicates
: TDuplicates read FDuplicates write FDuplicates
;
174 { IInterfaceList interface }
176 IInterfaceList
= interface
177 ['{285DEA8A-B865-11D1-AAA7-00C04FB17A72}']
178 function Get(Index
: Integer): IUnknown
;
179 function GetCapacity
: Integer;
180 function GetCount
: Integer;
181 procedure Put(Index
: Integer; Item
: IUnknown
);
182 procedure SetCapacity(NewCapacity
: Integer);
183 procedure SetCount(NewCount
: Integer);
186 procedure Delete(Index
: Integer);
187 procedure Exchange(Index1
, Index2
: Integer);
188 function First
: IUnknown
;
189 function IndexOf(Item
: IUnknown
): Integer;
190 function Add(Item
: IUnknown
): Integer;
191 procedure Insert(Index
: Integer; Item
: IUnknown
);
192 function Last
: IUnknown
;
193 function Remove(Item
: IUnknown
): Integer;
196 property Capacity
: Integer read GetCapacity write SetCapacity
;
197 property Count
: Integer read GetCount write SetCount
;
198 property Items
[Index
: Integer]: IUnknown read Get write Put
; default
;
201 { EXTERNALSYM IInterfaceList}
203 { TInterfaceList class }
205 TInterfaceList
= class(TInterfacedObject
, IInterfaceList
)
210 function Get(Index
: Integer): IUnknown
;
211 function GetCapacity
: Integer;
212 function GetCount
: Integer;
213 procedure Put(Index
: Integer; Item
: IUnknown
);
214 procedure SetCapacity(NewCapacity
: Integer);
215 procedure SetCount(NewCount
: Integer);
218 destructor Destroy
; override;
220 procedure Delete(Index
: Integer);
221 procedure Exchange(Index1
, Index2
: Integer);
222 function Expand
: TInterfaceList
;
223 function First
: IUnknown
;
224 function IndexOf(Item
: IUnknown
): Integer;
225 function Add(Item
: IUnknown
): Integer;
226 procedure Insert(Index
: Integer; Item
: IUnknown
);
227 function Last
: IUnknown
;
228 function Remove(Item
: IUnknown
): Integer;
231 property Capacity
: Integer read GetCapacity write SetCapacity
;
232 property Count
: Integer read GetCount write SetCount
;
233 property Items
[Index
: Integer]: IUnknown read Get write Put
; default
;
236 { EXTERNALSYM TInterfaceList}
245 procedure SetSize(Value
: Integer);
246 procedure SetBit(Index
: Integer; Value
: Boolean);
247 function GetBit(Index
: Integer): Boolean;
249 destructor Destroy
; override;
250 function OpenBit
: Integer;
251 property Bits
[Index
: Integer]: Boolean read GetBit write SetBit
; default
;
252 property Size
: Integer read FSize write SetSize
;
255 { TPersistent abstract class }
259 TPersistent
= class(TObject
)
261 procedure AssignError(Source
: TPersistent
);
263 procedure AssignTo(Dest
: TPersistent
); virtual;
264 procedure DefineProperties(Filer
: TFiler
); virtual;
265 function GetOwner
: TPersistent
; dynamic;
267 procedure Assign(Source
: TPersistent
); virtual;
268 function GetNamePath
: string; dynamic;
273 { TPersistent class reference type }
275 TPersistentClass
= class of TPersistent
;
277 { TCollection class }
281 TCollectionItem
= class(TPersistent
)
283 FCollection
: TCollection
;
285 function GetIndex
: Integer;
286 procedure SetCollection(Value
: TCollection
);
288 procedure Changed(AllItems
: Boolean);
289 function GetOwner
: TPersistent
; override;
290 function GetDisplayName
: string; virtual;
291 procedure SetIndex(Value
: Integer); virtual;
292 procedure SetDisplayName(const Value
: string); virtual;
294 constructor Create(Collection
: TCollection
); virtual;
295 destructor Destroy
; override;
296 function GetNamePath
: string; override;
297 property Collection
: TCollection read FCollection write SetCollection
;
298 property ID
: Integer read FID
;
299 property Index
: Integer read GetIndex write SetIndex
;
300 property DisplayName
: string read GetDisplayName write SetDisplayName
;
303 TCollectionItemClass
= class of TCollectionItem
;
305 TCollection
= class(TPersistent
)
307 FItemClass
: TCollectionItemClass
;
309 FUpdateCount
: Integer;
312 function GetCount
: Integer;
313 function GetPropName
: string;
314 procedure InsertItem(Item
: TCollectionItem
);
315 procedure RemoveItem(Item
: TCollectionItem
);
317 property NextID
: Integer read FNextID
;
318 { Design-time editor support }
319 function GetAttrCount
: Integer; dynamic;
320 function GetAttr(Index
: Integer): string; dynamic;
321 function GetItemAttr(Index
, ItemIndex
: Integer): string; dynamic;
323 function GetItem(Index
: Integer): TCollectionItem
;
324 procedure SetItem(Index
: Integer; Value
: TCollectionItem
);
325 procedure SetItemName(Item
: TCollectionItem
); virtual;
326 procedure Update(Item
: TCollectionItem
); virtual;
327 property PropName
: string read GetPropName write FPropName
;
328 property UpdateCount
: Integer read FUpdateCount
;
330 constructor Create(ItemClass
: TCollectionItemClass
);
331 destructor Destroy
; override;
332 function Add
: TCollectionItem
;
333 procedure Assign(Source
: TPersistent
); override;
334 procedure BeginUpdate
; virtual;
336 procedure Delete(Index
: Integer);
337 procedure EndUpdate
; virtual;
338 function FindItemID(ID
: Integer): TCollectionItem
;
339 function GetNamePath
: string; override;
340 function Insert(Index
: Integer): TCollectionItem
;
341 property Count
: Integer read GetCount
;
342 property ItemClass
: TCollectionItemClass read FItemClass
;
343 property Items
[Index
: Integer]: TCollectionItem read GetItem write SetItem
;
346 { Collection class that maintains an "Owner" in order to obtain property
347 path information at design-time }
349 TOwnedCollection
= class(TCollection
)
353 function GetOwner
: TPersistent
; override;
355 constructor Create(AOwner
: TPersistent
; ItemClass
: TCollectionItemClass
);
361 { Used in the TFormDesigner class to allow component/property editors access
362 to project specific information }
364 TGetModuleProc
= procedure(const FileName
, UnitName
, FormName
,
365 DesignClass
: string; CoClasses
: TStrings
) of object;
367 { IStringsAdapter interface }
368 { Maintains link between TStrings and IStrings implementations }
370 IStringsAdapter
= interface
371 ['{739C2F34-52EC-11D0-9EA6-0020AF3D82DA}']
372 procedure ReferenceStrings(S
: TStrings
);
373 procedure ReleaseStrings
;
378 TStrings
= class(TPersistent
)
380 FUpdateCount
: Integer;
381 FAdapter
: IStringsAdapter
;
382 function GetCommaText
: string;
383 function GetName(Index
: Integer): string;
384 function GetValue(const Name
: string): string;
385 procedure SetCommaText(const Value
: string);
386 procedure SetStringsAdapter(const Value
: IStringsAdapter
);
387 procedure SetValue(const Name
, Value
: string);
389 procedure Error(const Msg
: string; Data
: Integer); overload
;
390 procedure Error(Msg
: PResStringRec
; Data
: Integer); overload
;
391 function Get(Index
: Integer): string; virtual; abstract;
392 function GetCapacity
: Integer; virtual;
393 function GetCount
: Integer; virtual; abstract;
394 function GetObject(Index
: Integer): TObject
; virtual;
395 function GetTextStr
: string; virtual;
396 procedure Put(Index
: Integer; const S
: string); virtual;
397 procedure PutObject(Index
: Integer; AObject
: TObject
); virtual;
398 procedure SetCapacity(NewCapacity
: Integer); virtual;
399 procedure SetTextStr(const Value
: string); virtual;
400 procedure SetUpdateState(Updating
: Boolean); virtual;
402 destructor Destroy
; override;
403 function Add(const S
: string): Integer; virtual;
404 function AddObject(const S
: string; AObject
: TObject
): Integer; virtual;
405 procedure Append(const S
: string);
406 procedure AddStrings(Strings
: TStrings
); virtual;
407 procedure Assign(Source
: TPersistent
); override;
408 procedure BeginUpdate
;
409 procedure Clear
; virtual; abstract;
410 procedure Delete(Index
: Integer); virtual; abstract;
412 function Equals(Strings
: TStrings
): Boolean;
413 procedure Exchange(Index1
, Index2
: Integer); virtual;
414 function GetText
: PChar
; virtual;
415 function IndexOf(const S
: string): Integer; virtual;
416 function IndexOfName(const Name
: string): Integer;
417 function IndexOfObject(AObject
: TObject
): Integer;
418 procedure Insert(Index
: Integer; const S
: string); virtual; abstract;
419 procedure InsertObject(Index
: Integer; const S
: string;
421 procedure LoadFromFile(const FileName
: string); virtual;
422 procedure LoadFromStream(Stream
: TStream
); virtual;
423 procedure Move(CurIndex
, NewIndex
: Integer); virtual;
424 procedure SaveToFile(const FileName
: string); virtual;
425 procedure SaveToStream(Stream
: TStream
); virtual;
426 procedure SetText(Text: PChar
); virtual;
427 property Capacity
: Integer read GetCapacity write SetCapacity
;
428 property CommaText
: string read GetCommaText write SetCommaText
;
429 property Count
: Integer read GetCount
;
430 property Names
[Index
: Integer]: string read GetName
;
431 property Objects
[Index
: Integer]: TObject read GetObject write PutObject
;
432 property Values
[const Name
: string]: string read GetValue write SetValue
;
433 property Strings
[Index
: Integer]: string read Get write Put
; default
;
434 property Text: string read GetTextStr write SetTextStr
;
435 property StringsAdapter
: IStringsAdapter read FAdapter write SetStringsAdapter
;
438 { TStringList class }
442 PStringItem
= ^TStringItem
;
448 PStringItemList
= ^TStringItemList
;
449 TStringItemList
= array[0..MaxListSize
] of TStringItem
;
450 TStringListSortCompare
= function(List
: TStringList
; Index1
, Index2
: Integer): Integer;
452 TStringList
= class(TStrings
)
454 FList
: PStringItemList
;
458 FDuplicates
: TDuplicates
;
459 FOnChange
: TNotifyEvent
;
460 FOnChanging
: TNotifyEvent
;
461 procedure ExchangeItems(Index1
, Index2
: Integer);
463 procedure QuickSort(L
, R
: Integer; SCompare
: TStringListSortCompare
);
464 procedure InsertItem(Index
: Integer; const S
: string);
465 procedure SetSorted(Value
: Boolean);
467 procedure Changed
; virtual;
468 procedure Changing
; virtual;
469 function Get(Index
: Integer): string; override;
470 function GetCapacity
: Integer; override;
471 function GetCount
: Integer; override;
472 function GetObject(Index
: Integer): TObject
; override;
473 procedure Put(Index
: Integer; const S
: string); override;
474 procedure PutObject(Index
: Integer; AObject
: TObject
); override;
475 procedure SetCapacity(NewCapacity
: Integer); override;
476 procedure SetUpdateState(Updating
: Boolean); override;
478 destructor Destroy
; override;
479 function Add(const S
: string): Integer; override;
480 procedure Clear
; override;
481 procedure Delete(Index
: Integer); override;
482 procedure Exchange(Index1
, Index2
: Integer); override;
483 function Find(const S
: string; var Index
: Integer): Boolean; virtual;
484 function IndexOf(const S
: string): Integer; override;
485 procedure Insert(Index
: Integer; const S
: string); override;
486 procedure Sort
; virtual;
487 procedure CustomSort(Compare
: TStringListSortCompare
); virtual;
488 property Duplicates
: TDuplicates read FDuplicates write FDuplicates
;
489 property Sorted
: Boolean read FSorted write SetSorted
;
490 property OnChange
: TNotifyEvent read FOnChange write FOnChange
;
491 property OnChanging
: TNotifyEvent read FOnChanging write FOnChanging
;
494 { TStream abstract class }
496 TStream
= class(TObject
)
498 function GetPosition
: Longint;
499 procedure SetPosition(Pos
: Longint);
500 function GetSize
: Longint;
502 procedure SetSize(NewSize
: Longint); virtual;
504 function Read(var Buffer
; Count
: Longint): Longint; virtual; abstract;
505 function Write(const Buffer
; Count
: Longint): Longint; virtual; abstract;
506 function Seek(Offset
: Longint; Origin
: Word): Longint; virtual; abstract;
507 procedure ReadBuffer(var Buffer
; Count
: Longint);
508 procedure WriteBuffer(const Buffer
; Count
: Longint);
509 function CopyFrom(Source
: TStream
; Count
: Longint): Longint;
510 function ReadComponent(Instance
: TComponent
): TComponent
;
511 function ReadComponentRes(Instance
: TComponent
): TComponent
;
512 procedure WriteComponent(Instance
: TComponent
);
513 procedure WriteComponentRes(const ResName
: string; Instance
: TComponent
);
514 procedure WriteDescendent(Instance
, Ancestor
: TComponent
);
515 procedure WriteDescendentRes(const ResName
: string; Instance
, Ancestor
: TComponent
);
516 procedure WriteResourceHeader(const ResName
: string; out FixupInfo
: Integer);
517 procedure FixupResourceHeader(FixupInfo
: Integer);
518 procedure ReadResHeader
;
519 property Position
: Longint read GetPosition write SetPosition
;
520 property Size
: Longint read GetSize write SetSize
;
523 { THandleStream class }
525 THandleStream
= class(TStream
)
529 procedure SetSize(NewSize
: Longint); override;
531 constructor Create(AHandle
: Integer);
532 function Read(var Buffer
; Count
: Longint): Longint; override;
533 function Write(const Buffer
; Count
: Longint): Longint; override;
534 function Seek(Offset
: Longint; Origin
: Word): Longint; override;
535 property Handle
: Integer read FHandle
;
538 { TFileStream class }
540 TFileStream
= class(THandleStream
)
542 constructor Create(const FileName
: string; Mode
: Word);
543 destructor Destroy
; override;
546 { TCustomMemoryStream abstract class }
548 TCustomMemoryStream
= class(TStream
)
551 FSize
, FPosition
: Longint;
553 procedure SetPointer(Ptr
: Pointer; Size
: Longint);
555 function Read(var Buffer
; Count
: Longint): Longint; override;
556 function Seek(Offset
: Longint; Origin
: Word): Longint; override;
557 procedure SaveToStream(Stream
: TStream
);
558 procedure SaveToFile(const FileName
: string);
559 property Memory
: Pointer read FMemory
;
564 TMemoryStream
= class(TCustomMemoryStream
)
567 procedure SetCapacity(NewCapacity
: Longint);
569 function Realloc(var NewCapacity
: Longint): Pointer; virtual;
570 property Capacity
: Longint read FCapacity write SetCapacity
;
572 destructor Destroy
; override;
574 procedure LoadFromStream(Stream
: TStream
);
575 procedure LoadFromFile(const FileName
: string);
576 procedure SetSize(NewSize
: Longint); override;
577 function Write(const Buffer
; Count
: Longint): Longint; override;
582 TStringStream
= class(TStream
)
587 procedure SetSize(NewSize
: Longint); override;
589 constructor Create(const AString
: string);
590 function Read(var Buffer
; Count
: Longint): Longint; override;
591 function ReadString(Count
: Longint): string;
592 function Seek(Offset
: Longint; Origin
: Word): Longint; override;
593 function Write(const Buffer
; Count
: Longint): Longint; override;
594 procedure WriteString(const AString
: string);
595 property DataString
: string read FDataString
;
600 TResourceStream
= class(TCustomMemoryStream
)
604 procedure Initialize(Instance
: THandle
; Name
, ResType
: PChar
);
606 constructor Create(Instance
: THandle
; const ResName
: string; ResType
: PChar
);
607 constructor CreateFromID(Instance
: THandle
; ResID
: Integer; ResType
: PChar
);
608 destructor Destroy
; override;
609 function Write(const Buffer
; Count
: Longint): Longint; override;
613 { Implements OLE IStream on VCL TStream }
615 TStreamOwnership
= (soReference
, soOwned
);
617 TStreamAdapter
= class(TInterfacedObject
, IStream
)
620 FOwnership
: TStreamOwnership
;
622 constructor Create(Stream
: TStream
; Ownership
: TStreamOwnership
= soReference
);
623 destructor Destroy
; override;
624 function Read(pv
: Pointer; cb
: Longint;
625 pcbRead
: PLongint
): HResult
; virtual; stdcall;
626 function Write(pv
: Pointer; cb
: Longint;
627 pcbWritten
: PLongint
): HResult
; virtual; stdcall;
628 function Seek(dlibMove
: Largeint
; dwOrigin
: Longint;
629 out libNewPosition
: Largeint
): HResult
; virtual; stdcall;
630 function SetSize(libNewSize
: Largeint
): HResult
; virtual; stdcall;
631 function CopyTo(stm
: IStream
; cb
: Largeint
; out cbRead
: Largeint
;
632 out cbWritten
: Largeint
): HResult
; virtual; stdcall;
633 function Commit(grfCommitFlags
: Longint): HResult
; virtual; stdcall;
634 function Revert
: HResult
; virtual; stdcall;
635 function LockRegion(libOffset
: Largeint
; cb
: Largeint
;
636 dwLockType
: Longint): HResult
; virtual; stdcall;
637 function UnlockRegion(libOffset
: Largeint
; cb
: Largeint
;
638 dwLockType
: Longint): HResult
; virtual; stdcall;
639 function Stat(out statstg
: TStatStg
;
640 grfStatFlag
: Longint): HResult
; virtual; stdcall;
641 function Clone(out stm
: IStream
): HResult
; virtual; stdcall;
642 property Stream
: TStream read FStream
;
643 property StreamOwnership
: TStreamOwnership read FOwnership write FOwnership
;
648 TValueType
= (vaNull
, vaList
, vaInt8
, vaInt16
, vaInt32
, vaExtended
,
649 vaString
, vaIdent
, vaFalse
, vaTrue
, vaBinary
, vaSet
, vaLString
,
650 vaNil
, vaCollection
, vaSingle
, vaCurrency
, vaDate
, vaWString
, vaInt64
);
652 TFilerFlag
= (ffInherited
, ffChildPos
, ffInline
);
653 TFilerFlags
= set of TFilerFlag
;
655 TReaderProc
= procedure(Reader
: TReader
) of object;
656 TWriterProc
= procedure(Writer
: TWriter
) of object;
657 TStreamProc
= procedure(Stream
: TStream
) of object;
659 TFiler
= class(TObject
)
662 FLookupRoot
: TComponent
;
663 FAncestor
: TPersistent
;
664 FIgnoreChildren
: Boolean;
666 procedure SetRoot(Value
: TComponent
); virtual;
668 constructor Create(Stream
: TStream
; BufSize
: Integer);
669 procedure DefineProperty(const Name
: string;
670 ReadData
: TReaderProc
; WriteData
: TWriterProc
;
671 HasData
: Boolean); virtual; abstract;
672 procedure DefineBinaryProperty(const Name
: string;
673 ReadData
, WriteData
: TStreamProc
;
674 HasData
: Boolean); virtual; abstract;
675 procedure FlushBuffer
; virtual; abstract;
676 property Root
: TComponent read FRoot write SetRoot
;
677 property LookupRoot
: TComponent read FLookupRoot
;
678 property Ancestor
: TPersistent read FAncestor write FAncestor
;
679 property IgnoreChildren
: Boolean read FIgnoreChildren write FIgnoreChildren
;
682 { TComponent class reference type }
684 TComponentClass
= class of TComponent
;
688 TFindMethodEvent
= procedure(Reader
: TReader
; const MethodName
: string;
689 var Address
: Pointer; var Error
: Boolean) of object;
690 TSetNameEvent
= procedure(Reader
: TReader
; Component
: TComponent
;
691 var Name
: string) of object;
692 TReferenceNameEvent
= procedure(Reader
: TReader
; var Name
: string) of object;
693 TAncestorNotFoundEvent
= procedure(Reader
: TReader
; const ComponentName
: string;
694 ComponentClass
: TPersistentClass
; var Component
: TComponent
) of object;
695 TReadComponentsProc
= procedure(Component
: TComponent
) of object;
696 TReaderError
= procedure(Reader
: TReader
; const Message: string; var Handled
: Boolean) of object;
697 TFindComponentClassEvent
= procedure(Reader
: TReader
; const ClassName
: string;
698 var ComponentClass
: TComponentClass
) of object;
699 TCreateComponentEvent
= procedure(Reader
: TReader
;
700 ComponentClass
: TComponentClass
; var Component
: TComponent
) of object;
702 TReader
= class(TFiler
)
706 CanHandleExceptions
: Boolean;
707 function Error(const Message: string): Boolean; virtual;
708 function FindAncestorComponent(const Name
: string;
709 ComponentClass
: TPersistentClass
): TComponent
; virtual;
710 function FindMethod(Root
: TComponent
; const MethodName
: string): Pointer; virtual;
711 procedure SetName(Component
: TComponent
; var Name
: string); virtual;
712 procedure ReadProperty(AInstance
: TPersistent
);
713 procedure ReadPropValue(Instance
: TPersistent
; PropInfo
: Pointer);
714 procedure ReferenceName(var Name
: string); virtual;
715 procedure PropertyError
;
716 procedure ReadData(Instance
: TComponent
);
717 function ReadSet(SetType
: Pointer): Integer;
718 procedure SetPosition(Value
: Longint);
719 procedure SkipSetBody
;
721 procedure SkipProperty
;
722 procedure SkipComponent(SkipHeader
: Boolean);
727 OnError
: TReaderError
;
728 OnFindMethod
: TFindMethodEvent
;
729 OnSetName
: TSetNameEvent
;
730 OnReferenceName
: TReferenceNameEvent
;
731 OnAncestorNotFound
: TAncestorNotFoundEvent
;
732 OnCreateComponent
: TCreateComponentEvent
;
733 OnFindComponentClass
: TFindComponentClassEvent
;
735 procedure BeginReferences
;
736 procedure CheckValue(Value
: TValueType
);
737 procedure DefineProperty(const Name
: string;
738 ReadData
: TReaderProc
; WriteData
: TWriterProc
;
739 HasData
: Boolean); override;
740 procedure DefineBinaryProperty(const Name
: string;
741 ReadData
, WriteData
: TStreamProc
;
742 HasData
: Boolean); override;
743 function EndOfList
: Boolean;
744 procedure EndReferences
;
745 procedure FixupReferences
;
746 procedure FlushBuffer
; override;
747 function NextValue
: TValueType
;
748 procedure Read(var Buf
; Count
: Longint);
749 function ReadBoolean
: Boolean;
750 function ReadChar
: Char;
751 procedure ReadCollection(Collection
: TCollection
);
752 function ReadComponent(Component
: TComponent
): TComponent
;
753 procedure ReadComponents(AOwner
, AParent
: TComponent
;
754 Proc
: TReadComponentsProc
);
755 function ReadFloat
: Extended
;
756 function ReadSingle
: Single;
757 function ReadCurrency
: Currency
;
758 function ReadDate
: TDateTime
;
759 function ReadIdent
: string;
760 function ReadInteger
: Longint;
761 function ReadInt64
: Int64;
762 procedure ReadListBegin
;
763 procedure ReadListEnd
;
764 procedure ReadPrefix(var Flags
: TFilerFlags
; var AChildPos
: Integer); virtual;
765 function ReadRootComponent(Root
: TComponent
): TComponent
;
766 procedure ReadSignature
;
767 function ReadStr
: string;
768 function ReadString
: string;
769 function ReadWideString
: WideString
;
770 function ReadValue
: TValueType
;
771 procedure CopyValue(Writer
: TWriter
);
776 TFindAncestorEvent
= procedure (Writer
: TWriter
; Component
: TComponent
;
777 const Name
: string; var Ancestor
, RootAncestor
: TComponent
) of object;
779 TWriter
= class(TFiler
)
782 procedure WriteBinary(WriteData
: TStreamProc
);
783 procedure WritePrefix(Flags
: TFilerFlags
; AChildPos
: Integer);
784 procedure WriteProperty(Instance
: TPersistent
; PropInfo
: Pointer);
785 procedure WriteProperties(Instance
: TPersistent
);
786 procedure WritePropName(const PropName
: string);
787 procedure WriteValue(Value
: TValueType
);
790 RootAncestor
: TComponent
;
791 OnFindAncestor
: TFindAncestorEvent
;
793 procedure DefineProperty(const Name
: string;
794 ReadData
: TReaderProc
; WriteData
: TWriterProc
;
795 HasData
: Boolean); override;
796 procedure DefineBinaryProperty(const Name
: string;
797 ReadData
, WriteData
: TStreamProc
;
798 HasData
: Boolean); override;
799 procedure FlushBuffer
; override;
800 procedure Write(const Buf
; Count
: Longint);
801 procedure WriteBoolean(Value
: Boolean);
802 procedure WriteCollection(Value
: TCollection
);
803 procedure WriteComponent(Component
: TComponent
);
804 procedure WriteChar(Value
: Char);
805 procedure WriteDescendent(Root
: TComponent
; AAncestor
: TComponent
);
806 procedure WriteFloat(const Value
: Extended
);
807 procedure WriteSingle(const Value
: Single);
808 procedure WriteCurrency(const Value
: Currency
);
809 procedure WriteDate(const Value
: TDateTime
);
810 procedure WriteIdent(const Ident
: string);
811 procedure WriteInteger(Value
: Longint); overload
;
812 procedure WriteInteger(Value
: Int64); overload
;
813 procedure WriteListBegin
;
814 procedure WriteListEnd
;
815 procedure WriteRootComponent(Root
: TComponent
);
816 procedure WriteSignature
;
817 procedure WriteStr(const Value
: string);
818 procedure WriteString(const Value
: string);
819 procedure WriteWideString(const Value
: WideString
);
824 TParser
= class(TObject
)
835 FSourceLine
: Integer;
839 FWideStr
: WideString
;
840 procedure ReadBuffer
;
841 procedure SkipBlanks
;
843 constructor Create(Stream
: TStream
);
844 destructor Destroy
; override;
845 procedure CheckToken(T
: Char);
846 procedure CheckTokenSymbol(const S
: string);
847 procedure Error(const Ident
: string);
848 procedure ErrorFmt(const Ident
: string; const Args
: array of const);
849 procedure ErrorStr(const Message: string);
850 procedure HexToBinary(Stream
: TStream
);
851 function NextToken
: Char;
852 function SourcePos
: Longint;
853 function TokenComponentIdent
: string;
854 function TokenFloat
: Extended
;
855 function TokenInt
: Int64;
856 function TokenString
: string;
857 function TokenWideString
: WideString
;
858 function TokenSymbolIs(const S
: string): Boolean;
859 property FloatType
: Char read FFloatType
;
860 property SourceLine
: Integer read FSourceLine
;
861 property Token
: Char read FToken
;
866 EThread
= class(Exception
);
868 TThreadMethod
= procedure of object;
869 TThreadPriority
= (tpIdle
, tpLowest
, tpLower
, tpNormal
, tpHigher
, tpHighest
,
876 FTerminated
: Boolean;
878 FFreeOnTerminate
: Boolean;
880 FReturnValue
: Integer;
881 FOnTerminate
: TNotifyEvent
;
882 FMethod
: TThreadMethod
;
883 FSynchronizeException
: TObject
;
884 procedure CallOnTerminate
;
885 function GetPriority
: TThreadPriority
;
886 procedure SetPriority(Value
: TThreadPriority
);
887 procedure SetSuspended(Value
: Boolean);
889 procedure DoTerminate
; virtual;
890 procedure Execute
; virtual; abstract;
891 procedure Synchronize(Method
: TThreadMethod
);
892 property ReturnValue
: Integer read FReturnValue write FReturnValue
;
893 property Terminated
: Boolean read FTerminated
;
895 constructor Create(CreateSuspended
: Boolean);
896 destructor Destroy
; override;
900 function WaitFor
: LongWord
;
901 property FreeOnTerminate
: Boolean read FFreeOnTerminate write FFreeOnTerminate
;
902 property Handle
: THandle read FHandle
;
903 property Priority
: TThreadPriority read GetPriority write SetPriority
;
904 property Suspended
: Boolean read FSuspended write SetSuspended
;
905 property ThreadID
: THandle read FThreadID
;
906 property OnTerminate
: TNotifyEvent read FOnTerminate write FOnTerminate
;
911 TOperation
= (opInsert
, opRemove
);
912 TComponentState
= set of (csLoading
, csReading
, csWriting
, csDestroying
,
913 csDesigning
, csAncestor
, csUpdating
, csFixups
, csFreeNotification
,
914 csInline
, csDesignInstance
);
915 TComponentStyle
= set of (csInheritable
, csCheckPropAvail
);
916 TGetChildProc
= procedure (Child
: TComponent
) of object;
918 TComponentName
= type string;
920 IVCLComObject
= interface
921 ['{E07892A0-F52F-11CF-BD2F-0020AF0E5B81}']
922 function GetTypeInfoCount(out Count
: Integer): HResult
; stdcall;
923 function GetTypeInfo(Index
, LocaleID
: Integer; out TypeInfo
): HResult
; stdcall;
924 function GetIDsOfNames(const IID
: TGUID
; Names
: Pointer;
925 NameCount
, LocaleID
: Integer; DispIDs
: Pointer): HResult
; stdcall;
926 function Invoke(DispID: Integer; const IID
: TGUID
; LocaleID
: Integer;
927 Flags
: Word; var Params
; VarResult
, ExcepInfo
, ArgErr
: Pointer): HResult
; stdcall;
928 function SafeCallException(ExceptObject
: TObject
;
929 ExceptAddr
: Pointer): HResult
;
930 procedure FreeOnRelease
;
933 IDesignerNotify
= interface
934 ['{B971E807-E3A6-11D1-AAB1-00C04FB16FBC}']
936 procedure Notification(AnObject
: TPersistent
; Operation
: TOperation
);
939 TBasicAction
= class;
941 TComponent
= class(TPersistent
)
944 FName
: TComponentName
;
947 FFreeNotifies
: TList
;
948 FDesignInfo
: Longint;
949 FVCLComObject
: Pointer;
950 FComponentState
: TComponentState
;
951 function GetComObject
: IUnknown
;
952 function GetComponent(AIndex
: Integer): TComponent
;
953 function GetComponentCount
: Integer;
954 function GetComponentIndex
: Integer;
955 procedure Insert(AComponent
: TComponent
);
956 procedure Remove(AComponent
: TComponent
);
957 procedure RemoveNotification(AComponent
: TComponent
);
958 procedure SetComponentIndex(Value
: Integer);
959 procedure SetReference(Enable
: Boolean);
961 FComponentStyle
: TComponentStyle
;
962 procedure ChangeName(const NewName
: TComponentName
);
963 procedure ReadState(Reader
: TReader
); virtual;
964 procedure GetChildren(Proc
: TGetChildProc
; Root
: TComponent
); dynamic;
965 function GetChildOwner
: TComponent
; dynamic;
966 function GetChildParent
: TComponent
; dynamic;
967 function GetOwner
: TPersistent
; override;
968 procedure Loaded
; virtual;
969 procedure Notification(AComponent
: TComponent
;
970 Operation
: TOperation
); virtual;
971 procedure SetAncestor(Value
: Boolean);
972 procedure SetDesigning(Value
: Boolean; SetChildren
: Boolean = True);
973 procedure SetInline(Value
: Boolean);
974 procedure SetDesignInstance(Value
: Boolean);
975 procedure SetName(const NewName
: TComponentName
); virtual;
976 procedure SetChildOrder(Child
: TComponent
; Order
: Integer); dynamic;
977 procedure SetParentComponent(Value
: TComponent
); dynamic;
978 procedure Updating
; dynamic;
979 procedure Updated
; dynamic;
980 class procedure UpdateRegistry(Register: Boolean; const ClassID
, ProgID
: string); virtual;
981 procedure ValidateRename(AComponent
: TComponent
;
982 const CurName
, NewName
: string); virtual;
983 procedure ValidateContainer(AComponent
: TComponent
); dynamic;
984 procedure ValidateInsert(AComponent
: TComponent
); dynamic;
985 procedure WriteState(Writer
: TWriter
); virtual;
987 function QueryInterface(const IID
: TGUID
; out Obj
): HResult
; virtual; stdcall;
988 function _AddRef
: Integer; stdcall;
989 function _Release
: Integer; stdcall;
991 function GetTypeInfoCount(out Count
: Integer): HResult
; stdcall;
992 function GetTypeInfo(Index
, LocaleID
: Integer; out TypeInfo
): HResult
; stdcall;
993 function GetIDsOfNames(const IID
: TGUID
; Names
: Pointer;
994 NameCount
, LocaleID
: Integer; DispIDs
: Pointer): HResult
; stdcall;
995 function Invoke(DispID: Integer; const IID
: TGUID
; LocaleID
: Integer;
996 Flags
: Word; var Params
; VarResult
, ExcepInfo
, ArgErr
: Pointer): HResult
; stdcall;
998 constructor Create(AOwner
: TComponent
); virtual;
999 destructor Destroy
; override;
1000 procedure BeforeDestruction
; override;
1001 procedure DestroyComponents
;
1002 procedure Destroying
;
1003 function ExecuteAction(Action
: TBasicAction
): Boolean; dynamic;
1004 function FindComponent(const AName
: string): TComponent
;
1005 procedure FreeNotification(AComponent
: TComponent
);
1006 procedure RemoveFreeNotification(AComponent
: TComponent
);
1007 procedure FreeOnRelease
;
1008 function GetParentComponent
: TComponent
; dynamic;
1009 function GetNamePath
: string; override;
1010 function HasParent
: Boolean; dynamic;
1011 procedure InsertComponent(AComponent
: TComponent
);
1012 procedure RemoveComponent(AComponent
: TComponent
);
1013 function SafeCallException(ExceptObject
: TObject
;
1014 ExceptAddr
: Pointer): HResult
; override;
1015 function UpdateAction(Action
: TBasicAction
): Boolean; dynamic;
1016 property ComObject
: IUnknown read GetComObject
;
1017 property Components
[Index
: Integer]: TComponent read GetComponent
;
1018 property ComponentCount
: Integer read GetComponentCount
;
1019 property ComponentIndex
: Integer read GetComponentIndex write SetComponentIndex
;
1020 property ComponentState
: TComponentState read FComponentState
;
1021 property ComponentStyle
: TComponentStyle read FComponentStyle
;
1022 property DesignInfo
: Longint read FDesignInfo write FDesignInfo
;
1023 property Owner
: TComponent read FOwner
;
1024 property VCLComObject
: Pointer read FVCLComObject write FVCLComObject
;
1026 property Name
: TComponentName read FName write SetName stored
False;
1027 property Tag
: Longint read FTag write FTag default
0;
1030 { TBasicActionLink }
1032 TBasicActionLink
= class(TObject
)
1034 FOnChange
: TNotifyEvent
;
1036 FAction
: TBasicAction
;
1037 procedure AssignClient(AClient
: TObject
); virtual;
1038 procedure Change
; virtual;
1039 function IsOnExecuteLinked
: Boolean; virtual;
1040 procedure SetAction(Value
: TBasicAction
); virtual;
1041 procedure SetOnExecute(Value
: TNotifyEvent
); virtual;
1043 constructor Create(AClient
: TObject
); virtual;
1044 destructor Destroy
; override;
1045 function Execute
: Boolean; virtual;
1046 function Update
: Boolean; virtual;
1047 property Action
: TBasicAction read FAction write SetAction
;
1048 property OnChange
: TNotifyEvent read FOnChange write FOnChange
;
1051 TBasicActionLinkClass
= class of TBasicActionLink
;
1055 TBasicAction
= class(TComponent
)
1057 FOnChange
: TNotifyEvent
;
1058 FOnExecute
: TNotifyEvent
;
1059 FOnUpdate
: TNotifyEvent
;
1062 procedure Change
; virtual;
1063 procedure SetOnExecute(Value
: TNotifyEvent
); virtual;
1064 property OnChange
: TNotifyEvent read FOnChange write FOnChange
;
1066 constructor Create(AOwner
: TComponent
); override;
1067 destructor Destroy
; override;
1068 function HandlesTarget(Target
: TObject
): Boolean; virtual;
1069 procedure UpdateTarget(Target
: TObject
); virtual;
1070 procedure ExecuteTarget(Target
: TObject
); virtual;
1071 function Execute
: Boolean; dynamic;
1072 procedure RegisterChanges(Value
: TBasicActionLink
);
1073 procedure UnRegisterChanges(Value
: TBasicActionLink
);
1074 function Update
: Boolean; virtual;
1075 property OnExecute
: TNotifyEvent read FOnExecute write SetOnExecute
;
1076 property OnUpdate
: TNotifyEvent read FOnUpdate write FOnUpdate
;
1079 { TBasicAction class reference type }
1081 TBasicActionClass
= class of TBasicAction
;
1083 { Component registration handlers }
1085 TActiveXRegType
= (axrComponentOnly
, axrIncludeDescendants
);
1088 RegisterComponentsProc
: procedure(const Page
: string;
1089 ComponentClasses
: array of TComponentClass
) = nil;
1090 RegisterNoIconProc
: procedure(ComponentClasses
: array of TComponentClass
) = nil;
1091 RegisterNonActiveXProc
: procedure(ComponentClasses
: array of TComponentClass
;
1092 AxRegType
: TActiveXRegType
) = nil;
1093 CurrentGroup
: Integer = -1; { Current design group }
1094 CreateVCLComObjectProc
: procedure(Component
: TComponent
) = nil;
1096 { Point and rectangle constructors }
1098 function Point(AX
, AY
: Integer): TPoint
;
1099 function SmallPoint(AX
, AY
: SmallInt
): TSmallPoint
;
1100 function Rect(ALeft
, ATop
, ARight
, ABottom
: Integer): TRect
;
1101 function Bounds(ALeft
, ATop
, AWidth
, AHeight
: Integer): TRect
;
1103 { Class registration routines }
1105 procedure RegisterClass(AClass
: TPersistentClass
);
1106 procedure RegisterClasses(AClasses
: array of TPersistentClass
);
1107 procedure RegisterClassAlias(AClass
: TPersistentClass
; const Alias
: string);
1108 procedure UnRegisterClass(AClass
: TPersistentClass
);
1109 procedure UnRegisterClasses(AClasses
: array of TPersistentClass
);
1110 procedure UnRegisterModuleClasses(Module
: HMODULE
);
1111 function FindClass(const ClassName
: string): TPersistentClass
;
1112 function GetClass(const AClassName
: string): TPersistentClass
;
1114 { Component registration routines }
1116 procedure RegisterComponents(const Page
: string;
1117 ComponentClasses
: array of TComponentClass
);
1118 procedure RegisterNoIcon(ComponentClasses
: array of TComponentClass
);
1119 procedure RegisterNonActiveX(ComponentClasses
: array of TComponentClass
;
1120 AxRegType
: TActiveXRegType
);
1122 function GlobalNameSpace
: TMultiReadExclusiveWriteSynchronizer
;
1124 { Object filing routines }
1127 TIdentMapEntry
= record
1132 TIdentToInt
= function(const Ident
: string; var Int
: Longint): Boolean;
1133 TIntToIdent
= function(Int
: Longint; var Ident
: string): Boolean;
1134 TFindGlobalComponent
= function(const Name
: string): TComponent
;
1137 FindGlobalComponent
: TFindGlobalComponent
;
1139 procedure RegisterIntegerConsts(IntegerType
: Pointer; IdentToInt
: TIdentToInt
;
1140 IntToIdent
: TIntToIdent
);
1141 function IdentToInt(const Ident
: string; var Int
: Longint; const Map
: array of TIdentMapEntry
): Boolean;
1142 function IntToIdent(Int
: Longint; var Ident
: string; const Map
: array of TIdentMapEntry
): Boolean;
1143 function FindIntToIdent(AIntegerType
: Pointer): TIntToIdent
;
1144 function FindIdentToInt(AIntegerType
: Pointer): TIdentToInt
;
1146 function InitInheritedComponent(Instance
: TComponent
; RootAncestor
: TClass
): Boolean;
1147 function InitComponentRes(const ResName
: string; Instance
: TComponent
): Boolean;
1148 function ReadComponentRes(const ResName
: string; Instance
: TComponent
): TComponent
;
1149 function ReadComponentResEx(HInstance
: THandle
; const ResName
: string): TComponent
;
1150 function ReadComponentResFile(const FileName
: string; Instance
: TComponent
): TComponent
;
1151 procedure WriteComponentResFile(const FileName
: string; Instance
: TComponent
);
1153 procedure GlobalFixupReferences
;
1154 procedure GetFixupReferenceNames(Root
: TComponent
; Names
: TStrings
);
1155 procedure GetFixupInstanceNames(Root
: TComponent
;
1156 const ReferenceRootName
: string; Names
: TStrings
);
1157 procedure RedirectFixupReferences(Root
: TComponent
; const OldRootName
,
1158 NewRootName
: string);
1159 procedure RemoveFixupReferences(Root
: TComponent
; const RootName
: string);
1160 procedure RemoveFixups(Instance
: TPersistent
);
1161 function FindNestedComponent(Root
: TComponent
; const NamePath
: string): TComponent
;
1163 procedure BeginGlobalLoading
;
1164 procedure NotifyGlobalLoading
;
1165 procedure EndGlobalLoading
;
1167 function CollectionsEqual(C1
, C2
: TCollection
): Boolean;
1169 { Object conversion routines }
1172 TStreamOriginalFormat
= (sofUnknown
, sofBinary
, sofText
);
1174 procedure ObjectBinaryToText(Input
, Output
: TStream
); overload
;
1175 procedure ObjectBinaryToText(Input
, Output
: TStream
;
1176 var OriginalFormat
: TStreamOriginalFormat
); overload
;
1177 procedure ObjectTextToBinary(Input
, Output
: TStream
); overload
;
1178 procedure ObjectTextToBinary(Input
, Output
: TStream
;
1179 var OriginalFormat
: TStreamOriginalFormat
); overload
;
1181 procedure ObjectResourceToText(Input
, Output
: TStream
); overload
;
1182 procedure ObjectResourceToText(Input
, Output
: TStream
;
1183 var OriginalFormat
: TStreamOriginalFormat
); overload
;
1184 procedure ObjectTextToResource(Input
, Output
: TStream
); overload
;
1185 procedure ObjectTextToResource(Input
, Output
: TStream
;
1186 var OriginalFormat
: TStreamOriginalFormat
); overload
;
1188 function TestStreamFormat(Stream
: TStream
): TStreamOriginalFormat
;
1190 { Utility routines }
1192 function LineStart(Buffer
, BufPos
: PChar
): PChar
;
1193 function ExtractStrings(Separators
, WhiteSpace
: TSysCharSet
; Content
: PChar
;
1194 Strings
: TStrings
): Integer;
1196 procedure BinToHex(Buffer
, Text: PChar
; BufSize
: Integer);
1197 function HexToBin(Text, Buffer
: PChar
; BufSize
: Integer): Integer;
1199 function FindRootDesigner(Obj
: TPersistent
): IDesignerNotify
;
1203 uses Consts
{!, TypInfo};
1206 fGlobalNameSpace
: TMultiReadExclusiveWriteSynchronizer
;
1208 function GlobalNameSpace
: TMultiReadExclusiveWriteSynchronizer
;
1210 if fGlobalNameSpace
= nil then
1211 fGlobalNameSpace
:= TMultiReadExclusiveWriteSynchronizer
.Create
;
1212 Result
:= fGlobalNameSpace
;
1215 { Point and rectangle constructors }
1217 function Point(AX
, AY
: Integer): TPoint
;
1226 function SmallPoint(AX
, AY
: SmallInt
): TSmallPoint
;
1235 function Rect(ALeft
, ATop
, ARight
, ABottom
: Integer): TRect
;
1246 function Bounds(ALeft
, ATop
, AWidth
, AHeight
: Integer): TRect
;
1252 Right
:= ALeft
+ AWidth
;
1253 Bottom
:= ATop
+ AHeight
;
1257 { Class registration routines }
1260 PFieldClassTable
= ^TFieldClassTable
;
1261 TFieldClassTable
= packed record
1263 Classes
: array[0..8191] of ^TPersistentClass
;
1266 function GetFieldClassTable(AClass
: TClass
): PFieldClassTable
; assembler;
1268 MOV EAX,[EAX].vmtFieldTable
1271 MOV EAX,[EAX+2].Integer
1275 procedure ClassNotFound(const ClassName
: string);
1277 raise EClassNotFound
.CreateFmt(SClassNotFound
, [ClassName
]);
1280 function GetClass(const AClassName
: string): TPersistentClass
;
1285 function FindClass(const ClassName
: string): TPersistentClass
;
1287 Result
:= GetClass(ClassName
);
1288 if Result
= nil then ClassNotFound(ClassName
);
1291 function GetFieldClass(Instance
: TObject
;
1292 const ClassName
: string): TPersistentClass
;
1295 ClassTable
: PFieldClassTable
;
1298 ClassType
:= Instance
.ClassType
;
1299 while ClassType
<> TPersistent
do
1301 ClassTable
:= GetFieldClassTable(ClassType
);
1302 if ClassTable
<> nil then
1303 for I
:= 0 to ClassTable
^.Count
- 1 do
1305 Result
:= ClassTable
^.Classes
[I
]^;
1306 if SameText(Result
.ClassName
, ClassName
) then Exit
;
1308 ClassType
:= ClassType
.ClassParent
;
1310 Result
:= GetClass(ClassName
);
1313 procedure RegisterClass(AClass
: TPersistentClass
);
1317 procedure RegisterClasses(AClasses
: array of TPersistentClass
);
1321 for I
:= Low(AClasses
) to High(AClasses
) do RegisterClass(AClasses
[I
]);
1324 procedure RegisterClassAlias(AClass
: TPersistentClass
; const Alias
: string);
1328 procedure UnRegisterClass(AClass
: TPersistentClass
);
1332 procedure UnRegisterClasses(AClasses
: array of TPersistentClass
);
1336 for I
:= Low(AClasses
) to High(AClasses
) do UnRegisterClass(AClasses
[I
]);
1339 procedure UnRegisterModuleClasses(Module
: HMODULE
);
1343 { Component registration routines }
1345 procedure RegisterComponents(const Page
: string;
1346 ComponentClasses
: array of TComponentClass
);
1348 if Assigned(RegisterComponentsProc
) then
1349 RegisterComponentsProc(Page
, ComponentClasses
)
1351 raise EComponentError
.CreateRes(@SRegisterError
);
1354 procedure RegisterNoIcon(ComponentClasses
: array of TComponentClass
);
1356 if Assigned(RegisterNoIconProc
) then
1357 RegisterNoIconProc(ComponentClasses
)
1359 raise EComponentError
.CreateRes(@SRegisterError
);
1362 procedure RegisterNonActiveX(ComponentClasses
: array of TComponentClass
;
1363 AxRegType
: TActiveXRegType
);
1365 if not Assigned(RegisterNonActiveXProc
) then
1366 raise EComponentError
.CreateRes(@SRegisterError
);
1367 RegisterNonActiveXProc(ComponentClasses
, AxRegType
)
1370 { Component filing }
1372 procedure RegisterIntegerConsts(IntegerType
: Pointer; IdentToInt
: TIdentToInt
;
1373 IntToIdent
: TIntToIdent
);
1377 function FindIntToIdent(AIntegerType
: Pointer): TIntToIdent
;
1382 function FindIdentToInt(AIntegerType
: Pointer): TIdentToInt
;
1387 function IdentToInt(const Ident
: string; var Int
: Longint; const Map
: array of TIdentMapEntry
): Boolean;
1391 for I
:= Low(Map
) to High(Map
) do
1392 if SameText(Map
[I
].Name
, Ident
) then
1395 Int
:= Map
[I
].Value
;
1401 function IntToIdent(Int
: Longint; var Ident
: string; const Map
: array of TIdentMapEntry
): Boolean;
1405 for I
:= Low(Map
) to High(Map
) do
1406 if Map
[I
].Value
= Int
then
1409 Ident
:= Map
[I
].Name
;
1416 function InternalReadComponentRes(const ResName
: string; HInst
: THandle
; var Instance
: TComponent
): Boolean;
1419 begin { avoid possible EResNotFound exception }
1420 if HInst
= 0 then HInst
:= HInstance
;
1421 HRsrc
:= FindResource(HInst
, PChar(ResName
), RT_RCDATA
);
1422 Result
:= HRsrc
<> 0;
1423 if not Result
then Exit
;
1424 with TResourceStream
.Create(HInst
, ResName
, RT_RCDATA
) do
1426 Instance
:= ReadComponent(Instance
);
1434 GlobalLoaded
: TList
;
1437 procedure BeginGlobalLoading
;
1439 if GlobalLists
= nil then GlobalLists
:= TList
.Create
;
1440 GlobalLists
.Add(GlobalLoaded
);
1441 GlobalLoaded
:= TList
.Create
;
1444 procedure NotifyGlobalLoading
;
1449 G
:= GlobalLoaded
; // performance: eliminate repeated trips through TLS lookup
1450 for I
:= 0 to G
.Count
- 1 do
1451 TComponent(G
[I
]).Loaded
;
1454 procedure EndGlobalLoading
;
1457 GlobalLoaded
:= GlobalLists
.Last
;
1458 GlobalLists
.Delete(GlobalLists
.Count
- 1);
1459 if GlobalLists
.Count
= 0 then
1460 FreeAndNil(GlobalLists
);
1463 function InitInheritedComponent(Instance
: TComponent
; RootAncestor
: TClass
): Boolean;
1468 function InitComponentRes(const ResName
: string; Instance
: TComponent
): Boolean;
1470 Result
:= InternalReadComponentRes(ResName
, FindResourceHInstance(
1471 FindClassHInstance(Instance
.ClassType
)), Instance
);
1474 function ReadComponentRes(const ResName
: string; Instance
: TComponent
): TComponent
;
1478 if Instance
<> nil then
1479 HInstance
:= FindResourceHInstance(FindClassHInstance(Instance
.ClassType
))
1480 else HInstance
:= 0;
1481 if InternalReadComponentRes(ResName
, HInstance
, Instance
) then
1482 Result
:= Instance
else
1483 raise EResNotFound
.CreateFmt(SResNotFound
, [ResName
]);
1486 function ReadComponentResEx(HInstance
: THandle
; const ResName
: string): TComponent
;
1488 Instance
: TComponent
;
1491 if InternalReadComponentRes(ResName
, HInstance
, Instance
) then
1492 Result
:= Instance
else
1493 raise EResNotFound
.CreateFmt(SResNotFound
, [ResName
]);
1496 function ReadComponentResFile(const FileName
: string; Instance
: TComponent
): TComponent
;
1500 Stream
:= TFileStream
.Create(FileName
, fmOpenRead
or fmShareDenyWrite
);
1502 Result
:= Stream
.ReadComponentRes(Instance
);
1508 procedure WriteComponentResFile(const FileName
: string; Instance
: TComponent
);
1512 Stream
:= TFileStream
.Create(FileName
, fmCreate
);
1514 Stream
.WriteComponentRes(Instance
.ClassName
, Instance
);
1520 function CollectionsEqual(C1
, C2
: TCollection
): Boolean;
1522 S1
, S2
: TMemoryStream
;
1524 procedure WriteCollection(Stream
: TStream
; Collection
: TCollection
);
1528 Writer
:= TWriter
.Create(Stream
, 1024);
1530 Writer
.WriteCollection(Collection
);
1538 if C1
.ClassType
<> C2
.ClassType
then Exit
;
1539 if C1
.Count
<> C2
.Count
then Exit
;
1540 S1
:= TMemoryStream
.Create
;
1542 WriteCollection(S1
, C1
);
1543 S2
:= TMemoryStream
.Create
;
1545 WriteCollection(S2
, C2
);
1546 Result
:= (S1
.Size
= S2
.Size
) and CompareMem(S1
.Memory
, S2
.Memory
, S1
.Size
);
1555 { Utility routines }
1557 function LineStart(Buffer
, BufPos
: PChar
): PChar
; assembler;
1577 function ExtractStrings(Separators
, WhiteSpace
: TSysCharSet
; Content
: PChar
;
1578 Strings
: TStrings
): Integer;
1581 EOS
, InQuote
: Boolean;
1586 if (Content
= nil) or (Content
^=#0) or (Strings
= nil) then Exit
;
1590 Strings
.BeginUpdate
;
1593 while Tail
^ in WhiteSpace
+ [#13, #10] do Inc(Tail
);
1597 while (InQuote
and not (Tail
^ in ['''', '"', #0])) or
1598 not (Tail
^ in Separators
+ [#0, #13, #10, '''', '"']) do Inc(Tail
);
1599 if Tail
^ in ['''', '"'] then
1601 if (QuoteChar
<> #0) and (QuoteChar
= Tail
^) then
1603 else QuoteChar
:= Tail
^;
1604 InQuote
:= QuoteChar
<> #0;
1609 if (Head
<> Tail
) and (Head
^ <> #0) then
1611 if Strings
<> nil then
1613 SetString(Item
, Head
, Tail
- Head
);
1627 destructor TList
.Destroy
;
1632 function TList
.Add(Item
: Pointer): Integer;
1635 if Result
= FCapacity
then
1637 FList
^[Result
] := Item
;
1640 Notify(Item
, lnAdded
);
1643 procedure TList
.Clear
;
1649 procedure TList
.Delete(Index
: Integer);
1653 if (Index
< 0) or (Index
>= FCount
) then
1654 Error(@SListIndexError
, Index
);
1655 Temp
:= Items
[Index
];
1657 if Index
< FCount
then
1658 System
.Move(FList
^[Index
+ 1], FList
^[Index
],
1659 (FCount
- Index
) * SizeOf(Pointer));
1661 Notify(Temp
, lnDeleted
);
1664 class procedure TList
.Error(const Msg
: string; Data
: Integer);
1666 function ReturnAddr
: Pointer;
1672 raise EListError
.CreateFmt(Msg
, [Data
]) at ReturnAddr
;
1675 class procedure TList
.Error(Msg
: PResStringRec
; Data
: Integer);
1677 TList
.Error(LoadResString(Msg
), Data
);
1680 procedure TList
.Exchange(Index1
, Index2
: Integer);
1684 if (Index1
< 0) or (Index1
>= FCount
) then
1685 Error(@SListIndexError
, Index1
);
1686 if (Index2
< 0) or (Index2
>= FCount
) then
1687 Error(@SListIndexError
, Index2
);
1688 Item
:= FList
^[Index1
];
1689 FList
^[Index1
] := FList
^[Index2
];
1690 FList
^[Index2
] := Item
;
1693 function TList
.Expand
: TList
;
1695 if FCount
= FCapacity
then
1700 function TList
.First
: Pointer;
1705 function TList
.Get(Index
: Integer): Pointer;
1707 if (Index
< 0) or (Index
>= FCount
) then
1708 Error(@SListIndexError
, Index
);
1709 Result
:= FList
^[Index
];
1712 procedure TList
.Grow
;
1716 if FCapacity
> 64 then
1717 Delta
:= FCapacity
div 4
1719 if FCapacity
> 8 then
1723 SetCapacity(FCapacity
+ Delta
);
1726 function TList
.IndexOf(Item
: Pointer): Integer;
1729 while (Result
< FCount
) and (FList
^[Result
] <> Item
) do
1731 if Result
= FCount
then
1735 procedure TList
.Insert(Index
: Integer; Item
: Pointer);
1737 if (Index
< 0) or (Index
> FCount
) then
1738 Error(@SListIndexError
, Index
);
1739 if FCount
= FCapacity
then
1741 if Index
< FCount
then
1742 System
.Move(FList
^[Index
], FList
^[Index
+ 1],
1743 (FCount
- Index
) * SizeOf(Pointer));
1744 FList
^[Index
] := Item
;
1747 Notify(Item
, lnAdded
);
1750 function TList
.Last
: Pointer;
1752 Result
:= Get(FCount
- 1);
1755 procedure TList
.Move(CurIndex
, NewIndex
: Integer);
1759 if CurIndex
<> NewIndex
then
1761 if (NewIndex
< 0) or (NewIndex
>= FCount
) then
1762 Error(@SListIndexError
, NewIndex
);
1763 Item
:= Get(CurIndex
);
1764 FList
^[CurIndex
] := nil;
1766 Insert(NewIndex
, nil);
1767 FList
^[NewIndex
] := Item
;
1771 procedure TList
.Put(Index
: Integer; Item
: Pointer);
1775 if (Index
< 0) or (Index
>= FCount
) then
1776 Error(@SListIndexError
, Index
);
1777 Temp
:= FList
^[Index
];
1778 FList
^[Index
] := Item
;
1780 Notify(Temp
, lnDeleted
);
1782 Notify(Item
, lnAdded
);
1785 function TList
.Remove(Item
: Pointer): Integer;
1787 Result
:= IndexOf(Item
);
1792 procedure TList
.Pack
;
1796 for I
:= FCount
- 1 downto 0 do
1797 if Items
[I
] = nil then
1801 procedure TList
.SetCapacity(NewCapacity
: Integer);
1803 if (NewCapacity
< FCount
) or (NewCapacity
> MaxListSize
) then
1804 Error(@SListCapacityError
, NewCapacity
);
1805 if NewCapacity
<> FCapacity
then
1807 ReallocMem(FList
, NewCapacity
* SizeOf(Pointer));
1808 FCapacity
:= NewCapacity
;
1812 procedure TList
.SetCount(NewCount
: Integer);
1816 if (NewCount
< 0) or (NewCount
> MaxListSize
) then
1817 Error(@SListCountError
, NewCount
);
1818 if NewCount
> FCapacity
then
1819 SetCapacity(NewCount
);
1820 if NewCount
> FCount
then
1821 FillChar(FList
^[FCount
], (NewCount
- FCount
) * SizeOf(Pointer), 0)
1823 for I
:= FCount
- 1 downto NewCount
do
1828 procedure QuickSort(SortList
: PPointerList
; L
, R
: Integer;
1829 SCompare
: TListSortCompare
);
1837 P
:= SortList
^[(L
+ R
) shr 1];
1839 while SCompare(SortList
^[I
], P
) < 0 do
1841 while SCompare(SortList
^[J
], P
) > 0 do
1846 SortList
^[I
] := SortList
^[J
];
1853 QuickSort(SortList
, L
, J
, SCompare
);
1858 procedure TList
.Sort(Compare
: TListSortCompare
);
1860 if (FList
<> nil) and (Count
> 0) then
1861 QuickSort(FList
, 0, Count
- 1, Compare
);
1864 function TList
.Extract(Item
: Pointer): Pointer;
1875 Notify(Result
, lnExtracted
);
1879 procedure TList
.Notify(Ptr
: Pointer; Action
: TListNotification
);
1885 constructor TThreadList
.Create
;
1888 InitializeCriticalSection(FLock
);
1889 FList
:= TList
.Create
;
1890 FDuplicates
:= dupIgnore
;
1893 destructor TThreadList
.Destroy
;
1895 LockList
; // Make sure nobody else is inside the list.
1901 DeleteCriticalSection(FLock
);
1905 procedure TThreadList
.Add(Item
: Pointer);
1909 if (Duplicates
= dupAccept
) or
1910 (FList
.IndexOf(Item
) = -1) then
1912 else if Duplicates
= dupError
then
1913 FList
.Error(@SDuplicateItem
, Integer(Item
));
1919 procedure TThreadList
.Clear
;
1929 function TThreadList
.LockList
: TList
;
1931 EnterCriticalSection(FLock
);
1935 procedure TThreadList
.Remove(Item
: Pointer);
1945 procedure TThreadList
.UnlockList
;
1947 LeaveCriticalSection(FLock
);
1952 constructor TInterfaceList
.Create
;
1955 FList
:= TThreadList
.Create
;
1958 destructor TInterfaceList
.Destroy
;
1965 procedure TInterfaceList
.Clear
;
1969 if FList
<> nil then
1971 with FList
.LockList
do
1973 for I
:= 0 to Count
- 1 do
1974 IUnknown(List
[I
]) := nil;
1977 Self
.FList
.UnlockList
;
1982 procedure TInterfaceList
.Delete(Index
: Integer);
1984 with FList
.LockList
do
1986 Self
.Put(Index
, nil);
1989 Self
.FList
.UnlockList
;
1993 function TInterfaceList
.Expand
: TInterfaceList
;
1995 with FList
.LockList
do
2000 Self
.FList
.Unlocklist
;
2004 function TInterfaceList
.First
: IUnknown
;
2009 function TInterfaceList
.Get(Index
: Integer): IUnknown
;
2011 with FList
.LockList
do
2013 if (Index
< 0) or (Index
>= Count
) then Error(@SListIndexError
, Index
);
2014 Result
:= IUnknown(List
[Index
]);
2016 Self
.FList
.UnlockList
;
2020 function TInterfaceList
.GetCapacity
: Integer;
2022 with FList
.LockList
do
2026 Self
.FList
.UnlockList
;
2030 function TInterfaceList
.GetCount
: Integer;
2032 with FList
.LockList
do
2036 Self
.FList
.UnlockList
;
2040 function TInterfaceList
.IndexOf(Item
: IUnknown
): Integer;
2042 with FList
.LockList
do
2044 Result
:= IndexOf(Pointer(Item
));
2046 Self
.FList
.UnlockList
;
2050 function TInterfaceList
.Add(Item
: IUnknown
): Integer;
2052 with FList
.LockList
do
2055 IUnknown(List
[Result
]) := Item
;
2057 Self
.FList
.UnlockList
;
2061 procedure TInterfaceList
.Insert(Index
: Integer; Item
: IUnknown
);
2063 with FList
.LockList
do
2066 IUnknown(List
[Index
]) := Item
;
2068 Self
.FList
.UnlockList
;
2072 function TInterfaceList
.Last
: IUnknown
;
2074 with FList
.LockList
do
2076 Result
:= Self
.Get(Count
- 1);
2078 Self
.FList
.UnlockList
;
2082 procedure TInterfaceList
.Put(Index
: Integer; Item
: IUnknown
);
2084 with FList
.LockList
do
2086 if (Index
< 0) or (Index
>= Count
) then Error(@SListIndexError
, Index
);
2087 IUnknown(List
[Index
]) := Item
;
2089 Self
.FList
.UnlockList
;
2093 function TInterfaceList
.Remove(Item
: IUnknown
): Integer;
2095 with FList
.LockList
do
2097 Result
:= IndexOf(Pointer(Item
));
2100 IUnknown(List
[Result
]) := nil;
2104 Self
.FList
.UnlockList
;
2108 procedure TInterfaceList
.SetCapacity(NewCapacity
: Integer);
2110 with FList
.LockList
do
2112 Capacity
:= NewCapacity
;
2114 Self
.FList
.UnlockList
;
2118 procedure TInterfaceList
.SetCount(NewCount
: Integer);
2120 with FList
.LockList
do
2124 Self
.FList
.UnlockList
;
2128 procedure TInterfaceList
.Exchange(Index1
, Index2
: Integer);
2130 with FList
.LockList
do
2132 Exchange(Index1
, Index2
);
2134 Self
.FList
.UnlockList
;
2138 procedure TInterfaceList
.Lock
;
2143 procedure TInterfaceList
.Unlock
;
2151 BitsPerInt
= SizeOf(Integer) * 8;
2154 TBitEnum
= 0..BitsPerInt
- 1;
2155 TBitSet
= set of TBitEnum
;
2156 PBitArray
= ^TBitArray
;
2157 TBitArray
= array[0..4096] of TBitSet
;
2159 destructor TBits
.Destroy
;
2165 procedure TBits
.Error
;
2167 raise EBitsError
.CreateRes(@SBitsIndexError
);
2170 procedure TBits
.SetSize(Value
: Integer);
2173 NewMemSize
: Integer;
2174 OldMemSize
: Integer;
2176 function Min(X
, Y
: Integer): Integer;
2179 if X
> Y
then Result
:= Y
;
2183 if Value
<> Size
then
2185 if Value
< 0 then Error
;
2186 NewMemSize
:= ((Value
+ BitsPerInt
- 1) div BitsPerInt
) * SizeOf(Integer);
2187 OldMemSize
:= ((Size
+ BitsPerInt
- 1) div BitsPerInt
) * SizeOf(Integer);
2188 if NewMemSize
<> OldMemSize
then
2191 if NewMemSize
<> 0 then
2193 GetMem(NewMem
, NewMemSize
);
2194 FillChar(NewMem
^, NewMemSize
, 0);
2196 if OldMemSize
<> 0 then
2198 if NewMem
<> nil then
2199 Move(FBits
^, NewMem
^, Min(OldMemSize
, NewMemSize
));
2200 FreeMem(FBits
, OldMemSize
);
2208 procedure TBits
.SetBit(Index
: Integer; Value
: Boolean); assembler;
2210 CMP Index
,[EAX].FSize
2213 @@1: MOV EAX,[EAX].FBits
2219 @@2: BTR [EAX],Index
2235 function TBits
.GetBit(Index
: Integer): Boolean; assembler;
2237 CMP Index
,[EAX].FSize
2245 function TBits
.OpenBit
: Integer;
2252 E
:= (Size
+ BitsPerInt
- 1) div BitsPerInt
- 1;
2254 if PBitArray(FBits
)^[I
] <> [0..BitsPerInt
- 1] then
2256 B
:= PBitArray(FBits
)^[I
];
2257 for J
:= Low(J
) to High(J
) do
2259 if not (J
in B
) then
2261 Result
:= I
* BitsPerInt
+ J
;
2262 if Result
>= Size
then Result
:= Size
;
2272 procedure TPersistent
.Assign(Source
: TPersistent
);
2274 if Source
<> nil then Source
.AssignTo(Self
) else AssignError(nil);
2277 procedure TPersistent
.AssignError(Source
: TPersistent
);
2281 if Source
<> nil then
2282 SourceName
:= Source
.ClassName
else
2283 SourceName
:= 'nil';
2284 raise EConvertError
.CreateResFmt(@SAssignError
, [SourceName
, ClassName
]);
2287 procedure TPersistent
.AssignTo(Dest
: TPersistent
);
2289 Dest
.AssignError(Self
);
2292 procedure TPersistent
.DefineProperties(Filer
: TFiler
);
2296 function TPersistent
.GetNamePath
: string;
2300 Result
:= ClassName
;
2301 if (GetOwner
<> nil) then
2303 S
:= GetOwner
.GetNamePath
;
2305 Result
:= S
+ '.' + Result
;
2309 function TPersistent
.GetOwner
: TPersistent
;
2316 constructor TCollectionItem
.Create(Collection
: TCollection
);
2318 SetCollection(Collection
);
2321 destructor TCollectionItem
.Destroy
;
2327 procedure TCollectionItem
.Changed(AllItems
: Boolean);
2329 Item
: TCollectionItem
;
2331 if (FCollection
<> nil) and (FCollection
.FUpdateCount
= 0) then
2333 if AllItems
then Item
:= nil else Item
:= Self
;
2334 FCollection
.Update(Item
);
2338 function TCollectionItem
.GetIndex
: Integer;
2340 if FCollection
<> nil then
2341 Result
:= FCollection
.FItems
.IndexOf(Self
) else
2345 function TCollectionItem
.GetDisplayName
: string;
2347 Result
:= ClassName
;
2350 function TCollectionItem
.GetNamePath
: string;
2352 if FCollection
<> nil then
2353 Result
:= kol
.Format('%s[%d]',[FCollection
.GetNamePath
, Index
])
2355 Result
:= ClassName
;
2358 function TCollectionItem
.GetOwner
: TPersistent
;
2360 Result
:= FCollection
;
2363 procedure TCollectionItem
.SetCollection(Value
: TCollection
);
2365 if FCollection
<> Value
then
2367 if FCollection
<> nil then FCollection
.RemoveItem(Self
);
2368 if Value
<> nil then Value
.InsertItem(Self
);
2372 procedure TCollectionItem
.SetDisplayName(const Value
: string);
2377 procedure TCollectionItem
.SetIndex(Value
: Integer);
2381 CurIndex
:= GetIndex
;
2382 if (CurIndex
>= 0) and (CurIndex
<> Value
) then
2384 FCollection
.FItems
.Move(CurIndex
, Value
);
2391 constructor TCollection
.Create(ItemClass
: TCollectionItemClass
);
2393 FItemClass
:= ItemClass
;
2394 FItems
:= TList
.Create
;
2397 destructor TCollection
.Destroy
;
2400 if FItems
<> nil then Clear
;
2405 function TCollection
.Add
: TCollectionItem
;
2407 Result
:= FItemClass
.Create(Self
);
2410 procedure TCollection
.Assign(Source
: TPersistent
);
2414 if Source
is TCollection
then
2419 for I
:= 0 to TCollection(Source
).Count
- 1 do
2420 Add
.Assign(TCollection(Source
).Items
[I
]);
2426 inherited Assign(Source
);
2429 procedure TCollection
.BeginUpdate
;
2434 procedure TCollection
.Changed
;
2436 if FUpdateCount
= 0 then Update(nil);
2439 procedure TCollection
.Clear
;
2441 if FItems
.Count
> 0 then
2445 while FItems
.Count
> 0 do TCollectionItem(FItems
.Last
).Free
;
2452 procedure TCollection
.EndUpdate
;
2458 function TCollection
.FindItemID(ID
: Integer): TCollectionItem
;
2462 for I
:= 0 to FItems
.Count
-1 do
2464 Result
:= TCollectionItem(FItems
[I
]);
2465 if Result
.ID
= ID
then Exit
;
2470 function TCollection
.GetAttrCount
: Integer;
2475 function TCollection
.GetAttr(Index
: Integer): string;
2480 function TCollection
.GetItemAttr(Index
, ItemIndex
: Integer): string;
2482 Result
:= Items
[ItemIndex
].DisplayName
;
2485 function TCollection
.GetCount
: Integer;
2487 Result
:= FItems
.Count
;
2490 function TCollection
.GetItem(Index
: Integer): TCollectionItem
;
2492 Result
:= FItems
[Index
];
2495 function TCollection
.GetNamePath
: string;
2499 Result
:= ClassName
;
2500 if GetOwner
= nil then Exit
;
2501 S
:= GetOwner
.GetNamePath
;
2502 if S
= '' then Exit
;
2504 if P
= '' then Exit
;
2505 Result
:= S
+ '.' + P
;
2508 function TCollection
.GetPropName
: string;
2513 TypeData: PTypeData;
2517 Result
:= FPropName
;
2520 if (Result <> '') or (Owner = nil) or (Owner.ClassInfo = nil) then Exit;
2521 TypeData := GetTypeData(Owner.ClassInfo);
2522 if (TypeData = nil) or (TypeData^.PropCount = 0) then Exit;
2523 GetMem(Props, TypeData^.PropCount * sizeof(Pointer));
2525 GetPropInfos(Owner.ClassInfo, Props);
2526 for I := 0 to TypeData^.PropCount-1 do
2529 if (PropType^^.Kind = tkClass) and
2530 (GetOrdProp(Owner, Props^[I]) = Integer(Self)) then
2536 Result := FPropName;
2540 function TCollection
.Insert(Index
: Integer): TCollectionItem
;
2543 Result
.Index
:= Index
;
2546 // Out param is more code efficient for interfaces than function result
2547 procedure GetDesigner(Obj
: TPersistent
; out Result
: IDesignerNotify
);
2552 if Obj
= nil then Exit
;
2553 Temp
:= Obj
.GetOwner
;
2556 if (Obj
is TComponent
) and (csDesigning
in TComponent(Obj
).ComponentState
) then
2557 TComponent(Obj
).QueryInterface(IDesignerNotify
, Result
);
2561 if (Obj
is TComponent
) and
2562 not (csDesigning
in TComponent(Obj
).ComponentState
) then Exit
;
2563 GetDesigner(Temp
, Result
);
2567 function FindRootDesigner(Obj
: TPersistent
): IDesignerNotify
;
2569 GetDesigner(Obj
, Result
);
2572 procedure NotifyDesigner(Self
, Item
: TPersistent
; Operation
: TOperation
);
2574 Designer
: IDesignerNotify
;
2576 GetDesigner(Self
, Designer
);
2577 if Designer
<> nil then
2578 Designer
.Notification(Item
, Operation
);
2581 procedure TCollection
.InsertItem(Item
: TCollectionItem
);
2583 if not (Item
is FItemClass
) then TList
.Error(@SInvalidProperty
, 0);
2585 Item
.FCollection
:= Self
;
2586 Item
.FID
:= FNextID
;
2590 NotifyDesigner(Self
, Item
, opInsert
);
2593 procedure TCollection
.RemoveItem(Item
: TCollectionItem
);
2595 NotifyDesigner(Self
, Item
, opRemove
);
2596 FItems
.Remove(Item
);
2597 Item
.FCollection
:= nil;
2601 procedure TCollection
.SetItem(Index
: Integer; Value
: TCollectionItem
);
2603 TCollectionItem(FItems
[Index
]).Assign(Value
);
2606 procedure TCollection
.SetItemName(Item
: TCollectionItem
);
2610 procedure TCollection
.Update(Item
: TCollectionItem
);
2614 procedure TCollection
.Delete(Index
: Integer);
2616 TCollectionItem(FItems
[Index
]).Free
;
2619 { TOwnedCollection }
2621 constructor TOwnedCollection
.Create(AOwner
: TPersistent
;
2622 ItemClass
: TCollectionItemClass
);
2625 inherited Create(ItemClass
);
2628 function TOwnedCollection
.GetOwner
: TPersistent
;
2635 destructor TStrings
.Destroy
;
2637 StringsAdapter
:= nil;
2641 function TStrings
.Add(const S
: string): Integer;
2647 function TStrings
.AddObject(const S
: string; AObject
: TObject
): Integer;
2650 PutObject(Result
, AObject
);
2653 procedure TStrings
.Append(const S
: string);
2658 procedure TStrings
.AddStrings(Strings
: TStrings
);
2664 for I
:= 0 to Strings
.Count
- 1 do
2665 AddObject(Strings
[I
], Strings
.Objects
[I
]);
2671 procedure TStrings
.Assign(Source
: TPersistent
);
2673 if Source
is TStrings
then
2678 AddStrings(TStrings(Source
));
2684 inherited Assign(Source
);
2687 procedure TStrings
.BeginUpdate
;
2689 if FUpdateCount
= 0 then SetUpdateState(True);
2693 procedure TStrings
.EndUpdate
;
2696 if FUpdateCount
= 0 then SetUpdateState(False);
2699 function TStrings
.Equals(Strings
: TStrings
): Boolean;
2705 if Count
<> Strings
.GetCount
then Exit
;
2706 for I
:= 0 to Count
- 1 do if Get(I
) <> Strings
.Get(I
) then Exit
;
2710 procedure TStrings
.Error(const Msg
: string; Data
: Integer);
2712 function ReturnAddr
: Pointer;
2718 raise EStringListError
.CreateFmt(Msg
, [Data
]) at ReturnAddr
;
2721 procedure TStrings
.Error(Msg
: PResStringRec
; Data
: Integer);
2723 Error(LoadResString(Msg
), Data
);
2726 procedure TStrings
.Exchange(Index1
, Index2
: Integer);
2728 TempObject
: TObject
;
2733 TempString
:= Strings
[Index1
];
2734 TempObject
:= Objects
[Index1
];
2735 Strings
[Index1
] := Strings
[Index2
];
2736 Objects
[Index1
] := Objects
[Index2
];
2737 Strings
[Index2
] := TempString
;
2738 Objects
[Index2
] := TempObject
;
2744 function TStrings
.GetCapacity
: Integer;
2745 begin // descendants may optionally override/replace this default implementation
2749 function TStrings
.GetCommaText
: string;
2756 if (Count
= 1) and (Get(0) = '') then
2761 for I
:= 0 to Count
- 1 do
2765 while not (P
^ in [#0..' ','"',',']) do P
:= CharNext(P
);
2766 if (P
^ <> #0) then S
:= AnsiQuotedStr(S
, '"');
2767 Result
:= Result
+ S
+ ',';
2769 System
.Delete(Result
, Length(Result
), 1);
2773 function TStrings
.GetName(Index
: Integer): string;
2777 Result
:= Get(Index
);
2778 P
:= AnsiPos('=', Result
);
2780 SetLength(Result
, P
-1) else
2781 SetLength(Result
, 0);
2784 function TStrings
.GetObject(Index
: Integer): TObject
;
2789 function TStrings
.GetText
: PChar
;
2791 Result
:= StrNew(PChar(GetTextStr
));
2794 function TStrings
.GetTextStr
: string;
2796 I
, L
, Size
, Count
: Integer;
2802 for I
:= 0 to Count
- 1 do Inc(Size
, Length(Get(I
)) + 2);
2803 SetString(Result
, nil, Size
);
2804 P
:= Pointer(Result
);
2805 for I
:= 0 to Count
- 1 do
2811 System
.Move(Pointer(S
)^, P
^, L
);
2821 function TStrings
.GetValue(const Name
: string): string;
2825 I
:= IndexOfName(Name
);
2827 Result
:= Copy(Get(I
), Length(Name
) + 2, MaxInt
) else
2831 function TStrings
.IndexOf(const S
: string): Integer;
2833 for Result
:= 0 to GetCount
- 1 do
2834 if AnsiCompareText(Get(Result
), S
) = 0 then Exit
;
2838 function TStrings
.IndexOfName(const Name
: string): Integer;
2843 for Result
:= 0 to GetCount
- 1 do
2846 P
:= AnsiPos('=', S
);
2847 if (P
<> 0) and (AnsiCompareText(Copy(S
, 1, P
- 1), Name
) = 0) then Exit
;
2852 function TStrings
.IndexOfObject(AObject
: TObject
): Integer;
2854 for Result
:= 0 to GetCount
- 1 do
2855 if GetObject(Result
) = AObject
then Exit
;
2859 procedure TStrings
.InsertObject(Index
: Integer; const S
: string;
2863 PutObject(Index
, AObject
);
2866 procedure TStrings
.LoadFromFile(const FileName
: string);
2870 Stream
:= TFileStream
.Create(FileName
, fmOpenRead
or fmShareDenyWrite
);
2872 LoadFromStream(Stream
);
2878 procedure TStrings
.LoadFromStream(Stream
: TStream
);
2885 Size
:= Stream
.Size
- Stream
.Position
;
2886 SetString(S
, nil, Size
);
2887 Stream
.Read(Pointer(S
)^, Size
);
2894 procedure TStrings
.Move(CurIndex
, NewIndex
: Integer);
2896 TempObject
: TObject
;
2899 if CurIndex
<> NewIndex
then
2903 TempString
:= Get(CurIndex
);
2904 TempObject
:= GetObject(CurIndex
);
2906 InsertObject(NewIndex
, TempString
, TempObject
);
2913 procedure TStrings
.Put(Index
: Integer; const S
: string);
2915 TempObject
: TObject
;
2917 TempObject
:= GetObject(Index
);
2919 InsertObject(Index
, S
, TempObject
);
2922 procedure TStrings
.PutObject(Index
: Integer; AObject
: TObject
);
2926 procedure TStrings
.SaveToFile(const FileName
: string);
2930 Stream
:= TFileStream
.Create(FileName
, fmCreate
);
2932 SaveToStream(Stream
);
2938 procedure TStrings
.SaveToStream(Stream
: TStream
);
2943 Stream
.WriteBuffer(Pointer(S
)^, Length(S
));
2946 procedure TStrings
.SetCapacity(NewCapacity
: Integer);
2948 // do nothing - descendants may optionally implement this method
2951 procedure TStrings
.SetCommaText(const Value
: string);
2960 while P
^ in [#1..' '] do P
:= CharNext(P
);
2964 S
:= AnsiExtractQuotedStr(P
, '"')
2968 while (P
^ > ' ') and (P
^ <> ',') do P
:= CharNext(P
);
2969 SetString(S
, P1
, P
- P1
);
2972 while P
^ in [#1..' '] do P
:= CharNext(P
);
2976 until not (P
^ in [#1..' ']);
2983 procedure TStrings
.SetStringsAdapter(const Value
: IStringsAdapter
);
2985 if FAdapter
<> nil then FAdapter
.ReleaseStrings
;
2987 if FAdapter
<> nil then FAdapter
.ReferenceStrings(Self
);
2990 procedure TStrings
.SetText(Text: PChar
);
2995 procedure TStrings
.SetTextStr(const Value
: string);
3003 P
:= Pointer(Value
);
3008 while not (P
^ in [#0, #10, #13]) do Inc(P
);
3009 SetString(S
, Start
, P
- Start
);
3011 if P
^ = #13 then Inc(P
);
3012 if P
^ = #10 then Inc(P
);
3019 procedure TStrings
.SetUpdateState(Updating
: Boolean);
3023 procedure TStrings
.SetValue(const Name
, Value
: string);
3027 I
:= IndexOfName(Name
);
3030 if I
< 0 then I
:= Add('');
3031 Put(I
, Name
+ '=' + Value
);
3034 if I
>= 0 then Delete(I
);
3040 destructor TStringList
.Destroy
;
3045 if FCount
<> 0 then Finalize(FList
^[0], FCount
);
3050 function TStringList
.Add(const S
: string): Integer;
3055 if Find(S
, Result
) then
3058 dupError
: Error(@SDuplicateString
, 0);
3060 InsertItem(Result
, S
);
3063 procedure TStringList
.Changed
;
3065 if (FUpdateCount
= 0) and Assigned(FOnChange
) then FOnChange(Self
);
3068 procedure TStringList
.Changing
;
3070 if (FUpdateCount
= 0) and Assigned(FOnChanging
) then FOnChanging(Self
);
3073 procedure TStringList
.Clear
;
3078 Finalize(FList
^[0], FCount
);
3085 procedure TStringList
.Delete(Index
: Integer);
3087 if (Index
< 0) or (Index
>= FCount
) then Error(@SListIndexError
, Index
);
3089 Finalize(FList
^[Index
]);
3091 if Index
< FCount
then
3092 System
.Move(FList
^[Index
+ 1], FList
^[Index
],
3093 (FCount
- Index
) * SizeOf(TStringItem
));
3097 procedure TStringList
.Exchange(Index1
, Index2
: Integer);
3099 if (Index1
< 0) or (Index1
>= FCount
) then Error(@SListIndexError
, Index1
);
3100 if (Index2
< 0) or (Index2
>= FCount
) then Error(@SListIndexError
, Index2
);
3102 ExchangeItems(Index1
, Index2
);
3106 procedure TStringList
.ExchangeItems(Index1
, Index2
: Integer);
3109 Item1
, Item2
: PStringItem
;
3111 Item1
:= @FList
^[Index1
];
3112 Item2
:= @FList
^[Index2
];
3113 Temp
:= Integer(Item1
^.FString
);
3114 Integer(Item1
^.FString
) := Integer(Item2
^.FString
);
3115 Integer(Item2
^.FString
) := Temp
;
3116 Temp
:= Integer(Item1
^.FObject
);
3117 Integer(Item1
^.FObject
) := Integer(Item2
^.FObject
);
3118 Integer(Item2
^.FObject
) := Temp
;
3121 function TStringList
.Find(const S
: string; var Index
: Integer): Boolean;
3123 L
, H
, I
, C
: Integer;
3131 C
:= AnsiCompareText(FList
^[I
].FString
, S
);
3132 if C
< 0 then L
:= I
+ 1 else
3138 if Duplicates
<> dupAccept
then L
:= I
;
3145 function TStringList
.Get(Index
: Integer): string;
3147 if (Index
< 0) or (Index
>= FCount
) then Error(@SListIndexError
, Index
);
3148 Result
:= FList
^[Index
].FString
;
3151 function TStringList
.GetCapacity
: Integer;
3153 Result
:= FCapacity
;
3156 function TStringList
.GetCount
: Integer;
3161 function TStringList
.GetObject(Index
: Integer): TObject
;
3163 if (Index
< 0) or (Index
>= FCount
) then Error(@SListIndexError
, Index
);
3164 Result
:= FList
^[Index
].FObject
;
3167 procedure TStringList
.Grow
;
3171 if FCapacity
> 64 then Delta
:= FCapacity
div 4 else
3172 if FCapacity
> 8 then Delta
:= 16 else
3174 SetCapacity(FCapacity
+ Delta
);
3177 function TStringList
.IndexOf(const S
: string): Integer;
3179 if not Sorted
then Result
:= inherited IndexOf(S
) else
3180 if not Find(S
, Result
) then Result
:= -1;
3183 procedure TStringList
.Insert(Index
: Integer; const S
: string);
3185 if Sorted
then Error(@SSortedListError
, 0);
3186 if (Index
< 0) or (Index
> FCount
) then Error(@SListIndexError
, Index
);
3187 InsertItem(Index
, S
);
3190 procedure TStringList
.InsertItem(Index
: Integer; const S
: string);
3193 if FCount
= FCapacity
then Grow
;
3194 if Index
< FCount
then
3195 System
.Move(FList
^[Index
], FList
^[Index
+ 1],
3196 (FCount
- Index
) * SizeOf(TStringItem
));
3197 with FList
^[Index
] do
3199 Pointer(FString
) := nil;
3207 procedure TStringList
.Put(Index
: Integer; const S
: string);
3209 if Sorted
then Error(@SSortedListError
, 0);
3210 if (Index
< 0) or (Index
>= FCount
) then Error(@SListIndexError
, Index
);
3212 FList
^[Index
].FString
:= S
;
3216 procedure TStringList
.PutObject(Index
: Integer; AObject
: TObject
);
3218 if (Index
< 0) or (Index
>= FCount
) then Error(@SListIndexError
, Index
);
3220 FList
^[Index
].FObject
:= AObject
;
3224 procedure TStringList
.QuickSort(L
, R
: Integer; SCompare
: TStringListSortCompare
);
3233 while SCompare(Self
, I
, P
) < 0 do Inc(I
);
3234 while SCompare(Self
, J
, P
) > 0 do Dec(J
);
3237 ExchangeItems(I
, J
);
3246 if L
< J
then QuickSort(L
, J
, SCompare
);
3251 procedure TStringList
.SetCapacity(NewCapacity
: Integer);
3253 ReallocMem(FList
, NewCapacity
* SizeOf(TStringItem
));
3254 FCapacity
:= NewCapacity
;
3257 procedure TStringList
.SetSorted(Value
: Boolean);
3259 if FSorted
<> Value
then
3266 procedure TStringList
.SetUpdateState(Updating
: Boolean);
3268 if Updating
then Changing
else Changed
;
3271 function StringListAnsiCompare(List
: TStringList
; Index1
, Index2
: Integer): Integer;
3273 Result
:= AnsiCompareText(List
.FList
^[Index1
].FString
,
3274 List
.FList
^[Index2
].FString
);
3277 procedure TStringList
.Sort
;
3279 CustomSort(StringListAnsiCompare
);
3282 procedure TStringList
.CustomSort(Compare
: TStringListSortCompare
);
3284 if not Sorted
and (FCount
> 1) then
3287 QuickSort(0, FCount
- 1, Compare
);
3294 function TStream
.GetPosition
: Longint;
3296 Result
:= Seek(0, 1);
3299 procedure TStream
.SetPosition(Pos
: Longint);
3304 function TStream
.GetSize
: Longint;
3309 Result
:= Seek(0, 2);
3313 procedure TStream
.SetSize(NewSize
: Longint);
3315 // default = do nothing (read-only streams, etc)
3318 procedure TStream
.ReadBuffer(var Buffer
; Count
: Longint);
3320 if (Count
<> 0) and (Read(Buffer
, Count
) <> Count
) then
3321 raise EReadError
.CreateRes(@SReadError
);
3324 procedure TStream
.WriteBuffer(const Buffer
; Count
: Longint);
3326 if (Count
<> 0) and (Write(Buffer
, Count
) <> Count
) then
3327 raise EWriteError
.CreateRes(@SWriteError
);
3330 function TStream
.CopyFrom(Source
: TStream
; Count
: Longint): Longint;
3334 BufSize
, N
: Integer;
3339 Source
.Position
:= 0;
3340 Count
:= Source
.Size
;
3343 if Count
> MaxBufSize
then BufSize
:= MaxBufSize
else BufSize
:= Count
;
3344 GetMem(Buffer
, BufSize
);
3348 if Count
> BufSize
then N
:= BufSize
else N
:= Count
;
3349 Source
.ReadBuffer(Buffer
^, N
);
3350 WriteBuffer(Buffer
^, N
);
3354 FreeMem(Buffer
, BufSize
);
3358 function TStream
.ReadComponent(Instance
: TComponent
): TComponent
;
3362 Reader
:= TReader
.Create(Self
, 4096);
3364 Result
:= Reader
.ReadRootComponent(Instance
);
3370 procedure TStream
.WriteComponent(Instance
: TComponent
);
3372 WriteDescendent(Instance
, nil);
3375 procedure TStream
.WriteDescendent(Instance
, Ancestor
: TComponent
);
3379 Writer
:= TWriter
.Create(Self
, 4096);
3381 Writer
.WriteDescendent(Instance
, Ancestor
);
3387 function TStream
.ReadComponentRes(Instance
: TComponent
): TComponent
;
3390 Result
:= ReadComponent(Instance
);
3393 procedure TStream
.WriteComponentRes(const ResName
: string; Instance
: TComponent
);
3395 WriteDescendentRes(ResName
, Instance
, nil);
3398 procedure TStream
.WriteResourceHeader(const ResName
: string; out FixupInfo
: Integer);
3400 HeaderSize
: Integer;
3401 Header
: array[0..79] of Char;
3403 Byte((@Header
[0])^) := $FF;
3404 Word((@Header
[1])^) := 10;
3405 HeaderSize
:= StrLen(StrUpper(StrPLCopy(@Header
[3], ResName
, 63))) + 10;
3406 Word((@Header
[HeaderSize
- 6])^) := $1030;
3407 Longint((@Header
[HeaderSize
- 4])^) := 0;
3408 WriteBuffer(Header
, HeaderSize
);
3409 FixupInfo
:= Position
;
3412 procedure TStream
.FixupResourceHeader(FixupInfo
: Integer);
3416 ImageSize
:= Position
- FixupInfo
;
3417 Position
:= FixupInfo
- 4;
3418 WriteBuffer(ImageSize
, SizeOf(Longint));
3419 Position
:= FixupInfo
+ ImageSize
;
3422 procedure TStream
.WriteDescendentRes(const ResName
: string; Instance
,
3423 Ancestor
: TComponent
);
3427 WriteResourceHeader(ResName
, FixupInfo
);
3428 WriteDescendent(Instance
, Ancestor
);
3429 FixupResourceHeader(FixupInfo
);
3432 procedure TStream
.ReadResHeader
;
3434 ReadCount
: Cardinal;
3435 Header
: array[0..79] of Char;
3437 FillChar(Header
, SizeOf(Header
), 0);
3438 ReadCount
:= Read(Header
, SizeOf(Header
) - 1);
3439 if (Byte((@Header
[0])^) = $FF) and (Word((@Header
[1])^) = 10) then
3440 Seek(StrLen(Header
+ 3) + 10 - ReadCount
, 1)
3442 raise EInvalidImage
.CreateRes(@SInvalidImage
);
3447 constructor THandleStream
.Create(AHandle
: Integer);
3452 function THandleStream
.Read(var Buffer
; Count
: Longint): Longint;
3454 Result
:= FileRead(FHandle
, Buffer
, Count
);
3455 if Result
= -1 then Result
:= 0;
3458 function THandleStream
.Write(const Buffer
; Count
: Longint): Longint;
3460 Result
:= FileWrite(FHandle
, Buffer
, Count
);
3461 if Result
= -1 then Result
:= 0;
3464 function THandleStream
.Seek(Offset
: Longint; Origin
: Word): Longint;
3466 Result
:= FileSeek(FHandle
, Offset
, Origin
);
3469 procedure THandleStream
.SetSize(NewSize
: Longint);
3471 Seek(NewSize
, soFromBeginning
);
3472 Win32Check(SetEndOfFile(FHandle
));
3477 constructor TFileStream
.Create(const FileName
: string; Mode
: Word);
3479 if Mode
= fmCreate
then
3481 FHandle
:= FileCreate(FileName
);
3483 raise EFCreateError
.CreateResFmt(@SFCreateError
, [FileName
]);
3486 FHandle
:= FileOpen(FileName
, Mode
);
3488 raise EFOpenError
.CreateResFmt(@SFOpenError
, [FileName
]);
3492 destructor TFileStream
.Destroy
;
3494 if FHandle
>= 0 then FileClose(FHandle
);
3498 { TCustomMemoryStream }
3500 procedure TCustomMemoryStream
.SetPointer(Ptr
: Pointer; Size
: Longint);
3506 function TCustomMemoryStream
.Read(var Buffer
; Count
: Longint): Longint;
3508 if (FPosition
>= 0) and (Count
>= 0) then
3510 Result
:= FSize
- FPosition
;
3513 if Result
> Count
then Result
:= Count
;
3514 Move(Pointer(Longint(FMemory
) + FPosition
)^, Buffer
, Result
);
3515 Inc(FPosition
, Result
);
3522 function TCustomMemoryStream
.Seek(Offset
: Longint; Origin
: Word): Longint;
3525 soFromBeginning
: FPosition
:= Offset
;
3526 soFromCurrent
: Inc(FPosition
, Offset
);
3527 soFromEnd
: FPosition
:= FSize
+ Offset
;
3529 Result
:= FPosition
;
3532 procedure TCustomMemoryStream
.SaveToStream(Stream
: TStream
);
3534 if FSize
<> 0 then Stream
.WriteBuffer(FMemory
^, FSize
);
3537 procedure TCustomMemoryStream
.SaveToFile(const FileName
: string);
3541 Stream
:= TFileStream
.Create(FileName
, fmCreate
);
3543 SaveToStream(Stream
);
3552 MemoryDelta
= $2000; { Must be a power of 2 }
3554 destructor TMemoryStream
.Destroy
;
3560 procedure TMemoryStream
.Clear
;
3567 procedure TMemoryStream
.LoadFromStream(Stream
: TStream
);
3571 Stream
.Position
:= 0;
3572 Count
:= Stream
.Size
;
3574 if Count
<> 0 then Stream
.ReadBuffer(FMemory
^, Count
);
3577 procedure TMemoryStream
.LoadFromFile(const FileName
: string);
3581 Stream
:= TFileStream
.Create(FileName
, fmOpenRead
or fmShareDenyWrite
);
3583 LoadFromStream(Stream
);
3589 procedure TMemoryStream
.SetCapacity(NewCapacity
: Longint);
3591 SetPointer(Realloc(NewCapacity
), FSize
);
3592 FCapacity
:= NewCapacity
;
3595 procedure TMemoryStream
.SetSize(NewSize
: Longint);
3597 OldPosition
: Longint;
3599 OldPosition
:= FPosition
;
3600 SetCapacity(NewSize
);
3602 if OldPosition
> NewSize
then Seek(0, soFromEnd
);
3605 function TMemoryStream
.Realloc(var NewCapacity
: Longint): Pointer;
3607 if NewCapacity
> 0 then
3608 NewCapacity
:= (NewCapacity
+ (MemoryDelta
- 1)) and not (MemoryDelta
- 1);
3610 if NewCapacity
<> FCapacity
then
3612 if NewCapacity
= 0 then
3614 GlobalFreePtr(Memory
);
3618 if Capacity
= 0 then
3619 Result
:= GlobalAllocPtr(HeapAllocFlags
, NewCapacity
)
3621 Result
:= GlobalReallocPtr(Memory
, NewCapacity
, HeapAllocFlags
);
3622 if Result
= nil then raise EStreamError
.CreateRes(@SMemoryStreamError
);
3627 function TMemoryStream
.Write(const Buffer
; Count
: Longint): Longint;
3631 if (FPosition
>= 0) and (Count
>= 0) then
3633 Pos
:= FPosition
+ Count
;
3638 if Pos
> FCapacity
then
3642 System
.Move(Buffer
, Pointer(Longint(FMemory
) + FPosition
)^, Count
);
3653 constructor TStringStream
.Create(const AString
: string);
3656 FDataString
:= AString
;
3659 function TStringStream
.Read(var Buffer
; Count
: Longint): Longint;
3661 Result
:= Length(FDataString
) - FPosition
;
3662 if Result
> Count
then Result
:= Count
;
3663 Move(PChar(@FDataString
[FPosition
+ 1])^, Buffer
, Result
);
3664 Inc(FPosition
, Result
);
3667 function TStringStream
.Write(const Buffer
; Count
: Longint): Longint;
3670 SetLength(FDataString
, (FPosition
+ Result
));
3671 Move(Buffer
, PChar(@FDataString
[FPosition
+ 1])^, Result
);
3672 Inc(FPosition
, Result
);
3675 function TStringStream
.Seek(Offset
: Longint; Origin
: Word): Longint;
3678 soFromBeginning
: FPosition
:= Offset
;
3679 soFromCurrent
: FPosition
:= FPosition
+ Offset
;
3680 soFromEnd
: FPosition
:= Length(FDataString
) - Offset
;
3682 if FPosition
> Length(FDataString
) then
3683 FPosition
:= Length(FDataString
)
3684 else if FPosition
< 0 then FPosition
:= 0;
3685 Result
:= FPosition
;
3688 function TStringStream
.ReadString(Count
: Longint): string;
3692 Len
:= Length(FDataString
) - FPosition
;
3693 if Len
> Count
then Len
:= Count
;
3694 SetString(Result
, PChar(@FDataString
[FPosition
+ 1]), Len
);
3695 Inc(FPosition
, Len
);
3698 procedure TStringStream
.WriteString(const AString
: string);
3700 Write(PChar(AString
)^, Length(AString
));
3703 procedure TStringStream
.SetSize(NewSize
: Longint);
3705 SetLength(FDataString
, NewSize
);
3706 if FPosition
> NewSize
then FPosition
:= NewSize
;
3711 constructor TResourceStream
.Create(Instance
: THandle
; const ResName
: string;
3715 Initialize(Instance
, PChar(ResName
), ResType
);
3718 constructor TResourceStream
.CreateFromID(Instance
: THandle
; ResID
: Integer;
3722 Initialize(Instance
, PChar(ResID
), ResType
);
3725 procedure TResourceStream
.Initialize(Instance
: THandle
; Name
, ResType
: PChar
);
3729 raise EResNotFound
.CreateFmt(SResNotFound
, [Name
]);
3733 HResInfo
:= FindResource(Instance
, Name
, ResType
);
3734 if HResInfo
= 0 then Error
;
3735 HGlobal
:= LoadResource(Instance
, HResInfo
);
3736 if HGlobal
= 0 then Error
;
3737 SetPointer(LockResource(HGlobal
), SizeOfResource(Instance
, HResInfo
));
3740 destructor TResourceStream
.Destroy
;
3742 UnlockResource(HGlobal
);
3743 FreeResource(HGlobal
);
3747 function TResourceStream
.Write(const Buffer
; Count
: Longint): Longint;
3749 raise EStreamError
.CreateRes(@SCantWriteResourceStreamError
);
3754 constructor TFiler
.Create(Stream
: TStream
; BufSize
: Integer);
3760 function FindNestedComponent(Root
: TComponent
; const NamePath
: string): TComponent
;
3765 procedure GlobalFixupReferences
;
3769 function NameInStrings(Strings
: TStrings
; const Name
: string): Boolean;
3774 for I
:= 0 to Strings
.Count
- 1 do
3775 if SameText(Name
, Strings
[I
]) then Exit
;
3779 procedure GetFixupReferenceNames(Root
: TComponent
; Names
: TStrings
);
3783 procedure RedirectFixupReferences(Root
: TComponent
; const OldRootName
,
3784 NewRootName
: string);
3788 procedure RemoveFixupReferences(Root
: TComponent
; const RootName
: string);
3792 procedure RemoveFixups(Instance
: TPersistent
);
3796 procedure GetFixupInstanceNames(Root
: TComponent
;
3797 const ReferenceRootName
: string; Names
: TStrings
);
3801 procedure TFiler
.SetRoot(Value
: TComponent
);
3807 procedure ReadError(Ident
: PResStringRec
);
3811 procedure PropValueError
;
3815 procedure PropertyNotFound
;
3819 function EnumValue(EnumType: PTypeInfo; const EnumName: string): Integer;
3824 procedure TReader
.BeginReferences
;
3828 procedure TReader
.CheckValue(Value
: TValueType
);
3832 procedure TReader
.DefineProperty(const Name
: string;
3833 ReadData
: TReaderProc
; WriteData
: TWriterProc
; HasData
: Boolean);
3837 procedure TReader
.DefineBinaryProperty(const Name
: string;
3838 ReadData
, WriteData
: TStreamProc
; HasData
: Boolean);
3842 function TReader
.EndOfList
: Boolean;
3847 procedure TReader
.EndReferences
;
3851 function TReader
.Error(const Message: string): Boolean;
3856 function TReader
.FindMethod(Root
: TComponent
;
3857 const MethodName
: string): Pointer;
3862 procedure TReader
.FixupReferences
;
3866 procedure TReader
.FlushBuffer
;
3870 function TReader
.NextValue
: TValueType
;
3875 procedure TReader
.PropertyError
;
3879 procedure TReader
.Read(var Buf
; Count
: Longint);
3883 function TReader
.ReadBoolean
: Boolean;
3888 function TReader
.ReadChar
: Char;
3893 procedure TReader
.ReadCollection(Collection
: TCollection
);
3897 function TReader
.ReadComponent(Component
: TComponent
): TComponent
;
3902 procedure TReader
.ReadData(Instance
: TComponent
);
3906 function TReader
.ReadFloat
: Extended
;
3911 function TReader
.ReadSingle
: Single;
3916 function TReader
.ReadCurrency
: Currency
;
3921 function TReader
.ReadDate
: TDateTime
;
3926 function TReader
.ReadIdent
: string;
3931 function TReader
.ReadInteger
: Longint;
3936 function TReader
.ReadInt64
: Int64;
3941 procedure TReader
.ReadListBegin
;
3945 procedure TReader
.ReadListEnd
;
3949 procedure TReader
.ReadPrefix(var Flags
: TFilerFlags
; var AChildPos
: Integer);
3953 procedure TReader
.ReadProperty(AInstance
: TPersistent
);
3957 procedure TReader
.ReadPropValue(Instance
: TPersistent
; PropInfo
: Pointer);
3961 function TReader
.ReadRootComponent(Root
: TComponent
): TComponent
;
3966 procedure TReader
.ReadComponents(AOwner
, AParent
: TComponent
;
3967 Proc
: TReadComponentsProc
);
3971 function TReader
.ReadSet(SetType
: Pointer): Integer;
3976 procedure TReader
.ReadSignature
;
3980 function TReader
.ReadStr
: string;
3984 function TReader
.ReadString
: string;
3988 function TReader
.ReadWideString
: WideString
;
3992 function TReader
.ReadValue
: TValueType
;
3997 procedure TReader
.SetPosition(Value
: Longint);
4001 procedure TReader
.SkipSetBody
;
4005 procedure TReader
.SkipValue
;
4009 procedure TReader
.CopyValue(Writer
: TWriter
);
4013 procedure TReader
.SkipProperty
;
4017 procedure TReader
.SkipComponent(SkipHeader
: Boolean);
4021 function TReader
.FindAncestorComponent(const Name
: string;
4022 ComponentClass
: TPersistentClass
): TComponent
;
4027 procedure TReader
.ReferenceName(var Name
: string);
4031 procedure TReader
.SetName(Component
: TComponent
; var Name
: string);
4037 procedure TWriter
.DefineProperty(const Name
: string;
4038 ReadData
: TReaderProc
; WriteData
: TWriterProc
; HasData
: Boolean);
4042 procedure TWriter
.DefineBinaryProperty(const Name
: string;
4043 ReadData
, WriteData
: TStreamProc
; HasData
: Boolean);
4047 procedure TWriter
.FlushBuffer
;
4051 procedure TWriter
.Write(const Buf
; Count
: Longint);
4055 procedure TWriter
.WriteBinary(WriteData
: TStreamProc
);
4059 procedure TWriter
.WriteBoolean(Value
: Boolean);
4063 procedure TWriter
.WriteChar(Value
: Char);
4067 procedure TWriter
.WriteCollection(Value
: TCollection
);
4071 procedure TWriter
.WriteComponent(Component
: TComponent
);
4075 procedure TWriter
.WriteDescendent(Root
: TComponent
; AAncestor
: TComponent
);
4079 procedure TWriter
.WriteFloat(const Value
: Extended
);
4083 procedure TWriter
.WriteSingle(const Value
: Single);
4087 procedure TWriter
.WriteCurrency(const Value
: Currency
);
4091 procedure TWriter
.WriteDate(const Value
: TDateTime
);
4095 procedure TWriter
.WriteIdent(const Ident
: string);
4099 procedure TWriter
.WriteInteger(Value
: Longint);
4103 procedure TWriter
.WriteInteger(Value
: Int64);
4107 procedure TWriter
.WriteListBegin
;
4111 procedure TWriter
.WriteListEnd
;
4115 procedure TWriter
.WritePrefix(Flags
: TFilerFlags
; AChildPos
: Integer);
4119 procedure TWriter
.WriteProperties(Instance
: TPersistent
);
4123 procedure TWriter
.WriteProperty(Instance
: TPersistent
; PropInfo
: Pointer);
4127 procedure TWriter
.WritePropName(const PropName
: string);
4131 procedure TWriter
.WriteRootComponent(Root
: TComponent
);
4135 procedure TWriter
.WriteSignature
;
4139 procedure TWriter
.WriteStr(const Value
: string);
4143 procedure TWriter
.WriteString(const Value
: string);
4147 procedure TWriter
.WriteWideString(const Value
: WideString
);
4151 procedure TWriter
.WriteValue(Value
: TValueType
);
4158 ParseBufSize
= 4096;
4160 procedure BinToHex(Buffer
, Text: PChar
; BufSize
: Integer); assembler;
4168 @@0: DB '0123456789ABCDEF'
4172 MOV AH,@@0.
Byte[EDX]
4175 MOV AL,@@0.
Byte[EDX]
4183 function HexToBin(Text, Buffer
: PChar
; BufSize
: Integer): Integer; assembler;
4193 @@0: DB 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
4194 DB -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
4195 DB -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
4196 DB -1,10,11,12,13,14,15
4203 MOV AL,@@0.
Byte[EDX-'0']
4212 MOV AH,@@0.
Byte[EDX-'0']
4226 constructor TParser
.Create(Stream
: TStream
);
4229 GetMem(FBuffer
, ParseBufSize
);
4232 FBufEnd
:= FBuffer
+ ParseBufSize
;
4233 FSourcePtr
:= FBuffer
;
4234 FSourceEnd
:= FBuffer
;
4235 FTokenPtr
:= FBuffer
;
4240 destructor TParser
.Destroy
;
4242 if FBuffer
<> nil then
4244 FStream
.Seek(Longint(FTokenPtr
) - Longint(FBufPtr
), 1);
4245 FreeMem(FBuffer
, ParseBufSize
);
4249 procedure TParser
.CheckToken(T
: Char);
4254 Error(SIdentifierExpected
);
4255 toString
, toWString
:
4256 Error(SStringExpected
);
4258 Error(SNumberExpected
);
4260 ErrorFmt(SCharExpected
, [T
]);
4264 procedure TParser
.CheckTokenSymbol(const S
: string);
4266 if not TokenSymbolIs(S
) then ErrorFmt(SSymbolExpected
, [S
]);
4269 procedure TParser
.Error(const Ident
: string);
4274 procedure TParser
.ErrorFmt(const Ident
: string; const Args
: array of const);
4276 ErrorStr(Format(Ident
, Args
));
4279 procedure TParser
.ErrorStr(const Message: string);
4281 raise EParserError
.CreateResFmt(@SParseError
, [Message, FSourceLine
]);
4284 procedure TParser
.HexToBinary(Stream
: TStream
);
4287 Buffer
: array[0..255] of Char;
4290 while FSourcePtr
^ <> '}' do
4292 Count
:= HexToBin(FSourcePtr
, Buffer
, SizeOf(Buffer
));
4293 if Count
= 0 then Error(SInvalidBinary
);
4294 Stream
.Write(Buffer
, Count
);
4295 Inc(FSourcePtr
, Count
* 2);
4301 function TParser
.NextToken
: Char;
4311 'A'..'Z', 'a'..'z', '_':
4314 while P
^ in ['A'..'Z', 'a'..'z', '0'..'9', '_'] do Inc(P
);
4328 while P
^ in ['0'..'9'] do
4330 I
:= I
* 10 + (Ord(P
^) - Ord('0'));
4333 if (i
> 255) then IsWideStr
:= True;
4343 Error(SInvalidString
);
4347 if P
^ <> '''' then Break
;
4358 if IsWideStr
then SetLength(FWideStr
, J
);
4366 while P
^ in ['0'..'9'] do
4368 I
:= I
* 10 + (Ord(P
^) - Ord('0'));
4373 FWideStr
[J
] := WideChar(SmallInt(I
));
4388 Error(SInvalidString
);
4392 if P
^ <> '''' then Break
;
4397 FWideStr
[J
] := WideChar(P
^);
4412 Result
:= toWString
else
4418 while P
^ in ['0'..'9', 'A'..'F', 'a'..'f'] do Inc(P
);
4419 Result
:= toInteger
;
4424 while P
^ in ['0'..'9'] do Inc(P
);
4425 Result
:= toInteger
;
4426 while P
^ in ['0'..'9', '.', 'e', 'E', '+', '-'] do
4431 if (P
^ in ['c', 'C', 'd', 'D', 's', 'S']) then
4441 if Result
<> toEOF
then Inc(P
);
4447 procedure TParser
.ReadBuffer
;
4451 Inc(FOrigin
, FSourcePtr
- FBuffer
);
4452 FSourceEnd
[0] := FSaveChar
;
4453 Count
:= FBufPtr
- FSourcePtr
;
4454 if Count
<> 0 then Move(FSourcePtr
[0], FBuffer
[0], Count
);
4455 FBufPtr
:= FBuffer
+ Count
;
4456 Inc(FBufPtr
, FStream
.Read(FBufPtr
[0], FBufEnd
- FBufPtr
));
4457 FSourcePtr
:= FBuffer
;
4458 FSourceEnd
:= FBufPtr
;
4459 if FSourceEnd
= FBufEnd
then
4461 FSourceEnd
:= LineStart(FBuffer
, FSourceEnd
- 1);
4462 if FSourceEnd
= FBuffer
then Error(SLineTooLong
);
4464 FSaveChar
:= FSourceEnd
[0];
4465 FSourceEnd
[0] := #0;
4468 procedure TParser
.SkipBlanks
;
4476 if FSourcePtr
^ = #0 then Exit
;
4488 function TParser
.SourcePos
: Longint;
4490 Result
:= FOrigin
+ (FTokenPtr
- FBuffer
);
4493 function TParser
.TokenFloat
: Extended
;
4495 if FFloatType
<> #0 then Dec(FSourcePtr
);
4496 Result
:= StrToFloat(TokenString
);
4497 if FFloatType
<> #0 then Inc(FSourcePtr
);
4500 function TParser
.TokenInt
: Int64;
4502 Result
:= StrToInt64(TokenString
);
4505 function TParser
.TokenString
: string;
4509 if FToken
= toString
then
4510 L
:= FStringPtr
- FTokenPtr
else
4511 L
:= FSourcePtr
- FTokenPtr
;
4512 SetString(Result
, FTokenPtr
, L
);
4515 function TParser
.TokenWideString
: WideString
;
4520 function TParser
.TokenSymbolIs(const S
: string): Boolean;
4522 Result
:= (Token
= toSymbol
) and SameText(S
, TokenString
);
4525 function TParser
.TokenComponentIdent
: string;
4529 CheckToken(toSymbol
);
4534 if not (P
^ in ['A'..'Z', 'a'..'z', '_']) then
4535 Error(SIdentifierExpected
);
4538 until not (P
^ in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
4541 Result
:= TokenString
;
4544 { Binary to text conversion }
4546 procedure ObjectBinaryToText(Input
, Output
: TStream
);
4548 NestingLevel
: Integer;
4549 SaveSeparator
: Char;
4553 procedure WriteIndent
;
4555 Blanks
: array[0..1] of Char = ' ';
4559 for I
:= 1 to NestingLevel
do Writer
.Write(Blanks
, SizeOf(Blanks
));
4562 procedure WriteStr(const S
: string);
4564 Writer
.Write(S
[1], Length(S
));
4573 procedure ConvertValue
; forward;
4575 procedure ConvertHeader
;
4577 ClassName
, ObjectName
: string;
4581 Reader
.ReadPrefix(Flags
, Position
);
4582 ClassName
:= Reader
.ReadStr
;
4583 ObjectName
:= Reader
.ReadStr
;
4585 if ffInherited
in Flags
then
4586 WriteStr('inherited ')
4587 else if ffInline
in Flags
then
4590 WriteStr('object ');
4591 if ObjectName
<> '' then
4593 WriteStr(ObjectName
);
4596 WriteStr(ClassName
);
4597 if ffChildPos
in Flags
then
4600 WriteStr(IntToStr(Position
));
4606 procedure ConvertBinary
;
4613 Buffer
: array[0..BytesPerLine
- 1] of Char;
4614 Text: array[0..BytesPerLine
* 2 - 1] of Char;
4619 Reader
.Read(Count
, SizeOf(Count
));
4620 MultiLine
:= Count
>= BytesPerLine
;
4623 if MultiLine
then NewLine
;
4624 if Count
>= 32 then I
:= 32 else I
:= Count
;
4625 Reader
.Read(Buffer
, I
);
4626 BinToHex(Buffer
, Text, I
);
4627 Writer
.Write(Text, I
* 2);
4634 procedure ConvertProperty
; forward;
4636 procedure ConvertValue
;
4640 I
, J
, K
, L
: Integer;
4645 case Reader
.NextValue
of
4651 while not Reader
.EndOfList
do
4660 vaInt8
, vaInt16
, vaInt32
:
4661 WriteStr(IntToStr(Reader
.ReadInteger
));
4663 WriteStr(FloatToStr(Reader
.ReadFloat
));
4665 WriteStr(FloatToStr(Reader
.ReadSingle
) + 's');
4667 WriteStr(FloatToStr(Reader
.ReadCurrency
* 10000) + 'c');
4669 WriteStr(FloatToStr(Reader
.ReadDate
) + 'd');
4672 W
:= Reader
.ReadWideString
;
4674 if L
= 0 then WriteStr('''''') else
4679 if L
> LineLength
then NewLine
;
4683 if (W
[I
] >= ' ') and (W
[I
] <> '''') and (Ord(W
[i
]) <= 255) then
4688 until (I
> L
) or (W
[I
] < ' ') or (W
[I
] = '''') or
4689 ((I
- K
) >= LineLength
) or (Ord(W
[i
]) > 255);
4690 if ((I
- K
) >= LineLength
) then
4693 if ByteType(W
, I
) = mbTrailByte
then Dec(I
);
4698 WriteStr(Char(W
[J
]));
4705 WriteStr(IntToStr(Ord(W
[I
])));
4707 if ((I
- K
) >= LineLength
) then LineBreak
:= True;
4709 if LineBreak
and (I
<= L
) then
4721 vaString
, vaLString
:
4723 S
:= Reader
.ReadString
;
4725 if L
= 0 then WriteStr('''''') else
4730 if L
> LineLength
then NewLine
;
4734 if (S
[I
] >= ' ') and (S
[I
] <> '''') then
4739 until (I
> L
) or (S
[I
] < ' ') or (S
[I
] = '''') or
4740 ((I
- K
) >= LineLength
);
4741 if ((I
- K
) >= LineLength
) then
4744 if ByteType(S
, I
) = mbTrailByte
then Dec(I
);
4747 Writer
.Write(S
[J
], I
- J
);
4752 WriteStr(IntToStr(Ord(S
[I
])));
4754 if ((I
- K
) >= LineLength
) then LineBreak
:= True;
4756 if LineBreak
and (I
<= L
) then
4768 vaIdent
, vaFalse
, vaTrue
, vaNil
, vaNull
:
4769 WriteStr(Reader
.ReadIdent
);
4779 S
:= Reader
.ReadStr
;
4780 if S
= '' then Break
;
4781 if I
> 0 then WriteStr(', ');
4792 while not Reader
.EndOfList
do
4796 if Reader
.NextValue
in [vaInt8
, vaInt16
, vaInt32
] then
4803 Reader
.CheckValue(vaList
);
4805 while not Reader
.EndOfList
do ConvertProperty
;
4816 WriteStr(IntToStr(Reader
.ReadInt64
));
4820 procedure ConvertProperty
;
4823 WriteStr(Reader
.ReadStr
);
4829 procedure ConvertObject
;
4833 while not Reader
.EndOfList
do ConvertProperty
;
4835 while not Reader
.EndOfList
do ConvertObject
;
4839 WriteStr('end'#13#10);
4844 Reader
:= TReader
.Create(Input
, 4096);
4845 SaveSeparator
:= DecimalSeparator
;
4846 DecimalSeparator
:= '.';
4848 Writer
:= TWriter
.Create(Output
, 4096);
4850 Reader
.ReadSignature
;
4856 DecimalSeparator
:= SaveSeparator
;
4862 TObjectTextConvertProc
= procedure (Input
, Output
: TStream
);
4864 procedure InternalBinaryToText(Input
, Output
: TStream
;
4865 var OriginalFormat
: TStreamOriginalFormat
;
4866 ConvertProc
: TObjectTextConvertProc
;
4867 BinarySignature
: Integer; SignatureLength
: Byte);
4872 Pos
:= Input
.Position
;
4874 if SignatureLength
> sizeof(Signature
) then SignatureLength
:= sizeof(Signature
);
4875 Input
.Read(Signature
, SignatureLength
);
4876 Input
.Position
:= Pos
;
4877 if Signature
= BinarySignature
then
4878 begin // definitely binary format
4879 if OriginalFormat
= sofBinary
then
4880 Output
.CopyFrom(Input
, Input
.Size
- Input
.Position
)
4883 if OriginalFormat
= sofUnknown
then
4884 Originalformat
:= sofBinary
;
4885 ConvertProc(Input
, Output
);
4888 else // might be text format
4890 if OriginalFormat
= sofBinary
then
4891 ConvertProc(Input
, Output
)
4894 if OriginalFormat
= sofUnknown
then
4895 begin // text format may begin with "object", "inherited", or whitespace
4896 if Char(Signature
) in ['o','O','i','I',' ',#13,#11,#9] then
4897 OriginalFormat
:= sofText
4898 else // not binary, not text... let it raise the exception
4900 ConvertProc(Input
, Output
);
4904 if OriginalFormat
= sofText
then
4905 Output
.CopyFrom(Input
, Input
.Size
- Input
.Position
);
4910 procedure InternalTextToBinary(Input
, Output
: TStream
;
4911 var OriginalFormat
: TStreamOriginalFormat
;
4912 ConvertProc
: TObjectTextConvertProc
;
4913 BinarySignature
: Integer; SignatureLength
: Byte);
4918 Pos
:= Input
.Position
;
4920 if SignatureLength
> sizeof(Signature
) then SignatureLength
:= sizeof(Signature
);
4921 Input
.Read(Signature
, SignatureLength
);
4922 Input
.Position
:= Pos
;
4923 if Signature
= BinarySignature
then
4924 begin // definitely binary format
4925 if OriginalFormat
= sofUnknown
then
4926 Originalformat
:= sofBinary
;
4927 if OriginalFormat
= sofBinary
then
4928 Output
.CopyFrom(Input
, Input
.Size
- Input
.Position
)
4929 else // let it raise the exception
4930 ConvertProc(Input
, Output
);
4932 else // might be text format
4934 case OriginalFormat
of
4936 begin // text format may begin with "object", "inherited", or whitespace
4937 if Char(Signature
) in ['o','O','i','I',' ',#13,#11,#9] then
4938 OriginalFormat
:= sofText
;
4939 // if its not binary, not text... let it raise the exception
4940 ConvertProc(Input
, Output
);
4942 sofBinary
: ConvertProc(Input
, Output
);
4943 sofText
: Output
.CopyFrom(Input
, Input
.Size
- Input
.Position
);
4948 procedure ObjectBinaryToText(Input
, Output
: TStream
;
4949 var OriginalFormat
: TStreamOriginalFormat
);
4953 { Text to binary conversion }
4955 procedure ObjectTextToBinary(Input
, Output
: TStream
);
4957 SaveSeparator
: Char;
4961 function ConvertOrderModifier
: Integer;
4964 if Parser
.Token
= '[' then
4967 Parser
.CheckToken(toInteger
);
4968 Result
:= Parser
.TokenInt
;
4970 Parser
.CheckToken(']');
4975 procedure ConvertHeader(IsInherited
, IsInline
: Boolean);
4977 ClassName
, ObjectName
: string;
4981 Parser
.CheckToken(toSymbol
);
4982 ClassName
:= Parser
.TokenString
;
4984 if Parser
.NextToken
= ':' then
4987 Parser
.CheckToken(toSymbol
);
4988 ObjectName
:= ClassName
;
4989 ClassName
:= Parser
.TokenString
;
4993 Position
:= ConvertOrderModifier
;
4995 Include(Flags
, ffInherited
);
4997 Include(Flags
, ffInline
);
4998 if Position
>= 0 then
4999 Include(Flags
, ffChildPos
);
5000 Writer
.WritePrefix(Flags
, Position
);
5001 Writer
.WriteStr(ClassName
);
5002 Writer
.WriteStr(ObjectName
);
5005 procedure ConvertProperty
; forward;
5007 procedure ConvertValue
;
5011 function CombineString
: string;
5013 Result
:= Parser
.TokenString
;
5014 while Parser
.NextToken
= '+' do
5017 Parser
.CheckToken(toString
);
5018 Result
:= Result
+ Parser
.TokenString
;
5022 function CombineWideString
: WideString
;
5024 Result
:= Parser
.TokenWideString
;
5025 while Parser
.NextToken
= '+' do
5028 Parser
.CheckToken(toWString
);
5029 Result
:= Result
+ Parser
.TokenWideString
;
5034 if Parser
.Token
= toString
then
5035 Writer
.WriteString(CombineString
)
5036 else if Parser
.Token
= toWString
then
5037 Writer
.WriteWideString(CombineWideString
)
5040 case Parser
.Token
of
5042 Writer
.WriteIdent(Parser
.TokenComponentIdent
);
5044 Writer
.WriteInteger(Parser
.TokenInt
);
5047 case Parser
.FloatType
of
5048 's', 'S': Writer
.WriteSingle(Parser
.TokenFloat
);
5049 'c', 'C': Writer
.WriteCurrency(Parser
.TokenFloat
/ 10000);
5050 'd', 'D': Writer
.WriteDate(Parser
.TokenFloat
);
5052 Writer
.WriteFloat(Parser
.TokenFloat
);
5058 Writer
.WriteValue(vaSet
);
5059 if Parser
.Token
<> ']' then
5062 if Parser
.Token
<> toInteger
then
5063 Parser
.CheckToken(toSymbol
);
5064 Writer
.WriteStr(Parser
.TokenString
);
5065 if Parser
.NextToken
= ']' then Break
;
5066 Parser
.CheckToken(',');
5069 Writer
.WriteStr('');
5074 Writer
.WriteListBegin
;
5075 while Parser
.Token
<> ')' do ConvertValue
;
5076 Writer
.WriteListEnd
;
5079 Writer
.WriteBinary(Parser
.HexToBinary
);
5083 Writer
.WriteValue(vaCollection
);
5084 while Parser
.Token
<> '>' do
5086 Parser
.CheckTokenSymbol('item');
5088 Order
:= ConvertOrderModifier
;
5089 if Order
<> -1 then Writer
.WriteInteger(Order
);
5090 Writer
.WriteListBegin
;
5091 while not Parser
.TokenSymbolIs('end') do ConvertProperty
;
5092 Writer
.WriteListEnd
;
5095 Writer
.WriteListEnd
;
5098 Parser
.Error(SInvalidProperty
);
5104 procedure ConvertProperty
;
5108 Parser
.CheckToken(toSymbol
);
5109 PropName
:= Parser
.TokenString
;
5111 while Parser
.Token
= '.' do
5114 Parser
.CheckToken(toSymbol
);
5115 PropName
:= PropName
+ '.' + Parser
.TokenString
;
5118 Writer
.WriteStr(PropName
);
5119 Parser
.CheckToken('=');
5124 procedure ConvertObject
;
5126 InheritedObject
: Boolean;
5127 InlineObject
: Boolean;
5129 InheritedObject
:= False;
5130 InlineObject
:= False;
5131 if Parser
.TokenSymbolIs('INHERITED') then
5132 InheritedObject
:= True
5133 else if Parser
.TokenSymbolIs('INLINE') then
5134 InlineObject
:= True
5136 Parser
.CheckTokenSymbol('OBJECT');
5138 ConvertHeader(InheritedObject
, InlineObject
);
5139 while not Parser
.TokenSymbolIs('END') and
5140 not Parser
.TokenSymbolIs('OBJECT') and
5141 not Parser
.TokenSymbolIs('INHERITED') and
5142 not Parser
.TokenSymbolIs('INLINE') do
5144 Writer
.WriteListEnd
;
5145 while not Parser
.TokenSymbolIs('END') do ConvertObject
;
5146 Writer
.WriteListEnd
;
5151 Parser
:= TParser
.Create(Input
);
5152 SaveSeparator
:= DecimalSeparator
;
5153 DecimalSeparator
:= '.';
5155 Writer
:= TWriter
.Create(Output
, 4096);
5157 Writer
.WriteSignature
;
5163 DecimalSeparator
:= SaveSeparator
;
5168 procedure ObjectTextToBinary(Input
, Output
: TStream
;
5169 var OriginalFormat
: TStreamOriginalFormat
);
5173 { Resource to text conversion }
5175 procedure ObjectResourceToText(Input
, Output
: TStream
);
5177 Input
.ReadResHeader
;
5178 ObjectBinaryToText(Input
, Output
);
5181 procedure ObjectResourceToText(Input
, Output
: TStream
;
5182 var OriginalFormat
: TStreamOriginalFormat
);
5184 InternalBinaryToText(Input
, Output
, OriginalFormat
, ObjectResourceToText
, $FF, 1);
5187 { Text to resource conversion }
5189 procedure ObjectTextToResource(Input
, Output
: TStream
);
5193 MemoryStream
: TMemoryStream
;
5194 MemorySize
: Longint;
5195 Header
: array[0..79] of Char;
5197 MemoryStream
:= TMemoryStream
.Create
;
5199 ObjectTextToBinary(Input
, MemoryStream
);
5200 MemorySize
:= MemoryStream
.Size
;
5201 FillChar(Header
, SizeOf(Header
), 0);
5202 MemoryStream
.Position
:= SizeOf(Longint); { Skip header }
5203 MemoryStream
.Read(Len
, 1);
5205 { Skip over object prefix if it is present }
5206 if Len
and $F0 = $F0 then
5208 if ffChildPos
in TFilerFlags((Len
and $F0)) then
5210 MemoryStream
.Read(Len
, 1);
5211 case TValueType(Len
) of
5216 MemoryStream
.Read(Tmp
, Len
);
5218 MemoryStream
.Read(Len
, 1);
5221 MemoryStream
.Read(Header
[3], Len
);
5222 StrUpper(@Header
[3]);
5223 Byte((@Header
[0])^) := $FF;
5224 Word((@Header
[1])^) := 10;
5225 Word((@Header
[Len
+ 4])^) := $1030;
5226 Longint((@Header
[Len
+ 6])^) := MemorySize
;
5227 Output
.Write(Header
, Len
+ 10);
5228 Output
.Write(MemoryStream
.Memory
^, MemorySize
);
5234 procedure ObjectTextToResource(Input
, Output
: TStream
;
5235 var OriginalFormat
: TStreamOriginalFormat
);
5237 InternalTextToBinary(Input
, Output
, OriginalFormat
, ObjectTextToResource
, $FF, 1);
5240 function TestStreamFormat(Stream
: TStream
): TStreamOriginalFormat
;
5242 Result
:= sofUnknown
;
5245 { Thread management routines }
5248 CM_EXECPROC
= $8FFF;
5249 CM_DESTROYWINDOW
= $8FFE;
5252 PRaiseFrame
= ^TRaiseFrame
;
5253 TRaiseFrame
= record
5254 NextRaise
: PRaiseFrame
;
5255 ExceptAddr
: Pointer;
5256 ExceptObject
: TObject
;
5257 ExceptionRecord
: PExceptionRecord
;
5261 ThreadLock
: TRTLCriticalSection
;
5263 ThreadCount
: Integer;
5265 procedure FreeThreadWindow
;
5267 if ThreadWindow
<> 0 then
5269 DestroyWindow(ThreadWindow
);
5274 function ThreadWndProc(Window
: HWND
; Message, wParam
, lParam
: Longint): Longint; stdcall;
5278 with TThread(lParam
) do
5282 FSynchronizeException
:= nil;
5285 if RaiseList
<> nil then
5287 FSynchronizeException
:= PRaiseFrame(RaiseList
)^.ExceptObject
;
5288 PRaiseFrame(RaiseList
)^.ExceptObject
:= nil;
5294 EnterCriticalSection(ThreadLock
);
5297 if ThreadCount
= 0 then
5300 LeaveCriticalSection(ThreadLock
);
5305 Result
:= DefWindowProc(Window
, Message, wParam
, lParam
);
5310 ThreadWindowClass
: TWndClass
= (
5312 lpfnWndProc
: @ThreadWndProc
;
5320 lpszClassName
: 'TThreadWindow');
5322 procedure AddThread
;
5324 function AllocateWindow
: HWND
;
5326 TempClass
: TWndClass
;
5327 ClassRegistered
: Boolean;
5329 ThreadWindowClass
.hInstance
:= HInstance
;
5330 ClassRegistered
:= GetClassInfo(HInstance
, ThreadWindowClass
.lpszClassName
,
5332 if not ClassRegistered
or (TempClass
.lpfnWndProc
<> @ThreadWndProc
) then
5334 if ClassRegistered
then
5335 Windows
.UnregisterClass(ThreadWindowClass
.lpszClassName
, HInstance
);
5336 Windows
.RegisterClass(ThreadWindowClass
);
5338 Result
:= CreateWindow(ThreadWindowClass
.lpszClassName
, '', 0,
5339 0, 0, 0, 0, 0, 0, HInstance
, nil);
5343 EnterCriticalSection(ThreadLock
);
5345 if ThreadCount
= 0 then
5346 ThreadWindow
:= AllocateWindow
;
5349 LeaveCriticalSection(ThreadLock
);
5353 procedure RemoveThread
;
5355 EnterCriticalSection(ThreadLock
);
5357 if ThreadCount
= 1 then
5358 PostMessage(ThreadWindow
, CM_DESTROYWINDOW
, 0, 0);
5360 LeaveCriticalSection(ThreadLock
);
5366 function ThreadProc(Thread
: TThread
): Integer;
5368 FreeThread
: Boolean;
5373 FreeThread
:= Thread
.FFreeOnTerminate
;
5374 Result
:= Thread
.FReturnValue
;
5375 Thread
.FFinished
:= True;
5377 if FreeThread
then Thread
.Free
;
5382 constructor TThread
.Create(CreateSuspended
: Boolean);
5388 FSuspended
:= CreateSuspended
;
5390 if CreateSuspended
then Flags
:= CREATE_SUSPENDED
;
5391 FHandle
:= BeginThread(nil, 0, @ThreadProc
, Pointer(Self
), Flags
, FThreadID
);
5394 destructor TThread
.Destroy
;
5396 if not FFinished
and not Suspended
then
5401 if FHandle
<> 0 then CloseHandle(FHandle
);
5406 procedure TThread
.CallOnTerminate
;
5408 if Assigned(FOnTerminate
) then FOnTerminate(Self
);
5411 procedure TThread
.DoTerminate
;
5413 if Assigned(FOnTerminate
) then Synchronize(CallOnTerminate
);
5417 Priorities
: array [TThreadPriority
] of Integer =
5418 (THREAD_PRIORITY_IDLE
, THREAD_PRIORITY_LOWEST
, THREAD_PRIORITY_BELOW_NORMAL
,
5419 THREAD_PRIORITY_NORMAL
, THREAD_PRIORITY_ABOVE_NORMAL
,
5420 THREAD_PRIORITY_HIGHEST
, THREAD_PRIORITY_TIME_CRITICAL
);
5422 function TThread
.GetPriority
: TThreadPriority
;
5427 P
:= GetThreadPriority(FHandle
);
5429 for I
:= Low(TThreadPriority
) to High(TThreadPriority
) do
5430 if Priorities
[I
] = P
then Result
:= I
;
5433 procedure TThread
.SetPriority(Value
: TThreadPriority
);
5435 SetThreadPriority(FHandle
, Priorities
[Value
]);
5438 procedure TThread
.Synchronize(Method
: TThreadMethod
);
5440 FSynchronizeException
:= nil;
5442 SendMessage(ThreadWindow
, CM_EXECPROC
, 0, Longint(Self
));
5443 if Assigned(FSynchronizeException
) then raise FSynchronizeException
;
5446 procedure TThread
.SetSuspended(Value
: Boolean);
5448 if Value
<> FSuspended
then
5454 procedure TThread
.Suspend
;
5457 SuspendThread(FHandle
);
5460 procedure TThread
.Resume
;
5462 if ResumeThread(FHandle
) = 1 then FSuspended
:= False;
5465 procedure TThread
.Terminate
;
5467 FTerminated
:= True;
5470 function TThread
.WaitFor
: LongWord
;
5476 if GetCurrentThreadID
= MainThreadID
then
5477 while MsgWaitForMultipleObjects(1, H
, False, INFINITE
,
5478 QS_SENDMESSAGE
) = WAIT_OBJECT_0
+ 1 do PeekMessage(Msg
, 0, 0, 0, PM_NOREMOVE
)
5479 else WaitForSingleObject(H
, INFINITE
);
5480 GetExitCodeThread(H
, Result
);
5485 constructor TComponent
.Create(AOwner
: TComponent
);
5487 FComponentStyle
:= [csInheritable
];
5488 if AOwner
<> nil then AOwner
.InsertComponent(Self
);
5491 destructor TComponent
.Destroy
;
5496 if FFreeNotifies
<> nil then
5498 for I
:= FFreeNotifies
.Count
- 1 downto 0 do
5500 TComponent(FFreeNotifies
[I
]).Notification(Self
, opRemove
);
5501 if FFreeNotifies
= nil then Break
;
5504 FFreeNotifies
:= nil;
5507 if FOwner
<> nil then FOwner
.RemoveComponent(Self
);
5511 procedure TComponent
.BeforeDestruction
;
5513 if not (csDestroying
in ComponentState
) then
5517 procedure TComponent
.FreeNotification(AComponent
: TComponent
);
5519 if (Owner
= nil) or (AComponent
.Owner
<> Owner
) then
5521 if not Assigned(FFreeNotifies
) then FFreeNotifies
:= TList
.Create
;
5522 if FFreeNotifies
.IndexOf(AComponent
) < 0 then
5524 FFreeNotifies
.Add(AComponent
);
5525 AComponent
.FreeNotification(Self
);
5528 Include(FComponentState
, csFreeNotification
);
5531 procedure TComponent
.Insert(AComponent
: TComponent
);
5533 if FComponents
= nil then FComponents
:= TList
.Create
;
5534 FComponents
.Add(AComponent
);
5535 AComponent
.FOwner
:= Self
;
5538 procedure TComponent
.Remove(AComponent
: TComponent
);
5540 AComponent
.FOwner
:= nil;
5541 FComponents
.Remove(AComponent
);
5542 if FComponents
.Count
= 0 then
5549 procedure TComponent
.InsertComponent(AComponent
: TComponent
);
5551 AComponent
.ValidateContainer(Self
);
5552 ValidateRename(AComponent
, '', AComponent
.FName
);
5554 AComponent
.SetReference(True);
5555 if csDesigning
in ComponentState
then
5556 AComponent
.SetDesigning(True);
5557 Notification(AComponent
, opInsert
);
5560 procedure TComponent
.RemoveComponent(AComponent
: TComponent
);
5562 ValidateRename(AComponent
, AComponent
.FName
, '');
5563 Notification(AComponent
, opRemove
);
5564 AComponent
.SetReference(False);
5568 procedure TComponent
.DestroyComponents
;
5570 Instance
: TComponent
;
5572 while FComponents
<> nil do
5574 Instance
:= FComponents
.Last
;
5575 if (csFreeNotification
in Instance
.FComponentState
)
5576 or (FComponentState
* [csDesigning
, csInline
] = [csDesigning
, csInline
]) then
5577 RemoveComponent(Instance
)
5584 procedure TComponent
.Destroying
;
5588 if not (csDestroying
in FComponentState
) then
5590 Include(FComponentState
, csDestroying
);
5591 if FComponents
<> nil then
5592 for I
:= 0 to FComponents
.Count
- 1 do
5593 TComponent(FComponents
[I
]).Destroying
;
5597 procedure TComponent
.RemoveNotification(AComponent
: TComponent
);
5599 if FFreeNotifies
<> nil then
5601 FFreeNotifies
.Remove(AComponent
);
5602 if FFreeNotifies
.Count
= 0 then
5605 FFreeNotifies
:= nil;
5610 procedure TComponent
.RemoveFreeNotification(AComponent
: TComponent
);
5612 RemoveNotification(AComponent
);
5613 AComponent
.RemoveNotification(Self
);
5616 procedure TComponent
.Notification(AComponent
: TComponent
;
5617 Operation
: TOperation
);
5621 if (Operation
= opRemove
) and (AComponent
<> nil) then
5622 RemoveFreeNotification(AComponent
);
5623 if FComponents
<> nil then
5624 for I
:= 0 to FComponents
.Count
- 1 do
5625 TComponent(FComponents
[I
]).Notification(AComponent
, Operation
);
5628 function TComponent
.HasParent
: Boolean;
5633 procedure TComponent
.GetChildren(Proc
: TGetChildProc
; Root
: TComponent
);
5637 function TComponent
.GetChildOwner
: TComponent
;
5642 function TComponent
.GetChildParent
: TComponent
;
5647 function TComponent
.GetNamePath
: string;
5652 function TComponent
.GetOwner
: TPersistent
;
5657 procedure TComponent
.SetChildOrder(Child
: TComponent
; Order
: Integer);
5661 function TComponent
.GetParentComponent
: TComponent
;
5666 procedure TComponent
.SetParentComponent(Value
: TComponent
);
5670 procedure TComponent
.Updating
;
5672 Include(FComponentState
, csUpdating
);
5675 procedure TComponent
.Updated
;
5677 Exclude(FComponentState
, csUpdating
);
5680 procedure TComponent
.Loaded
;
5682 Exclude(FComponentState
, csLoading
);
5685 procedure TComponent
.ReadState(Reader
: TReader
);
5689 procedure TComponent
.WriteState(Writer
: TWriter
);
5693 procedure TComponent
.ValidateRename(AComponent
: TComponent
;
5694 const CurName
, NewName
: string);
5696 if (AComponent
<> nil) and not SameText(CurName
, NewName
) and
5697 (AComponent
.Owner
= Self
) and (FindComponent(NewName
) <> nil) then
5698 raise EComponentError
.CreateResFmt(@SDuplicateName
, [NewName
]);
5699 if (csDesigning
in ComponentState
) and (Owner
<> nil) then
5700 Owner
.ValidateRename(AComponent
, CurName
, NewName
);
5703 procedure TComponent
.ValidateContainer(AComponent
: TComponent
);
5705 AComponent
.ValidateInsert(Self
);
5708 procedure TComponent
.ValidateInsert(AComponent
: TComponent
);
5712 function TComponent
.FindComponent(const AName
: string): TComponent
;
5716 if (AName
<> '') and (FComponents
<> nil) then
5717 for I
:= 0 to FComponents
.Count
- 1 do
5719 Result
:= FComponents
[I
];
5720 if SameText(Result
.FName
, AName
) then Exit
;
5725 procedure TComponent
.SetName(const NewName
: TComponentName
);
5727 if FName
<> NewName
then
5729 if (NewName
<> '') and not IsValidIdent(NewName
) then
5730 raise EComponentError
.CreateResFmt(@SInvalidName
, [NewName
]);
5731 if FOwner
<> nil then
5732 FOwner
.ValidateRename(Self
, FName
, NewName
) else
5733 ValidateRename(nil, FName
, NewName
);
5734 SetReference(False);
5735 ChangeName(NewName
);
5740 procedure TComponent
.ChangeName(const NewName
: TComponentName
);
5745 function TComponent
.GetComponentIndex
: Integer;
5747 if (FOwner
<> nil) and (FOwner
.FComponents
<> nil) then
5748 Result
:= FOwner
.FComponents
.IndexOf(Self
) else
5752 function TComponent
.GetComponent(AIndex
: Integer): TComponent
;
5754 if FComponents
= nil then TList
.Error(@SListIndexError
, AIndex
);
5755 Result
:= FComponents
[AIndex
];
5758 function TComponent
.GetComponentCount
: Integer;
5760 if FComponents
<> nil then
5761 Result
:= FComponents
.Count
else
5765 procedure TComponent
.SetComponentIndex(Value
: Integer);
5769 if FOwner
<> nil then
5771 I
:= FOwner
.FComponents
.IndexOf(Self
);
5774 Count
:= FOwner
.FComponents
.Count
;
5775 if Value
< 0 then Value
:= 0;
5776 if Value
>= Count
then Value
:= Count
- 1;
5779 FOwner
.FComponents
.Delete(I
);
5780 FOwner
.FComponents
.Insert(Value
, Self
);
5786 procedure TComponent
.SetAncestor(Value
: Boolean);
5791 Include(FComponentState
, csAncestor
) else
5792 Exclude(FComponentState
, csAncestor
);
5793 for I
:= 0 to ComponentCount
- 1 do
5794 Components
[I
].SetAncestor(Value
);
5797 procedure TComponent
.SetDesigning(Value
, SetChildren
: Boolean);
5802 Include(FComponentState
, csDesigning
) else
5803 Exclude(FComponentState
, csDesigning
);
5805 for I
:= 0 to ComponentCount
- 1 do Components
[I
].SetDesigning(Value
);
5808 procedure TComponent
.SetInline(Value
: Boolean);
5811 Include(FComponentState
, csInline
) else
5812 Exclude(FComponentState
, csInline
);
5815 procedure TComponent
.SetDesignInstance(Value
: Boolean);
5818 Include(FComponentState
, csDesignInstance
) else
5819 Exclude(FComponentState
, csDesignInstance
);
5822 procedure TComponent
.SetReference(Enable
: Boolean);
5826 if FOwner
<> nil then
5828 Field
:= FOwner
.FieldAddress(FName
);
5829 if Field
<> nil then
5830 if Enable
then Field
^ := Self
else Field
^ := nil;
5834 function TComponent
.ExecuteAction(Action
: TBasicAction
): Boolean;//!
5836 if Action
.HandlesTarget(Self
) then
5838 Action
.ExecuteTarget(Self
);
5841 else Result
:= False;
5844 function TComponent
.UpdateAction(Action
: TBasicAction
): Boolean;//!
5846 if Action
.HandlesTarget(Self
) then
5848 Action
.UpdateTarget(Self
);
5851 else Result
:= False;
5854 function TComponent
.GetComObject
: IUnknown
;
5856 if FVCLComObject
= nil then
5858 if Assigned(CreateVCLComObjectProc
) then CreateVCLComObjectProc(Self
);
5859 if FVCLComObject
= nil then
5860 raise EComponentError
.CreateResFmt(@SNoComSupport
, [ClassName
]);
5862 IVCLComObject(FVCLComObject
).QueryInterface(IUnknown
, Result
);
5865 function TComponent
.SafeCallException(ExceptObject
: TObject
;
5866 ExceptAddr
: Pointer): HResult
;
5868 if FVCLComObject
<> nil then
5869 Result
:= IVCLComObject(FVCLComObject
).SafeCallException(
5870 ExceptObject
, ExceptAddr
)
5872 Result
:= inherited SafeCallException(ExceptObject
, ExceptAddr
);
5875 procedure TComponent
.FreeOnRelease
;
5877 if FVCLComObject
<> nil then IVCLComObject(FVCLComObject
).FreeOnRelease
;
5880 class procedure TComponent
.UpdateRegistry(Register: Boolean; const ClassID
, ProgID
: string);
5884 { TComponent.IUnknown }
5886 function TComponent
.QueryInterface(const IID
: TGUID
; out Obj
): HResult
;
5888 if FVCLComObject
= nil then
5890 if GetInterface(IID
, Obj
) then Result
:= S_OK
5891 else Result
:= E_NOINTERFACE
5894 Result
:= IVCLComObject(FVCLComObject
).QueryInterface(IID
, Obj
);
5897 function TComponent
._AddRef
: Integer;
5899 if FVCLComObject
= nil then
5900 Result
:= -1 // -1 indicates no reference counting is taking place
5902 Result
:= IVCLComObject(FVCLComObject
)._AddRef
;
5905 function TComponent
._Release
: Integer;
5907 if FVCLComObject
= nil then
5908 Result
:= -1 // -1 indicates no reference counting is taking place
5910 Result
:= IVCLComObject(FVCLComObject
)._Release
;
5913 { TComponent.IDispatch }
5915 function TComponent
.GetTypeInfoCount(out Count
: Integer): HResult
;
5917 if FVCLComObject
= nil then
5920 Result
:= IVCLComObject(FVCLComObject
).GetTypeInfoCount(Count
);
5923 function TComponent
.GetTypeInfo(Index
, LocaleID
: Integer; out TypeInfo
): HResult
;
5925 if FVCLComObject
= nil then
5928 Result
:= IVCLComObject(FVCLComObject
).GetTypeInfo(
5929 Index
, LocaleID
, TypeInfo
);
5932 function TComponent
.GetIDsOfNames(const IID
: TGUID
; Names
: Pointer;
5933 NameCount
, LocaleID
: Integer; DispIDs
: Pointer): HResult
;
5935 if FVCLComObject
= nil then
5938 Result
:= IVCLComObject(FVCLComObject
).GetIDsOfNames(IID
, Names
,
5939 NameCount
, LocaleID
, DispIDs
);
5942 function TComponent
.Invoke(DispID: Integer; const IID
: TGUID
; LocaleID
: Integer;
5943 Flags
: Word; var Params
; VarResult
, ExcepInfo
, ArgErr
: Pointer): HResult
;
5945 if FVCLComObject
= nil then
5948 Result
:= IVCLComObject(FVCLComObject
).Invoke(DispID, IID
, LocaleID
,
5949 Flags
, Params
, VarResult
, ExcepInfo
, ArgErr
);
5952 { TBasicActionLink }
5954 constructor TBasicActionLink
.Create(AClient
: TObject
);
5957 AssignClient(AClient
);
5960 procedure TBasicActionLink
.AssignClient(AClient
: TObject
);
5964 destructor TBasicActionLink
.Destroy
;
5966 if FAction
<> nil then FAction
.UnRegisterChanges(Self
);
5970 procedure TBasicActionLink
.Change
;
5972 if Assigned(OnChange
) then OnChange(FAction
);
5975 function TBasicActionLink
.Execute
: Boolean;
5977 Result
:= FAction
.Execute
;
5980 procedure TBasicActionLink
.SetAction(Value
: TBasicAction
);
5982 if Value
<> FAction
then
5984 if FAction
<> nil then FAction
.UnRegisterChanges(Self
);
5986 if Value
<> nil then Value
.RegisterChanges(Self
);
5990 function TBasicActionLink
.IsOnExecuteLinked
: Boolean;
5995 procedure TBasicActionLink
.SetOnExecute(Value
: TNotifyEvent
);
5999 function TBasicActionLink
.Update
: Boolean;
6001 Result
:= FAction
.Update
;
6006 constructor TBasicAction
.Create(AOwner
: TComponent
);
6008 inherited Create(AOwner
);
6009 FClients
:= TList
.Create
;
6012 destructor TBasicAction
.Destroy
;
6015 while FClients
.Count
> 0 do
6016 UnRegisterChanges(TBasicActionLink(FClients
.Last
));
6020 {!function TBasicAction.GetActionLinkClass: TBasicActionLinkClass;
6022 Result := TBasicActionLink;
6025 function TBasicAction
.HandlesTarget(Target
: TObject
): Boolean;
6030 procedure TBasicAction
.ExecuteTarget(Target
: TObject
);
6034 procedure TBasicAction
.UpdateTarget(Target
: TObject
);
6038 function TBasicAction
.Execute
: Boolean;
6040 if Assigned(FOnExecute
) then
6045 else Result
:= False;
6048 function TBasicAction
.Update
: Boolean;
6050 if Assigned(FOnUpdate
) then
6055 else Result
:= False;
6058 procedure TBasicAction
.SetOnExecute(Value
: TNotifyEvent
);
6062 if @Value
<> @OnExecute
then
6064 for I
:= 0 to FClients
.Count
- 1 do
6065 TBasicActionLink(FClients
[I
]).SetOnExecute(Value
);
6066 FOnExecute
:= Value
;
6071 procedure TBasicAction
.Change
;
6075 if Assigned(FOnChange
) then FOnChange(Self
);
6076 {! for I := 0 to FClients.Count - 1 do
6077 TBasicActionLink(FClients[I]).Change;!}
6080 procedure TBasicAction
.RegisterChanges(Value
: TBasicActionLink
);
6082 Value
.FAction
:= Self
;
6083 FClients
.Add(Value
);
6086 procedure TBasicAction
.UnRegisterChanges(Value
: TBasicActionLink
);
6090 for I
:= 0 to FClients
.Count
- 1 do
6091 if FClients
[I
] = Value
then
6093 Value
.{!}FAction
:= nil;
6101 constructor TStreamAdapter
.Create(Stream
: TStream
;
6102 Ownership
: TStreamOwnership
);
6106 FOwnership
:= Ownership
;
6109 destructor TStreamAdapter
.Destroy
;
6111 if FOwnership
= soOwned
then
6119 function TStreamAdapter
.Read(pv
: Pointer; cb
: Longint; pcbRead
: PLongint
): HResult
;
6126 Result
:= STG_E_INVALIDPOINTER
;
6129 NumRead
:= FStream
.Read(pv
^, cb
);
6130 if pcbRead
<> Nil then pcbRead
^ := NumRead
;
6137 function TStreamAdapter
.Write(pv
: Pointer; cb
: Longint; pcbWritten
: PLongint
): HResult
;
6139 NumWritten
: Longint;
6144 Result
:= STG_E_INVALIDPOINTER
;
6147 NumWritten
:= FStream
.Write(pv
^, cb
);
6148 if pcbWritten
<> Nil then pcbWritten
^ := NumWritten
;
6151 Result
:= STG_E_CANTSAVE
;
6155 function TStreamAdapter
.Seek(dlibMove
: Largeint
; dwOrigin
: Longint;
6156 out libNewPosition
: Largeint
): HResult
;
6161 if (dwOrigin
< STREAM_SEEK_SET
) or (dwOrigin
> STREAM_SEEK_END
) then
6163 Result
:= STG_E_INVALIDFUNCTION
;
6166 NewPos
:= FStream
.Seek(LongInt(dlibMove
), dwOrigin
);
6167 if @libNewPosition
<> nil then libNewPosition
:= NewPos
;
6170 Result
:= STG_E_INVALIDPOINTER
;
6174 function TStreamAdapter
.SetSize(libNewSize
: Largeint
): HResult
;
6177 FStream
.Size
:= LongInt(libNewSize
);
6178 if libNewSize
<> FStream
.Size
then
6183 Result
:= E_UNEXPECTED
;
6187 function TStreamAdapter
.CopyTo(stm
: IStream
; cb
: Largeint
; out cbRead
: Largeint
;
6188 out cbWritten
: Largeint
): HResult
;
6190 MaxBufSize
= 1024 * 1024; // 1mb
6193 BufSize
, N
, I
: Integer;
6194 BytesRead
, BytesWritten
, W
: LargeInt
;
6200 if cb
> MaxBufSize
then
6201 BufSize
:= MaxBufSize
6203 BufSize
:= Integer(cb
);
6204 GetMem(Buffer
, BufSize
);
6214 if I
> BufSize
then N
:= BufSize
else N
:= I
;
6215 Inc(BytesRead
, FStream
.Read(Buffer
^, N
));
6217 Result
:= stm
.Write(Buffer
, N
, @W
);
6218 Inc(BytesWritten
, W
);
6219 if (Result
= S_OK
) and (Integer(W
) <> N
) then Result
:= E_FAIL
;
6220 if Result
<> S_OK
then Exit
;
6227 if (@cbWritten
<> nil) then cbWritten
:= BytesWritten
;
6228 if (@cbRead
<> nil) then cbRead
:= BytesRead
;
6231 Result
:= E_UNEXPECTED
;
6235 function TStreamAdapter
.Commit(grfCommitFlags
: Longint): HResult
;
6240 function TStreamAdapter
.Revert
: HResult
;
6242 Result
:= STG_E_REVERTED
;
6245 function TStreamAdapter
.LockRegion(libOffset
: Largeint
; cb
: Largeint
;
6246 dwLockType
: Longint): HResult
;
6248 Result
:= STG_E_INVALIDFUNCTION
;
6251 function TStreamAdapter
.UnlockRegion(libOffset
: Largeint
; cb
: Largeint
;
6252 dwLockType
: Longint): HResult
;
6254 Result
:= STG_E_INVALIDFUNCTION
;
6257 function TStreamAdapter
.Stat(out statstg
: TStatStg
; grfStatFlag
: Longint): HResult
;
6261 if (@statstg
<> nil) then
6264 dwType
:= STGTY_STREAM
;
6265 cbSize
:= FStream
.Size
;
6266 mTime
.dwLowDateTime
:= 0;
6267 mTime
.dwHighDateTime
:= 0;
6268 cTime
.dwLowDateTime
:= 0;
6269 cTime
.dwHighDateTime
:= 0;
6270 aTime
.dwLowDateTime
:= 0;
6271 aTime
.dwHighDateTime
:= 0;
6272 grfLocksSupported
:= LOCK_WRITE
;
6275 Result
:= E_UNEXPECTED
;
6279 function TStreamAdapter
.Clone(out stm
: IStream
): HResult
;
6281 Result
:= E_NOTIMPL
;
6285 InitializeCriticalSection(ThreadLock
);
6289 FreeAndNil(fGlobalNameSpace
);
6290 DeleteCriticalSection(ThreadLock
);