📄 designeditors.~pas
字号:
procedure ValidateComponent(Component: TComponent); virtual;
function ValidateComponentClass(ComponentClass: TComponentClass): Boolean; virtual;
function Nestable: Boolean; virtual;
property Root: TComponent read FRoot;
property Designer: IDesigner read FDesigner;
end;
{ ClassInheritsFrom
Returns true if ClassType, or one of its ancestors, name matches
ClassName. This allows checking ancestor by name instead of by class
reference. }
function ClassInheritsFrom(ClassType: TClass; const ClassName: string): Boolean;
{ AncestorNameMatches
Returns true if either ClassType descends from AncestorClass or doesn't
contain an ancestor class by the same name as AncestorClass. This ensures that
if ClassType has an ancestor by the same name it is AncestorClass. }
function AncestorNameMatches(ClassType: TClass; AncestorClass: TClass): Boolean;
{ Find the top level component (form, module, etc) }
type
TGetTopLevelComponentFunc = function(Ignoring: TComponent = nil): TComponent;
var
GetTopLevelComponentFunc: TGetTopLevelComponentFunc;
resourcestring
sClassNotApplicable = 'Class %s is not applicable to this module';
sNotAvailable = '(Not available)';
function PossibleStream(const S: string): Boolean;
{ Routines used by the form designer for package management }
type
TGroupChangeProc = procedure(AGroup: Integer);
IDesignGroupChange = interface
['{8B5614E7-A726-4622-B2A7-F79340B1B78E}']
procedure FreeEditorGroup(Group: Integer);
end;
function NewEditorGroup: Integer;
procedure FreeEditorGroup(Group: Integer);
procedure NotifyGroupChange(AProc: TGroupChangeProc);
procedure UnnotifyGroupChange(AProc: TGroupChangeProc);
var
GReferenceExpandable: Boolean = True;
GShowReadOnlyProps: Boolean = True;
implementation
uses DesignConst, Consts, RTLConsts, Contnrs, Proxies;
function PossibleStream(const S: string): Boolean;
var
I: Integer;
begin
Result := True;
for I := 1 to Length(S) - 6 do
begin
if (S[I] in ['O','o']) and (CompareText(Copy(S, I, 6), 'OBJECT') = 0) then Exit;
if not (S[I] in [' ',#9, #13, #10]) then Break;
end;
Result := False;
end;
{ TPropertyEditor }
constructor TPropertyEditor.Create(const ADesigner: IDesigner;
APropCount: Integer);
begin
inherited Create(ADesigner, APropCount);
FDesigner := ADesigner;
GetMem(FPropList, APropCount * SizeOf(TInstProp));
FPropCount := APropCount;
end;
destructor TPropertyEditor.Destroy;
begin
if FPropList <> nil then
FreeMem(FPropList, FPropCount * SizeOf(TInstProp));
end;
procedure TPropertyEditor.Activate;
begin
end;
function TPropertyEditor.AllEqual: Boolean;
begin
Result := FPropCount = 1;
end;
procedure TPropertyEditor.Edit;
type
TGetStrFunc = function(const Value: string): Integer of object;
var
I: Integer;
Values: TStringList;
AddValue: TGetStrFunc;
begin
if not AutoFill then Exit;
Values := TStringList.Create;
Values.Sorted := paSortList in GetAttributes;
try
AddValue := Values.Add;
GetValues(TGetStrProc(AddValue));
if Values.Count > 0 then
begin
I := Values.IndexOf(Value) + 1;
if I = Values.Count then I := 0;
Value := Values[I];
end;
finally
Values.Free;
end;
end;
function TPropertyEditor.AutoFill: Boolean;
begin
Result := Assigned(GetPropInfo^.SetProc);
end;
function TPropertyEditor.GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paRevertable];
end;
function TPropertyEditor.GetComponent(Index: Integer): TPersistent;
begin
Result := FPropList^[Index].Instance;
end;
function TPropertyEditor.GetFloatValue: Extended;
begin
Result := GetFloatValueAt(0);
end;
function TPropertyEditor.GetFloatValueAt(Index: Integer): Extended;
begin
with FPropList^[Index] do Result := GetFloatProp(Instance, PropInfo);
end;
function TPropertyEditor.GetMethodValue: TMethod;
begin
Result := GetMethodValueAt(0);
end;
function TPropertyEditor.GetMethodValueAt(Index: Integer): TMethod;
begin
with FPropList^[Index] do Result := GetMethodProp(Instance, PropInfo);
end;
function TPropertyEditor.GetEditLimit: Integer;
begin
Result := 255;
end;
function TPropertyEditor.GetName: string;
begin
Result := FPropList^[0].PropInfo^.Name;
end;
function TPropertyEditor.GetOrdValue: Longint;
begin
Result := GetOrdValueAt(0);
end;
function TPropertyEditor.GetOrdValueAt(Index: Integer): Longint;
begin
with FPropList^[Index] do Result := GetOrdProp(Instance, PropInfo);
end;
function TPropertyEditor.GetPrivateDirectory: string;
begin
Result := '';
if Designer <> nil then
Result := Designer.GetPrivateDirectory;
end;
procedure TPropertyEditor.GetProperties(Proc: TGetPropProc);
begin
end;
function TPropertyEditor.GetPropInfo: PPropInfo;
begin
Result := FPropList^[0].PropInfo;
end;
function TPropertyEditor.GetPropType: PTypeInfo;
begin
Result := FPropList^[0].PropInfo^.PropType^;
end;
function TPropertyEditor.GetStrValue: string;
begin
Result := GetStrValueAt(0);
end;
function TPropertyEditor.GetStrValueAt(Index: Integer): string;
begin
with FPropList^[Index] do Result := GetStrProp(Instance, PropInfo);
end;
function TPropertyEditor.GetVarValue: Variant;
begin
Result := GetVarValueAt(0);
end;
function TPropertyEditor.GetVarValueAt(Index: Integer): Variant;
begin
with FPropList^[Index] do Result := GetVariantProp(Instance, PropInfo);
end;
function TPropertyEditor.GetValue: string;
begin
Result := srUnknown;
end;
function TPropertyEditor.GetVisualValue: string;
begin
if AllEqual then
Result := GetValue
else
Result := '';
end;
procedure TPropertyEditor.GetValues(Proc: TGetStrProc);
begin
end;
procedure TPropertyEditor.Initialize;
begin
end;
procedure TPropertyEditor.Modified;
begin
if Designer <> nil then
Designer.Modified;
end;
procedure TPropertyEditor.SetFloatValue(Value: Extended);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetFloatProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.SetMethodValue(const Value: TMethod);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetMethodProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.SetOrdValue(Value: Longint);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetOrdProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.SetPropEntry(Index: Integer;
AInstance: TPersistent; APropInfo: PPropInfo);
begin
with FPropList^[Index] do
begin
Instance := AInstance;
PropInfo := APropInfo;
end;
end;
procedure TPropertyEditor.SetStrValue(const Value: string);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetStrProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.SetVarValue(const Value: Variant);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetVariantProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.Revert;
var
I: Integer;
begin
if Designer <> nil then
for I := 0 to FPropCount - 1 do
with FPropList^[I] do Designer.Revert(Instance, PropInfo);
end;
procedure TPropertyEditor.SetValue(const Value: string);
begin
end;
function TPropertyEditor.ValueAvailable: Boolean;
var
I: Integer;
S: string;
begin
Result := True;
for I := 0 to FPropCount - 1 do
begin
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;
end;
function TPropertyEditor.GetInt64Value: Int64;
begin
Result := GetInt64ValueAt(0);
end;
function TPropertyEditor.GetInt64ValueAt(Index: Integer): Int64;
begin
with FPropList^[Index] do Result := GetInt64Prop(Instance, PropInfo);
end;
procedure TPropertyEditor.SetInt64Value(Value: Int64);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetInt64Prop(Instance, PropInfo, Value);
Modified;
end;
function TPropertyEditor.GetIntfValue: IInterface;
begin
Result := GetIntfValueAt(0);
end;
function TPropertyEditor.GetIntfValueAt(Index: Integer): IInterface;
begin
with FPropList^[Index] do Result := GetInterfaceProp(Instance, PropInfo);
end;
procedure TPropertyEditor.SetIntfValue(const Value: IInterface);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetInterfaceProp(Instance, PropInfo, Value);
Modified;
end;
function TPropertyEditor.GetEditValue(out Value: string): Boolean;
begin
Result := False;
try
Value := GetValue;
Result := Assigned(GetPropInfo^.SetProc);
except
on E: EPropWriteOnly do Value := sNotAvailable;
on E: Exception do Value := Format('(%s)', [E.Message]);
end;
end;
function TPropertyEditor.HasInstance(Instance: TPersistent): Boolean;
var
I: Integer;
begin
Result := True;
for I := 0 to FPropCount - 1 do
if FPropList^[I].Instance = Instance then Exit;
Result := False;
end;
{ TOrdinalProperty }
function TOrdinalProperty.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 TOrdinalProperty.GetEditLimit: Integer;
begin
Result := 63;
end;
{ TIntegerProperty }
function TIntegerProperty.GetValue: string;
begin
with GetTypeData(GetPropType)^ do
if OrdType = otULong then // unsigned
Result := IntToStr(Cardinal(GetOrdValue))
else
Result := IntToStr(GetOrdValue);
end;
procedure TIntegerProperty.SetValue(const Value: String);
procedure Error(const Args: array of const);
begin
raise EPropertyError.CreateResFmt(@SOutOfRange, Args);
end;
var
L: Int64;
begin
L := StrToInt64(Value);
with GetTypeData(GetPropType)^ do
if OrdType = otULong then
begin // unsigned compare and reporting needed
if (L < Cardinal(MinValue)) or (L > Cardinal(MaxValue)) then
// bump up to Int64 to get past the %d in the format string
Error([Int64(Cardinal(MinValue)), Int64(Cardinal(MaxValue))]);
end
else if (L < MinValue) or (L > MaxValue) then
Error([MinValue, MaxValue]);
SetOrdValue(L);
end;
{ TCharProperty }
function TCharProperty.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 TCharProperty.SetValue(const Value: string);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -