📄 designeditors.~pas
字号:
if (AInterface <> nil) and
Supports(AInterface, IInterfaceComponentReference, ICR) then
Result := ICR.GetComponent
else
Result := nil;
end;
function TInterfaceProperty.GetComponentReference: TComponent;
begin
Result := GetComponent(GetIntfValue);
end;
function TInterfaceProperty.GetSelections: IDesignerSelections;
var
I: Integer;
begin
Result := nil;
if (GetIntfValue <> nil) and AllEqual then
begin
Result := TDesignerSelections.Create;
for I := 0 to PropCount - 1 do
Result.Add(GetComponent(GetIntfValueAt(I)));
end;
end;
procedure TInterfaceProperty.ReceiveComponentNames(const S: string);
var
Temp: TComponent;
Intf: IInterface;
begin
Temp := Designer.GetComponent(S);
if Assigned(FGetValuesStrProc) and
Assigned(Temp) and
Supports(TObject(Temp), GetTypeData(GetPropType)^.Guid, Intf) then
FGetValuesStrProc(S);
end;
procedure TInterfaceProperty.GetValues(Proc: TGetStrProc);
begin
FGetValuesStrProc := Proc;
try
Designer.GetComponentNames(GetTypeData(TypeInfo(TComponent)), ReceiveComponentNames);
finally
FGetValuesStrProc := nil;
end;
end;
procedure TInterfaceProperty.SetValue(const Value: string);
var
Intf: IInterface;
Component: TComponent;
begin
if Value = '' then
Intf := nil
else
begin
Component := Designer.GetComponent(Value);
if (Component = nil) or
not Supports(TObject(Component), GetTypeData(GetPropType)^.Guid, Intf) then
raise EPropertyError.CreateRes(@SInvalidPropertyValue);
end;
SetIntfValue(Intf);
end;
{ TMethodProperty }
function TMethodProperty.AllEqual: Boolean;
var
I: Integer;
V, T: TMethod;
begin
Result := False;
if PropCount > 1 then
begin
V := GetMethodValue;
for I := 1 to PropCount - 1 do
begin
T := GetMethodValueAt(I);
if (T.Code <> V.Code) or (T.Data <> V.Data) then Exit;
end;
end;
Result := True;
end;
function TMethodProperty.AllNamed: Boolean;
var
I: Integer;
begin
Result := True;
for I := 0 to PropCount - 1 do
if GetComponent(I).GetNamePath = '' then
begin
Result := False;
Break;
end;
end;
procedure TMethodProperty.Edit;
var
FormMethodName: string;
begin
if not AllNamed then
raise EPropertyError.CreateRes(@SCannotCreateName);
FormMethodName := GetValue;
if (FormMethodName = '') or
Designer.MethodFromAncestor(GetMethodValue) then
begin
if FormMethodName = '' then
FormMethodName := GetFormMethodName;
if FormMethodName = '' then
raise EPropertyError.CreateRes(@SCannotCreateName);
SetValue(FormMethodName);
end;
Designer.ShowMethod(FormMethodName);
end;
function TMethodProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paValueList, paSortList, paRevertable];
end;
function TMethodProperty.GetEditLimit: Integer;
begin
Result := MaxIdentLength;
end;
function TMethodProperty.GetFormMethodName: string;
var
I: Integer;
begin
if GetComponent(0) = Designer.GetRoot then
begin
Result := Designer.GetRootClassName;
if (Result <> '') and (Result[1] = 'T') then
Delete(Result, 1, 1);
end
else
begin
Result := Designer.GetObjectName(GetComponent(0));
for I := Length(Result) downto 1 do
if Result[I] in ['.', '[', ']', '-', '>'] then
Delete(Result, I, 1);
end;
if Result = '' then
raise EPropertyError.CreateRes(@SCannotCreateName);
Result := Result + GetTrimmedEventName;
end;
function TMethodProperty.GetTrimmedEventName: string;
begin
Result := GetName;
if (Length(Result) >= 2) and
(Result[1] in ['O', 'o']) and (Result[2] in ['N', 'n']) then
Delete(Result,1,2);
end;
function TMethodProperty.GetValue: string;
begin
Result := Designer.GetMethodName(GetMethodValue);
end;
procedure TMethodProperty.GetValues(Proc: TGetStrProc);
begin
Designer.GetMethods(GetTypeData(GetPropType), Proc);
end;
procedure TMethodProperty.SetValue(const AValue: string);
procedure CheckChainCall(const MethodName: string; Method: TMethod);
var
Persistent: TPersistent;
Component: TComponent;
InstanceMethod: string;
Instance: TComponent;
begin
Persistent := GetComponent(0);
if Persistent is TComponent then
begin
Component := TComponent(Persistent);
if (Component.Name <> '') and (Method.Data <> Designer.GetRoot) and
(TObject(Method.Data) is TComponent) then
begin
Instance := TComponent(Method.Data);
InstanceMethod := Instance.MethodName(Method.Code);
if InstanceMethod <> '' then
Designer.ChainCall(MethodName, Instance.Name, InstanceMethod,
GetTypeData(GetPropType));
end;
end;
end;
var
NewMethod: Boolean;
CurValue: string;
OldMethod: TMethod;
begin
if not AllNamed then
raise EPropertyError.CreateRes(@SCannotCreateName);
CurValue:= GetValue;
if (CurValue <> '') and (AValue <> '') and (SameText(CurValue, AValue) or
not Designer.MethodExists(AValue)) and not Designer.MethodFromAncestor(GetMethodValue) then
Designer.RenameMethod(CurValue, AValue)
else
begin
NewMethod := (AValue <> '') and not Designer.MethodExists(AValue);
OldMethod := GetMethodValue;
SetMethodValue(Designer.CreateMethod(AValue, GetTypeData(GetPropType)));
if NewMethod then
begin
if (PropCount = 1) and (OldMethod.Data <> nil) and (OldMethod.Code <> nil) then
CheckChainCall(AValue, OldMethod);
Designer.ShowMethod(AValue);
end;
end;
end;
{ TDateProperty }
function TDateProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paRevertable];
end;
function TDateProperty.GetValue: string;
var
DT: TDateTime;
begin
DT := GetFloatValue;
if DT = 0.0 then Result := '' else
Result := DateToStr(DT);
end;
procedure TDateProperty.SetValue(const Value: string);
var
DT: TDateTime;
begin
if Value = '' then DT := 0.0
else DT := StrToDate(Value);
SetFloatValue(DT);
end;
{ TTimeProperty }
function TTimeProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paRevertable];
end;
function TTimeProperty.GetValue: string;
var
DT: TDateTime;
begin
DT := GetFloatValue;
if DT = 0.0 then Result := '' else
Result := TimeToStr(DT);
end;
procedure TTimeProperty.SetValue(const Value: string);
var
DT: TDateTime;
begin
if Value = '' then DT := 0.0
else DT := StrToTime(Value);
SetFloatValue(DT);
end;
{ TDateTimeProperty }
function TDateTimeProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paRevertable];
end;
function TDateTimeProperty.GetValue: string;
var
DT: TDateTime;
begin
DT := GetFloatValue;
if DT = 0.0 then Result := '' else
Result := DateTimeToStr(DT);
end;
procedure TDateTimeProperty.SetValue(const Value: string);
var
DT: TDateTime;
begin
if Value = '' then DT := 0.0
else DT := StrToDateTime(Value);
SetFloatValue(DT);
end;
{ TPropInfoList }
type
TPropInfoList = class
private
FList: PPropList;
FCount: Integer;
FSize: Integer;
function Get(Index: Integer): PPropInfo;
public
constructor Create(Instance: TPersistent; Filter: TTypeKinds);
destructor Destroy; override;
function Contains(P: PPropInfo): Boolean;
procedure Delete(Index: Integer);
procedure Intersect(List: TPropInfoList);
property Count: Integer read FCount;
property Items[Index: Integer]: PPropInfo read Get; default;
end;
constructor TPropInfoList.Create(Instance: TPersistent; Filter: TTypeKinds);
begin
FCount := GetPropList(Instance.ClassInfo, Filter, nil);
FSize := FCount * SizeOf(Pointer);
GetMem(FList, FSize);
GetPropList(Instance.ClassInfo, Filter, FList);
end;
destructor TPropInfoList.Destroy;
begin
if FList <> nil then FreeMem(FList, FSize);
end;
function TPropInfoList.Contains(P: PPropInfo): Boolean;
var
I: Integer;
begin
for I := 0 to FCount - 1 do
with FList^[I]^ do
if (PropType^ = P^.PropType^) and (CompareText(Name, P^.Name) = 0) then
begin
Result := True;
Exit;
end;
Result := False;
end;
procedure TPropInfoList.Delete(Index: Integer);
begin
Dec(FCount);
if Index < FCount then
Move(FList^[Index + 1], FList^[Index],
(FCount - Index) * SizeOf(Pointer));
end;
function TPropInfoList.Get(Index: Integer): PPropInfo;
begin
Result := FList^[Index];
end;
procedure TPropInfoList.Intersect(List: TPropInfoList);
var
I: Integer;
begin
for I := FCount - 1 downto 0 do
if not List.Contains(FList^[I]) then Delete(I);
end;
function InterfaceInheritsFrom(Child, Parent: PTypeData): Boolean;
begin
while (Child <> nil) and (Child <> Parent) and (Child^.IntfParent <> nil) do
Child := GetTypeData(Child^.IntfParent^);
Result := (Child <> nil) and (Child = Parent);
end;
{ Property Editor registration }
type
PPropertyClassRec = ^TPropertyClassRec;
TPropertyClassRec = record
Group: Integer;
PropertyType: PTypeInfo;
PropertyName: string;
ComponentClass: TClass;
ClassGroup: TPersistentClass;
EditorClass: TPropertyEditorClass;
end;
PPropertyMapperRec = ^TPropertyMapperRec;
TPropertyMapperRec = record
Group: Integer;
Mapper: TPropertyMapperFunc;
end;
const
PropClassMap: array[TypInfo.TTypeKind] of TPropertyEditorClass = (
nil, // tkUnknown
TIntegerProperty, // tkInteger
TCharProperty, // tkChar
TEnumProperty, // tkEnumeration
TFloatProperty, // tkFloat
TStringProperty, // tkString
TSetProperty, // tkSet
TClassProperty, // tkClass
TMethodProperty, // tkMethod
TPropertyEditor, // tkWChar
TStringProperty, // tkLString
TStringProperty, // tkWString
TVariantProperty, // tkVariant
nil, // tkArray
nil, // tkRecord
TInterfaceProperty, // tkInterface
TInt64Property, // tkInt64
nil); // tkDynArray
var
PropertyClassList: TList;
PropertyMapperList: TList = nil;
procedure RegisterPropertyEditor(PropertyType: PTypeInfo; ComponentClass: TClass;
const PropertyName: string; EditorClass: TPropertyEditorClass);
var
P: PPropertyClassRec;
begin
if PropertyClassList = nil then
PropertyClassList := TList.Create;
New(P);
P.Group := CurrentGroup;
P.PropertyType := PropertyType;
P.ComponentClass := ComponentClass;
P.PropertyName := '';
P.ClassGroup := nil;
if Assigned(ComponentClass) then P^.PropertyName := PropertyName;
P.EditorClass := EditorClass;
PropertyClassList.Insert(0, P);
end;
procedure SetPropertyEditorGroup(EditorClass: TPropertyEditorClass;
GroupClass: TPersistentClass);
var
P: PPropertyClassRec;
I: Integer;
begin
for I := 0 to PropertyClassList.Count - 1 do
begin
P := PropertyClassList[I];
if P^.EditorClass = EditorClass then
begin
P^.ClassGroup := ClassGroupOf(GroupClass);
Exit;
end;
end;
// Ignore it if the EditorClass is not found.
end;
function GetEditorClass(PropInfo: PPropInfo;
Obj: TPersistent): TPropertyEditorClass;
var
PropType: PTypeInfo;
P, C: PPropertyClassRec;
I: Integer;
begin
if PropertyMapperList <> nil then
begin
for I := 0 to PropertyMapperList.Count -1 do
with PPropertyMapperRec(PropertyMapperList[I])^ do
begin
Result := Mapper(Obj, PropInfo);
if Result <> nil then Exit;
end;
end;
PropType := PropInfo^.PropType^;
I := 0;
C := nil;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -