2181 lines
56 KiB
ObjectPascal
2181 lines
56 KiB
ObjectPascal
|
|
|
||
|
|
{********************************************************************}
|
||
|
|
{ }
|
||
|
|
{ Developer Express Visual Component Library }
|
||
|
|
{ Express Cross Platform Library classes }
|
||
|
|
{ }
|
||
|
|
{ Copyright (c) 2000-2006 Developer Express Inc. }
|
||
|
|
{ ALL RIGHTS RESERVED }
|
||
|
|
{ }
|
||
|
|
{ The entire contents of this file is protected by U.S. and }
|
||
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
||
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
||
|
|
{ the code contained in this file is strictly prohibited and may }
|
||
|
|
{ result in severe civil and criminal penalties and will be }
|
||
|
|
{ prosecuted to the maximum extent possible under the law. }
|
||
|
|
{ }
|
||
|
|
{ RESTRICTIONS }
|
||
|
|
{ }
|
||
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
||
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
||
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
||
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSCROSSPLATFORMLIBRARY AND ALL }
|
||
|
|
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM }
|
||
|
|
{ ONLY. }
|
||
|
|
{ }
|
||
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
||
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
||
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
||
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
||
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
||
|
|
{ }
|
||
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
||
|
|
{ ADDITIONAL RESTRICTIONS. }
|
||
|
|
{ }
|
||
|
|
{********************************************************************}
|
||
|
|
|
||
|
|
unit cxClasses;
|
||
|
|
|
||
|
|
{$I cxVer.inc}
|
||
|
|
|
||
|
|
interface
|
||
|
|
|
||
|
|
uses
|
||
|
|
{$IFDEF MSWINDOWS}
|
||
|
|
Windows, ShellAPI,
|
||
|
|
{$ELSE}
|
||
|
|
Libc,
|
||
|
|
{$ENDIF}
|
||
|
|
{$IFNDEF VCL}
|
||
|
|
Types,
|
||
|
|
{$ENDIF}
|
||
|
|
TypInfo, Classes;
|
||
|
|
|
||
|
|
type
|
||
|
|
{$IFDEF CLR}
|
||
|
|
Pointer = IntPtr;
|
||
|
|
{$ELSE}
|
||
|
|
PBytes = ^TBytes;
|
||
|
|
TBytes = array of Byte;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
TcxAlignmentVert = (vaTop, vaBottom, vaCenter);
|
||
|
|
TcxCollectionOperation = (coAdd, coDelete, coChanged);
|
||
|
|
TcxDirection = (dirNone, dirLeft, dirRight, dirUp, dirDown);
|
||
|
|
TcxGetComponent = function(ACaller: TComponent; Index: Integer): TComponent;
|
||
|
|
TcxGetCaptionForIntegerItemFunc = function(AItem: Integer): string;
|
||
|
|
TcxPosition = (posNone, posLeft, posRight, posTop, posBottom);
|
||
|
|
|
||
|
|
{$IFNDEF DELPHI5}
|
||
|
|
TImageIndex = Integer;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
TTag = Longint;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
IcxDesignSelectionChanged = interface
|
||
|
|
['{66B3AA59-1EBD-4135-AB18-E980F9C970F3}']
|
||
|
|
procedure DesignSelectionChanged(ASelection: TList);
|
||
|
|
end;
|
||
|
|
|
||
|
|
IcxDesignHelper = interface
|
||
|
|
['{4C78CC4F-699B-43BD-94AC-E3BD2233F7A1}']
|
||
|
|
procedure AddSelectionChangedListener(AObject: TPersistent);
|
||
|
|
function CanAddComponent(AOwner: TComponent): Boolean;
|
||
|
|
function CanDeleteComponent(AOwner: TComponent; AComponent: TComponent): Boolean;
|
||
|
|
procedure ChangeSelection(AOwner: TComponent; AObject: TPersistent);
|
||
|
|
function IsObjectSelected(AOwner: TComponent; AObject: TPersistent): Boolean;
|
||
|
|
procedure RemoveSelectionChangedListener(AObject: TPersistent);
|
||
|
|
procedure SelectObject(AOwner: TComponent; AObject: TPersistent; AClearSelection: Boolean = True;
|
||
|
|
AActivateOwner: Boolean = True);
|
||
|
|
procedure ShowComponentDefaultEventHandler(AComponent: TComponent);
|
||
|
|
procedure UnselectObject(AOwner: TComponent; AObject: TPersistent);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxInterfacedPersistent }
|
||
|
|
|
||
|
|
TcxInterfacedPersistentClass = class of TcxInterfacedPersistent;
|
||
|
|
|
||
|
|
TcxInterfacedPersistent = class({$IFDEF DELPHI6}TInterfacedPersistent{$ELSE}TPersistent, IUnknown{$ENDIF})
|
||
|
|
private
|
||
|
|
FOwner: TPersistent;
|
||
|
|
{$IFNDEF DELPHI6}
|
||
|
|
FOwnerInterface: IUnknown;
|
||
|
|
{$ENDIF}
|
||
|
|
protected
|
||
|
|
function GetOwner: TPersistent; override;
|
||
|
|
{$IFNDEF DELPHI6}
|
||
|
|
{ IUnknown }
|
||
|
|
function _AddRef: Integer; stdcall;
|
||
|
|
function _Release: Integer; stdcall;
|
||
|
|
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
|
||
|
|
{$ENDIF}
|
||
|
|
public
|
||
|
|
constructor Create(AOwner: TPersistent); virtual;
|
||
|
|
{$IFNDEF DELPHI6}
|
||
|
|
procedure AfterConstruction; override;
|
||
|
|
{$ENDIF}
|
||
|
|
property Owner: TPersistent read FOwner;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxComponent}
|
||
|
|
|
||
|
|
TcxComponent = class(TComponent{$IFNDEF DELPHI6}, IUnknown{$ENDIF})
|
||
|
|
private
|
||
|
|
FFakeComponentLink1: TComponent;
|
||
|
|
FFakeComponentLink2: TComponent;
|
||
|
|
FFakeComponentLink3: TComponent;
|
||
|
|
function GetFakeComponentLinkCount: Integer;
|
||
|
|
function GetIsDesigning: Boolean;
|
||
|
|
function GetIsDestroying: Boolean;
|
||
|
|
procedure SetFakeComponentLink(Index: Integer; Value: TComponent);
|
||
|
|
protected
|
||
|
|
procedure GetFakeComponentLinks(AList: TList); virtual;
|
||
|
|
procedure Loaded; override;
|
||
|
|
procedure UpdateFakeLinks;
|
||
|
|
public
|
||
|
|
destructor Destroy; override;
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
procedure BeforeDestruction; override;
|
||
|
|
{$ENDIF}
|
||
|
|
property IsDesigning: Boolean read GetIsDesigning;
|
||
|
|
property IsDestroying: Boolean read GetIsDestroying;
|
||
|
|
published
|
||
|
|
property FakeComponentLink1: TComponent read FFakeComponentLink1 write FFakeComponentLink1 stored False;
|
||
|
|
property FakeComponentLink2: TComponent read FFakeComponentLink2 write FFakeComponentLink2 stored False;
|
||
|
|
property FakeComponentLink3: TComponent read FFakeComponentLink3 write FFakeComponentLink3 stored False;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxCollection }
|
||
|
|
|
||
|
|
TcxCollection = class(TCollection)
|
||
|
|
public
|
||
|
|
procedure Assign(Source: TPersistent); override;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxObjectList }
|
||
|
|
|
||
|
|
TcxObjectList = class(TList)
|
||
|
|
private
|
||
|
|
function GetItem(Index: Integer): TObject;
|
||
|
|
public
|
||
|
|
procedure Clear; override;
|
||
|
|
property Items[Index: Integer]: TObject read GetItem; default;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxRegisteredClassList }
|
||
|
|
|
||
|
|
TcxRegisteredClassListItemData = class
|
||
|
|
ItemClass: TClass;
|
||
|
|
RegisteredClass: TClass;
|
||
|
|
end;
|
||
|
|
|
||
|
|
TcxRegisteredClassList = class
|
||
|
|
private
|
||
|
|
FItems: TList;
|
||
|
|
function GetCount: Integer;
|
||
|
|
function GetItem(Index: Integer): TcxRegisteredClassListItemData;
|
||
|
|
protected
|
||
|
|
function Find(AItemClass: TClass; var AIndex: Integer): Boolean; virtual;
|
||
|
|
public
|
||
|
|
constructor Create;
|
||
|
|
destructor Destroy; override;
|
||
|
|
procedure Clear;
|
||
|
|
function FindClass(AItemClass: TClass): TClass;
|
||
|
|
procedure Register(AItemClass, ARegisteredClass: TClass); virtual;
|
||
|
|
procedure Unregister(AItemClass, ARegisteredClass: TClass); virtual;
|
||
|
|
property Count: Integer read GetCount;
|
||
|
|
property Items[Index: Integer]: TcxRegisteredClassListItemData read GetItem; default;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxRegisteredClasses } // TODO: Name
|
||
|
|
|
||
|
|
TcxRegisteredClasses = class
|
||
|
|
private
|
||
|
|
FItems: TStringList;
|
||
|
|
FRegisterClasses: Boolean;
|
||
|
|
FSorted: Boolean;
|
||
|
|
function GetCount: Integer;
|
||
|
|
function GetDescription(Index: Integer): string;
|
||
|
|
function GetHint(Index: Integer): string;
|
||
|
|
function GetItem(Index: Integer): TClass;
|
||
|
|
procedure SetSorted(Value: Boolean);
|
||
|
|
protected
|
||
|
|
function CompareItems(AIndex1, AIndex2: Integer): Integer; virtual;
|
||
|
|
procedure Sort; virtual;
|
||
|
|
public
|
||
|
|
constructor Create(ARegisterClasses: Boolean = False);
|
||
|
|
destructor Destroy; override;
|
||
|
|
procedure Clear;
|
||
|
|
function FindByClassName(const AClassName: string): TClass;
|
||
|
|
function FindByDescription(const ADescription: string): TClass;
|
||
|
|
function GetDescriptionByClass(AClass: TClass): string;
|
||
|
|
function GetHintByClass(AClass: TClass): string;
|
||
|
|
function GetIndexByClass(AClass: TClass): Integer;
|
||
|
|
procedure Register(AClass: TClass; const ADescription: string);
|
||
|
|
procedure Unregister(AClass: TClass);
|
||
|
|
property Count: Integer read GetCount;
|
||
|
|
property Descriptions[Index: Integer]: string read GetDescription;
|
||
|
|
property Hints[Index: Integer]: string read GetHint;
|
||
|
|
property Items[Index: Integer]: TClass read GetItem; default;
|
||
|
|
property RegisterClasses: Boolean read FRegisterClasses write FRegisterClasses;
|
||
|
|
property Sorted: Boolean read FSorted write SetSorted;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxAutoWidthObject }
|
||
|
|
|
||
|
|
TcxAutoWidthItem = class
|
||
|
|
public
|
||
|
|
MinWidth: Integer;
|
||
|
|
Width: Integer;
|
||
|
|
Fixed: Boolean;
|
||
|
|
AutoWidth: Integer;
|
||
|
|
constructor Create;
|
||
|
|
end;
|
||
|
|
|
||
|
|
TcxAutoWidthObject = class
|
||
|
|
private
|
||
|
|
FAvailableWidth: Integer;
|
||
|
|
FItems: TList;
|
||
|
|
function GetCount: Integer;
|
||
|
|
function GetItem(Index: Integer): TcxAutoWidthItem;
|
||
|
|
function GetWidth: Integer;
|
||
|
|
protected
|
||
|
|
procedure Clear;
|
||
|
|
public
|
||
|
|
constructor Create(ACount: Integer);
|
||
|
|
destructor Destroy; override;
|
||
|
|
function AddItem: TcxAutoWidthItem;
|
||
|
|
procedure Calculate;
|
||
|
|
property AvailableWidth: Integer read FAvailableWidth write FAvailableWidth;
|
||
|
|
property Count: Integer read GetCount;
|
||
|
|
property Items[Index: Integer]: TcxAutoWidthItem read GetItem; default;
|
||
|
|
property Width: Integer read GetWidth;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxAlignment }
|
||
|
|
|
||
|
|
TcxAlignment = class(TPersistent)
|
||
|
|
private
|
||
|
|
FDefaultHorz: TAlignment;
|
||
|
|
FDefaultVert: TcxAlignmentVert;
|
||
|
|
FHorz: TAlignment;
|
||
|
|
FIsHorzAssigned: Boolean;
|
||
|
|
FIsVertAssigned: Boolean;
|
||
|
|
FOwner: TPersistent;
|
||
|
|
FUseAssignedValues: Boolean;
|
||
|
|
FVert: TcxAlignmentVert;
|
||
|
|
FOnChanged: TNotifyEvent;
|
||
|
|
function IsHorzStored: Boolean;
|
||
|
|
function IsVertStored: Boolean;
|
||
|
|
procedure SetHorz(const Value: TAlignment);
|
||
|
|
procedure SetVert(const Value: TcxAlignmentVert);
|
||
|
|
protected
|
||
|
|
procedure DoChanged;
|
||
|
|
function GetOwner: TPersistent; override;
|
||
|
|
public
|
||
|
|
constructor Create(AOwner: TPersistent; AUseAssignedValues: Boolean = False;
|
||
|
|
ADefaultHorz: TAlignment = taLeftJustify;
|
||
|
|
ADefaultVert: TcxAlignmentVert = vaTop); virtual;
|
||
|
|
procedure Assign(Source: TPersistent); override;
|
||
|
|
procedure Reset;
|
||
|
|
property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
|
||
|
|
published
|
||
|
|
property Horz: TAlignment read FHorz write SetHorz stored IsHorzStored;
|
||
|
|
property Vert: TcxAlignmentVert read FVert write SetVert stored IsVertStored;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ Object Links }
|
||
|
|
|
||
|
|
TcxObjectLink = class
|
||
|
|
Ref: TObject;
|
||
|
|
end;
|
||
|
|
|
||
|
|
TcxObjectLinkController = class
|
||
|
|
private
|
||
|
|
FLinks: TList;
|
||
|
|
public
|
||
|
|
constructor Create;
|
||
|
|
destructor Destroy; override;
|
||
|
|
|
||
|
|
function AddLink(AObject: TObject): TcxObjectLink;
|
||
|
|
procedure RemoveLink(ALink: TcxObjectLink);
|
||
|
|
procedure ClearLinks(AObject: TObject);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxFreeNotificator }
|
||
|
|
|
||
|
|
TcxFreeNotificationEvent = procedure(Sender: TComponent) of object;
|
||
|
|
|
||
|
|
TcxFreeNotificator = class(TComponent)
|
||
|
|
private
|
||
|
|
FOnFreeNotification: TcxFreeNotificationEvent;
|
||
|
|
protected
|
||
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||
|
|
public
|
||
|
|
procedure AddSender(ASender: TComponent);
|
||
|
|
procedure RemoveSender(ASender: TComponent);
|
||
|
|
property OnFreeNotification: TcxFreeNotificationEvent read FOnFreeNotification write FOnFreeNotification;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ MRU items support }
|
||
|
|
|
||
|
|
TcxMRUItemClass = class of TcxMRUItem;
|
||
|
|
|
||
|
|
TcxMRUItem = class
|
||
|
|
public
|
||
|
|
function Equals(AItem: TcxMRUItem): Boolean; virtual; abstract;
|
||
|
|
end;
|
||
|
|
|
||
|
|
TcxMRUItems = class
|
||
|
|
private
|
||
|
|
FItems: TList;
|
||
|
|
FMaxCount: Integer;
|
||
|
|
function GetCount: Integer;
|
||
|
|
function GetItem(Index: Integer): TcxMRUItem;
|
||
|
|
procedure SetCount(Value: Integer);
|
||
|
|
procedure SetMaxCount(Value: Integer);
|
||
|
|
protected
|
||
|
|
procedure Delete(AIndex: Integer);
|
||
|
|
procedure UpdateCount;
|
||
|
|
public
|
||
|
|
constructor Create; virtual;
|
||
|
|
destructor Destroy; override;
|
||
|
|
procedure Add(AItem: TcxMRUItem);
|
||
|
|
procedure ClearItems;
|
||
|
|
function IndexOf(AItem: TcxMRUItem): Integer;
|
||
|
|
|
||
|
|
property Count: Integer read GetCount write SetCount;
|
||
|
|
property Items[Index: Integer]: TcxMRUItem read GetItem; default;
|
||
|
|
property MaxCount: Integer read FMaxCount write SetMaxCount;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ Open list }
|
||
|
|
|
||
|
|
TcxOpenList = class(TList)
|
||
|
|
private
|
||
|
|
function GetItem(Index: Integer): TObject;
|
||
|
|
procedure SetItem(Index: Integer; Value: TObject);
|
||
|
|
public
|
||
|
|
property Items[Index: Integer]: TObject read GetItem write SetItem; default;
|
||
|
|
end;
|
||
|
|
|
||
|
|
|
||
|
|
{ TcxComponentCollectionItem }
|
||
|
|
|
||
|
|
TcxComponentCollection = class;
|
||
|
|
|
||
|
|
TcxComponentCollectionItem = class(TComponent)
|
||
|
|
private
|
||
|
|
FCollection: TcxComponentCollection;
|
||
|
|
FID: Integer;
|
||
|
|
procedure AddToCollection(ACollection: TcxComponentCollection);
|
||
|
|
function GetIndex: Integer;
|
||
|
|
procedure RemoveFromCollection(ACollection: TcxComponentCollection);
|
||
|
|
protected
|
||
|
|
procedure Changed(AAllItems: Boolean);
|
||
|
|
function GetCollectionFromParent(AParent: TComponent): TcxComponentCollection; virtual; abstract;
|
||
|
|
procedure SetCollection(AValue: TcxComponentCollection); virtual;
|
||
|
|
procedure SetIndex(AValue: Integer); virtual;
|
||
|
|
public
|
||
|
|
destructor Destroy; override;
|
||
|
|
function GetParentComponent: TComponent; override;
|
||
|
|
function HasParent: Boolean; override;
|
||
|
|
procedure SetParentComponent(Value: TComponent); override;
|
||
|
|
|
||
|
|
property Collection: TcxComponentCollection read FCollection write SetCollection;
|
||
|
|
property ID: Integer read FID;
|
||
|
|
property Index: Integer read GetIndex write SetIndex;
|
||
|
|
end;
|
||
|
|
|
||
|
|
TcxComponentCollectionItemClass = class of TcxComponentCollectionItem;
|
||
|
|
|
||
|
|
{ TcxComponentCollection }
|
||
|
|
|
||
|
|
TcxComponentCollectionNotification = (ccnAdded, ccnChanged, ccnExtracting, ccnExtracted, ccnDeleting);
|
||
|
|
TcxComponentCollectionChangeEvent = procedure(Sender: TObject;
|
||
|
|
AItem: TcxComponentCollectionItem; AAction: TcxComponentCollectionNotification) of object;
|
||
|
|
|
||
|
|
TcxComponentCollection = class(TPersistent)
|
||
|
|
private
|
||
|
|
FItemClass: TcxComponentCollectionItemClass;
|
||
|
|
FItems: TList;
|
||
|
|
FNextID: Integer;
|
||
|
|
FParentComponent: TComponent;
|
||
|
|
FUpdateCount: Integer;
|
||
|
|
FOnChange: TcxComponentCollectionChangeEvent;
|
||
|
|
function GetCount: Integer;
|
||
|
|
procedure InsertItem(AItem: TcxComponentCollectionItem);
|
||
|
|
procedure RemoveItem(AItem: TcxComponentCollectionItem);
|
||
|
|
protected
|
||
|
|
procedure Changed(AItem: TcxComponentCollectionItem = nil;
|
||
|
|
AAction: TcxComponentCollectionNotification = ccnChanged);
|
||
|
|
function GetItem(AIndex: Integer): TcxComponentCollectionItem;
|
||
|
|
procedure Notify(AItem: TcxComponentCollectionItem;
|
||
|
|
AAction: TcxComponentCollectionNotification); virtual;
|
||
|
|
procedure SetItem(AIndex: Integer; Value: TcxComponentCollectionItem);
|
||
|
|
procedure SetItemName(AItem: TcxComponentCollectionItem); virtual;
|
||
|
|
procedure Update(AItem: TcxComponentCollectionItem;
|
||
|
|
AAction: TcxComponentCollectionNotification); virtual;
|
||
|
|
|
||
|
|
property NextID: Integer read FNextID;
|
||
|
|
property UpdateCount: Integer read FUpdateCount;
|
||
|
|
public
|
||
|
|
constructor Create(AParentComponent: TComponent; AItemClass: TcxComponentCollectionItemClass); virtual;
|
||
|
|
destructor Destroy; override;
|
||
|
|
procedure Assign(Source: TPersistent); override;
|
||
|
|
function Add: TcxComponentCollectionItem;
|
||
|
|
procedure BeginUpdate; virtual;
|
||
|
|
procedure Clear;
|
||
|
|
procedure Delete(AIndex: Integer);
|
||
|
|
procedure EndUpdate(AForceUpdate: Boolean = True); virtual;
|
||
|
|
function FindItemByID(ID: Integer): TcxComponentCollectionItem;
|
||
|
|
function Insert(AIndex: Integer): TcxComponentCollectionItem;
|
||
|
|
procedure Remove(AItem: TcxComponentCollectionItem);
|
||
|
|
property Count: Integer read GetCount;
|
||
|
|
property ParentComponent: TComponent read FParentComponent;
|
||
|
|
property Items[AIndex: Integer]: TcxComponentCollectionItem read GetItem write SetItem; default;
|
||
|
|
property OnChange: TcxComponentCollectionChangeEvent read FOnChange write FOnChange;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFDEF CLR}
|
||
|
|
{ TComponentHelper2 }
|
||
|
|
|
||
|
|
TComponentHelper2 = class helper(TComponentHelper) for TComponent
|
||
|
|
public
|
||
|
|
function _GetComponentOwner: TPersistent;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TPersistentHelper2 }
|
||
|
|
|
||
|
|
TPersistentHelper2 = class helper(TPersistentHelper) for TPersistent
|
||
|
|
public
|
||
|
|
function _GetPersistentOwner: TPersistent;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxComponentAccess }
|
||
|
|
|
||
|
|
TcxComponentAccess = class
|
||
|
|
public
|
||
|
|
class procedure _UpdateFakeLinks(AInstance: TcxComponent);
|
||
|
|
end;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
function cxAddObjectLink(AObject: TObject): TcxObjectLink;
|
||
|
|
procedure cxRemoveObjectLink(ALink: TcxObjectLink);
|
||
|
|
procedure cxClearObjectLinks(AObject: TObject);
|
||
|
|
|
||
|
|
procedure CopyList(ASource, ADestination: TList);
|
||
|
|
procedure FillStringsWithEnumTypeValues(AStrings: TStrings; ATypeInfo: PTypeInfo;
|
||
|
|
AGetTypeItemCaption: TcxGetCaptionForIntegerItemFunc);
|
||
|
|
function GetPersistentOwner(APersistent: TPersistent): TPersistent;
|
||
|
|
function GetSubobjectName(AObject, ASubobject: TPersistent): string;
|
||
|
|
function GetValidName(AComponent: TComponent; const AName: string;
|
||
|
|
AIsBaseName: Boolean = False): string;
|
||
|
|
function HexToByte(const AHex: string): Byte;
|
||
|
|
{$IFNDEF VCL}
|
||
|
|
function MulDiv(Number, Numerator, Denominator: Integer): Integer;
|
||
|
|
procedure SetRectEmpty(var R: TRect);
|
||
|
|
{$ENDIF}
|
||
|
|
procedure RenameComponents(ACaller, AOwner: TComponent;
|
||
|
|
ANewName, AOldName: TComponentName;
|
||
|
|
AComponentCount: Integer; AGetComponent: TcxGetComponent);
|
||
|
|
function RoundDiv(I1, I2: Integer): Integer;
|
||
|
|
function Size(cx, cy: Longint): TSize;
|
||
|
|
procedure SwapIntegers(var I1, I2: Integer);
|
||
|
|
function GetRangeCenter(ABound1, ABound2: Integer): Integer;
|
||
|
|
function StreamsEqual(AStream1, AStream2: TMemoryStream): Boolean;
|
||
|
|
procedure OpenWebPage(const AWebAddress: string);
|
||
|
|
function GetCorrectPath(const S: string): string;
|
||
|
|
|
||
|
|
{$IFNDEF DELPHI5}
|
||
|
|
function Supports(const Instance: IUnknown; const Intf: TGUID; out Inst): Boolean; overload;
|
||
|
|
function Supports(Instance: TObject; const Intf: TGUID; out Inst): Boolean; overload;
|
||
|
|
procedure FreeAndNil(var Obj);
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
function cxStrCharLength(const AStr: string): Integer;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{$IFNDEF DELPHI6}
|
||
|
|
function Supports(const Instance: TObject; const IID: TGUID): Boolean; overload;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
function cxGetResourceStringNet(const ResString: string): string;
|
||
|
|
{$IFDEF DELPHI6}
|
||
|
|
function cxGetResourceString(const ResString: string): string; overload;
|
||
|
|
{$ENDIF}
|
||
|
|
procedure cxSetResourceStringNet(const ResString: string; const Value: string);
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
function cxGetResourceString(const ResString: Pointer): string; {$IFDEF DELPHI6} overload; {$ENDIF}
|
||
|
|
procedure cxSetResourceString(const ResString: Pointer; const Value: string);
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
function CreateUniqueName(AOwnerForm, AOwnerComponent, AComponent: TComponent;
|
||
|
|
const APrefixName, ASuffixName: string): string;
|
||
|
|
|
||
|
|
function ReadFromMemory(P: Pointer; AOffset: Integer): Byte;
|
||
|
|
procedure WriteToMemory(P: Pointer; AOffset: Integer; AValue: Byte);
|
||
|
|
|
||
|
|
{$IFDEF CLR}
|
||
|
|
function IsPropertyUnique(AInstance: TObject;
|
||
|
|
const APropertyName: string): Boolean;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{$IFDEF LINUX}
|
||
|
|
const
|
||
|
|
PreferredBrowser: string = 'konqueror';
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
implementation
|
||
|
|
|
||
|
|
uses
|
||
|
|
{$IFDEF CLR}
|
||
|
|
System.Runtime.InteropServices,
|
||
|
|
{$ENDIF}
|
||
|
|
SysUtils, Math, Graphics, Controls;
|
||
|
|
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
type
|
||
|
|
TPersistentAccess = class(TPersistent);
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
var
|
||
|
|
FObjectLinkController: TcxObjectLinkController;
|
||
|
|
FObjectLinkControllerRefCount: Integer;
|
||
|
|
|
||
|
|
function GetShortHint(const Hint: string): string;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
I := AnsiPos('|', Hint);
|
||
|
|
if I = 0 then
|
||
|
|
Result := Hint else
|
||
|
|
Result := Copy(Hint, 1, I - 1);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function GetLongHint(const Hint: string): string;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
I := AnsiPos('|', Hint);
|
||
|
|
if I = 0 then
|
||
|
|
Result := Hint else
|
||
|
|
Result := Copy(Hint, I + 1, Maxint);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFNDEF DELPHI5}
|
||
|
|
|
||
|
|
procedure FreeAndNil(var Obj);
|
||
|
|
var
|
||
|
|
Temp: TObject;
|
||
|
|
begin
|
||
|
|
Temp := TObject(Obj);
|
||
|
|
Pointer(Obj) := nil;
|
||
|
|
Temp.Free;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function Supports(const Instance: IUnknown; const Intf: TGUID; out Inst): Boolean; overload;
|
||
|
|
begin
|
||
|
|
Result := (Instance <> nil) and (Instance.QueryInterface(Intf, Inst) = 0);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function Supports(Instance: TObject; const Intf: TGUID; out Inst): Boolean; overload;
|
||
|
|
var
|
||
|
|
Unk: IUnknown;
|
||
|
|
begin
|
||
|
|
Result := (Instance <> nil) and Instance.GetInterface(IUnknown, Unk) and
|
||
|
|
Supports(Unk, Intf, Inst);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
function cxStrCharLength(const AStr: string): Integer;
|
||
|
|
var
|
||
|
|
APStr: PChar;
|
||
|
|
begin
|
||
|
|
APStr := PChar(AStr);
|
||
|
|
Result := Integer(CharNext(APStr)) - Integer(APStr);
|
||
|
|
end;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{$IFNDEF DELPHI6}
|
||
|
|
function Supports(const Instance: TObject; const IID: TGUID): Boolean;
|
||
|
|
var
|
||
|
|
Temp: IUnknown;
|
||
|
|
begin
|
||
|
|
Result := Supports(Instance, IID, Temp);
|
||
|
|
end;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{ TcxInterfacedPersistent }
|
||
|
|
|
||
|
|
constructor TcxInterfacedPersistent.Create(AOwner: TPersistent);
|
||
|
|
begin
|
||
|
|
inherited Create;
|
||
|
|
FOwner := AOwner;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxInterfacedPersistent.GetOwner: TPersistent;
|
||
|
|
begin
|
||
|
|
Result := FOwner;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFNDEF DELPHI6}
|
||
|
|
|
||
|
|
function TcxInterfacedPersistent._AddRef: Integer;
|
||
|
|
begin
|
||
|
|
if FOwnerInterface <> nil then
|
||
|
|
Result := FOwnerInterface._AddRef
|
||
|
|
else
|
||
|
|
Result := -1;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxInterfacedPersistent._Release: Integer;
|
||
|
|
begin
|
||
|
|
if FOwnerInterface <> nil then
|
||
|
|
Result := FOwnerInterface._Release
|
||
|
|
else
|
||
|
|
Result := -1;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxInterfacedPersistent.QueryInterface(const IID: TGUID; out Obj): HResult;
|
||
|
|
const
|
||
|
|
E_NOINTERFACE = HResult($80004002);
|
||
|
|
begin
|
||
|
|
if GetInterface(IID, Obj) then
|
||
|
|
Result := 0
|
||
|
|
else
|
||
|
|
Result := E_NOINTERFACE;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxInterfacedPersistent.AfterConstruction;
|
||
|
|
begin
|
||
|
|
inherited;
|
||
|
|
if GetOwner <> nil then
|
||
|
|
GetOwner.GetInterface(IUnknown, FOwnerInterface);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{ TcxComponent }
|
||
|
|
|
||
|
|
destructor TcxComponent.Destroy;
|
||
|
|
begin
|
||
|
|
cxClearObjectLinks(Self);
|
||
|
|
inherited Destroy;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponent.Loaded;
|
||
|
|
begin
|
||
|
|
inherited Loaded;
|
||
|
|
UpdateFakeLinks;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
procedure TcxComponent.BeforeDestruction;
|
||
|
|
begin
|
||
|
|
if not IsDestroying then Destroying;
|
||
|
|
end;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
procedure TcxComponent.GetFakeComponentLinks(AList: TList);
|
||
|
|
begin
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponent.UpdateFakeLinks;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
AList: TList;
|
||
|
|
begin
|
||
|
|
if not IsDesigning or IsDestroying or (Owner = nil) then Exit;
|
||
|
|
AList := TList.Create;
|
||
|
|
try
|
||
|
|
GetFakeComponentLinks(AList);
|
||
|
|
for I := 0 to GetFakeComponentLinkCount - 1 do
|
||
|
|
if I < AList.Count then
|
||
|
|
SetFakeComponentLink(I, TComponent(AList[I]))
|
||
|
|
else
|
||
|
|
SetFakeComponentLink(I, nil);
|
||
|
|
finally
|
||
|
|
AList.Free;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponent.GetFakeComponentLinkCount: Integer;
|
||
|
|
begin
|
||
|
|
Result := 3;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponent.GetIsDesigning: Boolean;
|
||
|
|
begin
|
||
|
|
Result := csDesigning in ComponentState;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponent.GetIsDestroying: Boolean;
|
||
|
|
begin
|
||
|
|
Result := csDestroying in ComponentState;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponent.SetFakeComponentLink(Index: Integer; Value: TComponent);
|
||
|
|
begin
|
||
|
|
case Index of
|
||
|
|
0: FFakeComponentLink1 := Value;
|
||
|
|
1: FFakeComponentLink2 := Value;
|
||
|
|
2: FFakeComponentLink3 := Value;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxCollection }
|
||
|
|
|
||
|
|
procedure TcxCollection.Assign(Source: TPersistent);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
AItem: TCollectionItem;
|
||
|
|
begin
|
||
|
|
if Source is TCollection then
|
||
|
|
begin
|
||
|
|
if (Count = 0) and (TCollection(Source).Count = 0) then Exit;
|
||
|
|
BeginUpdate;
|
||
|
|
try
|
||
|
|
for I := 0 to TCollection(Source).Count - 1 do
|
||
|
|
begin
|
||
|
|
if I > Count - 1 then
|
||
|
|
AItem := Add
|
||
|
|
else
|
||
|
|
AItem := Items[I];
|
||
|
|
AItem.Assign(TCollection(Source).Items[I]);
|
||
|
|
end;
|
||
|
|
for I := Count - 1 downto TCollection(Source).Count do
|
||
|
|
Delete(I);
|
||
|
|
finally
|
||
|
|
EndUpdate;
|
||
|
|
end;
|
||
|
|
end
|
||
|
|
else
|
||
|
|
inherited;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxObjectList }
|
||
|
|
|
||
|
|
procedure TcxObjectList.Clear;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
for I := 0 to Count - 1 do
|
||
|
|
Items[I].Free;
|
||
|
|
inherited Clear;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxObjectList.GetItem(Index: Integer): TObject;
|
||
|
|
begin
|
||
|
|
Result := inherited Items[Index];
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxRegisteredClassList }
|
||
|
|
|
||
|
|
constructor TcxRegisteredClassList.Create;
|
||
|
|
begin
|
||
|
|
inherited Create;
|
||
|
|
FItems := TList.Create;
|
||
|
|
end;
|
||
|
|
|
||
|
|
destructor TcxRegisteredClassList.Destroy;
|
||
|
|
begin
|
||
|
|
Clear;
|
||
|
|
FreeAndNil(FItems);
|
||
|
|
inherited Destroy;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxRegisteredClassList.Clear;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
for I := 0 to FItems.Count - 1 do
|
||
|
|
TcxRegisteredClassListItemData(FItems[I]).Free;
|
||
|
|
FItems.Clear;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClassList.FindClass(AItemClass: TClass): TClass;
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
if Find(AItemClass, AIndex) then
|
||
|
|
Result := Items[AIndex].RegisteredClass
|
||
|
|
else
|
||
|
|
Result := nil;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxRegisteredClassList.Register(AItemClass, ARegisteredClass: TClass);
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
AData: TcxRegisteredClassListItemData;
|
||
|
|
begin
|
||
|
|
AIndex := -1;
|
||
|
|
AData := TcxRegisteredClassListItemData.Create;
|
||
|
|
AData.ItemClass := AItemClass;
|
||
|
|
AData.RegisteredClass := ARegisteredClass;
|
||
|
|
if Find(AItemClass, AIndex) then
|
||
|
|
FItems.Insert(AIndex + 1, AData)
|
||
|
|
else
|
||
|
|
if AIndex <> -1 then
|
||
|
|
FItems.Insert(AIndex, AData)
|
||
|
|
else
|
||
|
|
FItems.Add(AData);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxRegisteredClassList.Unregister(AItemClass, ARegisteredClass: TClass);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
AData: TcxRegisteredClassListItemData;
|
||
|
|
begin
|
||
|
|
for I := FItems.Count - 1 downto 0 do
|
||
|
|
begin
|
||
|
|
AData := Items[I];
|
||
|
|
if (AData.ItemClass = AItemClass) and (AData.RegisteredClass = ARegisteredClass) then
|
||
|
|
begin
|
||
|
|
AData.Free;
|
||
|
|
FItems.Delete(I);
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClassList.Find(AItemClass: TClass; var AIndex: Integer): Boolean;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
AData: TcxRegisteredClassListItemData;
|
||
|
|
begin
|
||
|
|
Result := False;
|
||
|
|
for I := FItems.Count - 1 downto 0 do
|
||
|
|
begin
|
||
|
|
AData := Items[I];
|
||
|
|
if AItemClass.InheritsFrom(AData.ItemClass) then
|
||
|
|
begin
|
||
|
|
AIndex := I;
|
||
|
|
Result := True;
|
||
|
|
Break;
|
||
|
|
end
|
||
|
|
else
|
||
|
|
if AData.ItemClass.InheritsFrom(AItemClass) then
|
||
|
|
AIndex := I;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClassList.GetCount: Integer;
|
||
|
|
begin
|
||
|
|
Result := FItems.Count;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClassList.GetItem(Index: Integer): TcxRegisteredClassListItemData;
|
||
|
|
begin
|
||
|
|
Result := TcxRegisteredClassListItemData(FItems[Index]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxRegisteredClasses }
|
||
|
|
|
||
|
|
type
|
||
|
|
TcxRegisteredClassesStringList = class(TStringList)
|
||
|
|
public
|
||
|
|
Owner: TcxRegisteredClasses;
|
||
|
|
end;
|
||
|
|
|
||
|
|
constructor TcxRegisteredClasses.Create(ARegisterClasses: Boolean = False);
|
||
|
|
begin
|
||
|
|
inherited Create;
|
||
|
|
FRegisterClasses := ARegisterClasses;
|
||
|
|
FItems := TcxRegisteredClassesStringList.Create;
|
||
|
|
TcxRegisteredClassesStringList(FItems).Owner := Self;
|
||
|
|
end;
|
||
|
|
|
||
|
|
destructor TcxRegisteredClasses.Destroy;
|
||
|
|
begin
|
||
|
|
Clear;
|
||
|
|
FItems.Free;
|
||
|
|
inherited Destroy;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.GetCount: Integer;
|
||
|
|
begin
|
||
|
|
Result := FItems.Count;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.GetDescription(Index: Integer): string;
|
||
|
|
begin
|
||
|
|
Result := GetShortHint(FItems[Index]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.GetHint(Index: Integer): string;
|
||
|
|
begin
|
||
|
|
Result := GetLongHint(FItems[Index]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.GetItem(Index: Integer): TClass;
|
||
|
|
begin
|
||
|
|
Result := TClass(FItems.Objects[Index]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxRegisteredClasses.SetSorted(Value: Boolean);
|
||
|
|
begin
|
||
|
|
if FSorted <> Value then
|
||
|
|
begin
|
||
|
|
FSorted := Value;
|
||
|
|
if FSorted then Sort;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.CompareItems(AIndex1, AIndex2: Integer): Integer;
|
||
|
|
begin
|
||
|
|
Result := AnsiCompareText(Descriptions[AIndex1], Descriptions[AIndex2]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function SortClasses(List: TStringList; Index1, Index2: Integer): Integer;
|
||
|
|
begin
|
||
|
|
Result := TcxRegisteredClassesStringList(List).Owner.CompareItems(Index1, Index2);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxRegisteredClasses.Sort;
|
||
|
|
begin
|
||
|
|
FItems.CustomSort(SortClasses);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxRegisteredClasses.Clear;
|
||
|
|
begin
|
||
|
|
FItems.Clear;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.FindByClassName(const AClassName: string): TClass;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
Result := nil;
|
||
|
|
for I := 0 to Count - 1 do
|
||
|
|
begin
|
||
|
|
if Items[I].ClassName = AClassName then
|
||
|
|
begin
|
||
|
|
Result := Items[I];
|
||
|
|
Break;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.FindByDescription(const ADescription: string): TClass;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
Result := nil;
|
||
|
|
for I := 0 to Count - 1 do
|
||
|
|
begin
|
||
|
|
if Descriptions[I] = ADescription then
|
||
|
|
begin
|
||
|
|
Result := Items[I];
|
||
|
|
Break;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.GetDescriptionByClass(AClass: TClass): string;
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
AIndex := GetIndexByClass(AClass);
|
||
|
|
if AIndex = -1 then
|
||
|
|
Result := ''
|
||
|
|
else
|
||
|
|
Result := Descriptions[AIndex];
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.GetHintByClass(AClass: TClass): string;
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
AIndex := GetIndexByClass(AClass);
|
||
|
|
if AIndex = -1 then
|
||
|
|
Result := ''
|
||
|
|
else
|
||
|
|
Result := Hints[AIndex];
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxRegisteredClasses.GetIndexByClass(AClass: TClass): Integer;
|
||
|
|
begin
|
||
|
|
Result := FItems.IndexOfObject(TObject(AClass));
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxRegisteredClasses.Register(AClass: TClass; const ADescription: string);
|
||
|
|
begin
|
||
|
|
if GetIndexByClass(AClass) = -1 then
|
||
|
|
begin
|
||
|
|
FItems.AddObject(ADescription, TObject(AClass));
|
||
|
|
if FSorted then Sort;
|
||
|
|
if FRegisterClasses then RegisterClass(TPersistentClass(AClass));
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxRegisteredClasses.Unregister(AClass: TClass);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
I := GetIndexByClass(AClass);
|
||
|
|
if I <> -1 then
|
||
|
|
FItems.Delete(I);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxAutoWidthItem }
|
||
|
|
|
||
|
|
constructor TcxAutoWidthItem.Create;
|
||
|
|
begin
|
||
|
|
inherited;
|
||
|
|
AutoWidth := -1;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxAutoWidthObject }
|
||
|
|
|
||
|
|
constructor TcxAutoWidthObject.Create(ACount: Integer);
|
||
|
|
begin
|
||
|
|
inherited Create;
|
||
|
|
FItems := TList.Create;
|
||
|
|
FItems.Capacity := ACount;
|
||
|
|
end;
|
||
|
|
|
||
|
|
destructor TcxAutoWidthObject.Destroy;
|
||
|
|
begin
|
||
|
|
Clear;
|
||
|
|
FItems.Free;
|
||
|
|
inherited;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxAutoWidthObject.GetCount: Integer;
|
||
|
|
begin
|
||
|
|
Result := FItems.Count;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxAutoWidthObject.GetItem(Index: Integer): TcxAutoWidthItem;
|
||
|
|
begin
|
||
|
|
Result := TcxAutoWidthItem(FItems[Index]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxAutoWidthObject.GetWidth: Integer;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
Result := 0;
|
||
|
|
for I := 0 to Count - 1 do
|
||
|
|
Inc(Result, Items[I].Width);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxAutoWidthObject.Clear;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
for I := Count - 1 downto 0 do Items[I].Free;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxAutoWidthObject.AddItem: TcxAutoWidthItem;
|
||
|
|
begin
|
||
|
|
Result := TcxAutoWidthItem.Create;
|
||
|
|
FItems.Add(Result);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxAutoWidthObject.Calculate;
|
||
|
|
var
|
||
|
|
AAvailableWidth, AWidth, ANewAvailableWidth, ANewWidth, AOffset, I,
|
||
|
|
AItemAutoWidth: Integer;
|
||
|
|
AAssignAllWidths, AItemWithMinWidthFound: Boolean;
|
||
|
|
|
||
|
|
procedure RemoveItemFromCalculation(AItem: TcxAutoWidthItem);
|
||
|
|
begin
|
||
|
|
with AItem do
|
||
|
|
begin
|
||
|
|
Dec(ANewAvailableWidth, AutoWidth);
|
||
|
|
Dec(ANewWidth, Width);
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure ProcessFixedItems;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
|
||
|
|
procedure ProcessItem(AItem: TcxAutoWidthItem);
|
||
|
|
begin
|
||
|
|
with AItem do
|
||
|
|
if Fixed then
|
||
|
|
begin
|
||
|
|
AutoWidth := Width;
|
||
|
|
RemoveItemFromCalculation(AItem);
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
begin
|
||
|
|
for I := 0 to Count - 1 do ProcessItem(Items[I]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{procedure ProcessFixedColumns;
|
||
|
|
var
|
||
|
|
AFixedIndex, I: Integer;
|
||
|
|
begin
|
||
|
|
if not (gcsColumnSizing in GridDefinition.Controller.State) then Exit;
|
||
|
|
AFixedIndex :=
|
||
|
|
(GridDefinition.Controller.DragAndDropObject as TcxGridColumnHeaderSizingObject).Column.VisibleIndex;
|
||
|
|
if AFixedIndex = Count - 1 then Exit;
|
||
|
|
for I := 0 to Count - 1 do
|
||
|
|
if I <= AFixedIndex then
|
||
|
|
begin
|
||
|
|
AColumnWidth := Items[I].CalculateWidth;
|
||
|
|
Items[I].Width := AColumnWidth;
|
||
|
|
Dec(AAvailableWidth, AColumnWidth);
|
||
|
|
Dec(AWidth, AColumnWidth);
|
||
|
|
end;
|
||
|
|
end;}
|
||
|
|
|
||
|
|
procedure ProcessItem(AItem: TcxAutoWidthItem);
|
||
|
|
|
||
|
|
function CalculateItemAutoWidth: Integer;
|
||
|
|
begin
|
||
|
|
Result :=
|
||
|
|
MulDiv(AOffset + AItem.Width, AAvailableWidth, AWidth) -
|
||
|
|
MulDiv(AOffset, AAvailableWidth, AWidth);
|
||
|
|
end;
|
||
|
|
|
||
|
|
begin
|
||
|
|
AItemAutoWidth := CalculateItemAutoWidth;
|
||
|
|
if AAssignAllWidths then
|
||
|
|
AItem.AutoWidth := AItemAutoWidth
|
||
|
|
else
|
||
|
|
if AItemAutoWidth <= AItem.MinWidth then
|
||
|
|
begin
|
||
|
|
AItem.AutoWidth := AItem.MinWidth;
|
||
|
|
RemoveItemFromCalculation(AItem);
|
||
|
|
AItemWithMinWidthFound := True;
|
||
|
|
end;
|
||
|
|
Inc(AOffset, AItem.Width);
|
||
|
|
end;
|
||
|
|
|
||
|
|
begin
|
||
|
|
AAvailableWidth := FAvailableWidth;
|
||
|
|
AWidth := Width;
|
||
|
|
|
||
|
|
ANewAvailableWidth := AAvailableWidth;
|
||
|
|
ANewWidth := AWidth;
|
||
|
|
ProcessFixedItems;
|
||
|
|
AAssignAllWidths := False;
|
||
|
|
repeat
|
||
|
|
AAvailableWidth := ANewAvailableWidth;
|
||
|
|
AWidth := ANewWidth;
|
||
|
|
AOffset := 0;
|
||
|
|
AItemWithMinWidthFound := False;
|
||
|
|
|
||
|
|
for I := 0 to Count - 1 do
|
||
|
|
if Items[I].AutoWidth = -1 then ProcessItem(Items[I]);
|
||
|
|
|
||
|
|
if not AItemWithMinWidthFound then
|
||
|
|
AAssignAllWidths := not AAssignAllWidths;
|
||
|
|
until (ANewWidth = 0) or not AItemWithMinWidthFound and not AAssignAllWidths;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxAlignment }
|
||
|
|
|
||
|
|
constructor TcxAlignment.Create(AOwner: TPersistent; AUseAssignedValues: Boolean = False;
|
||
|
|
ADefaultHorz: TAlignment = taLeftJustify; ADefaultVert: TcxAlignmentVert = vaTop);
|
||
|
|
begin
|
||
|
|
inherited Create;
|
||
|
|
FOwner := AOwner;
|
||
|
|
FUseAssignedValues := AUseAssignedValues;
|
||
|
|
FDefaultHorz := ADefaultHorz;
|
||
|
|
FDefaultVert := ADefaultVert;
|
||
|
|
FHorz := FDefaultHorz;
|
||
|
|
FVert := FDefaultVert;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxAlignment.Assign(Source: TPersistent);
|
||
|
|
var
|
||
|
|
AChanged: Boolean;
|
||
|
|
begin
|
||
|
|
if Source is TcxAlignment then
|
||
|
|
with Source as TcxAlignment do
|
||
|
|
begin
|
||
|
|
AChanged := Self.FHorz <> FHorz;
|
||
|
|
Self.FHorz := FHorz;
|
||
|
|
AChanged := AChanged or (Self.FVert <> FVert);
|
||
|
|
Self.FVert := FVert;
|
||
|
|
Self.FIsHorzAssigned := FIsHorzAssigned;
|
||
|
|
Self.FIsVertAssigned := FIsVertAssigned;
|
||
|
|
if AChanged then
|
||
|
|
Self.DoChanged;
|
||
|
|
end
|
||
|
|
else
|
||
|
|
inherited Assign(Source);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxAlignment.Reset;
|
||
|
|
var
|
||
|
|
AChanged: Boolean;
|
||
|
|
begin
|
||
|
|
FIsHorzAssigned := False;
|
||
|
|
FIsVertAssigned := False;
|
||
|
|
AChanged := FHorz <> FDefaultHorz;
|
||
|
|
FHorz := FDefaultHorz;
|
||
|
|
AChanged := AChanged or (FVert <> FDefaultVert);
|
||
|
|
FVert := FDefaultVert;
|
||
|
|
if AChanged then
|
||
|
|
DoChanged;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxAlignment.DoChanged;
|
||
|
|
begin
|
||
|
|
if Assigned(FOnChanged) then
|
||
|
|
FOnChanged(Self);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxAlignment.GetOwner: TPersistent;
|
||
|
|
begin
|
||
|
|
Result := FOwner;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxAlignment.IsHorzStored: Boolean;
|
||
|
|
begin
|
||
|
|
if FUseAssignedValues then
|
||
|
|
Result := FIsHorzAssigned
|
||
|
|
else
|
||
|
|
Result := FHorz <> FDefaultHorz;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxAlignment.IsVertStored: Boolean;
|
||
|
|
begin
|
||
|
|
if FUseAssignedValues then
|
||
|
|
Result := FIsVertAssigned
|
||
|
|
else
|
||
|
|
Result := FVert <> FDefaultVert;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxAlignment.SetHorz(const Value: TAlignment);
|
||
|
|
begin
|
||
|
|
FIsHorzAssigned := True;
|
||
|
|
if Value <> FHorz then
|
||
|
|
begin
|
||
|
|
FHorz := Value;
|
||
|
|
DoChanged;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxAlignment.SetVert(const Value: TcxAlignmentVert);
|
||
|
|
begin
|
||
|
|
FIsVertAssigned := True;
|
||
|
|
if Value <> FVert then
|
||
|
|
begin
|
||
|
|
FVert := Value;
|
||
|
|
DoChanged;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxObjectLinkController }
|
||
|
|
|
||
|
|
constructor TcxObjectLinkController.Create;
|
||
|
|
begin
|
||
|
|
inherited Create;
|
||
|
|
FLinks := TList.Create;
|
||
|
|
end;
|
||
|
|
|
||
|
|
destructor TcxObjectLinkController.Destroy;
|
||
|
|
begin
|
||
|
|
FLinks.Free;
|
||
|
|
inherited Destroy;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxObjectLinkController.AddLink(AObject: TObject): TcxObjectLink;
|
||
|
|
begin
|
||
|
|
Result := TcxObjectLink.Create;
|
||
|
|
Result.Ref := AObject;
|
||
|
|
FLinks.Add(Result);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxObjectLinkController.RemoveLink(ALink: TcxObjectLink);
|
||
|
|
begin
|
||
|
|
if ALink.Ref <> nil then
|
||
|
|
FLinks.Remove(ALink);
|
||
|
|
ALink.Free;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxObjectLinkController.ClearLinks(AObject: TObject);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
ALink: TcxObjectLink;
|
||
|
|
begin
|
||
|
|
for I := FLinks.Count - 1 downto 0 do
|
||
|
|
begin
|
||
|
|
ALink := TcxObjectLink(FLinks[I]);
|
||
|
|
if ALink.Ref = AObject then
|
||
|
|
begin
|
||
|
|
ALink.Ref := nil;
|
||
|
|
FLinks.Delete(I);
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxFreeNotificator }
|
||
|
|
|
||
|
|
procedure TcxFreeNotificator.AddSender(ASender: TComponent);
|
||
|
|
begin
|
||
|
|
if ASender <> nil then
|
||
|
|
ASender.FreeNotification(Self);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxFreeNotificator.RemoveSender(ASender: TComponent);
|
||
|
|
begin
|
||
|
|
{$IFDEF DELPHI5}
|
||
|
|
if ASender <> nil then
|
||
|
|
ASender.RemoveFreeNotification(Self);
|
||
|
|
{$ENDIF}
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxFreeNotificator.Notification(AComponent: TComponent; Operation: TOperation);
|
||
|
|
begin
|
||
|
|
inherited Notification(AComponent, Operation);
|
||
|
|
if (Operation = opRemove) and Assigned(FOnFreeNotification) then
|
||
|
|
FOnFreeNotification(AComponent);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure AddObjectLinkControllerRefCount;
|
||
|
|
begin
|
||
|
|
Inc(FObjectLinkControllerRefCount);
|
||
|
|
if FObjectLinkController = nil then
|
||
|
|
FObjectLinkController := TcxObjectLinkController.Create;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure ReleaseObjectLinkControllerRefCount;
|
||
|
|
begin
|
||
|
|
Dec(FObjectLinkControllerRefCount);
|
||
|
|
if (FObjectLinkControllerRefCount = 0) and (FObjectLinkController <> nil) then
|
||
|
|
FreeAndNil(FObjectLinkController);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function cxAddObjectLink(AObject: TObject): TcxObjectLink;
|
||
|
|
begin
|
||
|
|
AddObjectLinkControllerRefCount;
|
||
|
|
Result := FObjectLinkController.AddLink(AObject);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure cxRemoveObjectLink(ALink: TcxObjectLink);
|
||
|
|
begin
|
||
|
|
FObjectLinkController.RemoveLink(ALink);
|
||
|
|
ReleaseObjectLinkControllerRefCount;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure cxClearObjectLinks(AObject: TObject);
|
||
|
|
begin
|
||
|
|
if FObjectLinkController <> nil then
|
||
|
|
FObjectLinkController.ClearLinks(AObject);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxMRUItems }
|
||
|
|
|
||
|
|
constructor TcxMRUItems.Create;
|
||
|
|
begin
|
||
|
|
inherited Create;
|
||
|
|
FItems := TList.Create;
|
||
|
|
end;
|
||
|
|
|
||
|
|
destructor TcxMRUItems.Destroy;
|
||
|
|
begin
|
||
|
|
ClearItems;
|
||
|
|
FItems.Free;
|
||
|
|
inherited;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxMRUItems.GetCount: Integer;
|
||
|
|
begin
|
||
|
|
Result := FItems.Count;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxMRUItems.GetItem(Index: Integer): TcxMRUItem;
|
||
|
|
begin
|
||
|
|
Result := TcxMRUItem(FItems[Index]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxMRUItems.SetCount(Value: Integer);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
if Value < Count then
|
||
|
|
for I := Count - 1 downto Value do
|
||
|
|
Delete(I);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxMRUItems.SetMaxCount(Value: Integer);
|
||
|
|
begin
|
||
|
|
if Value < 0 then Value := 0;
|
||
|
|
if FMaxCount <> Value then
|
||
|
|
begin
|
||
|
|
FMaxCount := Value;
|
||
|
|
UpdateCount;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxMRUItems.Delete(AIndex: Integer);
|
||
|
|
begin
|
||
|
|
Items[AIndex].Free;
|
||
|
|
FItems.Delete(AIndex);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxMRUItems.UpdateCount;
|
||
|
|
begin
|
||
|
|
if MaxCount <> 0 then Count := MaxCount;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxMRUItems.Add(AItem: TcxMRUItem);
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
AIndex := IndexOf(AItem);
|
||
|
|
if AIndex = -1 then
|
||
|
|
begin
|
||
|
|
FItems.Insert(0, AItem);
|
||
|
|
UpdateCount;
|
||
|
|
end
|
||
|
|
else
|
||
|
|
begin
|
||
|
|
FItems.Move(AIndex, 0);
|
||
|
|
AItem.Free;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxMRUItems.ClearItems;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
for I := Count - 1 downto 0 do
|
||
|
|
Delete(I);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxMRUItems.IndexOf(AItem: TcxMRUItem): Integer;
|
||
|
|
begin
|
||
|
|
for Result := 0 to Count - 1 do
|
||
|
|
if Items[Result].Equals(AItem) then Exit;
|
||
|
|
Result := -1;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxOpenList }
|
||
|
|
|
||
|
|
function TcxOpenList.GetItem(Index: Integer): TObject;
|
||
|
|
begin
|
||
|
|
Result := TObject(inherited Items[Index]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxOpenList.SetItem(Index: Integer; Value: TObject);
|
||
|
|
begin
|
||
|
|
{$IFDEF CLR}
|
||
|
|
if Count < 1 + Index then
|
||
|
|
Count := 1 + Index;
|
||
|
|
{$ELSE}
|
||
|
|
Count := Max(Count, 1 + Index);
|
||
|
|
{$ENDIF}
|
||
|
|
inherited Items[Index] := Value;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxComponentCollectionItem }
|
||
|
|
|
||
|
|
destructor TcxComponentCollectionItem.Destroy;
|
||
|
|
begin
|
||
|
|
SetCollection(nil);
|
||
|
|
inherited Destroy;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollectionItem.Changed(AAllItems: Boolean);
|
||
|
|
begin
|
||
|
|
if not (csDestroying in ComponentState) and (Collection <> nil) then
|
||
|
|
if AAllItems then
|
||
|
|
Collection.Changed
|
||
|
|
else
|
||
|
|
Collection.Changed(Self);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponentCollectionItem.GetParentComponent: TComponent;
|
||
|
|
begin
|
||
|
|
if Collection <> nil then
|
||
|
|
Result := Collection.ParentComponent
|
||
|
|
else
|
||
|
|
Result := inherited GetParentComponent;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponentCollectionItem.HasParent: Boolean;
|
||
|
|
begin
|
||
|
|
Result := GetParentComponent <> nil;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollectionItem.SetParentComponent(Value: TComponent);
|
||
|
|
begin
|
||
|
|
Collection := GetCollectionFromParent(Value);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollectionItem.SetCollection(AValue: TcxComponentCollection);
|
||
|
|
begin
|
||
|
|
if Collection <> AValue then
|
||
|
|
begin
|
||
|
|
RemoveFromCollection(Collection);
|
||
|
|
AddToCollection(AValue);
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollectionItem.SetIndex(AValue: Integer);
|
||
|
|
var
|
||
|
|
ACurIndex: Integer;
|
||
|
|
begin
|
||
|
|
ACurIndex := GetIndex;
|
||
|
|
if (ACurIndex >= 0) and (ACurIndex <> AValue) then
|
||
|
|
begin
|
||
|
|
Collection.FItems.Move(ACurIndex, AValue);
|
||
|
|
Changed(True);
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollectionItem.AddToCollection(ACollection: TcxComponentCollection);
|
||
|
|
begin
|
||
|
|
if ACollection <> nil then
|
||
|
|
ACollection.InsertItem(Self);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponentCollectionItem.GetIndex: Integer;
|
||
|
|
begin
|
||
|
|
if Collection <> nil then
|
||
|
|
Result := Collection.FItems.IndexOf(Self)
|
||
|
|
else
|
||
|
|
Result := -1;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollectionItem.RemoveFromCollection(ACollection: TcxComponentCollection);
|
||
|
|
begin
|
||
|
|
if ACollection <> nil then
|
||
|
|
ACollection.RemoveItem(Self);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxComponentCollection }
|
||
|
|
|
||
|
|
constructor TcxComponentCollection.Create(AParentComponent: TComponent; AItemClass: TcxComponentCollectionItemClass);
|
||
|
|
begin
|
||
|
|
inherited Create;
|
||
|
|
FItemClass := AItemClass;
|
||
|
|
FItems := TList.Create;
|
||
|
|
FParentComponent := AParentComponent;
|
||
|
|
end;
|
||
|
|
|
||
|
|
destructor TcxComponentCollection.Destroy;
|
||
|
|
begin
|
||
|
|
FUpdateCount := 1;
|
||
|
|
if FItems <> nil then
|
||
|
|
Clear;
|
||
|
|
FItems.Free;
|
||
|
|
inherited Destroy;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.Assign(Source: TPersistent);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
if Source is TcxComponentCollection then
|
||
|
|
begin
|
||
|
|
BeginUpdate;
|
||
|
|
try
|
||
|
|
Clear;
|
||
|
|
for I := 0 to TcxComponentCollection(Source).Count - 1 do
|
||
|
|
Add.Assign(TcxComponentCollection(Source).Items[I]);
|
||
|
|
finally
|
||
|
|
EndUpdate;
|
||
|
|
end;
|
||
|
|
end
|
||
|
|
else
|
||
|
|
inherited Assign(Source);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponentCollection.Add: TcxComponentCollectionItem;
|
||
|
|
begin
|
||
|
|
Result := FItemClass.Create(ParentComponent.Owner);
|
||
|
|
Result.SetParentComponent(ParentComponent);
|
||
|
|
SetItemName(Result);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.BeginUpdate;
|
||
|
|
begin
|
||
|
|
Inc(FUpdateCount);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.Clear;
|
||
|
|
begin
|
||
|
|
if FItems.Count = 0 then Exit;
|
||
|
|
BeginUpdate;
|
||
|
|
try
|
||
|
|
while FItems.Count > 0 do
|
||
|
|
TObject(FItems.Last).Free;
|
||
|
|
finally
|
||
|
|
EndUpdate;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.Delete(AIndex: Integer);
|
||
|
|
begin
|
||
|
|
Notify(Items[AIndex], ccnDeleting);
|
||
|
|
Items[AIndex].Free;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.EndUpdate(AForceUpdate: Boolean = True);
|
||
|
|
begin
|
||
|
|
Dec(FUpdateCount);
|
||
|
|
if AForceUpdate then
|
||
|
|
Changed;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponentCollection.FindItemByID(ID: Integer): TcxComponentCollectionItem;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
for I := 0 to FItems.Count-1 do
|
||
|
|
begin
|
||
|
|
Result := Items[I];
|
||
|
|
if Result.ID = ID then
|
||
|
|
Exit;
|
||
|
|
end;
|
||
|
|
Result := nil;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponentCollection.Insert(AIndex: Integer): TcxComponentCollectionItem;
|
||
|
|
begin
|
||
|
|
Result := Add;
|
||
|
|
Result.Index := AIndex;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.Remove(AItem: TcxComponentCollectionItem);
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
AIndex := FItems.IndexOf(AItem);
|
||
|
|
if AIndex > -1 then
|
||
|
|
Delete(AIndex);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.InsertItem(AItem: TcxComponentCollectionItem);
|
||
|
|
begin
|
||
|
|
if not (AItem is FItemClass) then
|
||
|
|
Exit;
|
||
|
|
FItems.Add(AItem);
|
||
|
|
AItem.FCollection := Self;
|
||
|
|
AItem.FID := FNextID;
|
||
|
|
Inc(FNextID);
|
||
|
|
Notify(AItem, ccnAdded);
|
||
|
|
Changed(AItem, ccnAdded);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.RemoveItem(AItem: TcxComponentCollectionItem);
|
||
|
|
begin
|
||
|
|
Notify(AItem, ccnExtracting);
|
||
|
|
FItems.Remove(AItem);
|
||
|
|
AItem.FCollection := nil;
|
||
|
|
Notify(AItem, ccnExtracted);
|
||
|
|
Changed(AItem, ccnExtracted);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.Changed(AItem: TcxComponentCollectionItem = nil;
|
||
|
|
AAction: TcxComponentCollectionNotification = ccnChanged);
|
||
|
|
begin
|
||
|
|
if FUpdateCount = 0 then
|
||
|
|
Update(AItem, AAction);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponentCollection.GetItem(AIndex: Integer): TcxComponentCollectionItem;
|
||
|
|
begin
|
||
|
|
Result := TcxComponentCollectionItem(FItems[AIndex]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.Notify(AItem: TcxComponentCollectionItem;
|
||
|
|
AAction: TcxComponentCollectionNotification);
|
||
|
|
begin
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.SetItem(AIndex: Integer; Value: TcxComponentCollectionItem);
|
||
|
|
begin
|
||
|
|
Items[AIndex].Assign(Value);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.SetItemName(AItem: TcxComponentCollectionItem);
|
||
|
|
begin
|
||
|
|
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure TcxComponentCollection.Update(AItem: TcxComponentCollectionItem;
|
||
|
|
AAction: TcxComponentCollectionNotification);
|
||
|
|
begin
|
||
|
|
if Assigned(OnChange) then
|
||
|
|
OnChange(Self, AItem, AAction);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function TcxComponentCollection.GetCount: Integer;
|
||
|
|
begin
|
||
|
|
Result := FItems.Count;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFDEF CLR}
|
||
|
|
{ TComponentHelper2 }
|
||
|
|
|
||
|
|
function TComponentHelper2._GetComponentOwner: TPersistent;
|
||
|
|
begin
|
||
|
|
Result := GetOwner;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TPersistentHelper2 }
|
||
|
|
|
||
|
|
function TPersistentHelper2._GetPersistentOwner: TPersistent;
|
||
|
|
begin
|
||
|
|
Result := GetOwner;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{ TcxComponentAccess }
|
||
|
|
|
||
|
|
class procedure TcxComponentAccess._UpdateFakeLinks(AInstance: TcxComponent);
|
||
|
|
begin
|
||
|
|
AInstance.UpdateFakeLinks;
|
||
|
|
end;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
{ functions }
|
||
|
|
|
||
|
|
procedure CopyList(ASource, ADestination: TList);
|
||
|
|
{$IFDEF CLR}
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
{$ENDIF}
|
||
|
|
begin
|
||
|
|
ADestination.Count := ASource.Count;
|
||
|
|
{$IFDEF CLR}
|
||
|
|
for I := 0 to ADestination.Count - 1 do
|
||
|
|
ADestination[I] := ASource[I];
|
||
|
|
{$ELSE}
|
||
|
|
Move(ASource.List^, ADestination.List^, ASource.Count * SizeOf(Pointer));
|
||
|
|
{$ENDIF}
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure FillStringsWithEnumTypeValues(AStrings: TStrings; ATypeInfo: PTypeInfo;
|
||
|
|
AGetTypeItemCaption: TcxGetCaptionForIntegerItemFunc);
|
||
|
|
var
|
||
|
|
ATypeData: PTypeData;
|
||
|
|
I: Integer;
|
||
|
|
S: string;
|
||
|
|
begin
|
||
|
|
ATypeData := GetTypeData(ATypeInfo);
|
||
|
|
AStrings.BeginUpdate;
|
||
|
|
try
|
||
|
|
for I := ATypeData.MinValue to ATypeData.MaxValue do
|
||
|
|
begin
|
||
|
|
S := AGetTypeItemCaption(I);
|
||
|
|
if S <> '' then
|
||
|
|
AStrings.AddObject(S, TObject(I));
|
||
|
|
end;
|
||
|
|
finally
|
||
|
|
AStrings.EndUpdate;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
function GetPersistentOwner(APersistent: TPersistent): TPersistent;
|
||
|
|
begin
|
||
|
|
Result := TPersistentAccess(APersistent).GetOwner;
|
||
|
|
end;
|
||
|
|
{$ELSE}
|
||
|
|
function GetPersistentOwner(APersistent: TPersistent): TPersistent;
|
||
|
|
begin
|
||
|
|
if APersistent is TComponent then
|
||
|
|
Result := TComponent(APersistent)._GetComponentOwner
|
||
|
|
else
|
||
|
|
Result := APersistent._GetPersistentOwner;
|
||
|
|
end;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
function GetSubobjectName(AObject, ASubobject: TPersistent): string;
|
||
|
|
var
|
||
|
|
APropList: PPropList;
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
Result := '';
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
I := GetPropList(AObject.ClassInfo, [tkClass], nil);
|
||
|
|
GetMem(APropList, I * SizeOf(PPropInfo));
|
||
|
|
GetPropList(AObject.ClassInfo, [tkClass], APropList);
|
||
|
|
{$ELSE}
|
||
|
|
APropList := GetPropList(AObject);
|
||
|
|
I := Length(APropList);
|
||
|
|
{$ENDIF}
|
||
|
|
try
|
||
|
|
for I := 0 to I - 1 do
|
||
|
|
if APropList[I].PropType{$IFNDEF CLR}^{$ENDIF} = ASubobject.ClassInfo then
|
||
|
|
begin
|
||
|
|
Result := APropList[I].Name;
|
||
|
|
Break;
|
||
|
|
end;
|
||
|
|
finally
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
FreeMem(APropList);
|
||
|
|
{$ENDIF}
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function GetValidName(AComponent: TComponent; const AName: string;
|
||
|
|
AIsBaseName: Boolean = False): string;
|
||
|
|
var
|
||
|
|
AOwner: TComponent;
|
||
|
|
I: Integer;
|
||
|
|
|
||
|
|
function GetNextName: string;
|
||
|
|
begin
|
||
|
|
Result := AName + IntToStr(I);
|
||
|
|
Inc(I);
|
||
|
|
end;
|
||
|
|
|
||
|
|
begin
|
||
|
|
Result := AName;
|
||
|
|
AOwner := AComponent.Owner;
|
||
|
|
if AOwner = nil then Exit;
|
||
|
|
I := 1;
|
||
|
|
if AIsBaseName then Result := GetNextName;
|
||
|
|
while AOwner.FindComponent(Result) <> nil do
|
||
|
|
Result := GetNextName;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function HexToByte(const AHex: string): Byte;
|
||
|
|
|
||
|
|
function CharToByte(C: Char): Byte;
|
||
|
|
begin
|
||
|
|
if C <= '9' then
|
||
|
|
Result := Ord(C) - Ord('0')
|
||
|
|
else
|
||
|
|
Result := 10 + Ord(Upcase(C)) - Ord('A');
|
||
|
|
end;
|
||
|
|
|
||
|
|
begin
|
||
|
|
Result := 16 * CharToByte(AHex[1]) + CharToByte(AHex[2]);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFNDEF VCL}
|
||
|
|
|
||
|
|
function MulDiv(Number, Numerator, Denominator: Integer): Integer;
|
||
|
|
begin
|
||
|
|
Result := Int64(Number) * Numerator div Denominator;
|
||
|
|
if Int64(Number) * Numerator mod Denominator >= Denominator div 2 then
|
||
|
|
Inc(Result);
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure SetRectEmpty(var R: TRect);
|
||
|
|
begin
|
||
|
|
R := Rect(0, 0, 0, 0);
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
procedure RenameComponents(ACaller, AOwner: TComponent;
|
||
|
|
ANewName, AOldName: TComponentName;
|
||
|
|
AComponentCount: Integer; AGetComponent: TcxGetComponent);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
AComponent: TComponent;
|
||
|
|
AComponentName, ANamePrefix: TComponentName;
|
||
|
|
begin
|
||
|
|
// Components introduced in an ancestor will be renamed by IDE.
|
||
|
|
// We cannot rename components introduced in a successor because
|
||
|
|
// IDE will not refresh source code in a successor.
|
||
|
|
if csAncestor in ACaller.ComponentState then Exit;
|
||
|
|
for I := 0 to AComponentCount - 1 do
|
||
|
|
begin
|
||
|
|
AComponent := AGetComponent(ACaller, I);
|
||
|
|
if (AComponent.Owner = AOwner) {and not (csAncestor in AComponent.ComponentState)} then
|
||
|
|
begin
|
||
|
|
AComponentName := AComponent.Name;
|
||
|
|
if Length(AComponentName) > Length(AOldName) then
|
||
|
|
begin
|
||
|
|
ANamePrefix := Copy(AComponentName, 1, Length(AOldName));
|
||
|
|
if CompareText(AOldName, ANamePrefix) = 0 then
|
||
|
|
begin
|
||
|
|
Delete(AComponentName, 1, Length(AOldName));
|
||
|
|
Insert(ANewName, AComponentName, 1);
|
||
|
|
try
|
||
|
|
AComponent.Name := AComponentName;
|
||
|
|
except
|
||
|
|
on EComponentError do { Ignore rename errors };
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function RoundDiv(I1, I2: Integer): Integer;
|
||
|
|
begin
|
||
|
|
Result := I1 div I2 + Ord(I1 mod I2 <> 0);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function Size(cx, cy: Longint): TSize;
|
||
|
|
begin
|
||
|
|
Result.cx := cx;
|
||
|
|
Result.cy := cy;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure SwapIntegers(var I1, I2: Integer);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
I := I1;
|
||
|
|
I1 := I2;
|
||
|
|
I2 := I;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function GetRangeCenter(ABound1, ABound2: Integer): Integer;
|
||
|
|
begin
|
||
|
|
if ABound1 + ABound2 > 0 then
|
||
|
|
Result := (ABound1 + ABound2) div 2
|
||
|
|
else
|
||
|
|
Result := (ABound1 + ABound2 - 1) div 2;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function StreamsEqual(AStream1, AStream2: TMemoryStream): Boolean;
|
||
|
|
begin
|
||
|
|
Result := (AStream1.Size = AStream2.Size) and
|
||
|
|
{$IFDEF CLR}
|
||
|
|
(StringOf(AStream1.Memory) = StringOf(AStream2.Memory));
|
||
|
|
{$ELSE}
|
||
|
|
CompareMem(AStream1.Memory, AStream2.Memory, AStream1.Size);
|
||
|
|
{$ENDIF}
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure OpenWebPage(const AWebAddress: string);
|
||
|
|
begin
|
||
|
|
{$IFDEF MSWINDOWS}
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
ShellExecute(0, 'OPEN', PChar(string(AWebAddress)), nil, nil, SW_SHOWMAXIMIZED);
|
||
|
|
{$ELSE}
|
||
|
|
ShellExecute(0, 'OPEN', string(AWebAddress), '', '', SW_SHOWMAXIMIZED);
|
||
|
|
{$ENDIF}
|
||
|
|
{$ELSE}
|
||
|
|
Libc.system(PChar(string(PreferredBrowser + ' ' + AWebAddress + '&'))); { TODO : make call to default browser }
|
||
|
|
{$ENDIF}
|
||
|
|
end;
|
||
|
|
|
||
|
|
function GetCorrectPath(const S: string): string;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
Result := S;
|
||
|
|
for I := 1 to Length(Result) do
|
||
|
|
if Result[I] = {$IFDEF MSWINDOWS}'/'{$ELSE}'\'{$ENDIF} then
|
||
|
|
Result[I] := {$IFDEF DELPHI6}PathDelim{$ELSE}'\'{$ENDIF};
|
||
|
|
end;
|
||
|
|
|
||
|
|
var
|
||
|
|
FResOriginalStrings: TStringList;
|
||
|
|
FResStrings: TStringList;
|
||
|
|
|
||
|
|
procedure CreateResStringLists;
|
||
|
|
begin
|
||
|
|
if FResOriginalStrings = nil then
|
||
|
|
begin
|
||
|
|
FResOriginalStrings := TStringList.Create;
|
||
|
|
{$IFDEF DELPHI6}
|
||
|
|
FResOriginalStrings.CaseSensitive := True;
|
||
|
|
{$ENDIF}
|
||
|
|
end;
|
||
|
|
if FResStrings = nil then
|
||
|
|
FResStrings := TStringList.Create;
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure DestroyResStringLists;
|
||
|
|
begin
|
||
|
|
FreeAndNil(FResOriginalStrings);
|
||
|
|
FreeAndNil(FResStrings);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function cxGetResourceStringNet(const ResString: string): string;
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
Result := ResString;
|
||
|
|
if FResOriginalStrings <> nil then
|
||
|
|
begin
|
||
|
|
AIndex := FResOriginalStrings.IndexOf(ResString);
|
||
|
|
if AIndex <> -1 then
|
||
|
|
Result := FResStrings[AIndex];
|
||
|
|
end
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFDEF DELPHI6}
|
||
|
|
function cxGetResourceString(const ResString: string): string;
|
||
|
|
begin
|
||
|
|
Result := cxGetResourceStringNet(ResString);
|
||
|
|
end;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
procedure cxSetResourceStringNet(const ResString: string; const Value: string);
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
CreateResStringLists;
|
||
|
|
AIndex := FResOriginalStrings.IndexOf(ResString);
|
||
|
|
if AIndex <> -1 then
|
||
|
|
FResStrings[AIndex] := Value
|
||
|
|
else
|
||
|
|
begin
|
||
|
|
FResOriginalStrings.Add(ResString);
|
||
|
|
FResStrings.Add(Value);
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFNDEF CLR}
|
||
|
|
|
||
|
|
function cxGetResourceString(const ResString: Pointer): string;
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
if FResOriginalStrings <> nil then
|
||
|
|
begin
|
||
|
|
AIndex := FResOriginalStrings.IndexOfObject(TObject(ResString));
|
||
|
|
if AIndex <> -1 then
|
||
|
|
Result := FResStrings[AIndex]
|
||
|
|
else
|
||
|
|
Result := LoadResString(PResStringRec(ResString));
|
||
|
|
end
|
||
|
|
else
|
||
|
|
Result := LoadResString(PResStringRec(ResString));
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure cxSetResourceString(const ResString: Pointer; const Value: string);
|
||
|
|
var
|
||
|
|
AIndex: Integer;
|
||
|
|
begin
|
||
|
|
CreateResStringLists;
|
||
|
|
AIndex := FResOriginalStrings.IndexOfObject(TObject(ResString));
|
||
|
|
if AIndex <> -1 then
|
||
|
|
FResStrings[AIndex] := Value
|
||
|
|
else
|
||
|
|
begin
|
||
|
|
FResOriginalStrings.AddObject(LoadResString(PResStringRec(ResString)), TObject(ResString));
|
||
|
|
FResStrings.Add(Value);
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
function CreateUniqueName(AOwnerForm, AOwnerComponent, AComponent: TComponent;
|
||
|
|
const APrefixName, ASuffixName: string): string;
|
||
|
|
var
|
||
|
|
I, J: Integer;
|
||
|
|
|
||
|
|
function GenerateName(AOwnerComponent: TComponent;
|
||
|
|
const AClassName, APrefixName, ASuffixName: string; ANumber: Integer): string;
|
||
|
|
var
|
||
|
|
S: string;
|
||
|
|
|
||
|
|
procedure CheckName(var AName: string);
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
I := 1;
|
||
|
|
while I <= Length(AName) do
|
||
|
|
if AName[I] in ['A'..'Z','a'..'z','_','0'..'9'] then
|
||
|
|
Inc(I)
|
||
|
|
else
|
||
|
|
if AName[I] in LeadBytes then
|
||
|
|
Delete(AName, I, 2)
|
||
|
|
else
|
||
|
|
Delete(AName, I, 1);
|
||
|
|
end;
|
||
|
|
|
||
|
|
begin
|
||
|
|
S := ASuffixName;
|
||
|
|
CheckName(S);
|
||
|
|
if ((S = '') or (S[1] in ['0'..'9'])) and (AClassName <> '') then
|
||
|
|
if (APrefixName <> '') and
|
||
|
|
(CompareText(APrefixName, Copy(AClassName, 1, Length(APrefixName))) = 0) then
|
||
|
|
S := Copy(AClassName, Length(APrefixName) + 1, Length(AClassName)) + S
|
||
|
|
else
|
||
|
|
begin
|
||
|
|
S := AClassName + S;
|
||
|
|
if S[1] = 'T' then Delete(S, 1, 1);
|
||
|
|
end;
|
||
|
|
if AOwnerComponent <> nil then
|
||
|
|
Result := AOwnerComponent.Name + S
|
||
|
|
else
|
||
|
|
Result := S;
|
||
|
|
if ANumber > 0 then
|
||
|
|
Result := Result + IntToStr(ANumber);
|
||
|
|
end;
|
||
|
|
|
||
|
|
function IsUnique(const AName: string): Boolean;
|
||
|
|
var
|
||
|
|
I: Integer;
|
||
|
|
begin
|
||
|
|
Result := True;
|
||
|
|
with AOwnerForm do
|
||
|
|
for I := 0 to ComponentCount - 1 do
|
||
|
|
if (Components[I] <> AComponent) and
|
||
|
|
(CompareText(Components[I].Name, AName) = 0) then
|
||
|
|
begin
|
||
|
|
Result := False;
|
||
|
|
Break;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
begin
|
||
|
|
if ASuffixName <> '' then
|
||
|
|
J := 0
|
||
|
|
else
|
||
|
|
J := 1;
|
||
|
|
for I := J to MaxInt do
|
||
|
|
begin
|
||
|
|
Result := GenerateName(AOwnerComponent, AComponent.ClassName,
|
||
|
|
APrefixName, ASuffixName, I);
|
||
|
|
if IsUnique(Result) then
|
||
|
|
Break;
|
||
|
|
end;
|
||
|
|
end;
|
||
|
|
|
||
|
|
function ReadFromMemory(P: Pointer; AOffset: Integer): Byte;
|
||
|
|
begin
|
||
|
|
{$IFDEF CLR}
|
||
|
|
Result := Marshal.ReadByte(P, AOffset);
|
||
|
|
{$ELSE}
|
||
|
|
Result := PByteArray(P)^[AOffset];
|
||
|
|
{$ENDIF}
|
||
|
|
end;
|
||
|
|
|
||
|
|
procedure WriteToMemory(P: Pointer; AOffset: Integer; AValue: Byte);
|
||
|
|
begin
|
||
|
|
{$IFDEF CLR}
|
||
|
|
Marshal.WriteByte(P, AOffset, AValue);
|
||
|
|
{$ELSE}
|
||
|
|
PByteArray(P)^[AOffset] := AValue;
|
||
|
|
{$ENDIF}
|
||
|
|
end;
|
||
|
|
|
||
|
|
{$IFDEF CLR}
|
||
|
|
function IsPropertyUnique(AInstance: TObject;
|
||
|
|
const APropertyName: string): Boolean;
|
||
|
|
var
|
||
|
|
APropList: TPropList;
|
||
|
|
ACount, I: Integer;
|
||
|
|
begin
|
||
|
|
APropList := GetPropList(TTypeInfo(AInstance.ClassInfo),
|
||
|
|
[tkUnknown..tkDynArray]);
|
||
|
|
ACount := 0;
|
||
|
|
for I := 0 to Length(APropList) - 1 do
|
||
|
|
if APropList[I].Name = APropertyName then
|
||
|
|
Inc(ACount);
|
||
|
|
Result := ACount = 1;
|
||
|
|
end;
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
initialization
|
||
|
|
{$IFDEF DELPHI6}
|
||
|
|
StartClassGroup(TControl);
|
||
|
|
GroupDescendentsWith(TcxComponent, TControl);
|
||
|
|
{$ENDIF}
|
||
|
|
|
||
|
|
finalization
|
||
|
|
DestroyResStringLists;
|
||
|
|
|
||
|
|
end.
|
||
|
|
|