📄 cxoi.pas
字号:
function IsDefaultValue: Boolean;
var
AncestorIntf: IInterface;
ASR: IInterfaceComponentReference;
begin
Result := Intf = nil;
if AncestorValid then
begin
AncestorIntf := GetInterfaceProp(Ancestor, PropInfo);
Result := Intf = AncestorIntf;
if not Result then
begin
if Supports(AncestorIntf, IInterfaceComponentReference, ASR) then
Result := ObjectAncestorMatch(ASR.GetComponent, Value);
end;
end;
end;
var
SR: IInterfaceComponentReference;
begin
Result := True;
Intf := GetInterfaceProp(Instance, PropInfo);
if (Intf = nil) or (not Supports(Intf, IInterfaceComponentReference, SR)) then
begin
if AncestorValid and (GetInterfaceProp(Ancestor, PropInfo) <> nil) then
Result := False;
end
else
begin
Value := SR.GetComponent;
if not IsDefaultValue then
begin
// We can only stream out components (ie: non-default ones)
// if they actually have a name
if Value.Name <> '' then
Result := False;
end;
end;
end;
function IsDefaultMethodProp: Boolean;
var
Value: TMethod;
DefaultCode: Pointer;
begin
Value := GetMethodProp(Instance, PropInfo);
DefaultCode := nil;
if AncestorValid then
DefaultCode := GetMethodProp(Ancestor, PropInfo).Code;
Result := (Value.Code = DefaultCode) or
((Value.Code <> nil) and (LookupRoot.MethodName(Value.Code) = ''));
end;
function IsDefaultVariantProp: Boolean;
var
Value: Variant;
begin
Value := GetVariantProp(Instance, PropInfo);
if AncestorValid then
Result := VarSameValue(Value, GetVariantProp(Ancestor, PropInfo))
else
Result := VarIsClear(Value);
end;
begin
Ancestor := nil;
Root := nil;
LookupRoot := nil;
RootAncestor := nil;
if Assigned(OnGetLookupInfo) then
OnGetLookupInfo(Ancestor, Root, LookupRoot, RootAncestor);
AncestorValid := AncestorIsValid(Ancestor, Root, RootAncestor);
Result := True;
if (PropInfo^.GetProc <> nil) and
((PropInfo^.SetProc <> nil) {$IFDEF DELPHI6} or
((PropInfo^.PropType^.Kind = tkClass) and
(TObject(GetOrdProp(Instance, PropInfo)) is TComponent) and
(csSubComponent in TComponent(GetOrdProp(Instance, PropInfo)).ComponentStyle)) {$ENDIF}) then
begin
PropType := PropInfo^.PropType^;
case PropType^.Kind of
tkInteger, tkChar, tkEnumeration, tkSet:
Result := IsDefaultOrdProp;
tkFloat:
Result := IsDefaultFloatProp;
tkString, tkLString, tkWString:
Result := IsDefaultStrProp;
tkClass:
Result := IsDefaultObjectProp;
tkMethod:
Result := IsDefaultMethodProp;
tkVariant:
Result := IsDefaultVariantProp;
tkInt64:
Result := IsDefaultInt64Prop;
tkInterface:
Result := IsDefaultInterfaceProp;
end;
end;
end;
{$ENDIF}
function TcxPropertyEditor.IsDefaultValue: Boolean;
function CheckProperties(AnObject: TObject): Boolean;
var
PropList: PPropList;
PropInfo: PPropInfo;
I, Count: Integer;
begin
Result := True;
// Go through each of the properties on the object
Count := GetTypeData(AnObject.ClassInfo)^.PropCount;
if Count > 0 then
begin
GetMem(PropList, Count * SizeOf(Pointer));
try
GetPropInfos(AnObject.ClassInfo, PropList);
for I := 0 to Count - 1 do
begin
PropInfo := PropList^[I];
if PropInfo = nil then
Break;
if not IsDefaultPropertyValue(AnObject, PropInfo, GetLookupInfo) then
begin
Result := False;
Break;
end;
end;
finally
FreeMem(PropList, Count * SizeOf(Pointer));
end;
end;
end;
var
FirstInstance: TObject;
FirstPropInfo: PPropInfo;
SubObject: TObject;
OldAncestor: TPersistent;
begin
Result := True;
if PropCount > 0 then
begin
// if they are not all equal, then they aren't all the default (at least one..)
if not AllEqual then
begin
Result := False;
Exit;
end;
FirstInstance := FPropList^[0].Instance;
FirstPropInfo := FPropList^[0].PropInfo;
if IsStoredProp(FirstInstance, FirstPropInfo) then
begin
// TWriter.WriteDescendent simulation
FRootAncestor := nil;
FAncestor := nil;
FRoot := FindRoot;
if FirstInstance is TComponent then
begin
FLookingFor := TComponent(FirstInstance);
// Only lookup the component if it was introduced in an ancestor form/frame
if csAncestor in FLookingFor.ComponentState then
begin
FDoneLooking := False;
WriteComponentSimulation(FRoot);
end
else
begin
FRootAncestor := nil;
FAncestor := nil;
end;
end
else
begin
// In this case, we will not look up the ancestor (there really
// isn't one - take columns on tlistview as an example)
FRootAncestor := nil;
FAncestor := nil;
end;
Result := IsDefaultPropertyValue(FirstInstance, FirstPropInfo, GetLookupInfo);
if not Result then
begin
if FirstPropInfo^.PropType^.Kind = tkClass then
begin
// If it was a class/object then we need to recursivly check that
// object to see if it has all default properties.
SubObject := GetObjectProp(FirstInstance, FirstPropInfo);
OldAncestor := FAncestor;
try
if AncestorIsValid(FAncestor, FRoot, FRootAncestor) then
FAncestor := TPersistent(GetOrdProp(FAncestor, FirstPropInfo));
Result := CheckProperties(SubObject);
finally
FAncestor := OldAncestor;
end;
if SubObject is TCollection then
begin
if not AncestorIsValid(FAncestor, FRoot, FRootAncestor) or
not CollectionsEqual(TCollection(SubObject),
TCollection(GetOrdProp(FAncestor, FirstPropInfo))
{$IFDEF DELPHI6}, FRoot, FRootAncestor{$ENDIF}) then
Result := False;
end;
end;
end;
end;
end;
end;
function TcxPropertyEditor.ValueAvailable: Boolean;
var
I: Integer;
S: string;
begin
Result := True;
for I := 0 to FPropCount - 1 do
if (FPropList^[I].Instance is TComponent) and
(csCheckPropAvail in TComponent(FPropList^[I].Instance).ComponentStyle) then
begin
try
S := GetValue;
AllEqual;
except
Result := False;
end;
Exit;
end;
end;
procedure TcxPropertyEditor.AddAncestor(Component: TComponent);
begin
FAncestorList.Add(Component);
end;
procedure TcxPropertyEditor.GetLookupInfo(var Ancestor: TPersistent;
var Root, LookupRoot, RootAncestor: TComponent);
begin
Ancestor := FAncestor;
Root := FRoot;
LookupRoot := FRoot; // Same in this case
RootAncestor := FRootAncestor;
end;
procedure TcxPropertyEditor.SetPropEntry(Index: Integer;
AInstance: TPersistent; APropInfo: PPropInfo);
begin
with FPropList^[Index] do
begin
Instance := AInstance;
PropInfo := APropInfo;
end;
end;
type
TComponentHack = class(TComponent);
procedure TcxPropertyEditor.WriteComponentSimulation(Component: TComponent);
function FindAncestor(const Name: string): TComponent;
var
I: Integer;
begin
for I := 0 to FAncestorList.Count - 1 do
begin
Result := FAncestorList[I];
if SameText(Result.Name, Name) then Exit;
end;
Result := nil;
end;
var
OldAncestor: TPersistent;
OldRoot, OldRootAncestor: TComponent;
OldAncestorList: TList;
TempAncestor: TPersistent;
begin
if FDoneLooking then
Exit;
OldAncestor := FAncestor;
OldRootAncestor := FRootAncestor;
try
if Assigned(FAncestorList) then
FAncestor := FindAncestor(Component.Name);
// If we are at the component we were looking for, then we
// can stop at this point
if FLookingFor = Component then
FDoneLooking := True
else if SameText(FLookingFor.Name, Component.Name) then
FDoneLooking := True
else
begin
if (FAncestor = nil) and (Component <> FRoot) then
begin
TempAncestor := FRoot;
if TempAncestor <> nil then
begin
FAncestor := TempAncestor;
FRootAncestor := TComponent(FAncestor);
end;
end;
// Component.WriteState(Self); // This is simulated below, inline
OldAncestorList := FAncestorList;
OldRoot := FRoot;
OldRootAncestor := FRootAncestor;
try
FAncestorList := nil;
try
if (FAncestor <> nil) and (FAncestor is TComponent) then
begin
{$IFDEF DELPHI5}
if csInline in TComponent(FAncestor).ComponentState then
FRootAncestor := TComponent(FAncestor);
{$ENDIF}
FAncestorList := TList.Create;
TComponentHack(FAncestor).GetChildren(AddAncestor, FRootAncestor);
end;
{$IFDEF DELPHI5}
if csInline in Component.ComponentState then
FRoot := Component;
{$ENDIF}
TComponentHack(Component).GetChildren(WriteComponentSimulation, FRoot);
finally
FAncestorList.Free;
end;
finally
FAncestorList := OldAncestorList;
if not FDoneLooking then
begin
FRoot := OldRoot;
FRootAncestor := OldRootAncestor;
end;
end;
end;
finally
if not FDoneLooking then
begin
// Only restore the ancestor if we were not done looking.
// This way, we can continue up the chaing looking for the
// component
FAncestor := OldAncestor;
FRootAncestor := OldRootAncestor;
end
end;
end;
{ TcxOrdinalProperty }
function TcxOrdinalProperty.AllEqual: Boolean;
var
I: Integer;
V: Longint;
begin
Result := False;
if PropCount > 1 then
begin
V := GetOrdValue;
for I := 1 to PropCount - 1 do
if GetOrdValueAt(I) <> V then Exit;
end;
Result := True;
end;
function TcxOrdinalProperty.GetEditLimit: Integer;
begin
Result := 63;
end;
{ TcxIntegerProperty }
function TcxIntegerProperty.GetValue: string;
begin
Result := IntToStr(GetOrdValue);
end;
procedure TcxIntegerProperty.SetValue(const Value: string);
procedure Error(const Args: array of const);
begin
raise EcxPropertyError.CreateFmt(SOutOfRange, Args);
end;
var
L: Int64;
begin
L := StrToInt64(Value);
with GetTypeData(GetPropType)^ do
{$IFDEF DELPHI5}
if OrdType = otULong then
begin
if (L < Cardinal(MinValue)) or (L > Cardinal(MaxValue)) then
Error([Int64(Cardinal(MinValue)), Int64(Cardinal(MaxValue))]);
end
else
{$ENDIF}if (L < MinValue) or (L > MaxValue) then
Error([MinValue, MaxValue]);
SetOrdValue(L);
end;
{ TCharProperty }
function TcxCharProperty.GetValue: string;
var
Ch: Char;
begin
Ch := Chr(GetOrdValue);
if Ch in [#33..#127] then
Result := Ch
else
FmtStr(Result, '#%d', [Ord(Ch)]);
end;
procedure TcxCharProperty.SetValue(const Value: string);
var
L: Longint;
begin
if Length(Value) = 0 then
L := 0
else
if Length(Value) = 1 then
L := Ord(Value[1])
else
if Value[1] = '#' then
L := StrToInt(Copy(Value, 2, Maxint))
else
raise EcxPropertyError.Create(SInvalidPropertyValue);
with GetTypeData(GetPropType)^ do
if (L < MinValue) or (L > MaxValue) then
raise EcxPropertyError.CreateFmt(SOutOfRange, [MinValue, MaxValue]);
SetOrdValue(L);
end;
{ TcxEnumProperty }
function TcxEnumProperty.GetAttributes: TcxPropertyAttributes;
begin
Result := [ipaMultiSelect, ipaValueList, ipaSortList, ipaRevertable];
end;
function TcxEnumProperty.GetValue: string;
var
L: Longint;
begin
L := GetOrdValue;
with GetTypeData(GetPropType)^ do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -